@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
@@ -0,0 +1,1628 @@
1
+ /* The left column: rail, outline, resources, the rail's head and its groups, plus the MCP details Help and the Agent chip share. */
2
+
3
+ /* ---- left rail ---------------------------------------------------------- */
4
+ /* Docked under the top bar, down to the timeline, its seam on the right. A
5
+ flex column that never scrolls itself: fixed rows (the context head, the
6
+ search) over ONE scroller, `.rail-scroll`.
7
+ `clip`, not `hidden`, so a focused control cannot scroll the column. */
8
+ .left-rail {
9
+ grid-column: edge-l / rail-r;
10
+ grid-row: main-t / main-b;
11
+ display: flex;
12
+ flex-direction: column;
13
+ overflow: clip;
14
+ background: var(--surface-panel);
15
+ border-right: 1px solid var(--line);
16
+ }
17
+
18
+ /* The chain that bounds the scroller: without `min-height: 0` at every step
19
+ the panel grows to its rows, nothing scrolls, and the outline cannot
20
+ virtualise. */
21
+ .left-rail > .file-panel {
22
+ flex: 1 1 auto;
23
+ min-height: 0;
24
+ display: flex;
25
+ flex-direction: column;
26
+ }
27
+
28
+ /* A ZERO BASIS, not `auto`: an auto basis is the whole list's height, and the
29
+ shrink it forces is shared with the fixed rows above, so a long outline
30
+ squeezed the tabs off the bar line. */
31
+ .rail-scroll {
32
+ flex: 1 1 0;
33
+ min-height: 0;
34
+ overflow: auto;
35
+ scrollbar-gutter: stable;
36
+ padding-bottom: var(--space-4);
37
+ }
38
+
39
+ /* ---- a mode's left column ----------------------------------------------- */
40
+ /* A mode portals its own left column into this slot (cellSlots.tsx), and the
41
+ Files panel steps aside while it does: hidden, not unmounted, so the
42
+ outline's scroll and open rows survive the round trip. The slot is
43
+ the column's one flexible row, bounded like `.rail-scroll`, and the mode
44
+ brings its own head at `--panel-head-h`. */
45
+ .left-rail > .rail-mode {
46
+ display: none;
47
+ }
48
+
49
+ .shell.is-mode .left-rail > .rail-mode {
50
+ display: flex;
51
+ flex-direction: column;
52
+ flex: 1 1 0;
53
+ min-height: 0;
54
+ }
55
+
56
+ .shell.is-mode .left-rail > .file-panel {
57
+ display: none;
58
+ }
59
+
60
+ /* ---- the Assets tab ------------------------------------------------------ */
61
+
62
+ /* The right-aligned byte count on an Other files row. */
63
+ .asset-size {
64
+ flex: none;
65
+ margin-left: auto;
66
+ color: var(--ink-3);
67
+ font-size: var(--type-micro);
68
+ }
69
+
70
+ .resource-asset-row {
71
+ display: flex;
72
+ align-items: center;
73
+ gap: var(--space-3);
74
+ min-width: 0;
75
+ min-height: var(--row-h);
76
+ padding: 0 var(--space-4) 0 var(--space-6);
77
+ }
78
+
79
+ /* ---- the manual ---------------------------------------------------------- */
80
+ /* The dialog's content column, mirroring `.export-dialog`: that is the shape a
81
+ shared `Dialog`'s children take in this chrome. */
82
+ .help-manual {
83
+ display: flex;
84
+ flex-direction: column;
85
+ gap: var(--space-5);
86
+ min-width: 0;
87
+ }
88
+
89
+ .help-basics {
90
+ list-style: disc;
91
+ margin: var(--space-3) 0;
92
+ padding: 0 var(--space-2) 0 var(--space-7);
93
+ color: var(--ink-2);
94
+ font-size: var(--type-sm);
95
+ line-height: var(--leading-body);
96
+ }
97
+
98
+ .help-basics li + li {
99
+ margin-top: var(--space-2);
100
+ }
101
+
102
+ .help-rows {
103
+ list-style: none;
104
+ margin: 0 0 var(--space-2);
105
+ padding: 0 var(--space-2);
106
+ }
107
+
108
+ /* Fifty-six shortcut rows in four groups, as two balanced columns inside the
109
+ 560px dialog. `break-inside: avoid` on the groups is load-bearing: a column
110
+ break through a group would leave its heading at the foot of one column and
111
+ its rows at the head of the other, which reads as two different groups. */
112
+ .help-groups {
113
+ columns: 2;
114
+ column-gap: var(--space-8);
115
+ }
116
+
117
+ .help-groups > div {
118
+ break-inside: avoid;
119
+ }
120
+
121
+ .help-row {
122
+ display: flex;
123
+ align-items: baseline;
124
+ justify-content: space-between;
125
+ gap: var(--space-4);
126
+ padding: var(--space-1) 0;
127
+ color: var(--ink-2);
128
+ font-size: var(--type-sm);
129
+ }
130
+
131
+ .help-row kbd,
132
+ .help-note code {
133
+ font: inherit;
134
+ font-size: var(--type-micro);
135
+ color: var(--ink-1);
136
+ background: var(--fill-rest);
137
+ border-radius: var(--radius-xs);
138
+ padding: 1px var(--space-2);
139
+ white-space: nowrap;
140
+ }
141
+
142
+ .help-note {
143
+ margin: 0 0 var(--space-3);
144
+ padding: 0 var(--space-2);
145
+ color: var(--ink-3);
146
+ font-size: var(--type-sm);
147
+ line-height: var(--leading-body);
148
+ }
149
+
150
+ /* ---- search -------------------------------------------------------------- */
151
+ /* The library dialog shows the same box in its own bar, with this gap under
152
+ it. In the column the search is a fixed row, inset like every row, so the
153
+ column's geometry is scoped to it. */
154
+ .file-search {
155
+ margin-bottom: var(--space-2);
156
+ }
157
+
158
+ /* Paper's Studio column insets its search 16px, like its heads. A container,
159
+ for the floor rule below. */
160
+ .left-rail .file-search {
161
+ flex: none;
162
+ margin: 0;
163
+ padding: var(--space-4) var(--space-7);
164
+ container: file-search / inline-size;
165
+ }
166
+
167
+ /* AT THE 168px RAIL FLOOR the field is 136 wide, and after its padding, the
168
+ magnifier, two gaps and the 20px "/" hint the input kept about 66px:
169
+ "Search layers" cut to "Search la". The hint gives way first, since the
170
+ placeholder is the field's only label you can see and the key still works
171
+ without it. Without the hint the input has about 94px, and the words fit. */
172
+ @container file-search (width < 160px) {
173
+ .search-field > .kbd {
174
+ display: none;
175
+ }
176
+ }
177
+
178
+ /* THE BARE INPUT, a DIRECT child only. The Files panel wraps its input in the
179
+ kit's `.search-field` (icon, input, "/" hint), and that recipe styles its
180
+ own input; a descendant selector here tied it on specificity and painted a
181
+ second box inside the field. */
182
+ .file-search > input {
183
+ width: 100%;
184
+ height: var(--control-h);
185
+ font: inherit;
186
+ color: var(--ink-1);
187
+ background: var(--fill-rest);
188
+ border: 1px solid transparent;
189
+ border-radius: var(--control-radius);
190
+ padding: 0 var(--space-5);
191
+ }
192
+
193
+ .file-search > input::placeholder {
194
+ color: var(--ink-3);
195
+ }
196
+
197
+ .file-search > input:focus {
198
+ outline: none;
199
+ border-color: var(--accent);
200
+ box-shadow: var(--focus-ring);
201
+ }
202
+
203
+ /* THE NAVIGATOR'S GROUP LABEL, and there is one spec for it.
204
+
205
+ The rail keeps caps micro-labels where the inspector keeps 12px sentence
206
+ case, on purpose: this is a dense tree, and a group label at row size
207
+ competes with the rows under it. What was NOT on purpose is that the rail
208
+ had three of these (SHOTS at 0.07em, a resource lane at 0.07em, MCP at
209
+ 0.04em in a different ink), which is not a register, it is drift. All three
210
+ now read from here. Paper's column heads set it at 11/600 in the secondary
211
+ ink, so the register is 11px, not the 10px micro size. */
212
+ .file-section-label,
213
+ .resource-lane-title,
214
+ .mcp-heading {
215
+ color: var(--ink-2);
216
+ text-transform: uppercase;
217
+ letter-spacing: var(--tracking-caps);
218
+ font-size: var(--type-sm);
219
+ font-weight: var(--weight-semibold);
220
+ }
221
+
222
+ .file-section-label {
223
+ margin: var(--space-6) 0 var(--space-3);
224
+ padding: 0 var(--space-2);
225
+ }
226
+
227
+ /* A section header with its count or verb on the same line (the Shots and
228
+ Layers heads). */
229
+ .file-section-label--actions {
230
+ display: flex;
231
+ align-items: center;
232
+ justify-content: space-between;
233
+ }
234
+
235
+ /* FULL BLEED: the lanes run edge to edge and every inset is the column's
236
+ 12px. What sits in a lane body carries that inset itself. */
237
+ .resource-lane {
238
+ margin: 0 0 var(--space-6);
239
+ }
240
+
241
+ /* A divider BETWEEN two lanes, so the first lane of a stack has none. Hidden
242
+ file inputs lead some stacks and a lane is a `<section>` or a `<details>`,
243
+ so neither `:first-child` nor `:first-of-type` names the first lane.
244
+ `--line-soft` and not `--line`: the panel EDGE is a border, a rule between
245
+ two groups inside one panel is a divider, and the inspector's sections draw
246
+ theirs with the softer token too. */
247
+ .resource-lane ~ .resource-lane {
248
+ border-top: 1px solid var(--line-soft);
249
+ }
250
+
251
+ .resource-lane-head,
252
+ .resource-lane > summary {
253
+ min-height: 32px;
254
+ display: flex;
255
+ align-items: center;
256
+ gap: var(--space-4);
257
+ padding: var(--space-2) var(--space-6);
258
+ color: var(--ink-3);
259
+ list-style: none;
260
+ }
261
+
262
+ /* The editable lanes carry both quota/provenance metadata and three add
263
+ actions. Give those two jobs their own rows in the narrow rail so neither
264
+ wraps through the other. Read-only summary rows keep the compact flex form. */
265
+ .resource-lane-head {
266
+ display: grid;
267
+ grid-template-columns: minmax(0, 1fr);
268
+ align-items: stretch;
269
+ gap: var(--space-1);
270
+ padding-top: var(--space-3);
271
+ }
272
+
273
+ .resource-lane-head > .resource-add-actions {
274
+ justify-self: end;
275
+ }
276
+
277
+ .resource-lane-head .resource-lane-title {
278
+ width: 100%;
279
+ display: grid;
280
+ grid-template-columns: minmax(0, 1fr) auto auto;
281
+ }
282
+
283
+ .resource-lane > summary {
284
+ cursor: pointer;
285
+ }
286
+
287
+ .resource-lane > summary::-webkit-details-marker,
288
+ .resource-row summary::-webkit-details-marker {
289
+ display: none;
290
+ }
291
+
292
+ /* ONE DISCLOSURE GLYPH ACROSS THE RAIL. These two lanes drew a `"›"` text
293
+ character in a `::before` while the outline tree beside them drew the house
294
+ `IconChevron`, so one rail carried two chevrons at two weights. Both lanes
295
+ take the icon now; `.chevron.is-open` cannot apply, because a native
296
+ `<details>` is uncontrolled and no React state knows it opened. */
297
+ .resource-lane > summary > .chevron,
298
+ .mcp-section > summary > .chevron {
299
+ flex: none;
300
+ width: 10px;
301
+ height: 10px;
302
+ color: var(--ink-3);
303
+ }
304
+
305
+ .resource-lane[open] > summary > .chevron,
306
+ .mcp-section[open] > summary > .chevron {
307
+ transform: rotate(90deg);
308
+ }
309
+
310
+ .resource-lane-title {
311
+ min-width: 0;
312
+ flex: 1;
313
+ display: flex;
314
+ align-items: baseline;
315
+ gap: var(--space-3);
316
+ }
317
+
318
+ .resource-count,
319
+ .resource-usage {
320
+ color: var(--ink-3);
321
+ font-variant-numeric: var(--numeric);
322
+ }
323
+
324
+ .resource-usage {
325
+ margin-left: auto;
326
+ white-space: nowrap;
327
+ text-transform: none;
328
+ letter-spacing: normal;
329
+ font-weight: 400;
330
+ }
331
+
332
+ .resource-add-actions,
333
+ .resource-row-actions,
334
+ .resource-form-actions {
335
+ display: flex;
336
+ align-items: center;
337
+ gap: var(--space-2);
338
+ }
339
+
340
+ .resource-add-actions button,
341
+ .resource-row-actions button,
342
+ .resource-form-actions button {
343
+ min-height: 22px;
344
+ padding: var(--space-1) var(--space-3);
345
+ font: inherit;
346
+ font-size: var(--type-micro);
347
+ font-weight: 500;
348
+ color: var(--ink-2);
349
+ background: var(--fill-rest);
350
+ border: 1px solid transparent;
351
+ border-radius: var(--radius-sm);
352
+ cursor: pointer;
353
+ }
354
+
355
+ .resource-add-actions button:hover:not(:disabled),
356
+ .resource-row-actions button:hover:not(:disabled),
357
+ .resource-form-actions button:hover:not(:disabled) {
358
+ color: var(--ink-1);
359
+ background: var(--fill-hover);
360
+ }
361
+
362
+ .resource-add-actions button:focus-visible,
363
+ .resource-row-actions button:focus-visible,
364
+ .resource-form-actions button:focus-visible {
365
+ outline: none;
366
+ box-shadow: var(--focus-ring);
367
+ }
368
+
369
+ .resource-add-actions button:disabled,
370
+ .resource-row-actions button:disabled {
371
+ opacity: var(--opacity-disabled);
372
+ cursor: default;
373
+ }
374
+
375
+ .resource-row-actions button.is-danger {
376
+ color: var(--danger-ink);
377
+ }
378
+
379
+ .resource-form-actions button.is-primary {
380
+ color: var(--ink-1);
381
+ background: var(--accent);
382
+ }
383
+
384
+ .resource-list {
385
+ list-style: none;
386
+ margin: 0;
387
+ padding: 0;
388
+ }
389
+
390
+ /* A resource row is a square band, edge to edge, with no card or stripe of
391
+ its own. The Brand tab's scope is a mark on the column edge: Shot-owned
392
+ rows lead in the stronger ink. File rows on the Assets tab carry no scope
393
+ and no mark. */
394
+ .resource-row.is-project {
395
+ box-shadow: inset 2px 0 0 var(--line);
396
+ }
397
+
398
+ .resource-row.is-shot {
399
+ box-shadow: inset 2px 0 0 var(--ink-3);
400
+ }
401
+
402
+ .resource-row > details > summary {
403
+ display: flex;
404
+ align-items: center;
405
+ gap: var(--space-3);
406
+ min-height: var(--row-h);
407
+ padding: 0 var(--space-4) 0 var(--space-6);
408
+ list-style: none;
409
+ cursor: pointer;
410
+ }
411
+
412
+ .resource-row > details > summary:hover {
413
+ background: var(--fill-hover);
414
+ }
415
+
416
+ .resource-row > details > summary:focus-visible {
417
+ outline: none;
418
+ box-shadow: var(--focus-ring);
419
+ }
420
+
421
+ .resource-thumb {
422
+ flex: none;
423
+ width: 24px;
424
+ height: 24px;
425
+ object-fit: cover;
426
+ border: 1px solid var(--line);
427
+ border-radius: var(--radius-xs);
428
+ background: var(--fill-rest);
429
+ }
430
+
431
+ .resource-thumb.is-kind {
432
+ display: inline-flex;
433
+ align-items: center;
434
+ justify-content: center;
435
+ color: var(--ink-2);
436
+ font-size: var(--type-micro);
437
+ font-weight: 600;
438
+ }
439
+
440
+ .resource-thumb.is-swatch {
441
+ box-shadow: inset 0 0 0 1px var(--line-soft);
442
+ }
443
+
444
+ .resource-label {
445
+ min-width: 0;
446
+ flex: 1;
447
+ overflow: hidden;
448
+ text-overflow: ellipsis;
449
+ white-space: nowrap;
450
+ color: var(--ink-1);
451
+ font-weight: 500;
452
+ }
453
+
454
+ .resource-badge,
455
+ .resource-used {
456
+ flex: none;
457
+ padding: 1px var(--space-2);
458
+ color: var(--ink-3);
459
+ background: var(--fill-rest);
460
+ border-radius: var(--radius-xs);
461
+ font-size: var(--type-micro);
462
+ }
463
+
464
+ .resource-used {
465
+ color: var(--ink-2);
466
+ }
467
+
468
+ /* Aligned to the column's content edge, like every row above it. */
469
+ .resource-detail {
470
+ display: grid;
471
+ gap: var(--space-3);
472
+ padding: var(--space-2) var(--space-6) var(--space-4);
473
+ color: var(--ink-2);
474
+ font-size: var(--type-micro);
475
+ }
476
+
477
+ .resource-detail > div:not(.resource-row-actions) {
478
+ display: grid;
479
+ grid-template-columns: 36px minmax(0, 1fr);
480
+ gap: var(--space-3);
481
+ }
482
+
483
+ .resource-detail code {
484
+ overflow: hidden;
485
+ color: var(--ink-2);
486
+ text-overflow: ellipsis;
487
+ white-space: nowrap;
488
+ }
489
+
490
+ .resource-detail p {
491
+ margin: 0;
492
+ line-height: var(--leading-body);
493
+ }
494
+
495
+ .resource-row-actions {
496
+ justify-content: flex-end;
497
+ }
498
+
499
+ .resource-empty,
500
+ .resource-pending {
501
+ padding: var(--space-2) var(--space-4) var(--space-4);
502
+ color: var(--ink-3);
503
+ font-size: var(--type-micro);
504
+ line-height: var(--leading-body);
505
+ }
506
+
507
+ /* In the column the notes take its 12px inset. The library dialog shows the
508
+ same empty note at the base inset above. */
509
+ .left-rail .resource-empty,
510
+ .left-rail .resource-pending {
511
+ padding-inline: var(--space-6);
512
+ }
513
+
514
+ .resource-form {
515
+ display: grid;
516
+ gap: var(--space-3);
517
+ margin: 0 var(--space-6) var(--space-3);
518
+ padding: var(--space-4);
519
+ background: var(--fill-rest);
520
+ border: 1px solid var(--line);
521
+ border-radius: var(--radius-sm);
522
+ }
523
+
524
+ .resource-form input {
525
+ width: 100%;
526
+ min-width: 0;
527
+ height: 28px;
528
+ padding: 0 var(--space-4);
529
+ font: inherit;
530
+ color: var(--ink-1);
531
+ background: var(--fill-rest);
532
+ border: 1px solid transparent;
533
+ border-radius: var(--radius-sm);
534
+ }
535
+
536
+ .resource-form input:focus {
537
+ outline: none;
538
+ border-color: var(--accent);
539
+ box-shadow: var(--focus-ring);
540
+ }
541
+
542
+ .resource-form-value {
543
+ display: grid;
544
+ grid-template-columns: auto minmax(0, 1fr);
545
+ gap: var(--space-2);
546
+ }
547
+
548
+ .resource-form input[type="color"] {
549
+ width: 32px;
550
+ padding: var(--space-1);
551
+ }
552
+
553
+ .resource-form-actions {
554
+ justify-content: flex-end;
555
+ }
556
+
557
+ /* No production caller passes `readOnly`: the board's old rail rendered the
558
+ panels editable. The prop and this rule stay with the panels' API, which
559
+ assetDrop.test still mounts read-only. */
560
+ .resource-stack.is-readonly .resource-lane-body {
561
+ padding-top: var(--space-1);
562
+ }
563
+
564
+ /* ---- the outline ---------------------------------------------------------- */
565
+ .scene-list,
566
+ .layer-list,
567
+ .layer-children,
568
+ .component-list {
569
+ list-style: none;
570
+ margin: 0;
571
+ padding: 0;
572
+ }
573
+
574
+ /* ONE INDENT SOURCE: every row pads by its own `--depth` (set on its LI), so
575
+ the nesting ul adds no step (the list reset above zeroes its box). It only
576
+ draws the guide, a 1px line under its parent's chevron: the parent's depth
577
+ is what the ul inherits. `pointer-events: none` so the line never takes a
578
+ row's click. */
579
+ .layer-children {
580
+ /* The centre of the 14px chevron column, where a guide stands. */
581
+ --chevron-mid: 7px;
582
+ position: relative;
583
+ }
584
+
585
+ .layer-children::before {
586
+ content: "";
587
+ position: absolute;
588
+ top: 0;
589
+ bottom: 0;
590
+ left: calc(var(--space-6) + var(--depth, 0) * var(--tree-indent) + var(--mask-inset, 0px) + var(--chevron-mid));
591
+ width: 1px;
592
+ background: var(--line-soft);
593
+ pointer-events: none;
594
+ }
595
+
596
+ /* Regular, as Paper's layer rows set it. A shot's name is the 500 one, on
597
+ `.scene-row`, and a component's sits on its own row. */
598
+ .layer-name {
599
+ font: inherit;
600
+ font-weight: 400;
601
+ color: var(--ink-1);
602
+ background: transparent;
603
+ border: 0;
604
+ padding: 0 var(--space-4);
605
+ height: var(--row-h);
606
+ width: 100%;
607
+ text-align: left;
608
+ cursor: pointer;
609
+ /* `--radius-md`, the house rule for a list item (design-system.md, Shape).
610
+ In the column it only shapes the focus ring: the row is the band. */
611
+ border-radius: var(--radius-md);
612
+ white-space: nowrap;
613
+ overflow: hidden;
614
+ text-overflow: ellipsis;
615
+ }
616
+
617
+ /* A SHOT ROW IS ITS LI: the fill runs under the Open button beside the name,
618
+ so hover and the current mark live on the item. Paper's Studio column draws
619
+ a shot as an INSET PILL, not a band: 16px in from each edge, 32 tall, the
620
+ 6px radius. A shot is a few big targets, where the layer tree is many small
621
+ ones, so the two lists keep different shapes. */
622
+ .scene-list-item {
623
+ display: flex;
624
+ align-items: center;
625
+ gap: var(--space-1);
626
+ min-height: var(--row-h-shot);
627
+ margin-inline: var(--space-7);
628
+ padding: 0 var(--space-4);
629
+ border-radius: var(--radius-sm);
630
+ }
631
+
632
+ /* The name button fills the row and lays out icon then label; the label
633
+ ellipsizes on its own (a flex container ignores text-overflow on a bare
634
+ text node). */
635
+ .scene-row {
636
+ flex: 1;
637
+ min-width: 0;
638
+ display: flex;
639
+ align-items: center;
640
+ gap: var(--space-3);
641
+ height: var(--row-h-shot);
642
+ padding: 0;
643
+ font: inherit;
644
+ font-weight: 500;
645
+ color: var(--ink-1);
646
+ background: transparent;
647
+ border: 0;
648
+ text-align: left;
649
+ cursor: pointer;
650
+ }
651
+
652
+ .row-label {
653
+ flex: 1;
654
+ min-width: 0;
655
+ overflow: hidden;
656
+ text-overflow: ellipsis;
657
+ white-space: nowrap;
658
+ }
659
+
660
+ /* The shot's length, in the chrome's one duration string (`formatDuration`,
661
+ "18.00s"), in a 48px mono slot so every row's number ends on one column.
662
+ A floor, not a width: six characters fill it at 12px, and a shot of 100s
663
+ or more grows its slot instead of painting over the row's edge. */
664
+ .scene-row-duration {
665
+ flex: none;
666
+ min-width: 48px;
667
+ text-align: right;
668
+ font-family: var(--font-numeric);
669
+ font-size: var(--type-md);
670
+ font-variant-numeric: var(--numeric);
671
+ color: var(--ink-2);
672
+ }
673
+
674
+ /* Add shot, under the list: the kit's dashed button, full width, on the same
675
+ 16px inset as the shot pills. */
676
+ .scene-list-add {
677
+ padding: var(--space-4) var(--space-7);
678
+ }
679
+
680
+ /* 13, Paper's Add shot label, a step over the kit button's 12. */
681
+ .scene-list-add > .btn {
682
+ width: 100%;
683
+ font-size: var(--type-lg);
684
+ }
685
+
686
+ .scene-list-add > .btn svg {
687
+ flex: none;
688
+ width: 16px;
689
+ height: 16px;
690
+ }
691
+
692
+ /* FULL BLEED: square, edge to edge, and inset 12px plus the row's own depth.
693
+ The three lists do NOT start on one edge, and Paper draws them that way: a
694
+ shot is an inset pill (16 margin plus 8 padding, so 24), a layer is a band
695
+ across the column (12), and a component is a bordered row on the 12px edge
696
+ (12 margin, 1 border, 4 padding, so 17). */
697
+ .layer-row {
698
+ position: relative;
699
+ display: flex;
700
+ align-items: center;
701
+ gap: var(--space-1);
702
+ /* `--mask-inset` is the room a mask's bracket takes (maskMarks.tsx). */
703
+ padding-left: calc(var(--space-6) + var(--depth, 0) * var(--tree-indent) + var(--mask-inset, 0px));
704
+ padding-right: var(--space-4);
705
+ min-height: var(--row-h);
706
+ }
707
+
708
+ /* The components list, with the instance count pulling right so a
709
+ definition's reach is readable at a glance: that number is what "editing
710
+ this changes N things" means. Paper's Rows board draws a component as a
711
+ BORDERED row, a thing you place rather than a node of the tree, 32 tall and
712
+ standing on the column's 12px edge. The list is flat, so there is no depth
713
+ to indent by. */
714
+ .component-row {
715
+ display: flex;
716
+ align-items: center;
717
+ gap: var(--space-2);
718
+ margin: 0 var(--space-6) var(--space-2);
719
+ padding: 0 var(--space-3) 0 var(--space-2);
720
+ min-height: var(--row-h-shot);
721
+ border: 1px solid var(--line);
722
+ border-radius: var(--radius-xs);
723
+ }
724
+
725
+ /* The rows' states: hover the soft state fill, selection the selected fill
726
+ (the kit's two state tokens) with the name in accent ink. Selection carries
727
+ a `:hover` twin so it outranks the hover by a class rather than by coming
728
+ later. */
729
+ .scene-list-item:hover,
730
+ .layer-row:hover,
731
+ .component-row:hover {
732
+ background: var(--fill-state-soft);
733
+ }
734
+
735
+ .scene-list-item.is-current,
736
+ .scene-list-item.is-current:hover,
737
+ .layer-row.is-selected,
738
+ .layer-row.is-selected:hover,
739
+ .component-row.is-current,
740
+ .component-row.is-current:hover {
741
+ background: var(--fill-selected);
742
+ }
743
+
744
+ .layer-row.is-selected .layer-name,
745
+ .component-row.is-current .layer-name {
746
+ color: var(--accent-ink);
747
+ }
748
+
749
+ /* The current SHOT inverts that: Paper keeps its name in the primary ink and
750
+ strokes the clapper in the accent, the pill's border colour. */
751
+ .scene-row.is-current .layer-kind {
752
+ color: var(--accent);
753
+ }
754
+
755
+ /* The kind icon. Fixed width so every name in the tree starts on the same
756
+ column.
757
+ NEUTRAL, and the shape carries the meaning — the Figma read. Every kind
758
+ painted in one accent made fifteen distinct glyphs read as one repeated blob,
759
+ which is the opposite of a taxonomy. Dim at rest, full ink on the row you are
760
+ pointing at or have selected.
761
+ THE COMPONENT FAMILY IS THE ONE EXCEPTION, and it is the point: the diamonds
762
+ (lone = a code component, diamond-in-diamond = a placed definition,
763
+ four-diamond = the definition itself) keep the accent, so components pop out
764
+ of a tree of shapes exactly the way they do in Figma and Framer. It stays
765
+ last so it survives hover and selection. */
766
+ .layer-kind {
767
+ flex: none;
768
+ width: 18px;
769
+ display: inline-flex;
770
+ align-items: center;
771
+ justify-content: center;
772
+ color: var(--ink-2);
773
+ user-select: none;
774
+ }
775
+
776
+ .layer-kind svg {
777
+ width: 16px;
778
+ height: 16px;
779
+ }
780
+
781
+ .layer-row:hover .layer-kind,
782
+ .layer-row.is-selected .layer-kind {
783
+ color: var(--ink-1);
784
+ }
785
+
786
+ .layer-kind.is-component {
787
+ color: var(--accent-ink);
788
+ }
789
+
790
+ /* A MASK'S OWN ROW keeps the accent too (Paper page 25): the glyph says "this
791
+ cuts", and its Mask group's glyph stays neutral. */
792
+ .layer-kind.is-mask {
793
+ color: var(--accent-ink);
794
+ }
795
+
796
+ /* A HIDDEN MASK switches masking off. Its row dims to the disabled ink and its
797
+ badge reads Off, so the cause of an unmasked picture is visible. */
798
+ .layer-row.is-mask-off .layer-name,
799
+ .layer-row.is-mask-off .layer-kind,
800
+ .layer-row.is-mask-off .mask-badge,
801
+ .lifespan-row.is-mask-off .lifespan-name,
802
+ .lifespan-row.is-mask-off .layer-kind,
803
+ .lifespan-row.is-mask-off .mask-badge {
804
+ color: var(--ink-disabled);
805
+ }
806
+
807
+ /* A live mask with nothing in front of it: one quiet line under its row, on
808
+ the name's column. */
809
+ .layer-mask-hint {
810
+ height: 22px;
811
+ display: flex;
812
+ align-items: center;
813
+ padding-left: calc(var(--space-6) + var(--depth, 0) * var(--tree-indent) + var(--mask-inset, 0px) + var(--space-8) + var(--space-7) + var(--space-2));
814
+ font-size: var(--type-sm);
815
+ line-height: var(--leading-xs);
816
+ color: var(--ink-disabled);
817
+ pointer-events: none;
818
+ }
819
+
820
+ /* The disclosure chevron. Always visible on a row that can fold (unlike the
821
+ hover-only flags: a fold changes what the LIST shows, so its affordance
822
+ cannot be a secret), pointing right and rotating open — the ui package's
823
+ IconChevron convention. The spacer keeps leaf rows' kind icons on the same
824
+ column. */
825
+ .layer-toggle {
826
+ display: inline-flex;
827
+ align-items: center;
828
+ justify-content: center;
829
+ color: var(--ink-2);
830
+ background: transparent;
831
+ border: 0;
832
+ cursor: pointer;
833
+ border-radius: var(--radius-xs);
834
+ padding: var(--space-1);
835
+ flex: none;
836
+ width: 14px;
837
+ }
838
+
839
+ .layer-toggle svg {
840
+ width: 10px;
841
+ height: 10px;
842
+ transition: transform var(--dur-fast) var(--ease);
843
+ }
844
+
845
+ .layer-toggle.is-open svg {
846
+ transform: rotate(90deg);
847
+ }
848
+
849
+ .layer-toggle:hover {
850
+ color: var(--ink-1);
851
+ background: var(--fill-hover);
852
+ }
853
+
854
+ .layer-toggle-spacer {
855
+ flex: none;
856
+ width: 14px;
857
+ }
858
+
859
+ /* A row's flags rest QUIET, not hidden. A control nobody can see is a
860
+ capability nobody finds, so the design system's rule is a low resting
861
+ opacity rather than opacity 0. Full strength on hover, focus, or when it is
862
+ ON. The outline's eye and lock go further and stay visible (below). */
863
+ .layer-flag {
864
+ display: inline-flex;
865
+ align-items: center;
866
+ justify-content: center;
867
+ color: var(--ink-2);
868
+ background: transparent;
869
+ border: 0;
870
+ cursor: pointer;
871
+ opacity: 0.28;
872
+ border-radius: var(--radius-xs);
873
+ padding: var(--space-2);
874
+ flex: none;
875
+ }
876
+
877
+ .layer-flag svg {
878
+ width: 13px;
879
+ height: 13px;
880
+ }
881
+
882
+ /* Paper's layer rows size the pair apart: the eye 14, the lock 12. Every
883
+ layer row carries both, so the columns still line up row to row. */
884
+ .layer-row .layer-flag.is-eye svg {
885
+ width: 14px;
886
+ height: 14px;
887
+ }
888
+
889
+ .layer-row .layer-flag.is-lock svg {
890
+ width: 12px;
891
+ height: 12px;
892
+ }
893
+
894
+ /* EVERY ROW THAT CARRIES THESE FLAGS, because a clip row's label cell holds
895
+ the same three buttons and only the outliner's row was lifting them: eye,
896
+ lock and mute sat at 0.28 through a hover that was visibly over them. A
897
+ shot's Open and a component's Place are flags too, and lift with their row.
898
+ No new colour and no fill step: the fix is the resting opacity lifting,
899
+ which is the rule already proven in both appearances. */
900
+ .layer-row:hover .layer-flag,
901
+ .lifespan-row:hover .layer-flag,
902
+ .scene-list-item:hover .layer-flag,
903
+ .component-row:hover .layer-flag,
904
+ .layer-flag[aria-pressed="true"],
905
+ .layer-flag:focus-visible,
906
+ .layer-flag:hover {
907
+ opacity: 1;
908
+ }
909
+
910
+ .layer-flag:hover {
911
+ background: var(--fill-hover);
912
+ }
913
+
914
+ /* THE OUTLINE'S FLAGS ARE VISIBLE AT REST. Paper's layer rows draw the eye
915
+ and the lock at full opacity in the tertiary ink, so the outline (and a
916
+ component row's Place) does not hide them behind a hover. ON and pointed-at
917
+ step up to the primary ink, which is what the resting opacity used to say.
918
+ The quiet rest above still holds for the timeline's lifespan rows and a
919
+ shot's Open. */
920
+ .layer-row .layer-flag,
921
+ .component-row .layer-flag {
922
+ opacity: 1;
923
+ color: var(--ink-3);
924
+ }
925
+
926
+ .layer-row .layer-flag[aria-pressed="true"],
927
+ .layer-row .layer-flag:hover,
928
+ .layer-row .layer-flag:focus-visible,
929
+ .component-row .layer-flag:hover,
930
+ .component-row .layer-flag:focus-visible {
931
+ color: var(--ink-1);
932
+ }
933
+
934
+ .layer-rename {
935
+ flex: 1;
936
+ min-width: 0;
937
+ font: inherit;
938
+ color: var(--ink-1);
939
+ background: var(--fill-rest);
940
+ border: 1px solid var(--accent);
941
+ border-radius: var(--radius-sm);
942
+ padding: var(--space-1) var(--space-3);
943
+ }
944
+
945
+ .layer-rename:focus {
946
+ outline: none;
947
+ box-shadow: var(--focus-ring);
948
+ }
949
+
950
+ /* ---- MCP (workspace endpoint, Project target) ---------------------------- */
951
+ /* A compact patch-bay row. Status stays visible in the summary, while the
952
+ private hosted command and setup detail remain behind an explicit expand.
953
+ Help and the Agent chip's popover both wear it. */
954
+ .mcp-section {
955
+ margin: 0 0 var(--space-2);
956
+ border-top: 1px solid var(--line-soft);
957
+ }
958
+
959
+ .mcp-section > summary {
960
+ min-height: 32px;
961
+ display: flex;
962
+ align-items: center;
963
+ gap: var(--space-3);
964
+ padding: 0 var(--space-2);
965
+ cursor: pointer;
966
+ list-style: none;
967
+ }
968
+
969
+ .mcp-section > summary::-webkit-details-marker {
970
+ display: none;
971
+ }
972
+
973
+ .mcp-section > summary:hover {
974
+ background: var(--fill-rest);
975
+ }
976
+
977
+ .mcp-section > summary:focus-visible {
978
+ outline: none;
979
+ box-shadow: var(--focus-ring);
980
+ }
981
+
982
+ .mcp-heading,
983
+ .mcp-status {
984
+ display: inline-flex;
985
+ align-items: center;
986
+ }
987
+
988
+ /* One line: in a narrow column the name ellipsizes before it wraps the row. */
989
+ .mcp-heading {
990
+ min-width: 0;
991
+ gap: var(--space-3);
992
+ white-space: nowrap;
993
+ }
994
+
995
+ .mcp-heading > span {
996
+ overflow: hidden;
997
+ text-overflow: ellipsis;
998
+ }
999
+
1000
+ .mcp-heading svg,
1001
+ .mcp-status svg,
1002
+ .mcp-readiness > svg {
1003
+ flex: none;
1004
+ width: 12px;
1005
+ height: 12px;
1006
+ }
1007
+
1008
+ .mcp-heading svg {
1009
+ color: var(--ink-3);
1010
+ }
1011
+
1012
+ .mcp-status {
1013
+ margin-left: auto;
1014
+ gap: var(--space-1);
1015
+ color: var(--ink-3);
1016
+ font-size: var(--type-micro);
1017
+ white-space: nowrap;
1018
+ }
1019
+
1020
+ .mcp-status.is-read svg,
1021
+ .mcp-readiness.is-read > svg {
1022
+ color: var(--accent-ink);
1023
+ }
1024
+
1025
+ .mcp-readiness.is-write > svg {
1026
+ color: var(--success);
1027
+ }
1028
+
1029
+ .mcp-status.is-write svg {
1030
+ color: var(--success);
1031
+ }
1032
+
1033
+ .mcp-status.is-off svg,
1034
+ .mcp-readiness.is-off > svg {
1035
+ color: var(--warn);
1036
+ }
1037
+
1038
+ .mcp-body {
1039
+ display: grid;
1040
+ gap: var(--space-4);
1041
+ padding: 0 var(--space-2) var(--space-4);
1042
+ }
1043
+
1044
+ .mcp-project {
1045
+ display: grid;
1046
+ gap: var(--space-2);
1047
+ min-width: 0;
1048
+ padding: var(--space-4);
1049
+ background: var(--fill-rest);
1050
+ border: 1px solid var(--line-soft);
1051
+ border-radius: var(--control-radius);
1052
+ }
1053
+
1054
+ .mcp-kicker,
1055
+ .mcp-command > span {
1056
+ color: var(--ink-3);
1057
+ font-size: var(--type-micro);
1058
+ font-weight: 600;
1059
+ letter-spacing: var(--tracking-caps);
1060
+ text-transform: uppercase;
1061
+ }
1062
+
1063
+ .mcp-project strong {
1064
+ overflow: hidden;
1065
+ color: var(--ink-1);
1066
+ font-size: var(--type-sm);
1067
+ font-weight: 500;
1068
+ text-overflow: ellipsis;
1069
+ white-space: nowrap;
1070
+ }
1071
+
1072
+ .mcp-project-name {
1073
+ display: grid;
1074
+ grid-template-columns: auto minmax(0, 1fr) auto;
1075
+ align-items: center;
1076
+ gap: var(--space-3);
1077
+ color: var(--ink-3);
1078
+ font-size: var(--type-micro);
1079
+ }
1080
+
1081
+ .mcp-project-name code {
1082
+ overflow: hidden;
1083
+ color: var(--ink-2);
1084
+ font: var(--type-micro)/var(--leading-none) var(--font-mono);
1085
+ text-overflow: ellipsis;
1086
+ white-space: nowrap;
1087
+ }
1088
+
1089
+ /* The handoff: what the copied prompt names, and its Copy. */
1090
+ .mcp-handoff {
1091
+ display: grid;
1092
+ grid-template-columns: minmax(0, 1fr) auto;
1093
+ align-items: center;
1094
+ gap: var(--space-3);
1095
+ color: var(--ink-3);
1096
+ font-size: var(--type-micro);
1097
+ }
1098
+
1099
+ .mcp-project p,
1100
+ .mcp-note,
1101
+ .mcp-footnote {
1102
+ margin: 0;
1103
+ color: var(--ink-3);
1104
+ font-size: var(--type-micro);
1105
+ line-height: var(--leading-body);
1106
+ }
1107
+
1108
+ .mcp-note code,
1109
+ .mcp-footnote code,
1110
+ .mcp-readiness code {
1111
+ color: var(--ink-2);
1112
+ font: var(--type-micro)/var(--leading-none) var(--font-mono);
1113
+ }
1114
+
1115
+ .mcp-readiness {
1116
+ display: grid;
1117
+ grid-template-columns: auto minmax(0, 1fr);
1118
+ align-items: start;
1119
+ gap: var(--space-3);
1120
+ padding: var(--space-3) 0;
1121
+ border-bottom: 1px solid var(--line-soft);
1122
+ }
1123
+
1124
+ .mcp-readiness.is-unknown {
1125
+ grid-template-columns: minmax(0, 1fr) auto;
1126
+ }
1127
+
1128
+ .mcp-readiness > div {
1129
+ display: grid;
1130
+ gap: var(--space-1);
1131
+ min-width: 0;
1132
+ }
1133
+
1134
+ .mcp-readiness strong {
1135
+ color: var(--ink-2);
1136
+ font-size: var(--type-micro);
1137
+ font-weight: 500;
1138
+ }
1139
+
1140
+ .mcp-readiness span {
1141
+ color: var(--ink-3);
1142
+ font-size: var(--type-micro);
1143
+ line-height: var(--leading-body);
1144
+ }
1145
+
1146
+ /* The hosted write switch: the label and what it means, the house toggle at
1147
+ the row's end, and a refusal under both. */
1148
+ .mcp-writes {
1149
+ display: grid;
1150
+ grid-template-columns: minmax(0, 1fr) auto;
1151
+ align-items: start;
1152
+ gap: var(--space-2) var(--space-3);
1153
+ padding-bottom: var(--space-3);
1154
+ border-bottom: 1px solid var(--line-soft);
1155
+ }
1156
+
1157
+ .mcp-writes > div {
1158
+ display: grid;
1159
+ gap: var(--space-1);
1160
+ min-width: 0;
1161
+ }
1162
+
1163
+ .mcp-writes strong {
1164
+ color: var(--ink-2);
1165
+ font-size: var(--type-micro);
1166
+ font-weight: 500;
1167
+ }
1168
+
1169
+ .mcp-writes span,
1170
+ .mcp-writes-problem {
1171
+ color: var(--ink-3);
1172
+ font-size: var(--type-micro);
1173
+ line-height: var(--leading-body);
1174
+ }
1175
+
1176
+ .mcp-writes-problem {
1177
+ grid-column: 1 / -1;
1178
+ margin: 0;
1179
+ color: var(--danger-ink);
1180
+ }
1181
+
1182
+ .mcp-setup {
1183
+ display: grid;
1184
+ gap: var(--space-3);
1185
+ }
1186
+
1187
+ .mcp-command {
1188
+ display: grid;
1189
+ gap: var(--space-1);
1190
+ }
1191
+
1192
+ .mcp-command > div {
1193
+ display: grid;
1194
+ grid-template-columns: minmax(0, 1fr) auto;
1195
+ align-items: start;
1196
+ gap: var(--space-2);
1197
+ }
1198
+
1199
+ .mcp-command code {
1200
+ min-width: 0;
1201
+ padding: var(--space-2) var(--space-3);
1202
+ color: var(--ink-1);
1203
+ background: var(--fill-rest);
1204
+ border-radius: var(--radius-sm);
1205
+ font: var(--type-micro)/var(--leading-none) var(--font-mono);
1206
+ line-height: var(--leading-body);
1207
+ word-break: break-all;
1208
+ }
1209
+
1210
+ .mcp-project-name button,
1211
+ .mcp-handoff button,
1212
+ .mcp-command button,
1213
+ .mcp-readiness button,
1214
+ .mcp-connect-link {
1215
+ min-height: 22px;
1216
+ padding: var(--space-1) var(--space-3);
1217
+ color: var(--ink-2);
1218
+ background: var(--fill-rest);
1219
+ border: 0;
1220
+ border-radius: var(--radius-sm);
1221
+ font: inherit;
1222
+ font-size: var(--type-micro);
1223
+ cursor: pointer;
1224
+ white-space: nowrap;
1225
+ }
1226
+
1227
+ .mcp-project-name button:hover,
1228
+ .mcp-handoff button:hover,
1229
+ .mcp-command button:hover,
1230
+ .mcp-readiness button:hover,
1231
+ .mcp-connect-link:hover {
1232
+ color: var(--ink-1);
1233
+ background: var(--fill-hover);
1234
+ }
1235
+
1236
+ .mcp-project-name button:focus-visible,
1237
+ .mcp-handoff button:focus-visible,
1238
+ .mcp-command button:focus-visible,
1239
+ .mcp-readiness button:focus-visible,
1240
+ .mcp-connect-link:focus-visible {
1241
+ outline: none;
1242
+ box-shadow: var(--focus-ring);
1243
+ }
1244
+
1245
+ /* Hosted, the one connect step: a link drawn as the rows' buttons, sized to
1246
+ its words rather than the grid's width. */
1247
+ .mcp-connect-link {
1248
+ justify-self: start;
1249
+ display: inline-flex;
1250
+ align-items: center;
1251
+ text-decoration: none;
1252
+ }
1253
+
1254
+ /* The Agent chip's details, floated under the top bar by `Popover` (portaled
1255
+ to <body>, so nothing here may depend on the bar's ancestors). The cap is
1256
+ measured at the open (McpPopover), and the body scrolls inside it. */
1257
+ .mcp-popover-body {
1258
+ width: 320px;
1259
+ max-width: calc(100vw - 2 * var(--space-6));
1260
+ overflow-y: auto;
1261
+ padding: var(--space-6);
1262
+ }
1263
+
1264
+ .mcp-popover-body > .mcp-body {
1265
+ padding: 0;
1266
+ }
1267
+
1268
+
1269
+ /* ═══════════════════════════════════════════════════════════════════════════
1270
+ THE UX OVERHAUL: SAYING WHERE YOU ARE
1271
+ ═══════════════════════════════════════════════════════════════════════════
1272
+
1273
+ One complaint underlies most of this section: the chrome knew which context
1274
+ the author was in (`enteredScene`, `editingDef`, the selection) and never
1275
+ said so out loud. The trail that named it was 11px of --text-dim with no
1276
+ back affordance, so the only control that LOOKED like a way out was a chip
1277
+ in the timeline head labelled with the shot's own name — which reads as a
1278
+ title, not a button.
1279
+
1280
+ So the same facts are now stated in the same words and with the same
1281
+ grammar in the header breadcrumb, the rail's head, the inspector's head,
1282
+ the canvas bar's back chip and the timeline's corner (which names the place
1283
+ and no longer leaves it). None of them is a new piece of state; all of them
1284
+ read the context bits that already existed.
1285
+ ────────────────────────────────────────────────────────────────────────── */
1286
+
1287
+ /* ---- the rail's head ---------------------------------------------------- */
1288
+ /* Replaces the flat crumb strip. ONE ROW, Paper's shot browser head
1289
+ (2026-10-13 design review): the way OUT first, in the accent ink with its
1290
+ chevron, then a slash, then what you are IN at 12/600. It was two stacked
1291
+ rows (about 42px), which only fit the old 48px head line by centring; the
1292
+ head line is 40 now, and one row reads the same two answers left to right.
1293
+ It is the panel's FIRST child, so it takes the shell's head line: exactly
1294
+ one panel head tall (`--panel-head-h`) with the hairline under it, 16px in
1295
+ like Paper's head. A fixed HEIGHT, not a floor: a long name ellipsizes
1296
+ inside the row rather than growing it past the seam the dockedShellE2e
1297
+ pins at the canvas bar's foot. */
1298
+ .rail-head {
1299
+ flex: none;
1300
+ display: flex;
1301
+ align-items: center;
1302
+ gap: var(--space-4);
1303
+ height: var(--panel-head-h);
1304
+ min-width: 0;
1305
+ padding: 0 var(--space-7);
1306
+ overflow: hidden;
1307
+ border-bottom: 1px solid var(--line);
1308
+ }
1309
+
1310
+ /* The way back, one level. A real control with a chevron, in the accent ink
1311
+ Paper gives the way out: this is the control that was missing, and the dim
1312
+ text crumb it replaces is why the author reported having none. It gives
1313
+ way to the subject: the subject is the row's heading. */
1314
+ .rail-back {
1315
+ display: flex;
1316
+ flex: 0 1 auto;
1317
+ align-items: center;
1318
+ gap: var(--space-2);
1319
+ min-width: 0;
1320
+ max-width: 60%;
1321
+ font: inherit;
1322
+ font-size: var(--type-md);
1323
+ color: var(--accent-ink);
1324
+ background: transparent;
1325
+ border: 0;
1326
+ border-radius: var(--radius-xs);
1327
+ padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1);
1328
+ cursor: pointer;
1329
+ white-space: nowrap;
1330
+ overflow: hidden;
1331
+ text-overflow: ellipsis;
1332
+ }
1333
+
1334
+ .rail-back:hover {
1335
+ background: var(--fill-hover);
1336
+ }
1337
+
1338
+ .rail-back svg {
1339
+ flex: none;
1340
+ width: 14px;
1341
+ height: 14px;
1342
+ }
1343
+
1344
+ /* What you are inside. A heading, not a crumb: semibold and full ink, so
1345
+ the panel has a subject the eye lands on before the tree under it. */
1346
+ .rail-subject {
1347
+ display: flex;
1348
+ flex: 1 1 0;
1349
+ align-items: center;
1350
+ gap: var(--space-2);
1351
+ min-width: 0;
1352
+ }
1353
+
1354
+ /* After the way back, Paper's slash between the two answers. Decorative, so
1355
+ its alternative text is empty and a reader hears the two controls alone.
1356
+ The subject's own glyph steps aside there: the slash already says "inside",
1357
+ and Paper's row has none. */
1358
+ .rail-back + .rail-subject::before {
1359
+ content: "/" / "";
1360
+ flex: none;
1361
+ color: var(--ink-2);
1362
+ }
1363
+
1364
+ .rail-back + .rail-subject .rail-subject-icon {
1365
+ display: none;
1366
+ }
1367
+
1368
+ .rail-subject-icon {
1369
+ flex: none;
1370
+ display: inline-flex;
1371
+ align-items: center;
1372
+ color: var(--ink-2);
1373
+ }
1374
+
1375
+ .rail-subject-icon svg {
1376
+ width: 15px;
1377
+ height: 15px;
1378
+ }
1379
+
1380
+ /* The component family keeps the accent here for the reason it keeps it in the
1381
+ outliner: a definition is a different KIND of subject, not just another one.
1382
+ Two classes, so it outranks the neutral rule. */
1383
+ .rail-subject-icon.is-component {
1384
+ color: var(--accent-ink);
1385
+ }
1386
+
1387
+ .rail-subject-name {
1388
+ flex: 1;
1389
+ min-width: 0;
1390
+ font-size: var(--type-md);
1391
+ font-weight: var(--weight-semibold);
1392
+ color: var(--ink-1);
1393
+ white-space: nowrap;
1394
+ overflow: hidden;
1395
+ text-overflow: ellipsis;
1396
+ }
1397
+
1398
+ /* A definition edits every placement at once, so its heading takes the accent. */
1399
+ .rail-subject.is-definition .rail-subject-name {
1400
+ color: var(--accent-ink);
1401
+ }
1402
+
1403
+ /* ---- section labels that carry a count ---------------------------------- */
1404
+ /* A collapsed section still has to say what is inside it, which a bare caps
1405
+ label does not. Right-aligned so the labels stay a column. */
1406
+ .file-section-label {
1407
+ display: flex;
1408
+ align-items: center;
1409
+ gap: var(--space-2);
1410
+ }
1411
+
1412
+ /* Mono 11 in the secondary ink, Paper's LAYERS and COMPONENTS counts. */
1413
+ .file-section-count {
1414
+ margin-left: auto;
1415
+ font-family: var(--font-numeric);
1416
+ font-size: var(--type-sm);
1417
+ font-weight: 400;
1418
+ color: var(--ink-2);
1419
+ font-variant-numeric: var(--numeric);
1420
+ letter-spacing: 0;
1421
+ }
1422
+
1423
+ /* A section head: the kit's section header height (32) on Paper's 16px
1424
+ inset, the same inset as the head, the search and the shot pills.
1425
+
1426
+ The count MUST be a sibling of `.file-section-label`, never a child: the
1427
+ resourcesPanel column tests compare that element's textContent by equality
1428
+ against "Layers" and "Inside", so a nested span renames
1429
+ the section rather than annotating it. The Components group needs no rule of
1430
+ its own, its `summary` already is this row. The wrapper owns the spacing and
1431
+ the label drops its own. */
1432
+ .file-section-head {
1433
+ display: flex;
1434
+ align-items: center;
1435
+ gap: var(--space-2);
1436
+ min-height: var(--section-header-h);
1437
+ margin-top: var(--space-3);
1438
+ padding: 0 var(--space-7);
1439
+ }
1440
+
1441
+ .file-section-head > .file-section-label {
1442
+ margin: 0;
1443
+ padding: 0;
1444
+ flex: 1;
1445
+ }
1446
+
1447
+ /* ---- a collapsible rail group ------------------------------------------- */
1448
+ /* A native `details`, like the MCP row, and NOT the inspector's section
1449
+ component: that one unmounts its body when collapsed, and the outliner's
1450
+ rows have to stay queryable and measurable whether or not the group is
1451
+ open. Its summary is a section head. */
1452
+ .rail-group {
1453
+ margin: 0;
1454
+ }
1455
+
1456
+ .rail-group > summary {
1457
+ display: flex;
1458
+ align-items: center;
1459
+ gap: var(--space-2);
1460
+ cursor: pointer;
1461
+ list-style: none;
1462
+ /* 28 under a full `--line`, Paper's COMPONENTS head: a row-height divider,
1463
+ a step shorter than the 32 section heads above it. */
1464
+ min-height: var(--row-h);
1465
+ margin-top: var(--space-3);
1466
+ padding: 0 var(--space-7);
1467
+ border-top: 1px solid var(--line);
1468
+ }
1469
+
1470
+ .rail-group > summary::-webkit-details-marker {
1471
+ display: none;
1472
+ }
1473
+
1474
+ .rail-group > summary .file-section-label {
1475
+ margin: 0;
1476
+ padding: 0;
1477
+ flex: 1;
1478
+ }
1479
+
1480
+ .rail-group-chevron {
1481
+ flex: none;
1482
+ display: inline-flex;
1483
+ align-items: center;
1484
+ color: var(--ink-3);
1485
+ transition: transform var(--dur-fast) var(--ease);
1486
+ }
1487
+
1488
+ .rail-group[open] .rail-group-chevron {
1489
+ transform: rotate(90deg);
1490
+ }
1491
+
1492
+ .rail-group-chevron svg {
1493
+ width: 12px;
1494
+ height: 12px;
1495
+ }
1496
+
1497
+ /* The group's own create verb. NOT `.layer-flag`: that class rests at 0.28 and
1498
+ is lifted by its row's hover, and this button is not inside a row, so it
1499
+ sat permanently dimmed with no hover that could ever reach it. */
1500
+ .rail-group-action {
1501
+ flex: none;
1502
+ display: inline-flex;
1503
+ align-items: center;
1504
+ justify-content: center;
1505
+ width: 18px;
1506
+ height: 18px;
1507
+ font: inherit;
1508
+ font-size: var(--type-lg);
1509
+ line-height: var(--leading-none);
1510
+ color: var(--ink-2);
1511
+ background: transparent;
1512
+ border: 0;
1513
+ border-radius: var(--radius-xs);
1514
+ cursor: pointer;
1515
+ }
1516
+
1517
+ .rail-group-action:hover {
1518
+ color: var(--ink-1);
1519
+ background: var(--fill-hover);
1520
+ }
1521
+
1522
+ /* The subject name is a BUTTON in the Project and Shot contexts (it carries the
1523
+ `scene-crumb` / `shot-crumb` contract), and a plain span where the subject
1524
+ cannot act. The heading rule styles the text; this strips the UA button chrome
1525
+ so the two render identically. */
1526
+ button.rail-subject-name {
1527
+ background: transparent;
1528
+ border: 0;
1529
+ padding: 0;
1530
+ text-align: left;
1531
+ cursor: pointer;
1532
+ }
1533
+
1534
+ /* The two families are two lists (authored definitions, then the repo
1535
+ components a shot places). Adjacent means both are present, and the gap is
1536
+ what keeps them from reading as one run of rows. */
1537
+ .component-list + .component-list {
1538
+ margin-top: var(--space-2);
1539
+ }
1540
+
1541
+ /* A span on a definition row and a BUTTON on a code row (where it selects the
1542
+ placements), so the chrome reset is here rather than at the call site: the
1543
+ number has to read identically whichever it is, or the two lists look like
1544
+ two products. */
1545
+ .component-count {
1546
+ margin-left: auto;
1547
+ padding: 0 var(--space-1);
1548
+ border: 0;
1549
+ background: transparent;
1550
+ font: inherit;
1551
+ color: var(--ink-3);
1552
+ font-variant-numeric: var(--numeric);
1553
+ }
1554
+
1555
+ button.component-count {
1556
+ border-radius: var(--radius-md);
1557
+ cursor: pointer;
1558
+ }
1559
+
1560
+ button.component-count:hover:not(:disabled) {
1561
+ background: var(--fill-hover);
1562
+ color: var(--ink-1);
1563
+ }
1564
+
1565
+ /* Not `opacity`: the number still has to be readable. Nothing to press is the
1566
+ claim, and a cursor that says so is the whole affordance. */
1567
+ button.component-count:disabled {
1568
+ cursor: default;
1569
+ }
1570
+
1571
+ /* Outline drop feedback. A LINE for "beside this row", a filled ring for
1572
+ "inside it" — the two gestures have to look different before the drop, or
1573
+ reparenting happens by accident. The layers outline is FRONT FIRST, so the
1574
+ line above a row lands in front of it and the line below lands behind it;
1575
+ the storyboard outline shares the two lines under its own meaning. */
1576
+ .layer-row.is-drop-before {
1577
+ box-shadow: inset 0 2px 0 var(--accent);
1578
+ }
1579
+
1580
+ .layer-row.is-drop-after {
1581
+ box-shadow: inset 0 -2px 0 var(--accent);
1582
+ }
1583
+
1584
+ .layer-row.is-drop-into {
1585
+ box-shadow: inset 0 0 0 2px var(--accent);
1586
+ }
1587
+
1588
+ /* The lower line of an EXPANDED parent sits over its first child row, and it
1589
+ drops INTO the parent, at the front (Figma's rule). So it starts at the
1590
+ children's indent rather than the parent's, and reads as "inside" before the
1591
+ drop. A background layer, not a shadow, because a shadow cannot be inset
1592
+ from one side; the longhands leave the hover and selection fill alone. */
1593
+ .layer-row.is-drop-inside {
1594
+ background-image: linear-gradient(var(--accent), var(--accent));
1595
+ background-repeat: no-repeat;
1596
+ background-position: right bottom;
1597
+ background-size: calc(100% - var(--space-6) - (var(--depth, 0) + 1) * var(--tree-indent) - var(--mask-inset, 0px)) 2px;
1598
+ }
1599
+
1600
+ /* JUST PLACED: a layer the Insert drawer added without selecting it ("Use as
1601
+ background"). The row takes the accent wash and the name the accent ink,
1602
+ arriving once, so the eye finds where it went. The next selection clears
1603
+ it (`justPlaced`). Paper page 27, artboard 5. */
1604
+ @keyframes layer-just-placed-in {
1605
+ from { background: var(--accent-quiet); }
1606
+ }
1607
+
1608
+ .layer-row.is-just-placed,
1609
+ .layer-row.is-just-placed:hover {
1610
+ background: var(--accent-soft);
1611
+ }
1612
+
1613
+ .layer-row.is-just-placed .layer-name,
1614
+ .layer-row.is-just-placed .layer-kind {
1615
+ color: var(--accent-ink);
1616
+ }
1617
+
1618
+ @media (prefers-reduced-motion: no-preference) {
1619
+ .layer-row.is-just-placed { animation: layer-just-placed-in var(--dur-med) var(--ease); }
1620
+ }
1621
+
1622
+ .layer-placed-note {
1623
+ margin: 0;
1624
+ padding: var(--space-4) var(--space-6) 0;
1625
+ font-size: var(--type-sm);
1626
+ line-height: var(--leading-xs);
1627
+ color: var(--ink-3);
1628
+ }