@jxsuite/studio 2.0.0 → 2.1.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 (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-0hzentwq.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-0hzentwq.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-2c188n41.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-97qcgvdn.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-97qcgvdn.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-hhj92gcr.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-ygzav7z5.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-n9zmpxjg.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +23711 -35185
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +34 -9
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +270 -262
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -120
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +75 -2
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +113 -0
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qct0gt8f.js +0 -531
  363. package/dist/chunks/extension-sections-qct0gt8f.js.map +0 -12
  364. package/dist/chunks/files-02zn5y24.js +0 -50
  365. package/dist/chunks/files-02zn5y24.js.map +0 -9
  366. package/dist/chunks/git-panel-mbb0y0hz.js +0 -28
  367. package/dist/chunks/git-panel-mbb0y0hz.js.map +0 -9
  368. package/dist/chunks/layers-panel-9qekmqk1.js +0 -26
  369. package/dist/chunks/layers-panel-9qekmqk1.js.map +0 -9
  370. package/dist/chunks/settings-modal-gj0hrah4.js +0 -29
  371. package/dist/chunks/settings-modal-gj0hrah4.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  381. package/dist/chunks/studio-568nx4t5.js +0 -469
  382. package/dist/chunks/studio-568nx4t5.js.map +0 -14
  383. package/dist/chunks/studio-9smfzqhc.js +0 -19
  384. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  385. package/dist/chunks/studio-asvf0j9e.js +0 -429
  386. package/dist/chunks/studio-asvf0j9e.js.map +0 -13
  387. package/dist/chunks/studio-d77qm3pk.js +0 -3427
  388. package/dist/chunks/studio-d77qm3pk.js.map +0 -26
  389. package/dist/chunks/studio-j6gqyjf4.js +0 -1854
  390. package/dist/chunks/studio-j6gqyjf4.js.map +0 -18
  391. package/dist/chunks/studio-n9zmpxjg.js.map +0 -115
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-rq0vxb19.js +0 -3744
  394. package/dist/chunks/studio-rq0vxb19.js.map +0 -22
  395. package/dist/chunks/studio-wd6ewdvd.js +0 -853
  396. package/dist/chunks/studio-wd6ewdvd.js.map +0 -12
  397. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  398. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  399. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  400. package/dist/chunks/studio-ygzav7z5.js.map +0 -46
  401. package/dist/chunks/studio-zmy7241e.js +0 -399
  402. package/dist/chunks/studio-zmy7241e.js.map +0 -12
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-2c188n41.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-hhj92gcr.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
package/index.html CHANGED
@@ -5,4701 +5,41 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <title>Jx Studio</title>
7
7
  <link rel="stylesheet" href="./dist/studio.css" />
8
- <style>
9
- /* Jx brand mono font, vendored in ./fonts (SIL OFL 1.1, see fonts/OFL.txt).
10
- Latin subset only; the stack falls back to SF Mono / Fira Code for
11
- other scripts. Monaco remeasures after load (src/services/monaco-setup.ts). */
12
- @font-face {
13
- font-family: "JetBrains Mono";
14
- font-style: normal;
15
- font-weight: 400;
16
- font-display: swap;
17
- src: url("./fonts/jetbrains-mono-400.woff2") format("woff2");
18
- }
19
- @font-face {
20
- font-family: "JetBrains Mono";
21
- font-style: normal;
22
- font-weight: 500;
23
- font-display: swap;
24
- src: url("./fonts/jetbrains-mono-500.woff2") format("woff2");
25
- }
26
- @font-face {
27
- font-family: "JetBrains Mono";
28
- font-style: normal;
29
- font-weight: 700;
30
- font-display: swap;
31
- src: url("./fonts/jetbrains-mono-700.woff2") format("woff2");
32
- }
33
- *,
34
- *::before,
35
- *::after {
36
- box-sizing: border-box;
37
- margin: 0;
38
- }
39
- sp-tab:not(:first-of-type) {
40
- margin-inline-start: var(--mod-tabs-item-horizontal-spacing, 8px);
41
- }
42
- html,
43
- body {
44
- height: 100%;
45
- overflow: hidden;
46
- /* html/body sit outside <sp-theme>, so the --spectrum-* tokens are not
47
- in scope here; the hex fallback is the intentional pre-theme backdrop
48
- shown behind the app before sp-theme fills the viewport. */
49
- background: var(--spectrum-background-layer-1-color, #111111);
50
- }
51
- /* Panel layout widths. These must live on :root (the <html> element),
52
- not on sp-theme or #app, because the resize logic in
53
- src/ui/panel-resize.ts reads and writes them as inline styles on
54
- document.documentElement. A definition on any closer ancestor of #app
55
- (sp-theme or body) would shadow that inline override and freeze the
56
- sidebars. The #app.left/right-collapsed rules override per instance. */
57
- :root {
58
- --panel-w-left: 240px;
59
- --panel-w-right: 280px;
60
- --panel-w-chat: 320px;
61
- }
62
- /* Studio semantic token layer.
63
- Declared on sp-theme — not :root — so each var(--spectrum-*) reference
64
- resolves against the tokens sp-theme exposes via its :host rules. At
65
- :root (the <html> ancestor of sp-theme) every --spectrum-* is undefined,
66
- so these would silently collapse to the hex fallback and the app would
67
- never respond to the Spectrum theme. All studio chrome, including the
68
- #layer-* overlay hosts, lives inside <sp-theme>. */
69
- sp-theme {
70
- display: block;
71
- height: 100%;
72
- /* Surfaces. The hex fallbacks mirror the Jx brand ramp installed by
73
- the 'app' theme fragment (src/ui/jx-theme.ts). */
74
- --bg: var(--spectrum-background-layer-1-color, #111111);
75
- --bg-panel: var(--spectrum-background-layer-2-color, #1a1a1a);
76
- --bg-input: var(--spectrum-gray-100, #1a1a1a);
77
- --border: var(--spectrum-gray-200, #222222);
78
- /* Text */
79
- --fg: var(--spectrum-neutral-content-color-default, #e4e4e7);
80
- --fg-dim: var(--spectrum-gray-600, #a1a1aa);
81
- /* Accent and status. Under the brand ramp (src/ui/jx-theme.ts),
82
- accent-color-700 is the exact Jx brand blue and 900 is the soft
83
- on-dark tint. */
84
- --accent: var(--spectrum-accent-color-700, #3b82f6);
85
- --accent-fg: var(--spectrum-white, #ffffff);
86
- --danger: var(--spectrum-negative-color-900, #f44747);
87
- --success: var(--spectrum-positive-color-900, #89d185);
88
- --tag: var(--spectrum-informative-color-900, #93c5fd);
89
- --signal: var(--spectrum-notice-color-900, #dcdcaa);
90
- --handler: var(--spectrum-purple-900, #c586c0);
91
- --warning: var(--spectrum-orange-900, #c5a332);
92
- --map: var(--spectrum-indigo-900, #5b4fc7);
93
- --slot-c: var(--spectrum-seafoam-900, #1a8a7a);
94
- --switch-c: var(--danger);
95
- --case-c: var(--spectrum-informative-color-800, #60a5fa);
96
- /* Corner radius */
97
- --radius: var(--spectrum-corner-radius-100, 3px);
98
- /* Monospace stack for code/source chrome. JetBrains Mono is the Jx
99
- brand mono (vendored in ./fonts); SF Mono / Fira Code remain as
100
- system fallbacks ahead of the Spectrum stack (Source Code Pro /
101
- Monaco). The brand fragment sets the same order on
102
- --spectrum-code-font-family-stack for SWC components. */
103
- --font-mono:
104
- "JetBrains Mono", "SF Mono", "Fira Code",
105
- var(--spectrum-code-font-family-stack, monospace);
106
- /* Hover wash and accent tints */
107
- --hover-bg: rgba(255, 255, 255, 0.04);
108
- --accent-8: color-mix(in srgb, var(--accent) 8%, transparent);
109
- --accent-10: color-mix(in srgb, var(--accent) 10%, transparent);
110
- --accent-15: color-mix(in srgb, var(--accent) 15%, transparent);
111
- --accent-20: color-mix(in srgb, var(--accent) 20%, transparent);
112
- --accent-50: color-mix(in srgb, var(--accent) 50%, transparent);
113
- /* Light canvas palette (stylebook, block/element previews, content
114
- mode). These surfaces always render as a light "document" regardless
115
- of the app chrome, so the ramp is derived from the theme-independent
116
- Spectrum white/black tokens via color-mix rather than hard-coded hex.
117
- The percentage is the black (foreground) or white (background) blend
118
- of each step; this keeps the canvas light even in the dark chrome
119
- while still being Spectrum-sourced. */
120
- --canvas-fg: color-mix(
121
- in srgb,
122
- var(--spectrum-black, #000) 90%,
123
- var(--spectrum-white, #fff)
124
- );
125
- --canvas-fg-2: color-mix(
126
- in srgb,
127
- var(--spectrum-black, #000) 80%,
128
- var(--spectrum-white, #fff)
129
- );
130
- --canvas-fg-3: color-mix(
131
- in srgb,
132
- var(--spectrum-black, #000) 67%,
133
- var(--spectrum-white, #fff)
134
- );
135
- --canvas-dim: color-mix(
136
- in srgb,
137
- var(--spectrum-black, #000) 47%,
138
- var(--spectrum-white, #fff)
139
- );
140
- --canvas-muted: color-mix(
141
- in srgb,
142
- var(--spectrum-black, #000) 40%,
143
- var(--spectrum-white, #fff)
144
- );
145
- --canvas-light: color-mix(
146
- in srgb,
147
- var(--spectrum-black, #000) 27%,
148
- var(--spectrum-white, #fff)
149
- );
150
- --canvas-border: color-mix(
151
- in srgb,
152
- var(--spectrum-black, #000) 13%,
153
- var(--spectrum-white, #fff)
154
- );
155
- --canvas-rule: color-mix(
156
- in srgb,
157
- var(--spectrum-black, #000) 7%,
158
- var(--spectrum-white, #fff)
159
- );
160
- --canvas-bg-1: color-mix(
161
- in srgb,
162
- var(--spectrum-white, #fff) 96%,
163
- var(--spectrum-black, #000)
164
- );
165
- --canvas-bg-2: color-mix(
166
- in srgb,
167
- var(--spectrum-white, #fff) 94%,
168
- var(--spectrum-black, #000)
169
- );
170
- --canvas-track: color-mix(
171
- in srgb,
172
- var(--spectrum-white, #fff) 88%,
173
- var(--spectrum-black, #000)
174
- );
175
- /* Data explorer syntax colors (mapped to nearest Spectrum hues) */
176
- --data-key: var(--spectrum-blue-700, #3b82f6);
177
- --data-string: var(--spectrum-orange-700, #ce9178);
178
- --data-number: var(--spectrum-celery-700, #b5cea8);
179
- --data-boolean: var(--tag);
180
- /* Typography — align the chrome with the Spectrum sans stack used by
181
- the SWC components; 12px maps exactly to font-size-75. line-height
182
- stays 1.5 (a deliberate reading height; the Spectrum body token is
183
- 1.3, which would tighten the whole UI). */
184
- color: var(--fg);
185
- background: var(--bg);
186
- font-family: var(
187
- --spectrum-sans-font-family-stack,
188
- -apple-system,
189
- BlinkMacSystemFont,
190
- "Segoe UI",
191
- system-ui,
192
- sans-serif
193
- );
194
- font-size: var(--spectrum-font-size-75, 12px);
195
- line-height: 1.5;
196
- }
197
-
198
- /* ─── Layout ─────────────────────────────────── */
199
- #app {
200
- display: grid;
201
- grid-template-rows: 36px auto auto auto minmax(0, 1fr) 24px;
202
- grid-template-columns: 48px var(--panel-w-left) 1fr var(--panel-w-right) var(
203
- --panel-w-chat
204
- );
205
- height: 100%;
206
- }
207
- #toolbar {
208
- grid-column: 1 / -1;
209
- display: flex;
210
- align-items: center;
211
- gap: 6px;
212
- padding: 0 8px;
213
- background: var(--bg);
214
- border-bottom: 1px solid var(--border);
215
- overflow: hidden;
216
- min-width: 0;
217
- /* Drive the responsive collapse below off the toolbar's own width. */
218
- container-type: inline-size;
219
- container-name: toolbar;
220
- }
221
- #toolbar > :not(.window-controls) {
222
- min-width: 0;
223
- flex-shrink: 1;
224
- overflow: hidden;
225
- }
226
- #toolbar > .tb-spacer {
227
- flex-shrink: 999;
228
- }
229
- #toolbar.electrobun-webkit-app-region-drag {
230
- -webkit-app-region: drag;
231
- }
232
- #toolbar sp-action-group,
233
- #toolbar sp-action-button,
234
- #toolbar .breadcrumb {
235
- -webkit-app-region: no-drag;
236
- }
237
- .window-controls {
238
- margin-left: auto;
239
- flex-shrink: 0;
240
- }
241
- .window-controls .csd-close:hover {
242
- background: var(--spectrum-negative-background-color-default, #e34850);
243
- color: white;
244
- }
245
- /* macOS traffic-light buttons */
246
- .window-controls.mac {
247
- margin-left: 0;
248
- margin-right: 8px;
249
- order: -1;
250
- gap: 8px;
251
- }
252
- .window-controls.mac sp-action-button {
253
- /* explicit min/max needed: as a flex item the button's auto min-width
254
- is the inner shadow-DOM button's min-content size (~28px), which
255
- would override width and squash the circle into an oval */
256
- --spectrum-actionbutton-min-width: 12px;
257
- --mod-actionbutton-min-width: 12px;
258
- --mod-actionbutton-height: 12px;
259
- --mod-actionbutton-edge-to-text: 0px;
260
- --mod-actionbutton-edge-to-visual-only: 0px;
261
- width: 12px;
262
- min-width: 12px;
263
- max-width: 12px;
264
- height: 12px;
265
- min-height: 12px;
266
- max-height: 12px;
267
- border-radius: 50%;
268
- overflow: hidden;
269
- border: none;
270
- padding: 0;
271
- }
272
- .window-controls.mac .csd-close {
273
- background: #ff5f57;
274
- }
275
- .window-controls.mac .csd-minimize {
276
- background: #febc2e;
277
- }
278
- .window-controls.mac .csd-maximize {
279
- background: #28c840;
280
- }
281
- .window-controls.mac sp-action-button:hover {
282
- filter: brightness(0.85);
283
- }
284
- .window-controls.mac sp-action-button sp-icon-remove,
285
- .window-controls.mac sp-action-button sp-icon-rectangle,
286
- .window-controls.mac sp-action-button sp-icon-close {
287
- display: none;
288
- }
289
- .window-controls.mac:hover sp-action-button sp-icon-remove,
290
- .window-controls.mac:hover sp-action-button sp-icon-rectangle,
291
- .window-controls.mac:hover sp-action-button sp-icon-close {
292
- display: inline-flex;
293
- color: rgba(0, 0, 0, 0.5);
294
- width: 8px;
295
- height: 8px;
296
- }
297
- /* Resize edge zones */
298
- .resize-edge {
299
- position: fixed;
300
- z-index: 9999;
301
- -webkit-app-region: no-drag;
302
- }
303
- .resize-edge.top {
304
- top: 0;
305
- left: 6px;
306
- right: 6px;
307
- height: 4px;
308
- cursor: ns-resize;
309
- }
310
- .resize-edge.bottom {
311
- bottom: 0;
312
- left: 6px;
313
- right: 6px;
314
- height: 4px;
315
- cursor: ns-resize;
316
- }
317
- .resize-edge.left {
318
- left: 0;
319
- top: 6px;
320
- bottom: 6px;
321
- width: 4px;
322
- cursor: ew-resize;
323
- }
324
- .resize-edge.right {
325
- right: 0;
326
- top: 6px;
327
- bottom: 6px;
328
- width: 4px;
329
- cursor: ew-resize;
330
- }
331
- .resize-edge.top-left {
332
- top: 0;
333
- left: 0;
334
- width: 6px;
335
- height: 6px;
336
- cursor: nwse-resize;
337
- }
338
- .resize-edge.top-right {
339
- top: 0;
340
- right: 0;
341
- width: 6px;
342
- height: 6px;
343
- cursor: nesw-resize;
344
- }
345
- .resize-edge.bottom-left {
346
- bottom: 0;
347
- left: 0;
348
- width: 6px;
349
- height: 6px;
350
- cursor: nesw-resize;
351
- }
352
- .resize-edge.bottom-right {
353
- bottom: 0;
354
- right: 0;
355
- width: 6px;
356
- height: 6px;
357
- cursor: nwse-resize;
358
- }
359
-
360
- #tab-strip {
361
- grid-row: 2;
362
- grid-column: 3;
363
- min-height: 0;
364
- min-width: 0;
365
- }
366
- #tab-strip:empty {
367
- display: none;
368
- }
369
- #tab-bar {
370
- grid-row: 3;
371
- grid-column: 3;
372
- min-width: 0;
373
- }
374
- #tab-bar:empty {
375
- display: none;
376
- }
377
- /* Above-canvas frontmatter Properties panel (content-collection docs, edit mode) */
378
- #frontmatter-panel {
379
- grid-row: 4;
380
- grid-column: 3;
381
- overflow-y: auto;
382
- max-height: 40vh;
383
- background: var(--bg);
384
- border-bottom: 1px solid var(--border);
385
- }
386
- #frontmatter-panel sp-accordion {
387
- border: none;
388
- }
389
- #frontmatter-panel sp-accordion-item {
390
- --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-50, 11px);
391
- }
392
- #frontmatter-panel[hidden] {
393
- display: none;
394
- }
395
- .fm-panel-body {
396
- max-width: 760px;
397
- margin: 0 auto;
398
- padding: 2px 12px 8px;
399
- }
400
- .fm-panel-body .style-row > sp-textfield,
401
- .fm-panel-body .style-row > .media-picker {
402
- width: 100%;
403
- }
404
- #activity-bar {
405
- grid-row: 2 / 6;
406
- grid-column: 1;
407
- display: flex;
408
- flex-direction: column;
409
- background: var(--bg);
410
- border-right: 1px solid var(--border);
411
- }
412
- #left-panel {
413
- grid-row: 2 / 6;
414
- grid-column: 2;
415
- overflow-y: auto;
416
- background: var(--bg-panel);
417
- border-right: 1px solid var(--border);
418
- }
419
- #canvas-wrap {
420
- grid-row: 5;
421
- grid-column: 3;
422
- position: relative;
423
- overflow: auto;
424
- background: var(--bg-panel);
425
- }
426
- #right-panel {
427
- grid-row: 2 / 6;
428
- grid-column: 4;
429
- overflow-y: auto;
430
- background: var(--bg);
431
- border-left: 1px solid var(--border);
432
- }
433
- /* Persistent AI chat sidebar — always a flex column (the chat UI owns its
434
- own scrolling), unlike #right-panel which scrolls the whole panel. */
435
- #chat-panel {
436
- grid-row: 2 / 6;
437
- grid-column: 5;
438
- display: flex;
439
- flex-direction: column;
440
- overflow: hidden;
441
- background: var(--bg);
442
- border-left: 1px solid var(--border);
443
- }
444
- #chat-panel .panel-body {
445
- flex: 1;
446
- min-height: 0;
447
- display: flex;
448
- flex-direction: column;
449
- overflow: hidden;
450
- }
451
-
452
- /* ─── Collapsed sidebars ──────────────────────── */
453
- #app.left-collapsed {
454
- --panel-w-left: 0px;
455
- }
456
- #app.left-collapsed #left-panel,
457
- #app.left-collapsed #resize-left {
458
- display: none;
459
- }
460
- #app.right-collapsed {
461
- --panel-w-right: 0px;
462
- }
463
- #app.right-collapsed #right-panel,
464
- #app.right-collapsed #resize-right {
465
- display: none;
466
- }
467
- #app.chat-collapsed {
468
- --panel-w-chat: 0px;
469
- }
470
- #app.chat-collapsed #chat-panel,
471
- #app.chat-collapsed #resize-chat {
472
- display: none;
473
- }
474
-
475
- /* ─── AI Panel Chat UI ──────────────────────────── */
476
- .ai-tab-body {
477
- display: flex;
478
- flex-direction: column;
479
- flex: 1;
480
- min-height: 0;
481
- overflow: hidden;
482
- }
483
- .ai-chat-header {
484
- flex-shrink: 0;
485
- display: flex;
486
- align-items: center;
487
- gap: 4px;
488
- padding: 4px 6px;
489
- min-width: 0;
490
- border-bottom: 1px solid var(--border);
491
- font-size: var(--spectrum-font-size-75, 12px);
492
- }
493
- .ai-chat-title {
494
- min-width: 0;
495
- overflow: hidden;
496
- text-overflow: ellipsis;
497
- white-space: nowrap;
498
- font-weight: 600;
499
- }
500
- .ai-header-spacer {
501
- flex: 1;
502
- }
503
- /* THE chat scroller — bounded by min-height:0 at every flex level above. */
504
- .ai-chat-messages {
505
- flex: 1 1 0;
506
- min-height: 0;
507
- overflow-y: auto;
508
- overscroll-behavior: contain;
509
- display: flex;
510
- flex-direction: column;
511
- gap: 8px;
512
- padding: 8px;
513
- font-size: var(--spectrum-font-size-75, 12px);
514
- line-height: 1.5;
515
- }
516
- .ai-chat-empty {
517
- color: var(--fg-dim);
518
- text-align: center;
519
- padding: 24px 12px;
520
- }
521
- .ai-msg-user {
522
- align-self: flex-end;
523
- max-width: 85%;
524
- background: var(--accent-15);
525
- border-radius: 8px 8px 2px 8px;
526
- padding: 6px 10px;
527
- }
528
- .ai-msg-user-body {
529
- white-space: pre-wrap;
530
- overflow-wrap: anywhere;
531
- }
532
- .ai-msg-assistant {
533
- align-self: stretch;
534
- min-width: 0;
535
- }
536
- .ai-msg-md {
537
- overflow-wrap: anywhere;
538
- }
539
- .ai-msg-md > *:first-child {
540
- margin-top: 0;
541
- }
542
- .ai-msg-md > *:last-child {
543
- margin-bottom: 0;
544
- }
545
- .ai-msg-md code {
546
- background: rgba(0, 0, 0, 0.3);
547
- padding: 1px 4px;
548
- border-radius: var(--radius);
549
- font-size: var(--spectrum-font-size-50, 11px);
550
- font-family: var(--font-mono);
551
- }
552
- .ai-msg-md pre {
553
- background: rgba(0, 0, 0, 0.3);
554
- padding: 8px;
555
- border-radius: var(--radius);
556
- overflow-x: auto;
557
- margin: 6px 0;
558
- }
559
- .ai-msg-md pre code {
560
- background: none;
561
- padding: 0;
562
- }
563
- .ai-msg-md table {
564
- border-collapse: collapse;
565
- margin: 6px 0;
566
- }
567
- .ai-msg-md th,
568
- .ai-msg-md td {
569
- border: 1px solid var(--border);
570
- padding: 2px 6px;
571
- }
572
- .ai-msg-streaming {
573
- white-space: pre-wrap;
574
- overflow-wrap: anywhere;
575
- }
576
- .ai-msg-streaming::after {
577
- content: "▋";
578
- color: var(--accent);
579
- animation: ai-cursor-blink 1s steps(2) infinite;
580
- }
581
- @keyframes ai-cursor-blink {
582
- 50% {
583
- opacity: 0;
584
- }
585
- }
586
- .ai-msg-typing {
587
- display: flex;
588
- gap: 4px;
589
- padding: 4px 2px;
590
- }
591
- .ai-msg-typing span {
592
- width: 6px;
593
- height: 6px;
594
- border-radius: 50%;
595
- background: var(--fg-dim);
596
- animation: ai-typing-bounce 1.2s infinite;
597
- }
598
- .ai-msg-typing span:nth-child(2) {
599
- animation-delay: 0.2s;
600
- }
601
- .ai-msg-typing span:nth-child(3) {
602
- animation-delay: 0.4s;
603
- }
604
- @keyframes ai-typing-bounce {
605
- 0%,
606
- 60%,
607
- 100% {
608
- opacity: 0.3;
609
- }
610
- 30% {
611
- opacity: 1;
612
- }
613
- }
614
- .ai-msg-tools {
615
- display: flex;
616
- flex-direction: column;
617
- gap: 4px;
618
- margin-top: 6px;
619
- }
620
- .ai-tool-chip {
621
- display: inline-flex;
622
- align-items: center;
623
- gap: 6px;
624
- align-self: flex-start;
625
- max-width: 100%;
626
- overflow: hidden;
627
- text-overflow: ellipsis;
628
- white-space: nowrap;
629
- background: var(--hover-bg);
630
- border-left: 2px solid var(--accent);
631
- border-radius: var(--radius);
632
- padding: 3px 8px;
633
- font-size: var(--spectrum-font-size-50, 11px);
634
- color: var(--fg-dim);
635
- font-family: var(--font-mono);
636
- }
637
- .ai-msg-tool-error {
638
- background: var(--hover-bg);
639
- border-left: 2px solid var(--danger);
640
- border-radius: var(--radius);
641
- padding: 4px 8px;
642
- font-size: var(--spectrum-font-size-50, 11px);
643
- color: var(--fg-dim);
644
- }
645
- .ai-msg-error {
646
- border-left: 2px solid var(--danger);
647
- border-radius: var(--radius);
648
- background: var(--hover-bg);
649
- padding: 6px 8px;
650
- color: var(--danger);
651
- }
652
- .ai-msg-error-advice {
653
- margin-top: 4px;
654
- color: var(--fg-dim);
655
- }
656
- .ai-msg-context-chips {
657
- display: flex;
658
- flex-wrap: wrap;
659
- gap: 4px;
660
- margin-top: 6px;
661
- }
662
- .ai-context-chip {
663
- display: inline-flex;
664
- align-items: center;
665
- gap: 2px;
666
- max-width: 100%;
667
- overflow: hidden;
668
- text-overflow: ellipsis;
669
- white-space: nowrap;
670
- background: var(--bg-input);
671
- border: 1px solid var(--border);
672
- border-radius: var(--radius);
673
- padding: 1px 6px;
674
- font-size: var(--spectrum-font-size-50, 11px);
675
- color: var(--fg-dim);
676
- }
677
- /* Sticky composer */
678
- .ai-composer {
679
- flex-shrink: 0;
680
- display: flex;
681
- flex-direction: column;
682
- gap: 6px;
683
- padding: 8px;
684
- border-top: 1px solid var(--border);
685
- }
686
- .ai-composer-chips {
687
- display: flex;
688
- flex-wrap: wrap;
689
- gap: 4px;
690
- }
691
- .ai-composer-input {
692
- width: 100%;
693
- box-sizing: border-box;
694
- resize: none;
695
- min-height: 30px;
696
- max-height: 120px;
697
- overflow-y: auto;
698
- background: var(--bg-input);
699
- color: var(--fg);
700
- border: 1px solid var(--border);
701
- border-radius: var(--radius);
702
- padding: 6px 8px;
703
- font-size: var(--spectrum-font-size-75, 12px);
704
- font-family: inherit;
705
- line-height: 1.4;
706
- }
707
- .ai-composer-input:focus {
708
- border-color: var(--accent);
709
- outline: none;
710
- }
711
- .ai-composer-row {
712
- display: flex;
713
- align-items: center;
714
- gap: 4px;
715
- min-width: 0;
716
- }
717
- .ai-model-picker {
718
- max-width: 140px;
719
- min-width: 0;
720
- }
721
- /* Sessions list */
722
- .ai-sessions {
723
- flex: 1 1 0;
724
- min-height: 0;
725
- overflow-y: auto;
726
- font-size: var(--spectrum-font-size-75, 12px);
727
- }
728
- .ai-sessions-empty {
729
- color: var(--fg-dim);
730
- text-align: center;
731
- padding: 24px 12px;
732
- }
733
- .ai-session-row {
734
- display: flex;
735
- align-items: center;
736
- gap: 4px;
737
- padding: 6px 8px;
738
- cursor: pointer;
739
- border-bottom: 1px solid var(--border);
740
- min-width: 0;
741
- }
742
- .ai-session-row:hover {
743
- background: var(--hover-bg);
744
- }
745
- .ai-session-text {
746
- flex: 1;
747
- min-width: 0;
748
- }
749
- .ai-session-title {
750
- font-weight: 600;
751
- overflow: hidden;
752
- text-overflow: ellipsis;
753
- white-space: nowrap;
754
- }
755
- .ai-session-meta {
756
- color: var(--fg-dim);
757
- font-size: var(--spectrum-font-size-50, 11px);
758
- }
759
- .ai-session-delete {
760
- visibility: hidden;
761
- }
762
- .ai-session-row:hover .ai-session-delete {
763
- visibility: visible;
764
- }
765
- .ai-status-center {
766
- display: flex;
767
- flex-direction: column;
768
- align-items: center;
769
- justify-content: center;
770
- flex: 1;
771
- gap: 12px;
772
- padding: 24px;
773
- text-align: center;
774
- color: var(--fg-dim);
775
- font-size: var(--spectrum-font-size-75, 12px);
776
- }
777
- .ai-code-snippet {
778
- background: var(--bg-input);
779
- padding: 4px 8px;
780
- border-radius: var(--radius);
781
- font-size: var(--spectrum-font-size-50, 11px);
782
- }
783
- .ai-managed-connect {
784
- display: flex;
785
- flex-direction: column;
786
- align-items: center;
787
- gap: 10px;
788
- width: 100%;
789
- }
790
- .ai-managed-connect-error {
791
- color: var(--danger);
792
- font-size: var(--spectrum-font-size-50, 11px);
793
- max-width: 260px;
794
- }
795
- .ai-managed-connect-divider {
796
- color: var(--fg-dim);
797
- font-size: var(--spectrum-font-size-50, 11px);
798
- margin-top: 6px;
799
- }
800
- #statusbar {
801
- grid-row: 6;
802
- grid-column: 1 / -1;
803
- display: flex;
804
- align-items: center;
805
- padding: 0 8px;
806
- font-size: var(--spectrum-font-size-50, 11px);
807
- color: var(--fg-dim);
808
- background: var(--bg);
809
- border-top: 1px solid var(--border);
810
- }
811
- #statusbar .sb-path-seg {
812
- cursor: pointer;
813
- border-radius: var(--spectrum-corner-radius-75, 2px);
814
- padding: 0 2px;
815
- }
816
- #statusbar .sb-path-seg:hover {
817
- color: var(--fg);
818
- background: var(--hover-bg);
819
- text-decoration: underline;
820
- }
821
- #statusbar .sb-path-sep {
822
- color: var(--fg-dim);
823
- }
824
-
825
- /* ─── Tab strip ───────────────────────────────── */
826
- .tab-strip {
827
- display: flex;
828
- align-items: stretch;
829
- gap: 0;
830
- padding: 0 8px;
831
- background: var(--bg-panel);
832
- border-bottom: 1px solid var(--border);
833
- overflow-x: auto;
834
- overflow-y: hidden;
835
- scrollbar-width: none;
836
- }
837
- .tab-strip::-webkit-scrollbar {
838
- display: none;
839
- }
840
- .tab-strip-tab {
841
- display: flex;
842
- align-items: center;
843
- gap: 4px;
844
- padding: 4px 8px;
845
- font-size: var(--spectrum-font-size-50, 11px);
846
- color: var(--fg-dim);
847
- cursor: pointer;
848
- white-space: nowrap;
849
- border-bottom: 2px solid transparent;
850
- user-select: none;
851
- flex-shrink: 0;
852
- }
853
- .tab-strip-tab:hover {
854
- color: var(--fg);
855
- background: var(--hover-bg);
856
- }
857
- .tab-strip-tab.active {
858
- color: var(--fg);
859
- border-bottom-color: var(--accent);
860
- }
861
- .tab-strip-label {
862
- max-width: 140px;
863
- overflow: hidden;
864
- text-overflow: ellipsis;
865
- }
866
- .tab-strip-dirty {
867
- color: var(--accent);
868
- font-size: 8px;
869
- line-height: 1;
870
- }
871
- .tab-strip-close {
872
- display: flex;
873
- align-items: center;
874
- justify-content: center;
875
- width: 16px;
876
- height: 16px;
877
- padding: 0;
878
- border: none;
879
- background: none;
880
- color: var(--fg-dim);
881
- font-size: var(--spectrum-font-size-100, 14px);
882
- line-height: 1;
883
- border-radius: var(--radius);
884
- cursor: pointer;
885
- opacity: 0;
886
- }
887
- .tab-strip-tab:hover .tab-strip-close,
888
- .tab-strip-tab.active .tab-strip-close {
889
- opacity: 1;
890
- }
891
- .tab-strip-close:hover {
892
- background: var(--hover-bg);
893
- color: var(--fg);
894
- }
895
-
896
- /* ─── Resize handles ─────────────────────────── */
897
- .resize-handle {
898
- grid-row: 5;
899
- width: 5px;
900
- margin-left: -3px;
901
- margin-right: -2px;
902
- cursor: col-resize;
903
- z-index: 10;
904
- position: relative;
905
- }
906
- .resize-handle:hover,
907
- .resize-handle.dragging {
908
- background: var(--accent, #3b82f6);
909
- opacity: 0.5;
910
- }
911
- #resize-left {
912
- grid-column: 3;
913
- justify-self: start;
914
- }
915
- #resize-right {
916
- grid-column: 4;
917
- justify-self: start;
918
- }
919
- #resize-chat {
920
- grid-column: 5;
921
- justify-self: start;
922
- }
923
-
924
- /* ─── Canvas (multi-panel) ────────────────────── */
925
- #canvas-wrap {
926
- display: flex;
927
- gap: 24px;
928
- align-items: flex-start;
929
- }
930
- .panzoom-wrap {
931
- display: inline-flex;
932
- gap: 24px;
933
- align-items: flex-start;
934
- transform-origin: 0 0;
935
- margin-block: auto;
936
- }
937
- .canvas-panel {
938
- flex-shrink: 0;
939
- }
940
- .source-wrap {
941
- display: flex;
942
- flex-direction: column;
943
- width: 100%;
944
- height: 100%;
945
- flex: 1;
946
- min-width: 0;
947
- }
948
- .tab-bar {
949
- display: flex;
950
- align-items: center;
951
- gap: 8px;
952
- padding: 4px 8px;
953
- border-bottom: 1px solid var(--border);
954
- background: var(--bg-panel);
955
- }
956
- .tab-bar .tb-spacer {
957
- flex: 1;
958
- }
959
- .tab-bar sp-picker.tab-bar-param {
960
- max-width: 200px;
961
- }
962
- /* Zoom widget label: fixed floor so the row doesn't jitter as the % digits change. */
963
- .tab-bar .tb-zoom-label {
964
- min-width: 48px;
965
- font-family: var(--font-mono);
966
- }
967
- .source-editor {
968
- flex: 1;
969
- min-height: 0;
970
- }
971
- /* ─── Content edit mode canvas ─────────────── */
972
- .content-edit-canvas {
973
- width: 100%;
974
- height: 100%;
975
- overflow-y: auto;
976
- overflow-x: hidden;
977
- display: flex;
978
- justify-content: center;
979
- padding: 32px 0;
980
- }
981
- .content-edit-column {
982
- width: 100%;
983
- min-height: 100%;
984
- }
985
- /* A content PAGE fills the viewport (a document-like surface you can click into below the
986
- text). A component DEFINITION is a fragment — flooring its column to the viewport and letting
987
- the flex parent vertical-stretch it leaves dead scrollable space below a short component.
988
- `is-component` (set by renderCanvas when the doc root is a custom element) makes the column
989
- hug its iframe and sit at the top instead. */
990
- .content-edit-column.is-component {
991
- min-height: 0;
992
- align-self: flex-start;
993
- }
994
- .content-edit-column .canvas-panel.full-width {
995
- flex: 1;
996
- min-width: 0;
997
- }
998
- .content-edit-column .canvas-panel-viewport {
999
- border: none;
1000
- background: transparent;
1001
- }
1002
- .function-editor-header {
1003
- display: flex;
1004
- align-items: center;
1005
- justify-content: space-between;
1006
- padding: 4px 8px;
1007
- background: var(--bg-panel);
1008
- border-bottom: 1px solid var(--border);
1009
- font-size: var(--spectrum-font-size-75, 12px);
1010
- color: var(--fg);
1011
- font-family: var(--font-mono);
1012
- }
1013
- .canvas-panel-header {
1014
- padding: 4px 8px;
1015
- font-size: var(--spectrum-font-size-50, 11px);
1016
- color: var(--fg-dim);
1017
- background: var(--bg-panel);
1018
- border: 1px solid var(--border);
1019
- border-bottom: none;
1020
- border-radius: var(--radius) var(--radius) 0 0;
1021
- text-align: center;
1022
- cursor: pointer;
1023
- user-select: none;
1024
- font-family: var(--font-mono);
1025
- }
1026
- .canvas-panel-header.active {
1027
- color: var(--accent);
1028
- border-color: var(--accent);
1029
- }
1030
- .canvas-panel-viewport {
1031
- position: relative;
1032
- background: var(--spectrum-white, #fff);
1033
- border: 1px solid var(--border);
1034
- /* The viewport is a light document surface, so pin a light color-scheme
1035
- for native form controls and scrollbars rendered inside it. */
1036
- color-scheme: light;
1037
- }
1038
- .canvas-panel-header.active + .canvas-panel-viewport {
1039
- border-color: var(--accent);
1040
- }
1041
- .canvas-panel-canvas {
1042
- isolation: isolate;
1043
- }
1044
- .canvas-panel-canvas * {
1045
- cursor: default;
1046
- }
1047
- .canvas-panel-canvas slot:empty {
1048
- display: block;
1049
- min-height: 3rem;
1050
- border: 2px dashed var(--spectrum-gray-400, #999);
1051
- border-radius: var(--radius);
1052
- position: relative;
1053
- background: repeating-linear-gradient(
1054
- 45deg,
1055
- transparent,
1056
- transparent 10px,
1057
- rgba(128, 128, 128, 0.03) 10px,
1058
- rgba(128, 128, 128, 0.03) 20px
1059
- );
1060
- }
1061
- .canvas-panel-canvas slot:empty::before {
1062
- content: "slot";
1063
- position: absolute;
1064
- top: 50%;
1065
- left: 50%;
1066
- transform: translate(-50%, -50%);
1067
- font-size: 0.75rem;
1068
- color: var(--spectrum-gray-500, #888);
1069
- font-family: var(--font-mono);
1070
- pointer-events: none;
1071
- }
1072
- /* Single-canvas fallback (no $media) */
1073
- .canvas-panel.full-width {
1074
- min-width: 0;
1075
- }
1076
- .overlay-box {
1077
- position: absolute;
1078
- pointer-events: none;
1079
- }
1080
- .overlay-selection {
1081
- border: 2px solid var(--accent);
1082
- }
1083
- .overlay-hover {
1084
- border: 1px solid var(--accent-50);
1085
- }
1086
- .overlay-layout {
1087
- border-style: dashed !important;
1088
- border-color: var(--spectrum-purple-600, #9256d9) !important;
1089
- }
1090
- .overlay-layout-badge {
1091
- position: absolute;
1092
- top: -16px;
1093
- left: 0;
1094
- font-size: 9px;
1095
- padding: 1px 5px;
1096
- background: var(--spectrum-purple-600, #9256d9);
1097
- color: white;
1098
- border-radius: var(--radius);
1099
- text-transform: uppercase;
1100
- letter-spacing: 0.5px;
1101
- pointer-events: none;
1102
- }
1103
- .overlay-label {
1104
- position: absolute;
1105
- top: -20px;
1106
- left: -2px;
1107
- padding: 1px 5px;
1108
- font-size: 10px;
1109
- background: var(--accent);
1110
- color: var(--accent-fg);
1111
- border-radius: var(--spectrum-corner-radius-75) var(--spectrum-corner-radius-75) 0 0;
1112
- white-space: nowrap;
1113
- pointer-events: none;
1114
- }
1115
-
1116
- /* ─── Unified block action bar ─────────────── */
1117
- .block-action-bar {
1118
- position: fixed;
1119
- pointer-events: auto;
1120
- display: flex;
1121
- align-items: center;
1122
- gap: 2px;
1123
- background: var(--bg-panel);
1124
- border: 1px solid var(--border);
1125
- border-radius: var(--radius);
1126
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
1127
- padding: 2px 4px;
1128
- white-space: nowrap;
1129
- z-index: 100;
1130
- }
1131
- .block-action-bar .bar-tag {
1132
- font-size: 10px;
1133
- padding: 0 4px;
1134
- border-radius: var(--spectrum-corner-radius-75, 2px);
1135
- color: var(--accent-fg);
1136
- background: var(--tag);
1137
- max-width: 140px;
1138
- overflow: hidden;
1139
- text-overflow: ellipsis;
1140
- }
1141
- .block-action-bar .bar-tag--interactive {
1142
- cursor: pointer;
1143
- }
1144
- .block-action-bar .bar-tag--interactive:hover {
1145
- background: var(--accent);
1146
- color: var(--bg);
1147
- }
1148
- .block-action-bar .bar-drag-handle {
1149
- cursor: grab;
1150
- font-size: var(--spectrum-font-size-100, 14px);
1151
- padding: 0 4px;
1152
- opacity: 0.7;
1153
- user-select: none;
1154
- display: inline-flex;
1155
- align-items: center;
1156
- line-height: 1;
1157
- transform: translateY(1px);
1158
- }
1159
- .block-action-bar .bar-drag-handle:hover {
1160
- opacity: 1;
1161
- }
1162
- .block-action-bar .bar-drag-handle:active {
1163
- cursor: grabbing;
1164
- }
1165
- .block-action-bar sp-divider {
1166
- height: 20px;
1167
- margin: 0 2px;
1168
- }
1169
-
1170
- .link-popover {
1171
- display: flex;
1172
- gap: 4px;
1173
- align-items: center;
1174
- padding: 8px;
1175
- background: var(--bg-panel);
1176
- border: 1px solid var(--border);
1177
- border-radius: var(--radius);
1178
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
1179
- }
1180
-
1181
- /* ─── Activity bar (vertical icon tabs) ──────── */
1182
- #activity-bar sp-tabs {
1183
- --mod-tabs-item-horizontal-spacing: 0px;
1184
- --mod-tabs-start-to-tab-item: 0px;
1185
- --mod-tabs-color: var(--fg-dim);
1186
- --mod-tabs-color-selected: var(--fg);
1187
- }
1188
- #activity-bar sp-tab {
1189
- position: relative;
1190
- width: 48px;
1191
- height: 48px;
1192
- display: flex;
1193
- align-items: center;
1194
- justify-content: center;
1195
- color: var(--fg-dim);
1196
- opacity: 0.6;
1197
- margin: 0;
1198
- }
1199
- .activity-badge {
1200
- position: absolute;
1201
- top: 6px;
1202
- right: 4px;
1203
- min-width: 16px;
1204
- height: 16px;
1205
- padding: 0 4px;
1206
- border-radius: var(--spectrum-corner-radius-200, 8px);
1207
- background: var(--accent);
1208
- color: var(--spectrum-white);
1209
- font-size: 9px;
1210
- font-weight: 700;
1211
- display: flex;
1212
- align-items: center;
1213
- justify-content: center;
1214
- pointer-events: none;
1215
- }
1216
- #activity-bar sp-tab:hover {
1217
- opacity: 1;
1218
- }
1219
- #activity-bar sp-tab[selected] {
1220
- color: var(--fg);
1221
- opacity: 1;
1222
- }
1223
-
1224
- /* ─── Panel tabs (right: horizontal icon tabs) ── */
1225
- .panel-tabs {
1226
- border-bottom: 1px solid var(--border);
1227
- }
1228
- .panel-tabs sp-tabs {
1229
- --mod-tabs-item-horizontal-spacing: 0px;
1230
- --mod-tabs-start-to-tab-item: 0px;
1231
- --mod-tabs-color: var(--fg-dim);
1232
- --mod-tabs-color-selected: var(--fg);
1233
- --spectrum-tabs-top-to-text: 0px;
1234
- --spectrum-tabs-bottom-to-text: 0px;
1235
- }
1236
- .panel-tabs sp-tab {
1237
- padding: 4px 10px;
1238
- color: var(--fg-dim);
1239
- opacity: 0.7;
1240
- min-block-size: unset;
1241
- block-size: 36px;
1242
- box-sizing: border-box;
1243
- }
1244
- .panel-tabs sp-tab:hover {
1245
- opacity: 1;
1246
- }
1247
- .panel-tabs sp-tab[selected] {
1248
- color: var(--fg);
1249
- opacity: 1;
1250
- }
1251
- .panel-body {
1252
- padding: 0;
1253
- }
1254
-
1255
- /* ─── File tree ──────────────────────────────── */
1256
- .files-toolbar {
1257
- display: flex;
1258
- gap: 4px;
1259
- padding: 4px 8px;
1260
- border-bottom: 1px solid var(--border);
1261
- align-items: center;
1262
- }
1263
- .files-toolbar sp-search {
1264
- flex: 1;
1265
- --spectrum-textfield-height: 24px;
1266
- }
1267
- .file-tree {
1268
- overflow-y: auto;
1269
- }
1270
- .file-tree-item {
1271
- display: flex;
1272
- align-items: center;
1273
- gap: 6px;
1274
- padding: 3px 8px;
1275
- cursor: pointer;
1276
- font-size: var(--spectrum-font-size-75, 12px);
1277
- color: var(--fg);
1278
- user-select: none;
1279
- }
1280
- .file-tree-item:hover {
1281
- background: var(--hover-bg);
1282
- }
1283
- .file-tree-item.selected {
1284
- background: var(--accent-20);
1285
- }
1286
- .file-tree-item.dragging {
1287
- opacity: 0.4;
1288
- }
1289
- .file-tree-item.drag-over {
1290
- background: var(--accent-20);
1291
- outline: 1px solid var(--accent);
1292
- outline-offset: -1px;
1293
- }
1294
- .file-tree.drag-over-root {
1295
- background: var(--hover-bg);
1296
- }
1297
- .file-tree-toggle {
1298
- width: 14px;
1299
- text-align: center;
1300
- font-size: 8px;
1301
- color: var(--fg-dim);
1302
- flex-shrink: 0;
1303
- cursor: pointer;
1304
- }
1305
- .file-tree-toggle.empty {
1306
- visibility: hidden;
1307
- }
1308
- .file-tree-icon {
1309
- flex-shrink: 0;
1310
- display: flex;
1311
- align-items: center;
1312
- }
1313
- .file-tree-icon sp-icon-folder,
1314
- .file-tree-icon sp-icon-folder-open,
1315
- .file-tree-icon sp-icon-document,
1316
- .file-tree-icon sp-icon-file-code,
1317
- .file-tree-icon sp-icon-file-txt,
1318
- .file-tree-icon sp-icon-file-css,
1319
- .file-tree-icon sp-icon-image {
1320
- --spectrum-icon-size-100: 16px;
1321
- }
1322
- .file-tree-name {
1323
- overflow: hidden;
1324
- text-overflow: ellipsis;
1325
- white-space: nowrap;
1326
- flex: 1;
1327
- }
1328
- .file-tree-empty {
1329
- padding: 24px;
1330
- text-align: center;
1331
- color: var(--fg-dim);
1332
- font-size: var(--spectrum-font-size-75, 12px);
1333
- }
1334
- .project-header {
1335
- display: flex;
1336
- align-items: center;
1337
- padding: 6px 12px;
1338
- border-bottom: 1px solid var(--border);
1339
- gap: 6px;
1340
- }
1341
- .project-name {
1342
- font-size: var(--spectrum-font-size-75, 12px);
1343
- font-weight: 600;
1344
- overflow: hidden;
1345
- text-overflow: ellipsis;
1346
- white-space: nowrap;
1347
- }
1348
-
1349
- /* ─── Layers ─────────────────────────────────── */
1350
- .layer-row {
1351
- display: flex;
1352
- align-items: center;
1353
- gap: 4px;
1354
- padding: 3px 8px;
1355
- cursor: grab;
1356
- white-space: nowrap;
1357
- user-select: none;
1358
- border-left: 2px solid transparent;
1359
- transition: transform 150ms ease;
1360
- }
1361
- .layer-row:hover {
1362
- background: var(--hover-bg);
1363
- }
1364
- .layer-row.selected {
1365
- background: var(--accent-20);
1366
- border-left-color: var(--accent);
1367
- }
1368
- .layer-row.dragging {
1369
- opacity: 0.4;
1370
- transition: none;
1371
- }
1372
- .layer-row.drop-target {
1373
- background: var(--accent-15);
1374
- outline: 1px dashed var(--accent);
1375
- outline-offset: -1px;
1376
- }
1377
- .layer-indent {
1378
- flex-shrink: 0;
1379
- }
1380
- .layer-actions {
1381
- display: none;
1382
- align-items: center;
1383
- gap: 0;
1384
- }
1385
- /* Row actions are built for the SELECTED row only — five sp-action-buttons per row is
1386
- ~5 custom elements with shadow roots per visible row, which is what made a large document's
1387
- layer tree slow to render. The row itself stays fully draggable (dnd's canDrag excludes
1388
- only .layer-actions), so reordering non-selected rows is unaffected. */
1389
- .layer-row.selected .layer-actions {
1390
- display: flex;
1391
- }
1392
- .layer-row:hover .layer-drag-handle,
1393
- .layer-row.selected .layer-drag-handle {
1394
- display: inline-block;
1395
- }
1396
- .layer-row:has(.layer-title-input) .layer-actions {
1397
- display: none;
1398
- }
1399
- /* The grab affordance is a plain span, so it stays on every row (revealed on hover) while the
1400
- Spectrum action buttons are built for the selected row only. It sits OUTSIDE .layer-actions
1401
- so dnd's canDrag no longer refuses drags that start on it. */
1402
- .layer-drag-handle {
1403
- display: none;
1404
- color: var(--fg-dim);
1405
- opacity: 0.6;
1406
- font-size: var(--spectrum-font-size-50, 11px);
1407
- cursor: grab;
1408
- padding: 0 4px 0 0;
1409
- }
1410
- .layer-toggle {
1411
- width: 14px;
1412
- text-align: center;
1413
- font-size: 9px;
1414
- color: var(--fg-dim);
1415
- cursor: pointer;
1416
- flex-shrink: 0;
1417
- }
1418
- .layer-tag {
1419
- padding: 0 4px;
1420
- font-size: 10px;
1421
- border-radius: var(--spectrum-corner-radius-75, 2px);
1422
- color: var(--accent-fg);
1423
- background: var(--tag);
1424
- flex-shrink: 0;
1425
- }
1426
- .layer-label {
1427
- overflow: hidden;
1428
- text-overflow: ellipsis;
1429
- white-space: nowrap;
1430
- min-width: 24px;
1431
- flex: 1;
1432
- }
1433
- .layer-title-input {
1434
- width: 100%;
1435
- background: var(--bg);
1436
- color: inherit;
1437
- border: 1px solid var(--accent, #3b82f6);
1438
- border-radius: var(--spectrum-corner-radius-75, 2px);
1439
- font: inherit;
1440
- font-size: inherit;
1441
- padding: 0 2px;
1442
- outline: none;
1443
- }
1444
- .layer-dot {
1445
- font-size: 9px;
1446
- flex-shrink: 0;
1447
- }
1448
- .layer-delete {
1449
- color: var(--danger);
1450
- }
1451
- .map-tag {
1452
- background: var(--map) !important;
1453
- color: var(--accent-fg) !important;
1454
- font-size: 9px;
1455
- letter-spacing: 0.5px;
1456
- }
1457
- .repeater-perimeter {
1458
- border: 1px dashed color-mix(in srgb, var(--map) 25%, transparent);
1459
- border-radius: var(--radius);
1460
- padding: 4px;
1461
- min-height: 24px;
1462
- position: relative;
1463
- }
1464
- .repeater-perimeter::before {
1465
- content: "↻ Repeater";
1466
- position: absolute;
1467
- top: -9px;
1468
- left: 6px;
1469
- font-size: 9px;
1470
- color: color-mix(in srgb, var(--map) 50%, transparent);
1471
- background: var(--spectrum-white, #fff);
1472
- padding: 0 3px;
1473
- font-family: var(--font-mono);
1474
- pointer-events: none;
1475
- }
1476
- /* Empty element placeholders (design/edit mode only) */
1477
- .empty-media-placeholder {
1478
- display: inline-block;
1479
- min-width: 120px;
1480
- min-height: 80px;
1481
- border: 1px dashed color-mix(in srgb, var(--fg-dim, #808080) 30%, transparent);
1482
- border-radius: var(--radius);
1483
- background: color-mix(in srgb, var(--fg-dim, #808080) 5%, transparent)
1484
- url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' fill='none'%3E%3Crect x='4' y='8' width='32' height='24' rx='2' stroke='%23808080' stroke-opacity='.4' stroke-width='1.5'/%3E%3Ccircle cx='13' cy='16' r='3' stroke='%23808080' stroke-opacity='.4' stroke-width='1.5'/%3E%3Cpath d='M8 28l8-8 5 5 4-4 7 7' stroke='%23808080' stroke-opacity='.4' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
1485
- center / 40px no-repeat;
1486
- color: transparent;
1487
- font-size: 0;
1488
- overflow: hidden;
1489
- }
1490
- .empty-text-placeholder:not([contenteditable])::after {
1491
- content: "Click here to add text...";
1492
- color: color-mix(in srgb, var(--fg-dim, #808080) 40%, transparent);
1493
- font-style: italic;
1494
- font-size: 13px;
1495
- pointer-events: none;
1496
- }
1497
- .empty-container-placeholder {
1498
- border: 1px dashed color-mix(in srgb, var(--fg-dim, #808080) 25%, transparent);
1499
- border-radius: var(--radius);
1500
- min-height: 32px;
1501
- position: relative;
1502
- }
1503
- .empty-container-placeholder::after {
1504
- content: "Drag elements here...";
1505
- position: absolute;
1506
- top: 50%;
1507
- left: 50%;
1508
- transform: translate(-50%, -50%);
1509
- color: color-mix(in srgb, var(--fg-dim, #808080) 40%, transparent);
1510
- font-style: italic;
1511
- font-size: var(--spectrum-font-size-50, 11px);
1512
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
1513
- pointer-events: none;
1514
- white-space: nowrap;
1515
- }
1516
- [contenteditable="plaintext-only"]:focus {
1517
- outline: 1px solid var(--accent) !important;
1518
- outline-offset: -1px;
1519
- }
1520
- .switch-tag {
1521
- background: var(--switch-c) !important;
1522
- color: var(--accent-fg) !important;
1523
- }
1524
- .case-tag {
1525
- background: var(--case-c) !important;
1526
- color: var(--accent-fg) !important;
1527
- font-style: italic;
1528
- font-size: 9px;
1529
- max-width: 60px;
1530
- overflow: hidden;
1531
- text-overflow: ellipsis;
1532
- }
1533
- .slot-tag {
1534
- background: var(--slot-c) !important;
1535
- color: var(--accent-fg) !important;
1536
- }
1537
- .component-row {
1538
- opacity: 0.9;
1539
- cursor: grab;
1540
- }
1541
- .component-row.available {
1542
- opacity: 0.6;
1543
- }
1544
- .component-row.available:hover {
1545
- opacity: 0.8;
1546
- }
1547
- .component-tag {
1548
- font-size: 9px;
1549
- width: 18px;
1550
- text-align: center;
1551
- }
1552
- .components-section {
1553
- padding: 0 0 2px;
1554
- }
1555
- .imports-panel {
1556
- overflow-y: auto;
1557
- padding: 4px;
1558
- }
1559
- .imports-section {
1560
- margin-bottom: 12px;
1561
- }
1562
- .imports-section-header {
1563
- display: flex;
1564
- align-items: center;
1565
- gap: 6px;
1566
- padding: 6px 8px 2px;
1567
- font-size: var(--spectrum-font-size-50, 11px);
1568
- font-weight: 600;
1569
- color: var(--fg-dim);
1570
- text-transform: uppercase;
1571
- letter-spacing: 0.5px;
1572
- }
1573
- .imports-count {
1574
- font-weight: 400;
1575
- color: var(--text-hint);
1576
- }
1577
- .imports-list {
1578
- padding: 0 4px;
1579
- }
1580
- .import-row {
1581
- display: flex;
1582
- align-items: center;
1583
- gap: 4px;
1584
- padding: 3px 4px;
1585
- font-size: var(--spectrum-font-size-50, 11px);
1586
- border-radius: var(--radius);
1587
- }
1588
- .import-row:hover {
1589
- background: var(--hover-bg);
1590
- }
1591
- .import-name {
1592
- font-weight: 500;
1593
- white-space: nowrap;
1594
- }
1595
- .import-path {
1596
- color: var(--fg-dim);
1597
- overflow: hidden;
1598
- text-overflow: ellipsis;
1599
- flex: 1;
1600
- white-space: nowrap;
1601
- font-family: var(--font-mono, monospace);
1602
- font-size: 10px;
1603
- }
1604
- .import-mono {
1605
- font-family: var(--font-mono, monospace);
1606
- }
1607
- .imports-empty {
1608
- padding: 8px 12px;
1609
- font-size: var(--spectrum-font-size-50, 11px);
1610
- color: var(--text-hint);
1611
- font-style: italic;
1612
- }
1613
- .import-add-form {
1614
- display: flex;
1615
- align-items: center;
1616
- gap: 4px;
1617
- padding: 4px;
1618
- }
1619
- .import-add-form sp-textfield {
1620
- flex: 1;
1621
- }
1622
- .import-picker {
1623
- width: 100%;
1624
- }
1625
- /* Head panel */
1626
- .head-section-body {
1627
- padding: 0 4px;
1628
- }
1629
- .head-section-body .style-row > sp-textfield,
1630
- .head-section-body .style-row > .media-picker {
1631
- width: 100%;
1632
- }
1633
- .head-add-form {
1634
- display: flex;
1635
- align-items: center;
1636
- gap: 4px;
1637
- padding: 4px;
1638
- }
1639
- .head-add-form sp-textfield {
1640
- flex: 1;
1641
- }
1642
- .head-add-form sp-picker {
1643
- min-width: 70px;
1644
- }
1645
- .breadcrumb {
1646
- display: flex;
1647
- align-items: center;
1648
- gap: 2px;
1649
- font-size: var(--spectrum-font-size-50, 11px);
1650
- margin-left: 8px;
1651
- }
1652
- .breadcrumb-item {
1653
- color: var(--fg-dim);
1654
- cursor: default;
1655
- white-space: nowrap;
1656
- }
1657
- .breadcrumb-item.clickable {
1658
- cursor: pointer;
1659
- }
1660
- .breadcrumb-item.clickable:hover {
1661
- color: var(--fg);
1662
- text-decoration: underline;
1663
- }
1664
- .breadcrumb-item.current {
1665
- color: var(--fg);
1666
- font-weight: 600;
1667
- }
1668
- .breadcrumb-sep {
1669
- color: var(--fg-dim);
1670
- }
1671
- .element-card {
1672
- cursor: grab;
1673
- display: flex;
1674
- flex-direction: column;
1675
- width: 100%;
1676
- border: 1px solid var(--border);
1677
- border-radius: var(--radius);
1678
- overflow: hidden;
1679
- margin-bottom: 6px;
1680
- }
1681
- .element-card:hover {
1682
- border-color: var(--accent);
1683
- }
1684
- .element-card-preview {
1685
- background: var(--spectrum-white, #fff);
1686
- padding: 6px 8px;
1687
- min-height: 32px;
1688
- max-height: 120px;
1689
- display: flex;
1690
- align-items: center;
1691
- overflow: hidden;
1692
- pointer-events: none;
1693
- }
1694
- .element-card-preview > * {
1695
- max-width: 100%;
1696
- color: var(--canvas-fg-2);
1697
- margin: 0;
1698
- padding: 0;
1699
- }
1700
- .element-card-preview > hr {
1701
- width: 100%;
1702
- border: none;
1703
- border-top: 1px solid var(--canvas-muted);
1704
- }
1705
- .element-card-preview > input,
1706
- .element-card-preview > textarea,
1707
- .element-card-preview > select,
1708
- .element-card-preview > button,
1709
- .element-card-preview > progress,
1710
- .element-card-preview > meter {
1711
- font-size: 10px;
1712
- }
1713
- .element-card-label {
1714
- padding: 2px 6px;
1715
- font-size: 10px;
1716
- color: var(--fg-dim);
1717
- background: var(--bg-input);
1718
- text-align: center;
1719
- font-family: var(--font-mono);
1720
- }
1721
- .elements-list {
1722
- border: none;
1723
- }
1724
- .elements-list sp-accordion-item {
1725
- --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-50, 11px);
1726
- border-bottom: 1px solid var(--border);
1727
- }
1728
-
1729
- /* ─── Drop indicator ──────────────────────────── */
1730
- .drop-indicator {
1731
- display: none;
1732
- position: absolute;
1733
- height: 2px;
1734
- background: var(--accent);
1735
- z-index: 5;
1736
- pointer-events: none;
1737
- }
1738
-
1739
- /* ─── Canvas drop indicator ───────────────────── */
1740
- .canvas-drop-indicator {
1741
- position: absolute;
1742
- pointer-events: none;
1743
- z-index: 11;
1744
- }
1745
- .canvas-drop-indicator.line {
1746
- height: 2px;
1747
- background: var(--accent);
1748
- }
1749
- .canvas-drop-indicator.inside {
1750
- border: 2px dashed var(--accent);
1751
- background: var(--accent-8);
1752
- }
1753
- /* An external file drop over an existing image: "this picture is about to be replaced".
1754
- Solid, not dashed, so it reads differently from the insert indicator above. */
1755
- .canvas-replace-target {
1756
- position: absolute;
1757
- pointer-events: none;
1758
- z-index: 11;
1759
- border: 2px solid var(--accent);
1760
- background: var(--accent-8);
1761
- border-radius: var(--radius);
1762
- }
1763
-
1764
- /* ─── Git diff highlighting ──────────────────── */
1765
- .element-diff-added {
1766
- background-color: color-mix(in srgb, var(--success) 15%, transparent);
1767
- outline: 1px solid var(--success);
1768
- }
1769
- .element-diff-removed {
1770
- background-color: color-mix(in srgb, var(--danger) 15%, transparent);
1771
- outline: 1px solid var(--danger);
1772
- }
1773
- .element-diff-modified {
1774
- background-color: color-mix(in srgb, var(--signal) 15%, transparent);
1775
- outline: 1px solid var(--signal);
1776
- }
1777
-
1778
- /* ─── Insertion helper ─────────────────────────── */
1779
- .insertion-helper {
1780
- position: absolute;
1781
- position-anchor: --jx-insert;
1782
- z-index: 12;
1783
- pointer-events: auto;
1784
- width: 20px;
1785
- height: 20px;
1786
- border-radius: 50%;
1787
- border: 1.5px solid var(--accent);
1788
- background: var(--bg-panel);
1789
- color: var(--accent);
1790
- font-size: var(--spectrum-font-size-100, 14px);
1791
- font-weight: 500;
1792
- line-height: 1;
1793
- cursor: pointer;
1794
- display: none;
1795
- place-items: center;
1796
- padding: 0;
1797
- opacity: 0;
1798
- transition: opacity 0.15s ease;
1799
- }
1800
- .insertion-helper.visible {
1801
- display: grid;
1802
- opacity: 1;
1803
- }
1804
- .insertion-helper:hover {
1805
- background: var(--accent);
1806
- color: var(--accent-fg);
1807
- transform: scale(1.15);
1808
- }
1809
- /* Line pseudo element — extends beyond button as a visual cue */
1810
- .insertion-helper::before {
1811
- content: "";
1812
- position: absolute;
1813
- background: var(--accent);
1814
- opacity: 0.5;
1815
- pointer-events: none;
1816
- border-radius: 1px;
1817
- }
1818
- /* Horizontal edges (column / block layout) */
1819
- .insertion-helper[data-edge="top"],
1820
- .insertion-helper[data-edge="bottom"] {
1821
- left: anchor(center);
1822
- translate: -50% 0;
1823
- }
1824
- .insertion-helper[data-edge="top"] {
1825
- bottom: anchor(top);
1826
- translate: -50% 50%;
1827
- }
1828
- .insertion-helper[data-edge="bottom"] {
1829
- top: anchor(bottom);
1830
- translate: -50% -50%;
1831
- }
1832
- .insertion-helper[data-edge="top"]::before,
1833
- .insertion-helper[data-edge="bottom"]::before {
1834
- width: 80px;
1835
- height: 2px;
1836
- top: 50%;
1837
- left: 50%;
1838
- translate: -50% -50%;
1839
- z-index: -1;
1840
- }
1841
- /* Vertical edges (row / inline layout) */
1842
- .insertion-helper[data-edge="left"],
1843
- .insertion-helper[data-edge="right"] {
1844
- top: anchor(center);
1845
- translate: 0 -50%;
1846
- }
1847
- .insertion-helper[data-edge="left"] {
1848
- right: anchor(left);
1849
- translate: 50% -50%;
1850
- }
1851
- .insertion-helper[data-edge="right"] {
1852
- left: anchor(right);
1853
- translate: -50% -50%;
1854
- }
1855
- .insertion-helper[data-edge="left"]::before,
1856
- .insertion-helper[data-edge="right"]::before {
1857
- height: 80px;
1858
- width: 2px;
1859
- top: 50%;
1860
- left: 50%;
1861
- translate: -50% -50%;
1862
- z-index: -1;
1863
- }
1864
- /* Empty container center */
1865
- .insertion-helper[data-edge="center"] {
1866
- top: anchor(center);
1867
- left: anchor(center);
1868
- translate: -50% -50%;
1869
- }
1870
-
1871
- /* ─── Inspector ──────────────────────────────── */
1872
- .inspector-fields {
1873
- padding: 4px 8px 8px;
1874
- }
1875
- .inspector-fields.hidden {
1876
- display: none;
1877
- }
1878
- .field-row {
1879
- display: flex;
1880
- align-items: center;
1881
- gap: 6px;
1882
- margin-bottom: 4px;
1883
- }
1884
- .field-label {
1885
- width: 80px;
1886
- flex-shrink: 0;
1887
- font-size: var(--spectrum-font-size-50, 11px);
1888
- color: var(--fg-dim);
1889
- text-align: right;
1890
- overflow: hidden;
1891
- text-overflow: ellipsis;
1892
- white-space: nowrap;
1893
- }
1894
- .field-input {
1895
- flex: 1;
1896
- min-width: 0;
1897
- padding: 3px 6px;
1898
- font: inherit;
1899
- font-size: var(--spectrum-font-size-50, 11px);
1900
- color: var(--fg);
1901
- background: var(--bg-input);
1902
- border: 1px solid var(--border);
1903
- border-radius: var(--radius);
1904
- outline: none;
1905
- }
1906
- .field-input:focus {
1907
- border-color: var(--accent);
1908
- }
1909
- .field-input[type="checkbox"] {
1910
- width: auto;
1911
- flex: none;
1912
- }
1913
- textarea.field-input {
1914
- resize: vertical;
1915
- min-height: 60px;
1916
- font-family: var(--font-mono);
1917
- }
1918
- /* Spectrum components inside field rows */
1919
- .field-row sp-textfield,
1920
- .field-row sp-picker {
1921
- flex: 1;
1922
- min-width: 0;
1923
- }
1924
- .field-row sp-textfield {
1925
- --spectrum-textfield-height: 26px;
1926
- }
1927
- .field-row sp-picker {
1928
- --spectrum-picker-min-width: 0;
1929
- }
1930
- .field-row sp-checkbox {
1931
- flex: none;
1932
- }
1933
- .field-row sp-field-label {
1934
- width: 80px;
1935
- flex-shrink: 0;
1936
- font-size: var(--spectrum-font-size-50, 11px);
1937
- color: var(--fg-dim);
1938
- text-align: right;
1939
- }
1940
- .signal-editor .field-row sp-field-label {
1941
- width: 65px;
1942
- font-size: 10px;
1943
- }
1944
- .signal-editor .field-row sp-textfield {
1945
- --spectrum-textfield-height: 24px;
1946
- }
1947
-
1948
- /* ─── Style editor (key-value list) ──────────── */
1949
- .kv-row {
1950
- display: flex;
1951
- gap: 4px;
1952
- margin-bottom: 3px;
1953
- }
1954
- .kv-key {
1955
- width: 90px;
1956
- flex-shrink: 0;
1957
- }
1958
- .kv-val {
1959
- flex: 1;
1960
- min-width: 0;
1961
- }
1962
- .kv-del {
1963
- width: 20px;
1964
- text-align: center;
1965
- cursor: pointer;
1966
- color: var(--danger);
1967
- font-size: 13px;
1968
- line-height: 24px;
1969
- }
1970
- .kv-add {
1971
- display: inline-block;
1972
- padding: 2px 8px;
1973
- font-size: var(--spectrum-font-size-50, 11px);
1974
- cursor: pointer;
1975
- color: var(--accent);
1976
- }
1977
- .kv-add:hover {
1978
- text-decoration: underline;
1979
- }
1980
-
1981
- /* ─── Style sidebar (Spectrum accordion) ──────── */
1982
- .style-sidebar sp-accordion {
1983
- border: none;
1984
- }
1985
- .style-sidebar sp-accordion-item {
1986
- --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-50, 11px);
1987
- }
1988
- .style-sidebar sp-accordion-item [slot="heading"] {
1989
- display: flex;
1990
- align-items: center;
1991
- gap: 4px;
1992
- }
1993
- .style-row {
1994
- display: flex;
1995
- flex-direction: column;
1996
- align-items: stretch;
1997
- gap: 2px;
1998
- padding: 2px 0;
1999
- }
2000
- .style-row--child {
2001
- padding-left: 16px;
2002
- }
2003
- /* removed: .style-row--horizontal — all rows use top labels now */
2004
- .style-row-label {
2005
- display: flex;
2006
- align-items: center;
2007
- gap: 4px;
2008
- font-size: 10px;
2009
- color: var(--fg-dim);
2010
- }
2011
- .set-dot {
2012
- display: inline-block;
2013
- width: 6px;
2014
- height: 6px;
2015
- border-radius: 50%;
2016
- background: var(--accent);
2017
- cursor: pointer;
2018
- flex-shrink: 0;
2019
- vertical-align: middle;
2020
- }
2021
- .set-dot:hover {
2022
- background: var(--danger);
2023
- }
2024
- .set-dot--section {
2025
- width: 7px;
2026
- height: 7px;
2027
- }
2028
- .style-row--warning .style-row-label {
2029
- color: var(--warning);
2030
- }
2031
- .style-row--warning .style-row-label::before {
2032
- content: "⚠ ";
2033
- }
2034
- .style-row > sp-textfield,
2035
- .style-row > sp-number-field,
2036
- .style-row > sp-picker,
2037
- .style-row > sp-combobox,
2038
- .style-row > textarea {
2039
- width: 100%;
2040
- }
2041
- .style-input-color {
2042
- display: flex;
2043
- align-items: center;
2044
- gap: 6px;
2045
- flex: 1;
2046
- min-width: 0;
2047
- }
2048
- .style-input-color sp-swatch {
2049
- flex-shrink: 0;
2050
- cursor: pointer;
2051
- }
2052
- .style-input-color sp-textfield {
2053
- flex: 1;
2054
- min-width: 0;
2055
- }
2056
- .color-popover-inner {
2057
- display: flex;
2058
- flex-direction: column;
2059
- gap: 8px;
2060
- width: 200px;
2061
- overflow: hidden;
2062
- }
2063
- .color-popover-inner sp-textfield {
2064
- width: 100%;
2065
- }
2066
- .color-popover-swatches-label {
2067
- font-size: 10px;
2068
- color: var(--spectrum-gray-600);
2069
- text-transform: uppercase;
2070
- letter-spacing: 0.05em;
2071
- }
2072
- .color-popover-inner sp-swatch-group {
2073
- --mod-swatch-border-color: var(--spectrum-gray-400);
2074
- }
2075
- .font-token-item {
2076
- display: flex;
2077
- flex-direction: column;
2078
- gap: 1px;
2079
- }
2080
- .font-token-preview {
2081
- font-size: var(--spectrum-font-size-75, 12px);
2082
- line-height: 1.3;
2083
- }
2084
- .font-token-name {
2085
- font-size: 9px;
2086
- color: var(--spectrum-gray-600);
2087
- font-family: monospace;
2088
- }
2089
- /* jx-styled-combobox — dual-mode styled combobox component */
2090
- jx-styled-combobox {
2091
- display: contents;
2092
- }
2093
- jx-styled-combobox sp-picker {
2094
- width: 100%;
2095
- }
2096
- .jx-combobox-group {
2097
- display: inline-flex;
2098
- position: relative;
2099
- width: 100%;
2100
- }
2101
- .jx-combobox-group sp-textfield {
2102
- flex: 1 1 auto;
2103
- min-width: 0;
2104
- --mod-textfield-border-start-end-radius: 0;
2105
- --mod-textfield-border-end-end-radius: 0;
2106
- margin-inline-end: calc(-1 * var(--spectrum-border-width-100, 1px));
2107
- }
2108
- .jx-combobox-group sp-picker-button {
2109
- flex: 0 0 auto;
2110
- --mod-picker-button-border-start-start-radius: 0;
2111
- --mod-picker-button-border-end-start-radius: 0;
2112
- --mod-picker-button-border-color: var(--spectrum-gray-400);
2113
- }
2114
- /* Number-unit compound input: textfield + picker-button */
2115
- .style-input-number-unit {
2116
- flex: 1;
2117
- min-width: 0;
2118
- }
2119
- /* Combobox-like composite: textfield + picker-button, matching sp-combobox visually */
2120
- .input-group {
2121
- display: inline-flex;
2122
- position: relative;
2123
- width: 100%;
2124
- }
2125
- .input-group sp-textfield {
2126
- flex: 1 1 auto;
2127
- min-width: 0;
2128
- /* Zero out the inline-end corners so the textfield abuts the picker-button */
2129
- --mod-textfield-border-start-end-radius: 0;
2130
- --mod-textfield-border-end-end-radius: 0;
2131
- /* Pull textfield's border into the picker-button so they share one line */
2132
- margin-inline-end: calc(-1 * var(--spectrum-border-width-100, 1px));
2133
- }
2134
- .input-group sp-picker-button {
2135
- flex: 0 0 auto;
2136
- /* Zero out the inline-start corners to abut the textfield */
2137
- --mod-picker-button-border-start-start-radius: 0;
2138
- --mod-picker-button-border-end-start-radius: 0;
2139
- --mod-picker-button-border-color: var(--spectrum-gray-400);
2140
- }
2141
- .input-group.is-expression sp-picker-button {
2142
- display: none;
2143
- }
2144
- .input-group.is-expression sp-textfield {
2145
- --mod-textfield-text-color-default: var(--spectrum-accent-color-800);
2146
- --mod-textfield-border-start-end-radius: var(--spectrum-corner-radius-100);
2147
- --mod-textfield-border-end-end-radius: var(--spectrum-corner-radius-100);
2148
- margin-inline-end: 0;
2149
- }
2150
- .style-shorthand-header {
2151
- display: flex;
2152
- align-items: center;
2153
- gap: 4px;
2154
- }
2155
- .style-shorthand-header sp-textfield {
2156
- flex: 1;
2157
- min-width: 0;
2158
- }
2159
-
2160
- /* Button-group + overflow picker-button combo */
2161
- .button-group-combo {
2162
- display: inline-flex;
2163
- align-items: stretch;
2164
- }
2165
- .button-group-combo.has-overflow sp-action-group {
2166
- --mod-actionbutton-border-radius: 0;
2167
- }
2168
- .button-group-combo sp-picker-button {
2169
- flex: 0 0 auto;
2170
- --mod-picker-button-border-start-start-radius: 0;
2171
- --mod-picker-button-border-end-start-radius: 0;
2172
- --mod-picker-button-border-color: var(--spectrum-gray-400);
2173
- margin-inline-start: calc(-1 * var(--spectrum-border-width-100, 1px));
2174
- }
2175
- .button-group-combo sp-picker-button.has-selection {
2176
- --mod-picker-button-background-color: var(--spectrum-accent-background-color-default);
2177
- }
2178
-
2179
- /* ─── Grid section layout (Size panel) ─── */
2180
- .style-section-body--grid {
2181
- display: grid;
2182
- grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
2183
- gap: 6px 8px;
2184
- }
2185
- .style-section-body--grid .style-row {
2186
- min-width: 0;
2187
- overflow: hidden;
2188
- }
2189
-
2190
- /* ─── Signals tab ────────────────────────────── */
2191
- .signal-row {
2192
- display: flex;
2193
- align-items: center;
2194
- gap: 4px;
2195
- padding: 4px 8px;
2196
- cursor: pointer;
2197
- border-left: 2px solid transparent;
2198
- user-select: none;
2199
- }
2200
- .signal-row:hover {
2201
- background: var(--hover-bg);
2202
- }
2203
- .signal-row.expanded {
2204
- background: var(--accent-10);
2205
- border-left-color: var(--accent);
2206
- }
2207
- .signal-badge {
2208
- padding: 0 4px;
2209
- font-size: 10px;
2210
- border-radius: var(--spectrum-corner-radius-75, 2px);
2211
- font-weight: 600;
2212
- flex-shrink: 0;
2213
- min-width: 18px;
2214
- text-align: center;
2215
- }
2216
- .signal-badge.state {
2217
- background: color-mix(in srgb, var(--signal) 25%, transparent);
2218
- color: var(--signal);
2219
- }
2220
- .signal-badge.computed {
2221
- background: color-mix(in srgb, var(--success) 25%, transparent);
2222
- color: var(--success);
2223
- }
2224
- .signal-badge.data {
2225
- background: color-mix(in srgb, var(--tag) 25%, transparent);
2226
- color: var(--tag);
2227
- }
2228
- .signal-badge.handler {
2229
- background: color-mix(in srgb, var(--handler) 25%, transparent);
2230
- color: var(--handler);
2231
- }
2232
- .signal-name {
2233
- flex: 1;
2234
- font-family: var(--font-mono);
2235
- font-size: var(--spectrum-font-size-50, 11px);
2236
- overflow: hidden;
2237
- text-overflow: ellipsis;
2238
- }
2239
- .signal-hint {
2240
- font-size: 10px;
2241
- color: var(--fg-dim);
2242
- flex-shrink: 0;
2243
- max-width: 80px;
2244
- overflow: hidden;
2245
- text-overflow: ellipsis;
2246
- }
2247
- .signal-del {
2248
- visibility: hidden;
2249
- cursor: pointer;
2250
- color: var(--danger);
2251
- font-size: var(--spectrum-font-size-50, 11px);
2252
- flex-shrink: 0;
2253
- }
2254
- .signal-row:hover .signal-del {
2255
- visibility: visible;
2256
- }
2257
- .signal-editor {
2258
- padding: 4px 8px 8px 26px;
2259
- border-bottom: 1px solid var(--border);
2260
- }
2261
- /* Signals panel accordion (matches style-sidebar pattern) */
2262
- .signals-panel sp-accordion {
2263
- border: none;
2264
- }
2265
- .signals-panel sp-accordion-item {
2266
- --spectrum-accordion-item-header-font-size: var(--spectrum-font-size-50, 11px);
2267
- }
2268
- .signals-add {
2269
- display: flex;
2270
- align-items: center;
2271
- gap: 4px;
2272
- padding: 6px 8px;
2273
- }
2274
-
2275
- /* ─── Data explorer ──────────────────────────── */
2276
- .data-explorer-toolbar {
2277
- padding: 4px 8px;
2278
- border-bottom: 1px solid var(--border);
2279
- display: flex;
2280
- justify-content: flex-end;
2281
- }
2282
- .data-refresh-btn {
2283
- font-size: var(--spectrum-font-size-50, 11px);
2284
- padding: 2px 8px;
2285
- background: var(--bg-input);
2286
- border: 1px solid var(--border);
2287
- border-radius: var(--radius);
2288
- color: var(--fg);
2289
- cursor: pointer;
2290
- }
2291
- .data-refresh-btn:hover {
2292
- border-color: var(--accent);
2293
- }
2294
- .data-row {
2295
- border-bottom: 1px solid var(--border);
2296
- }
2297
- .data-row-header {
2298
- display: flex;
2299
- align-items: center;
2300
- gap: 4px;
2301
- padding: 4px 8px;
2302
- cursor: pointer;
2303
- user-select: none;
2304
- }
2305
- .data-row-header:hover {
2306
- background: var(--hover-bg);
2307
- }
2308
- .data-row-header::before {
2309
- content: "\25B6";
2310
- font-size: 8px;
2311
- color: var(--fg-dim);
2312
- transition: transform 0.15s;
2313
- }
2314
- .data-row-header.expanded::before {
2315
- transform: rotate(90deg);
2316
- }
2317
- .data-name {
2318
- flex: 1;
2319
- font-family: var(--font-mono, monospace);
2320
- font-size: var(--spectrum-font-size-50, 11px);
2321
- overflow: hidden;
2322
- text-overflow: ellipsis;
2323
- white-space: nowrap;
2324
- }
2325
- .data-type {
2326
- font-size: 10px;
2327
- color: var(--fg-dim);
2328
- flex-shrink: 0;
2329
- }
2330
- .data-tree {
2331
- padding: 2px 0;
2332
- max-height: 300px;
2333
- overflow-y: auto;
2334
- }
2335
- .data-leaf,
2336
- .data-branch {
2337
- font-size: var(--spectrum-font-size-50, 11px);
2338
- font-family: var(--font-mono, monospace);
2339
- padding: 1px 8px;
2340
- line-height: 1.5;
2341
- white-space: nowrap;
2342
- overflow: hidden;
2343
- text-overflow: ellipsis;
2344
- }
2345
- .data-key {
2346
- color: var(--data-key);
2347
- }
2348
- .data-value {
2349
- color: var(--fg);
2350
- }
2351
- .data-null {
2352
- color: var(--fg-dim);
2353
- font-style: italic;
2354
- }
2355
- .data-string {
2356
- color: var(--data-string);
2357
- }
2358
- .data-number {
2359
- color: var(--data-number);
2360
- }
2361
- .data-boolean {
2362
- color: var(--data-boolean);
2363
- }
2364
- .data-object-label {
2365
- color: var(--fg-dim);
2366
- font-style: italic;
2367
- }
2368
- .data-ellipsis {
2369
- color: var(--fg-dim);
2370
- font-style: italic;
2371
- }
2372
- .data-pending {
2373
- animation: pulse 1.5s ease-in-out infinite;
2374
- }
2375
- @keyframes pulse {
2376
- 0%,
2377
- 100% {
2378
- opacity: 1;
2379
- }
2380
- 50% {
2381
- opacity: 0.4;
2382
- }
2383
- }
2384
- .field-check {
2385
- width: auto;
2386
- margin: 0;
2387
- }
2388
-
2389
- /* ─── Binding toggle ─────────────────────────── */
2390
- .bind-toggle {
2391
- width: 20px;
2392
- height: 20px;
2393
- display: flex;
2394
- align-items: center;
2395
- justify-content: center;
2396
- font-size: var(--spectrum-font-size-50, 11px);
2397
- cursor: pointer;
2398
- color: var(--fg-dim);
2399
- border: 1px solid transparent;
2400
- border-radius: var(--radius);
2401
- flex-shrink: 0;
2402
- }
2403
- .bind-toggle:hover {
2404
- color: var(--fg);
2405
- background: var(--hover-bg);
2406
- }
2407
- .bind-toggle.bound {
2408
- color: var(--accent);
2409
- }
2410
-
2411
- /* ─── Events section ─────────────────────────── */
2412
- .events-panel {
2413
- padding: 8px;
2414
- }
2415
- .events-section {
2416
- margin-bottom: 8px;
2417
- }
2418
- .declared-event-row {
2419
- display: flex;
2420
- gap: 6px;
2421
- align-items: center;
2422
- padding: 2px 0;
2423
- font-size: var(--spectrum-font-size-50, 11px);
2424
- }
2425
- .event-code {
2426
- font-family: monospace;
2427
- color: var(--accent);
2428
- }
2429
- .event-source {
2430
- color: var(--fg-dim);
2431
- font-size: 10px;
2432
- }
2433
- .event-type {
2434
- margin-left: auto;
2435
- color: var(--fg-dim);
2436
- font-size: 10px;
2437
- }
2438
- .event-binding {
2439
- margin-bottom: 8px;
2440
- }
2441
- .event-row {
2442
- display: flex;
2443
- gap: 4px;
2444
- align-items: center;
2445
- }
2446
- .event-name {
2447
- flex: 1;
2448
- min-width: 0;
2449
- }
2450
- .event-mode {
2451
- width: 72px;
2452
- flex-shrink: 0;
2453
- }
2454
- .event-handler {
2455
- width: 100%;
2456
- }
2457
- .event-body-row {
2458
- display: flex;
2459
- gap: 4px;
2460
- align-items: start;
2461
- margin-top: 3px;
2462
- }
2463
- .event-body-row sp-textfield {
2464
- flex: 1;
2465
- font-size: var(--spectrum-font-size-50, 11px);
2466
- }
2467
-
2468
- /* ─── Toolbar ────────────────────────────────── */
2469
- .tb-filename {
2470
- font-size: var(--spectrum-font-size-50, 11px);
2471
- color: var(--fg-dim);
2472
- max-width: 200px;
2473
- overflow: hidden;
2474
- text-overflow: ellipsis;
2475
- }
2476
- .tb-file-title {
2477
- font-size: var(--spectrum-font-size-50, 11px);
2478
- color: var(--fg);
2479
- max-width: 300px;
2480
- overflow: hidden;
2481
- text-overflow: ellipsis;
2482
- white-space: nowrap;
2483
- padding: 0 8px;
2484
- font-family: var(--font-mono);
2485
- }
2486
- .tb-dirty {
2487
- color: var(--accent);
2488
- font-size: 16px;
2489
- line-height: 1;
2490
- margin-left: 4px;
2491
- }
2492
- .tb-split-btn {
2493
- display: flex;
2494
- }
2495
- .tb-split-btn .tb-split-main {
2496
- border-top-right-radius: 0;
2497
- border-bottom-right-radius: 0;
2498
- }
2499
- .tb-split-btn .tb-split-trigger,
2500
- .tb-split-btn overlay-trigger > sp-action-button {
2501
- border-top-left-radius: 0;
2502
- border-bottom-left-radius: 0;
2503
- border-left: 1px solid rgba(0, 0, 0, 0.15);
2504
- }
2505
- .tb-spacer {
2506
- flex: 1;
2507
- }
2508
- .tb-search-trigger {
2509
- flex: 0 1 280px;
2510
- border: 1px solid var(--spectrum-gray-300, #393939);
2511
- border-radius: var(--radius);
2512
- --mod-actionbutton-edge-to-text: 10px;
2513
- }
2514
- .tb-search-trigger:hover {
2515
- border-color: var(--spectrum-gray-400, #4a4a4a);
2516
- }
2517
- .tb-search-label {
2518
- flex: 1;
2519
- text-align: left;
2520
- color: var(--spectrum-gray-600, #666);
2521
- font-weight: normal;
2522
- font-size: var(--spectrum-font-size-75, 12px);
2523
- }
2524
- .tb-search-label kbd {
2525
- font-family: inherit;
2526
- opacity: 0.6;
2527
- }
2528
- /* ─── Responsive toolbar collapse ──────────────────
2529
- As the window narrows the toolbar sheds width in two stages so the
2530
- window controls and every action stay reachable instead of clipping:
2531
- 1. the quick-access (file search) bar collapses to a search icon
2532
- 2. every button drops its text label, leaving an icon (the `title`
2533
- attribute supplies a tooltip with the full name)
2534
- The breakpoints are the toolbar widths at which each fuller layout
2535
- stops fitting (measured against the English labels); re-tune them if
2536
- the toolbar's buttons or labels change. */
2537
- @container toolbar (max-width: 1360px) {
2538
- .tb-search-trigger {
2539
- flex: 0 0 auto;
2540
- gap: 0;
2541
- }
2542
- .tb-search-label {
2543
- display: none;
2544
- }
2545
- }
2546
- @container toolbar (max-width: 1140px) {
2547
- #toolbar .tb-label {
2548
- display: none;
2549
- }
2550
- /* Collapse the icon-to-(now hidden)-label gap so buttons read as icons. */
2551
- #toolbar sp-action-button {
2552
- gap: 0;
2553
- }
2554
- }
2555
- .quick-search-overlay {
2556
- position: fixed;
2557
- inset: 0;
2558
- z-index: 1000;
2559
- display: flex;
2560
- justify-content: center;
2561
- padding-top: 60px;
2562
- background: rgba(0, 0, 0, 0.4);
2563
- }
2564
- .quick-search-panel {
2565
- width: 560px;
2566
- max-height: 420px;
2567
- display: flex;
2568
- flex-direction: column;
2569
- background: var(--spectrum-gray-100, #1e1e1e);
2570
- border: 1px solid var(--spectrum-gray-300, #393939);
2571
- border-radius: var(--spectrum-corner-radius-200, 8px);
2572
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
2573
- overflow: hidden;
2574
- align-self: flex-start;
2575
- }
2576
- .quick-search-input {
2577
- width: 100%;
2578
- padding: 12px 16px;
2579
- font-size: var(--spectrum-font-size-100, 14px);
2580
- border: none;
2581
- outline: none;
2582
- background: var(--spectrum-gray-75, #141414);
2583
- color: var(--spectrum-gray-900, #e0e0e0);
2584
- border-bottom: 1px solid var(--spectrum-gray-300, #393939);
2585
- }
2586
- .quick-search-results {
2587
- overflow-y: auto;
2588
- flex: 1;
2589
- }
2590
- .quick-search-item {
2591
- display: flex;
2592
- align-items: center;
2593
- gap: 8px;
2594
- padding: 6px 16px;
2595
- cursor: pointer;
2596
- font-size: 13px;
2597
- color: var(--spectrum-gray-800, #ccc);
2598
- }
2599
- .quick-search-item.selected {
2600
- background: var(--spectrum-blue-700, #0054a3);
2601
- color: var(--spectrum-white, #fff);
2602
- }
2603
- .quick-search-item:hover:not(.selected) {
2604
- background: var(--spectrum-gray-200, #2a2a2a);
2605
- }
2606
- .quick-search-icon {
2607
- flex-shrink: 0;
2608
- opacity: 0.7;
2609
- }
2610
- .quick-search-name {
2611
- font-weight: 500;
2612
- white-space: nowrap;
2613
- }
2614
- .quick-search-path {
2615
- opacity: 0.5;
2616
- font-size: var(--spectrum-font-size-75, 12px);
2617
- white-space: nowrap;
2618
- overflow: hidden;
2619
- text-overflow: ellipsis;
2620
- }
2621
- .quick-search-badge {
2622
- margin-left: auto;
2623
- font-size: var(--spectrum-font-size-50, 11px);
2624
- padding: 1px 6px;
2625
- border-radius: var(--radius);
2626
- background: var(--spectrum-gray-300, #393939);
2627
- color: var(--spectrum-gray-700, #999);
2628
- }
2629
- .quick-search-empty {
2630
- padding: 16px;
2631
- text-align: center;
2632
- color: var(--spectrum-gray-600, #666);
2633
- font-size: 13px;
2634
- }
2635
- .quick-search-section-label {
2636
- padding: 8px 16px 4px;
2637
- font-size: var(--spectrum-font-size-50, 11px);
2638
- text-transform: uppercase;
2639
- color: var(--spectrum-gray-600, #666);
2640
- letter-spacing: 0.5px;
2641
- }
2642
-
2643
- /* ─── Browse modal ──────────────────────────────── */
2644
- .browse-modal {
2645
- position: fixed;
2646
- inset: 40px;
2647
- z-index: 1000;
2648
- display: flex;
2649
- flex-direction: column;
2650
- background: var(--bg-panel);
2651
- border: 1px solid var(--border);
2652
- border-radius: var(--spectrum-corner-radius-200, 8px);
2653
- box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
2654
- overflow: hidden;
2655
- }
2656
- .browse-modal-header {
2657
- display: flex;
2658
- align-items: center;
2659
- justify-content: space-between;
2660
- padding: 12px 16px;
2661
- border-bottom: 1px solid var(--border);
2662
- }
2663
- .browse-modal-title {
2664
- margin: 0;
2665
- font-size: var(--spectrum-font-size-100, 14px);
2666
- font-weight: 600;
2667
- color: var(--fg);
2668
- }
2669
- .browse-modal-content {
2670
- flex: 1;
2671
- min-height: 0;
2672
- overflow: hidden;
2673
- }
2674
-
2675
- /* ─── Browse view ────────────────────────────── */
2676
- .browse-view {
2677
- display: flex;
2678
- flex-direction: column;
2679
- width: 100%;
2680
- height: 100%;
2681
- overflow: hidden;
2682
- }
2683
- .browse-view.browse-drop-active {
2684
- outline: 2px dashed var(--spectrum-blue-600, #0070c1);
2685
- outline-offset: -4px;
2686
- }
2687
- .browse-filter-bar {
2688
- display: flex;
2689
- align-items: center;
2690
- gap: 12px;
2691
- padding: 8px 16px;
2692
- background: var(--bg-panel);
2693
- border-bottom: 1px solid var(--border);
2694
- flex-shrink: 0;
2695
- }
2696
- .browse-filter-bar sp-search {
2697
- width: 240px;
2698
- }
2699
- .browse-table {
2700
- flex: 1;
2701
- overflow: auto;
2702
- padding: 0 16px 16px;
2703
- }
2704
- .browse-table sp-table {
2705
- width: 100%;
2706
- min-width: 100%;
2707
- }
2708
- .browse-table sp-table-head-cell:nth-child(1),
2709
- .browse-table sp-table-cell:nth-child(1) {
2710
- flex: 3;
2711
- }
2712
- .browse-table sp-table-head-cell:nth-child(2),
2713
- .browse-table sp-table-cell:nth-child(2) {
2714
- flex: 0 0 80px;
2715
- }
2716
- .browse-table sp-table-head-cell:nth-child(3),
2717
- .browse-table sp-table-cell:nth-child(3) {
2718
- flex: 0 0 60px;
2719
- }
2720
- .browse-table sp-table-head-cell:nth-child(4),
2721
- .browse-table sp-table-cell:nth-child(4) {
2722
- flex: 2;
2723
- }
2724
- .browse-row {
2725
- cursor: pointer;
2726
- }
2727
- .browse-row-media,
2728
- sp-table-row:has(.browse-thumb) {
2729
- cursor: default;
2730
- }
2731
- .browse-row:hover {
2732
- background: var(--spectrum-gray-200, #333);
2733
- }
2734
- .browse-name-cell {
2735
- font-weight: 500;
2736
- }
2737
- .browse-thumb {
2738
- width: 32px;
2739
- height: 32px;
2740
- object-fit: cover;
2741
- border-radius: var(--radius);
2742
- vertical-align: middle;
2743
- margin-right: 8px;
2744
- background: var(--spectrum-gray-200, #2a2a2a);
2745
- }
2746
- .browse-path-cell {
2747
- color: var(--fg-dim);
2748
- font-family: var(--font-mono);
2749
- font-size: var(--spectrum-font-size-50, 11px);
2750
- }
2751
- .browse-view-switcher {
2752
- display: flex;
2753
- gap: 2px;
2754
- margin-left: auto;
2755
- }
2756
- .browse-grid {
2757
- display: grid;
2758
- grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
2759
- gap: 12px;
2760
- padding: 12px;
2761
- align-items: start;
2762
- }
2763
- .browse-grid .element-card {
2764
- cursor: pointer;
2765
- margin-bottom: 0;
2766
- overflow: hidden;
2767
- }
2768
- .browse-grid .element-card-preview {
2769
- aspect-ratio: 4/3;
2770
- max-height: none;
2771
- min-height: unset;
2772
- display: block;
2773
- overflow: hidden;
2774
- }
2775
- .browse-grid-empty {
2776
- padding: 24px;
2777
- text-align: center;
2778
- color: var(--fg-dim);
2779
- }
2780
- .browse-body {
2781
- flex: 1;
2782
- overflow-y: auto;
2783
- min-height: 0;
2784
- }
2785
-
2786
- /* ─── Settings Modal ─── */
2787
- .settings-modal {
2788
- position: fixed;
2789
- inset: 40px;
2790
- z-index: 1000;
2791
- display: flex;
2792
- flex-direction: column;
2793
- background: var(--bg-panel);
2794
- border: 1px solid var(--border);
2795
- border-radius: var(--spectrum-corner-radius-200, 8px);
2796
- box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
2797
- overflow: hidden;
2798
- }
2799
- .about-modal {
2800
- position: fixed;
2801
- top: 50%;
2802
- left: 50%;
2803
- transform: translate(-50%, -50%);
2804
- width: min(440px, calc(100vw - 48px));
2805
- max-height: calc(100vh - 80px);
2806
- z-index: 1000;
2807
- display: flex;
2808
- flex-direction: column;
2809
- background: var(--bg-panel);
2810
- border: 1px solid var(--border);
2811
- border-radius: var(--spectrum-corner-radius-200, 8px);
2812
- box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
2813
- overflow: hidden;
2814
- }
2815
- .about-modal-body {
2816
- flex: 1;
2817
- overflow-y: auto;
2818
- padding: 20px;
2819
- }
2820
- .about-meta {
2821
- margin: 0 0 16px;
2822
- display: flex;
2823
- flex-direction: column;
2824
- gap: 6px;
2825
- }
2826
- .about-meta-row {
2827
- display: flex;
2828
- gap: 12px;
2829
- font-size: 13px;
2830
- }
2831
- .about-meta-label {
2832
- width: 96px;
2833
- min-width: 96px;
2834
- margin: 0;
2835
- color: var(--fg-dim);
2836
- }
2837
- .about-meta-value {
2838
- margin: 0;
2839
- color: var(--fg);
2840
- word-break: break-word;
2841
- }
2842
- .about-links {
2843
- display: flex;
2844
- gap: 16px;
2845
- padding: 12px 0;
2846
- margin-bottom: 12px;
2847
- border-top: 1px solid var(--border);
2848
- border-bottom: 1px solid var(--border);
2849
- font-size: 13px;
2850
- }
2851
- .about-links a {
2852
- color: var(--spectrum-accent-color-1000, #6aa9ff);
2853
- text-decoration: none;
2854
- }
2855
- .about-links a:hover {
2856
- text-decoration: underline;
2857
- }
2858
- .about-section-title {
2859
- margin: 0 0 8px;
2860
- font-size: 13px;
2861
- font-weight: 600;
2862
- color: var(--fg);
2863
- }
2864
- .about-muted {
2865
- margin: 0;
2866
- font-size: 13px;
2867
- color: var(--fg-dim);
2868
- }
2869
- .about-packages {
2870
- list-style: none;
2871
- margin: 0;
2872
- padding: 0;
2873
- display: flex;
2874
- flex-direction: column;
2875
- gap: 4px;
2876
- }
2877
- .about-package-row {
2878
- display: flex;
2879
- justify-content: space-between;
2880
- gap: 12px;
2881
- font-size: var(--spectrum-font-size-75, 12px);
2882
- }
2883
- .about-package-name {
2884
- color: var(--fg-dim);
2885
- }
2886
- .about-package-version {
2887
- color: var(--fg);
2888
- font-variant-numeric: tabular-nums;
2889
- }
2890
- .settings-modal-header {
2891
- display: flex;
2892
- align-items: center;
2893
- justify-content: space-between;
2894
- padding: 12px 16px;
2895
- border-bottom: 1px solid var(--border);
2896
- }
2897
- .settings-modal-title {
2898
- margin: 0;
2899
- font-size: var(--spectrum-font-size-100, 14px);
2900
- font-weight: 600;
2901
- color: var(--fg);
2902
- }
2903
- .settings-modal-body {
2904
- display: flex;
2905
- flex: 1;
2906
- min-height: 0;
2907
- }
2908
- .settings-modal-nav {
2909
- width: 180px;
2910
- min-width: 180px;
2911
- padding: 8px 0;
2912
- border-right: 1px solid var(--border);
2913
- overflow-y: auto;
2914
- display: flex;
2915
- flex-direction: column;
2916
- }
2917
- .settings-nav-item {
2918
- display: block;
2919
- width: 100%;
2920
- padding: 8px 16px;
2921
- border: none;
2922
- background: none;
2923
- color: var(--fg-dim);
2924
- font-size: 13px;
2925
- text-align: left;
2926
- cursor: pointer;
2927
- border-radius: 0;
2928
- }
2929
- .settings-nav-item:hover {
2930
- background: var(--spectrum-gray-200, #333);
2931
- color: var(--fg);
2932
- }
2933
- .settings-nav-item.active {
2934
- background: var(--spectrum-gray-300, #444);
2935
- color: var(--fg);
2936
- font-weight: 500;
2937
- }
2938
- .settings-modal-content {
2939
- flex: 1;
2940
- overflow-y: auto;
2941
- padding: 24px;
2942
- }
2943
- .settings-section-title {
2944
- margin: 0 0 16px;
2945
- font-size: 16px;
2946
- font-weight: 600;
2947
- color: var(--fg);
2948
- }
2949
- .settings-field {
2950
- margin-bottom: 20px;
2951
- }
2952
- .settings-field-label {
2953
- display: block;
2954
- font-size: 13px;
2955
- font-weight: 500;
2956
- color: var(--fg);
2957
- margin-bottom: 2px;
2958
- }
2959
- .settings-field-desc {
2960
- margin: 0 0 6px;
2961
- font-size: var(--spectrum-font-size-75, 12px);
2962
- color: var(--fg-dim);
2963
- }
2964
- .settings-field-row {
2965
- display: flex;
2966
- gap: 8px;
2967
- align-items: center;
2968
- margin-bottom: 8px;
2969
- }
2970
- .settings-media-list {
2971
- display: flex;
2972
- flex-direction: column;
2973
- gap: 6px;
2974
- }
2975
- .settings-media-row {
2976
- display: flex;
2977
- gap: 6px;
2978
- align-items: center;
2979
- }
2980
- .settings-media-name-fixed {
2981
- width: 80px;
2982
- font-size: var(--spectrum-font-size-75, 12px);
2983
- font-weight: 500;
2984
- color: var(--fg-dim);
2985
- padding: 0 8px;
2986
- }
2987
- .settings-media-name {
2988
- width: 80px;
2989
- }
2990
- .settings-media-value {
2991
- flex: 1;
2992
- }
2993
- /* New Project modal */
2994
- .new-project-modal {
2995
- position: fixed;
2996
- top: 50%;
2997
- left: 50%;
2998
- transform: translate(-50%, -50%);
2999
- z-index: 1000;
3000
- display: flex;
3001
- flex-direction: column;
3002
- background: var(--bg-panel);
3003
- border: 1px solid var(--border);
3004
- border-radius: var(--spectrum-corner-radius-200, 8px);
3005
- box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
3006
- width: min(720px, calc(100vw - 48px));
3007
- max-height: 80vh;
3008
- }
3009
- .new-project-modal-header {
3010
- display: flex;
3011
- align-items: center;
3012
- justify-content: space-between;
3013
- padding: 12px 16px;
3014
- border-bottom: 1px solid var(--border);
3015
- }
3016
- .new-project-modal-title {
3017
- margin: 0;
3018
- font-size: var(--spectrum-font-size-100, 14px);
3019
- font-weight: 600;
3020
- color: var(--fg);
3021
- }
3022
- .new-project-modal-body {
3023
- padding: 16px;
3024
- overflow-y: auto;
3025
- display: flex;
3026
- flex-direction: column;
3027
- gap: 12px;
3028
- }
3029
- .new-project-modal-footer {
3030
- display: flex;
3031
- justify-content: flex-end;
3032
- gap: 8px;
3033
- padding: 12px 16px;
3034
- border-top: 1px solid var(--border);
3035
- }
3036
- .new-project-field {
3037
- display: flex;
3038
- flex-direction: column;
3039
- gap: 4px;
3040
- }
3041
- .new-project-label {
3042
- font-size: var(--spectrum-font-size-75, 12px);
3043
- font-weight: 500;
3044
- color: var(--fg-dim);
3045
- }
3046
- .new-project-error {
3047
- font-size: var(--spectrum-font-size-75, 12px);
3048
- color: var(--danger);
3049
- padding: 4px 0;
3050
- }
3051
- /* Destination row: the Location field takes the slack, Browse… stays its natural width. */
3052
- .new-project-location-row {
3053
- display: flex;
3054
- align-items: center;
3055
- gap: 8px;
3056
- }
3057
- .new-project-location-row .new-project-location {
3058
- flex: 1;
3059
- min-width: 0;
3060
- }
3061
- /* Live preview of where the project will land — the answer to "where did that go?". */
3062
- .new-project-destination-preview {
3063
- font-size: var(--spectrum-font-size-75, 12px);
3064
- color: var(--fg-dim);
3065
- padding: 2px 0 4px;
3066
- overflow-wrap: anywhere;
3067
- }
3068
- .new-project-destination-preview code {
3069
- font-family: var(--font-mono, ui-monospace, monospace);
3070
- color: var(--fg);
3071
- }
3072
- /* Backend/global creation errors sit between the scroll body and the footer so they are
3073
- visible regardless of scroll position. */
3074
- .new-project-error--global {
3075
- flex: none;
3076
- padding: 8px 16px;
3077
- border-top: 1px solid var(--border);
3078
- }
3079
- .add-repo-modal .new-project-modal-body {
3080
- display: flex;
3081
- flex-direction: column;
3082
- gap: 8px;
3083
- }
3084
- .add-repo-list {
3085
- display: flex;
3086
- flex-direction: column;
3087
- max-height: 320px;
3088
- overflow-y: auto;
3089
- }
3090
- .add-repo-row {
3091
- display: flex;
3092
- align-items: baseline;
3093
- gap: 8px;
3094
- width: 100%;
3095
- padding: 5px 8px;
3096
- background: none;
3097
- border: none;
3098
- border-radius: var(--radius);
3099
- font: inherit;
3100
- font-size: 13px;
3101
- color: var(--fg);
3102
- cursor: pointer;
3103
- text-align: left;
3104
- }
3105
- .add-repo-row:hover:not([disabled]) {
3106
- background: var(--hover-bg);
3107
- }
3108
- .add-repo-row[disabled] {
3109
- opacity: 0.6;
3110
- cursor: default;
3111
- }
3112
- .add-repo-name {
3113
- color: var(--accent);
3114
- }
3115
- .add-repo-meta {
3116
- display: flex;
3117
- align-items: baseline;
3118
- gap: 6px;
3119
- font-size: var(--spectrum-font-size-50, 11px);
3120
- color: var(--fg-dim);
3121
- }
3122
- .add-repo-badge {
3123
- padding: 0 5px;
3124
- border: 1px solid var(--border);
3125
- border-radius: 8px;
3126
- }
3127
- .add-repo-busy {
3128
- margin-left: auto;
3129
- font-size: var(--spectrum-font-size-50, 11px);
3130
- color: var(--fg-dim);
3131
- }
3132
- .add-repo-empty {
3133
- padding: 12px 8px;
3134
- font-size: var(--spectrum-font-size-75, 12px);
3135
- color: var(--fg-dim);
3136
- }
3137
- .add-repo-install {
3138
- color: var(--accent, #1473e6);
3139
- text-decoration: underline;
3140
- }
3141
- /* Repository-access footer: widen the GitHub App, or reload after doing so. */
3142
- .add-repo-access {
3143
- display: flex;
3144
- flex-wrap: wrap;
3145
- align-items: baseline;
3146
- gap: 6px;
3147
- padding-top: 8px;
3148
- border-top: 1px solid var(--border);
3149
- font-size: var(--spectrum-font-size-50, 11px);
3150
- color: var(--fg-dim);
3151
- }
3152
- .add-repo-access-note {
3153
- flex: 1 1 auto;
3154
- }
3155
- .add-repo-access-links {
3156
- display: flex;
3157
- flex-wrap: wrap;
3158
- gap: 8px;
3159
- }
3160
- .add-repo-access-link {
3161
- color: var(--accent, #1473e6);
3162
- text-decoration: underline;
3163
- }
3164
- .add-repo-refresh {
3165
- padding: 2px 8px;
3166
- background: none;
3167
- border: 1px solid var(--border);
3168
- border-radius: var(--radius);
3169
- font: inherit;
3170
- font-size: var(--spectrum-font-size-50, 11px);
3171
- color: var(--fg);
3172
- cursor: pointer;
3173
- }
3174
- .add-repo-refresh:hover:not([disabled]) {
3175
- background: var(--hover-bg);
3176
- }
3177
- .add-repo-refresh[disabled] {
3178
- opacity: 0.5;
3179
- cursor: default;
3180
- }
3181
- .new-project-tabs {
3182
- padding: 0 16px;
3183
- border-bottom: 1px solid var(--border);
3184
- }
3185
- .new-project-tab-intro {
3186
- font-size: var(--spectrum-font-size-75, 12px);
3187
- color: var(--fg-dim);
3188
- line-height: 1.5;
3189
- }
3190
- .new-project-creds {
3191
- display: flex;
3192
- flex-direction: column;
3193
- max-width: 480px;
3194
- }
3195
- .new-project-import-grid {
3196
- display: grid;
3197
- grid-template-columns: 1fr 1fr;
3198
- gap: 12px;
3199
- }
3200
- .new-project-import-progress {
3201
- display: flex;
3202
- align-items: center;
3203
- gap: 8px;
3204
- font-size: var(--spectrum-font-size-75, 12px);
3205
- color: var(--fg);
3206
- }
3207
- .new-project-import-log {
3208
- font-family: var(--font-mono);
3209
- font-size: 11px;
3210
- line-height: 1.6;
3211
- background: var(--bg-input);
3212
- border: 1px solid var(--border);
3213
- border-radius: var(--radius);
3214
- padding: 8px 10px;
3215
- max-height: 240px;
3216
- overflow-y: auto;
3217
- white-space: pre-wrap;
3218
- word-break: break-word;
3219
- }
3220
- .new-project-import-log-line {
3221
- color: var(--fg);
3222
- }
3223
- .new-project-import-phase {
3224
- color: var(--fg-dim);
3225
- margin-right: 6px;
3226
- }
3227
- .new-project-agent-prompt {
3228
- min-height: 120px;
3229
- }
3230
- .new-project-step-context {
3231
- font-size: var(--spectrum-font-size-75, 12px);
3232
- color: var(--fg-dim);
3233
- }
3234
- .new-project-step-heading {
3235
- font-size: var(--spectrum-font-size-200, 16px);
3236
- font-weight: 600;
3237
- color: var(--fg);
3238
- margin-bottom: 4px;
3239
- }
3240
- .new-project-design-section {
3241
- display: flex;
3242
- flex-direction: column;
3243
- gap: 8px;
3244
- padding-top: 8px;
3245
- border-top: 1px solid var(--border);
3246
- }
3247
- .new-project-design-heading {
3248
- font-size: var(--spectrum-font-size-75, 12px);
3249
- font-weight: 600;
3250
- color: var(--fg);
3251
- text-transform: uppercase;
3252
- letter-spacing: 0.5px;
3253
- }
3254
- .new-project-color-row {
3255
- display: flex;
3256
- align-items: center;
3257
- gap: 8px;
3258
- }
3259
- .new-project-color-row .new-project-label {
3260
- min-width: 90px;
3261
- }
3262
- .new-project-color-row sp-textfield {
3263
- flex: 1;
3264
- }
3265
- .new-project-logo-row {
3266
- display: flex;
3267
- align-items: center;
3268
- gap: 10px;
3269
- color: var(--fg);
3270
- font-size: var(--spectrum-font-size-75, 12px);
3271
- }
3272
- .new-project-logo-name {
3273
- display: inline-flex;
3274
- align-items: center;
3275
- gap: 4px;
3276
- color: var(--fg-dim);
3277
- }
3278
- .new-project-media-row {
3279
- display: flex;
3280
- align-items: center;
3281
- gap: 8px;
3282
- }
3283
- .new-project-media-row .new-project-media-name {
3284
- width: 110px;
3285
- }
3286
- .new-project-media-row .new-project-media-value {
3287
- flex: 1;
3288
- }
3289
- .new-project-templates {
3290
- display: grid;
3291
- grid-template-columns: 1fr 1fr 1fr;
3292
- gap: 8px;
3293
- }
3294
- .new-project-template {
3295
- text-align: left;
3296
- border: 1px solid var(--border);
3297
- border-radius: 6px;
3298
- overflow: hidden;
3299
- cursor: pointer;
3300
- background: var(--bg-panel);
3301
- padding: 0;
3302
- display: flex;
3303
- flex-direction: column;
3304
- }
3305
- .new-project-template:hover {
3306
- border-color: var(--fg-dim);
3307
- }
3308
- .new-project-template.selected {
3309
- border-color: var(--accent, #3b82f6);
3310
- box-shadow: 0 0 0 1px var(--accent, #3b82f6);
3311
- }
3312
- .new-project-template-thumb {
3313
- width: 100%;
3314
- aspect-ratio: 16 / 10;
3315
- object-fit: cover;
3316
- display: block;
3317
- background: var(--bg-elevated, #1a1a1a);
3318
- }
3319
- .new-project-template-blank {
3320
- display: flex;
3321
- align-items: center;
3322
- justify-content: center;
3323
- aspect-ratio: 16 / 10;
3324
- color: var(--fg-dim);
3325
- font-size: 28px;
3326
- background: var(--bg-elevated, #1a1a1a);
3327
- }
3328
- .new-project-template-body {
3329
- padding: 6px 8px 8px;
3330
- }
3331
- .new-project-template-name {
3332
- font-size: 12px;
3333
- font-weight: 600;
3334
- color: var(--fg);
3335
- }
3336
- .new-project-template-tag {
3337
- font-size: 11px;
3338
- color: var(--fg-dim);
3339
- margin-top: 2px;
3340
- line-height: 1.3;
3341
- }
3342
- /* CSS Vars editor */
3343
- .css-vars-group {
3344
- margin-bottom: 24px;
3345
- }
3346
- .css-vars-group-title {
3347
- margin: 0 0 8px;
3348
- font-size: 13px;
3349
- font-weight: 600;
3350
- color: var(--fg);
3351
- text-transform: uppercase;
3352
- letter-spacing: 0.5px;
3353
- }
3354
- .css-var-row {
3355
- display: flex;
3356
- align-items: center;
3357
- gap: 8px;
3358
- padding: 4px 0;
3359
- }
3360
- .css-var-name {
3361
- font-size: var(--spectrum-font-size-75, 12px);
3362
- color: var(--fg-dim);
3363
- min-width: 100px;
3364
- }
3365
- .css-var-swatch {
3366
- width: 24px;
3367
- height: 24px;
3368
- border-radius: var(--radius);
3369
- border: 1px solid var(--border);
3370
- position: relative;
3371
- overflow: hidden;
3372
- cursor: pointer;
3373
- }
3374
- .css-var-swatch input[type="color"] {
3375
- position: absolute;
3376
- inset: 0;
3377
- opacity: 0;
3378
- cursor: pointer;
3379
- width: 100%;
3380
- height: 100%;
3381
- }
3382
- .css-var-font-preview {
3383
- font-size: 13px;
3384
- color: var(--fg-dim);
3385
- padding: 4px 0 12px 108px;
3386
- }
3387
- .css-var-media-overrides {
3388
- padding-left: 108px;
3389
- margin-bottom: 8px;
3390
- }
3391
- .css-var-media-row {
3392
- display: flex;
3393
- align-items: center;
3394
- gap: 8px;
3395
- padding: 2px 0;
3396
- }
3397
- .css-var-media-label {
3398
- font-size: var(--spectrum-font-size-50, 11px);
3399
- color: var(--fg-dim);
3400
- min-width: 60px;
3401
- }
3402
- .css-var-add-row {
3403
- display: flex;
3404
- gap: 8px;
3405
- align-items: center;
3406
- padding: 8px 0;
3407
- border-top: 1px solid var(--border);
3408
- margin-top: 8px;
3409
- }
3410
- /* Head editor */
3411
- .head-entry {
3412
- border: 1px solid var(--border);
3413
- border-radius: var(--radius);
3414
- padding: 12px;
3415
- margin-bottom: 8px;
3416
- }
3417
- .head-entry-header {
3418
- display: flex;
3419
- align-items: center;
3420
- justify-content: space-between;
3421
- margin-bottom: 8px;
3422
- }
3423
- .head-entry-tag {
3424
- font-size: var(--spectrum-font-size-75, 12px);
3425
- font-weight: 600;
3426
- color: var(--fg);
3427
- }
3428
- .head-code-editor {
3429
- width: 100%;
3430
- min-height: 80px;
3431
- padding: 8px;
3432
- font-family: var(--font-mono);
3433
- font-size: var(--spectrum-font-size-75, 12px);
3434
- background: var(--spectrum-gray-100, #1e1e1e);
3435
- color: var(--fg);
3436
- border: 1px solid var(--border);
3437
- border-radius: var(--radius);
3438
- resize: vertical;
3439
- }
3440
-
3441
- /* ─── Settings editors (Collections / Definitions) ─── */
3442
- .settings-two-col {
3443
- display: flex;
3444
- height: 100%;
3445
- gap: 1px;
3446
- background: var(--border);
3447
- }
3448
- .settings-list-panel {
3449
- display: flex;
3450
- flex-direction: column;
3451
- gap: 4px;
3452
- padding: 12px;
3453
- width: 200px;
3454
- min-width: 200px;
3455
- background: var(--bg-panel);
3456
- overflow-y: auto;
3457
- }
3458
- .settings-list-panel sp-action-button {
3459
- width: 100%;
3460
- justify-content: flex-start;
3461
- }
3462
- .settings-editor-panel {
3463
- flex: 1;
3464
- padding: 16px;
3465
- background: var(--bg-panel);
3466
- overflow-y: auto;
3467
- }
3468
- .settings-editor-header {
3469
- display: flex;
3470
- align-items: center;
3471
- gap: 12px;
3472
- margin-bottom: 16px;
3473
- }
3474
- .settings-editor-header h3 {
3475
- margin: 0;
3476
- font-size: var(--spectrum-font-size-100, 14px);
3477
- font-weight: 600;
3478
- }
3479
- .settings-empty-state {
3480
- flex: 1;
3481
- display: flex;
3482
- align-items: center;
3483
- justify-content: center;
3484
- background: var(--bg-panel);
3485
- color: var(--fg-dim);
3486
- font-size: 13px;
3487
- }
3488
- .settings-inline-form {
3489
- display: flex;
3490
- align-items: center;
3491
- gap: 6px;
3492
- }
3493
- .settings-top-chrome {
3494
- z-index: 16 !important;
3495
- }
3496
-
3497
- /* ─── Schema field cards ─── */
3498
- .schema-field-list {
3499
- display: flex;
3500
- flex-direction: column;
3501
- gap: 4px;
3502
- margin-bottom: 12px;
3503
- }
3504
- .schema-field-card {
3505
- border: 1px solid var(--border);
3506
- border-radius: var(--radius);
3507
- padding: 6px 10px;
3508
- }
3509
- .schema-field-row {
3510
- display: flex;
3511
- align-items: center;
3512
- gap: 8px;
3513
- }
3514
- .schema-field-nested {
3515
- margin-left: 16px;
3516
- margin-top: 6px;
3517
- padding-left: 8px;
3518
- border-left: 2px solid var(--border);
3519
- }
3520
- .schema-field-name-input {
3521
- flex: 1;
3522
- max-width: 140px;
3523
- }
3524
- .schema-field-card--nested {
3525
- border-color: var(--spectrum-gray-300, #444);
3526
- }
3527
- .schema-nested-add {
3528
- display: flex;
3529
- align-items: center;
3530
- gap: 6px;
3531
- padding: 4px 0;
3532
- }
3533
- .schema-nested-add-name {
3534
- flex: 1;
3535
- max-width: 120px;
3536
- }
3537
- .schema-add-field {
3538
- display: flex;
3539
- align-items: center;
3540
- gap: 8px;
3541
- padding: 8px 0;
3542
- }
3543
-
3544
- /* ─── Media picker ─────────────────────────────── */
3545
- .media-picker {
3546
- display: flex;
3547
- align-items: center;
3548
- gap: 4px;
3549
- flex: 1;
3550
- }
3551
- .media-picker sp-textfield {
3552
- flex: 1;
3553
- min-width: 0;
3554
- }
3555
- /* Upload + Browse always render, so the field yields width before the buttons do. */
3556
- .media-picker sp-action-button {
3557
- flex-shrink: 0;
3558
- }
3559
- .media-picker-thumb {
3560
- width: 24px;
3561
- height: 24px;
3562
- object-fit: cover;
3563
- border-radius: var(--radius);
3564
- border: 1px solid var(--border);
3565
- flex-shrink: 0;
3566
- }
3567
- /* .media-picker-popover is no longer used — inlined in media-picker.ts */
3568
-
3569
- /* ─── Source view ────────────────────────────── */
3570
- #source-view {
3571
- width: 100%;
3572
- height: 100%;
3573
- background: var(--bg);
3574
- color: var(--fg);
3575
- font: 11px/1.6 var(--font-mono, monospace);
3576
- border: none;
3577
- padding: 8px;
3578
- resize: none;
3579
- outline: none;
3580
- }
3581
-
3582
- /* ─── Empty state ────────────────────────────── */
3583
- .empty-state {
3584
- padding: 24px;
3585
- text-align: center;
3586
- color: var(--fg-dim);
3587
- font-size: 13px;
3588
- }
3589
-
3590
- /* ─── Style toolbar (media tabs + selector) ──── */
3591
- .style-toolbar {
3592
- display: flex;
3593
- align-items: center;
3594
- padding: 4px 8px;
3595
- gap: 8px;
3596
- }
3597
- .style-toolbar-tabs {
3598
- flex: 1;
3599
- min-width: 0;
3600
- }
3601
- .style-toolbar .selector-select {
3602
- flex-shrink: 0;
3603
- max-width: 120px;
3604
- }
3605
- .style-filter-bar {
3606
- display: flex;
3607
- align-items: center;
3608
- padding: 2px 8px 4px;
3609
- gap: 6px;
3610
- }
3611
- .style-filter-input {
3612
- flex: 1;
3613
- min-width: 0;
3614
- --spectrum-textfield-texticon-min-width: 0;
3615
- }
3616
- .style-filter-toggle[selected] {
3617
- background: var(--accent);
3618
- color: var(--accent-fg);
3619
- }
3620
- .selector-select {
3621
- min-width: 0;
3622
- font-size: 10px;
3623
- }
3624
- .selector-custom-input {
3625
- flex: 1;
3626
- min-width: 0;
3627
- padding: 3px 6px;
3628
- font: inherit;
3629
- font-size: 10px;
3630
- font-family: var(--font-mono);
3631
- color: var(--fg);
3632
- background: var(--bg-input);
3633
- border: 1px solid var(--accent);
3634
- border-radius: var(--radius);
3635
- outline: none;
3636
- }
3637
-
3638
- /* ─── Git panel ──────────────────────────────── */
3639
- .git-panel {
3640
- display: flex;
3641
- flex-direction: column;
3642
- height: 100%;
3643
- font-size: var(--spectrum-font-size-75, 12px);
3644
- }
3645
-
3646
- /* Sync status bar */
3647
- .git-sync-bar {
3648
- display: flex;
3649
- align-items: center;
3650
- gap: 10px;
3651
- padding: 12px 12px;
3652
- border-bottom: 1px solid var(--border);
3653
- }
3654
- .git-sync-icon {
3655
- flex-shrink: 0;
3656
- }
3657
- .git-sync-text {
3658
- display: flex;
3659
- flex-direction: column;
3660
- gap: 2px;
3661
- flex: 1;
3662
- }
3663
- .git-sync-actions {
3664
- flex-shrink: 0;
3665
- margin-left: auto;
3666
- }
3667
- .git-sync-label {
3668
- font-size: 13px;
3669
- font-weight: 600;
3670
- color: var(--fg);
3671
- }
3672
- .git-sync-time {
3673
- font-size: var(--spectrum-font-size-50, 11px);
3674
- color: var(--fg-dim);
3675
- }
3676
-
3677
- /* Branch selector row */
3678
- .git-branch-row {
3679
- display: flex;
3680
- align-items: center;
3681
- gap: 10px;
3682
- padding: 10px 12px;
3683
- border-bottom: 1px solid var(--border);
3684
- }
3685
- .git-branch-icon {
3686
- flex-shrink: 0;
3687
- color: var(--fg-dim);
3688
- }
3689
- .git-branch-text {
3690
- display: flex;
3691
- flex-direction: column;
3692
- gap: 1px;
3693
- flex: 1;
3694
- min-width: 0;
3695
- }
3696
- .git-branch-label {
3697
- font-size: var(--spectrum-font-size-50, 11px);
3698
- color: var(--fg-dim);
3699
- }
3700
- .git-branch-name {
3701
- font-size: 13px;
3702
- font-weight: 600;
3703
- color: var(--fg);
3704
- }
3705
- .git-branch-picker {
3706
- flex-shrink: 0;
3707
- --spectrum-picker-min-width: 0;
3708
- }
3709
-
3710
- /* Tabs: Local Changes / History */
3711
- .git-tabs {
3712
- display: flex;
3713
- border-bottom: 1px solid var(--border);
3714
- }
3715
- .git-tab {
3716
- flex: 1;
3717
- padding: 8px 12px;
3718
- font: inherit;
3719
- font-size: var(--spectrum-font-size-75, 12px);
3720
- font-weight: 600;
3721
- background: var(--hover-bg);
3722
- border: none;
3723
- border-bottom: 2px solid transparent;
3724
- color: var(--fg-dim);
3725
- cursor: pointer;
3726
- transition:
3727
- color 0.15s,
3728
- border-color 0.15s;
3729
- }
3730
- .git-tab:hover {
3731
- color: var(--fg);
3732
- }
3733
- .git-tab.active {
3734
- color: var(--fg);
3735
- border-bottom-color: var(--accent, #e2b93d);
3736
- background: transparent;
3737
- }
3738
-
3739
- /* Commit area */
3740
- .git-commit-area {
3741
- display: flex;
3742
- flex-direction: column;
3743
- gap: 8px;
3744
- padding: 12px;
3745
- border-bottom: 1px solid var(--border);
3746
- }
3747
- .git-commit-label {
3748
- font-size: var(--spectrum-font-size-75, 12px);
3749
- font-weight: 500;
3750
- color: var(--fg-dim);
3751
- }
3752
- .git-commit-input {
3753
- width: 100%;
3754
- --spectrum-textfield-texticon-min-width: 0;
3755
- }
3756
- .git-commit-actions {
3757
- display: flex;
3758
- }
3759
- .git-split-btn {
3760
- display: flex;
3761
- flex: 1;
3762
- position: relative;
3763
- }
3764
- .git-split-btn .git-commit-btn {
3765
- flex: 1;
3766
- border-top-right-radius: 0;
3767
- border-bottom-right-radius: 0;
3768
- }
3769
- .git-split-btn .git-split-trigger {
3770
- border-top-left-radius: 0;
3771
- border-bottom-left-radius: 0;
3772
- border-left: 1px solid rgba(0, 0, 0, 0.15);
3773
- }
3774
- .git-split-menu {
3775
- position: absolute;
3776
- top: 100%;
3777
- left: 0;
3778
- right: 0;
3779
- margin-top: 4px;
3780
- background: var(--bg-panel);
3781
- border: 1px solid var(--border);
3782
- border-radius: var(--radius);
3783
- z-index: 10;
3784
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
3785
- }
3786
- .git-split-menu-item {
3787
- display: block;
3788
- width: 100%;
3789
- padding: 6px 12px;
3790
- font: inherit;
3791
- font-size: var(--spectrum-font-size-75, 12px);
3792
- color: var(--fg);
3793
- background: none;
3794
- border: none;
3795
- text-align: left;
3796
- cursor: pointer;
3797
- }
3798
- .git-split-menu-item:hover {
3799
- background: var(--hover-bg);
3800
- }
3801
-
3802
- /* Changed Components grouping */
3803
- .git-component-group {
3804
- margin-bottom: 2px;
3805
- }
3806
- .git-component-header {
3807
- display: flex;
3808
- align-items: center;
3809
- gap: 6px;
3810
- padding: 4px 8px;
3811
- }
3812
- .git-component-overflow {
3813
- flex-shrink: 0;
3814
- }
3815
- .git-component-name {
3816
- font-size: var(--spectrum-font-size-75, 12px);
3817
- font-weight: 500;
3818
- color: var(--fg);
3819
- }
3820
-
3821
- /* Sections */
3822
- .git-section {
3823
- border-bottom: 1px solid var(--border);
3824
- }
3825
- .git-section-header {
3826
- display: flex;
3827
- align-items: center;
3828
- gap: 6px;
3829
- padding: 8px 12px 6px;
3830
- font-size: var(--spectrum-font-size-75, 12px);
3831
- font-weight: 700;
3832
- color: var(--fg);
3833
- }
3834
- .git-count {
3835
- display: inline-flex;
3836
- align-items: center;
3837
- justify-content: center;
3838
- min-width: 18px;
3839
- height: 18px;
3840
- padding: 0 5px;
3841
- border-radius: 9px;
3842
- background: var(--accent-15);
3843
- color: var(--accent);
3844
- font-size: 10px;
3845
- font-weight: 600;
3846
- }
3847
- .git-section-header .git-count {
3848
- margin-right: auto;
3849
- }
3850
-
3851
- /* File rows */
3852
- .git-file-row {
3853
- display: flex;
3854
- align-items: center;
3855
- gap: 4px;
3856
- padding: 2px 8px 2px 16px;
3857
- cursor: default;
3858
- }
3859
- .git-file-row:hover {
3860
- background: var(--hover-bg);
3861
- }
3862
- .git-file-info {
3863
- flex: 1;
3864
- min-width: 0;
3865
- display: flex;
3866
- align-items: baseline;
3867
- gap: 6px;
3868
- overflow: hidden;
3869
- }
3870
- .git-file-name {
3871
- white-space: nowrap;
3872
- overflow: hidden;
3873
- text-overflow: ellipsis;
3874
- }
3875
- .git-file-dir {
3876
- font-size: 10px;
3877
- color: var(--fg-dim);
3878
- white-space: nowrap;
3879
- overflow: hidden;
3880
- text-overflow: ellipsis;
3881
- }
3882
- .git-file-actions {
3883
- display: flex;
3884
- gap: 0;
3885
- opacity: 0;
3886
- }
3887
- .git-file-row:hover .git-file-actions {
3888
- opacity: 1;
3889
- }
3890
- .git-file-badge {
3891
- flex-shrink: 0;
3892
- width: 16px;
3893
- text-align: center;
3894
- font-size: 10px;
3895
- font-weight: 700;
3896
- font-family: var(--font-mono);
3897
- }
3898
- .git-status-M {
3899
- color: var(--signal);
3900
- }
3901
- .git-status-A {
3902
- color: var(--success);
3903
- }
3904
- .git-status-D {
3905
- color: var(--danger);
3906
- }
3907
- .git-status-R {
3908
- color: var(--tag);
3909
- }
3910
- .git-status-U {
3911
- color: var(--success);
3912
- }
3913
- .git-status-C {
3914
- color: var(--tag);
3915
- }
3916
-
3917
- /* History tab */
3918
- .git-history {
3919
- padding: 4px 0;
3920
- overflow-y: auto;
3921
- flex: 1;
3922
- }
3923
- .git-history-entry {
3924
- display: flex;
3925
- flex-direction: column;
3926
- gap: 2px;
3927
- padding: 6px 12px;
3928
- border-bottom: 1px solid var(--border);
3929
- }
3930
- .git-history-entry:hover {
3931
- background: var(--hover-bg);
3932
- }
3933
- .git-history-hash {
3934
- font-size: 10px;
3935
- font-family: var(--font-mono);
3936
- color: var(--accent);
3937
- }
3938
- .git-history-message {
3939
- font-size: var(--spectrum-font-size-75, 12px);
3940
- color: var(--fg);
3941
- }
3942
- .git-history-meta {
3943
- font-size: 10px;
3944
- color: var(--fg-dim);
3945
- }
3946
-
3947
- /* Utility */
3948
- .git-loading {
3949
- padding: 8px;
3950
- text-align: center;
3951
- color: var(--fg-dim);
3952
- font-size: var(--spectrum-font-size-50, 11px);
3953
- }
3954
- .git-error {
3955
- padding: 6px 8px;
3956
- font-size: var(--spectrum-font-size-50, 11px);
3957
- color: var(--danger);
3958
- background: color-mix(in srgb, var(--danger) 8%, transparent);
3959
- border-bottom: 1px solid var(--border);
3960
- }
3961
- .git-empty {
3962
- padding: 16px 8px;
3963
- text-align: center;
3964
- color: var(--fg-dim);
3965
- font-size: var(--spectrum-font-size-75, 12px);
3966
- }
3967
-
3968
- .git-panel-empty {
3969
- justify-content: center;
3970
- align-items: center;
3971
- }
3972
- .git-empty-state {
3973
- display: flex;
3974
- flex-direction: column;
3975
- align-items: center;
3976
- gap: 12px;
3977
- padding: 24px 16px;
3978
- text-align: center;
3979
- color: var(--fg-dim);
3980
- }
3981
- .git-empty-state p {
3982
- margin: 0;
3983
- font-size: var(--spectrum-font-size-75, 12px);
3984
- }
3985
- .git-sync-bar--no-remote {
3986
- gap: 8px;
3987
- }
3988
-
3989
- /* GitHub auth dialog */
3990
- .github-auth-dialog {
3991
- text-align: center;
3992
- padding: 16px 0;
3993
- }
3994
- .github-auth-dialog p {
3995
- margin: 8px 0;
3996
- font-size: 13px;
3997
- }
3998
- .github-auth-code {
3999
- font-size: 24px;
4000
- font-weight: 700;
4001
- letter-spacing: 2px;
4002
- font-family: var(--font-mono, monospace);
4003
- padding: 12px 16px;
4004
- background: var(--hover-bg);
4005
- border-radius: var(--radius);
4006
- display: inline-block;
4007
- margin: 8px 0;
4008
- }
4009
- .github-auth-waiting {
4010
- color: var(--fg-dim);
4011
- font-style: italic;
4012
- }
4013
-
4014
- /* GitHub publish dialog */
4015
- .github-publish-dialog {
4016
- display: flex;
4017
- flex-direction: column;
4018
- gap: 8px;
4019
- padding: 8px 0;
4020
- }
4021
- .github-publish-dialog sp-textfield {
4022
- width: 100%;
4023
- }
4024
-
4025
- /* ─── Feature toggle (stylebook) ─────────────── */
4026
- .tb-toggle {
4027
- padding: 3px 8px;
4028
- font: inherit;
4029
- font-size: var(--spectrum-font-size-50, 11px);
4030
- color: var(--fg-dim);
4031
- background: transparent;
4032
- border: 1px solid var(--border);
4033
- border-radius: var(--radius);
4034
- cursor: pointer;
4035
- }
4036
- .tb-toggle:hover {
4037
- background: var(--hover-bg);
4038
- }
4039
- .tb-toggle.active {
4040
- color: var(--accent);
4041
- border-color: var(--accent);
4042
- background: var(--accent-15);
4043
- }
4044
-
4045
- /* ─── Stylebook ─────────────────────────────────── */
4046
- .stylebook-style-header {
4047
- padding: 6px 8px;
4048
- font-size: var(--spectrum-font-size-50, 11px);
4049
- font-weight: 600;
4050
- color: var(--accent);
4051
- border-bottom: 1px solid var(--border);
4052
- font-family: var(--font-mono);
4053
- }
4054
-
4055
- /* Chrome bar (tabs + filter) above the canvas viewport */
4056
- .sb-chrome {
4057
- display: flex;
4058
- align-items: center;
4059
- padding: 4px 8px;
4060
- background: var(--bg-panel);
4061
- border-bottom: 1px solid var(--border);
4062
- gap: 4px;
4063
- flex-shrink: 0;
4064
- }
4065
-
4066
- /* Section layout in canvas */
4067
- .sb-section {
4068
- margin-bottom: 24px;
4069
- }
4070
- .sb-label {
4071
- font-size: 10px;
4072
- font-weight: 700;
4073
- text-transform: uppercase;
4074
- letter-spacing: 0.08em;
4075
- color: var(--canvas-muted);
4076
- padding: 8px 0 4px;
4077
- border-bottom: 1px solid var(--canvas-rule);
4078
- margin-bottom: 8px;
4079
- }
4080
- .sb-body {
4081
- padding: 4px 0;
4082
- display: flex;
4083
- flex-direction: column;
4084
- gap: 6px;
4085
- }
4086
-
4087
- /* Variable rows — unified layout for existing + add-new */
4088
- .sb-var-row {
4089
- display: flex;
4090
- flex-direction: column;
4091
- gap: 4px;
4092
- padding: 10px 0;
4093
- border-bottom: 1px solid var(--canvas-rule);
4094
- }
4095
- .sb-var-row:last-child {
4096
- border-bottom: none;
4097
- }
4098
- .sb-var-row-header {
4099
- display: flex;
4100
- align-items: baseline;
4101
- gap: 6px;
4102
- min-height: 18px;
4103
- flex-wrap: wrap;
4104
- }
4105
- .sb-var-row-title {
4106
- font-weight: 600;
4107
- font-size: var(--spectrum-font-size-75, 12px);
4108
- color: var(--canvas-fg-2);
4109
- white-space: nowrap;
4110
- }
4111
- .sb-var-row-ref {
4112
- font-size: 10px;
4113
- color: var(--canvas-muted);
4114
- font-family: var(--font-mono);
4115
- overflow: hidden;
4116
- text-overflow: ellipsis;
4117
- }
4118
- .sb-var-row-header .sb-var-del {
4119
- margin-left: auto;
4120
- }
4121
- .sb-var-row sp-textfield {
4122
- pointer-events: auto;
4123
- }
4124
- /* Existing variable: horizontal swatch + value */
4125
- .sb-var-input-row {
4126
- display: flex;
4127
- align-items: flex-end;
4128
- gap: 8px;
4129
- }
4130
- .sb-var-col-name {
4131
- min-width: 0;
4132
- }
4133
- .sb-var-col-value {
4134
- flex: 1;
4135
- min-width: 0;
4136
- }
4137
- .sb-var-col-name sp-textfield,
4138
- .sb-var-col-value sp-textfield {
4139
- width: 100%;
4140
- }
4141
- .sb-var-col-label {
4142
- font-size: 10px;
4143
- color: var(--canvas-dim);
4144
- margin-bottom: 2px;
4145
- font-weight: 500;
4146
- }
4147
- /* Add-new form: horizontal layout matching existing rows */
4148
- .sb-var-row.is-new .sb-var-input-row {
4149
- flex-wrap: nowrap;
4150
- align-items: flex-end;
4151
- }
4152
- .sb-var-row.is-new .sb-var-col-name {
4153
- flex: 2;
4154
- min-width: 0;
4155
- }
4156
- .sb-var-row.is-new .sb-var-col-value {
4157
- flex: 3;
4158
- min-width: 0;
4159
- }
4160
- .sb-var-row.is-new .sb-var-swatch {
4161
- align-self: flex-end;
4162
- margin-bottom: 2px;
4163
- }
4164
- .sb-var-swatch {
4165
- width: 28px;
4166
- height: 28px;
4167
- border-radius: var(--radius);
4168
- border: 1px solid var(--canvas-border);
4169
- cursor: pointer;
4170
- position: relative;
4171
- flex-shrink: 0;
4172
- align-self: flex-end;
4173
- margin-bottom: 2px;
4174
- }
4175
- .sb-var-swatch input[type="color"] {
4176
- position: absolute;
4177
- inset: 0;
4178
- width: 100%;
4179
- height: 100%;
4180
- opacity: 0;
4181
- cursor: pointer;
4182
- pointer-events: auto;
4183
- }
4184
- .sb-var-preview {
4185
- margin-top: 2px;
4186
- padding: 8px;
4187
- background: var(--canvas-bg-1);
4188
- border-radius: var(--radius);
4189
- border: 1px solid var(--canvas-rule);
4190
- }
4191
- .sb-var-font-preview {
4192
- font-size: var(--spectrum-font-size-100, 14px);
4193
- line-height: 1.4;
4194
- color: var(--canvas-fg-2);
4195
- }
4196
- .sb-var-size-track {
4197
- background: var(--canvas-track);
4198
- height: 8px;
4199
- border-radius: var(--radius);
4200
- width: 100%;
4201
- overflow: hidden;
4202
- }
4203
- .sb-var-size-bar {
4204
- height: 100%;
4205
- background: var(--accent, #3b82f6);
4206
- transition: width 0.3s;
4207
- border-radius: var(--radius);
4208
- }
4209
- .sb-var-del {
4210
- opacity: 0;
4211
- transition: opacity 0.15s;
4212
- flex-shrink: 0;
4213
- }
4214
- .sb-var-row:hover .sb-var-del {
4215
- opacity: 1;
4216
- }
4217
- .sb-var-empty {
4218
- padding: 16px 8px;
4219
- text-align: center;
4220
- color: var(--canvas-light);
4221
- font-size: var(--spectrum-font-size-75, 12px);
4222
- font-style: italic;
4223
- }
4224
- .sb-var-add-btn {
4225
- margin-top: 6px;
4226
- pointer-events: auto;
4227
- background: none;
4228
- border: 1px dashed var(--canvas-border);
4229
- border-radius: var(--radius);
4230
- padding: 5px 10px;
4231
- font-size: var(--spectrum-font-size-75, 12px);
4232
- color: var(--canvas-fg-3);
4233
- cursor: pointer;
4234
- display: flex;
4235
- align-items: center;
4236
- gap: 4px;
4237
- transition: all 0.15s;
4238
- }
4239
- .sb-var-add-btn:hover {
4240
- border-color: var(--canvas-muted);
4241
- color: var(--canvas-fg-2);
4242
- background: var(--canvas-bg-1);
4243
- }
4244
- .sb-var-add-icon {
4245
- font-size: var(--spectrum-font-size-100, 14px);
4246
- font-weight: 600;
4247
- }
4248
- .sb-var-add-actions {
4249
- display: flex;
4250
- gap: 4px;
4251
- align-items: center;
4252
- flex-shrink: 0;
4253
- align-self: flex-end;
4254
- margin-bottom: 2px;
4255
- }
4256
- .sb-unit-input {
4257
- position: relative;
4258
- display: flex;
4259
- align-items: center;
4260
- width: 100%;
4261
- }
4262
- .sb-unit-input sp-textfield {
4263
- width: 100%;
4264
- }
4265
- .sb-unit-input sp-picker {
4266
- position: absolute;
4267
- right: 2px;
4268
- --mod-picker-border-width: 0;
4269
- --mod-picker-min-width: 56px;
4270
- }
4271
- .sb-var-add-preview {
4272
- font-size: 10px;
4273
- color: var(--canvas-muted);
4274
- font-family: var(--font-mono);
4275
- min-height: 14px;
4276
- }
4277
-
4278
- /* ─── Inline editing ─────────────────────────── */
4279
- .canvas-panel-canvas [contenteditable="true"] {
4280
- outline: 2px solid var(--accent);
4281
- outline-offset: 1px;
4282
- cursor: text;
4283
- min-height: 1.5em;
4284
- border-radius: var(--spectrum-corner-radius-75, 2px);
4285
- }
4286
- .canvas-panel-canvas [contenteditable="true"]:focus {
4287
- outline-color: var(--accent);
4288
- box-shadow: 0 0 0 3px var(--accent-15);
4289
- }
4290
-
4291
- /* ─── Welcome screen ─────────────────────────── */
4292
- .welcome-screen {
4293
- width: 100%;
4294
- height: 100%;
4295
- display: flex;
4296
- align-items: flex-start;
4297
- justify-content: center;
4298
- padding-top: 10vh;
4299
- overflow-y: auto;
4300
- }
4301
- .welcome-content {
4302
- max-width: 500px;
4303
- width: 100%;
4304
- padding: 0 24px;
4305
- }
4306
- .welcome-title {
4307
- font-size: 28px;
4308
- font-weight: 300;
4309
- color: var(--fg);
4310
- margin: 0;
4311
- letter-spacing: -0.5px;
4312
- }
4313
- .welcome-subtitle {
4314
- font-size: var(--spectrum-font-size-100, 14px);
4315
- color: var(--fg-dim);
4316
- margin: 2px 0 0;
4317
- }
4318
- .welcome-section {
4319
- margin-top: 28px;
4320
- }
4321
- .welcome-section-title {
4322
- font-size: 13px;
4323
- font-weight: 600;
4324
- color: var(--fg);
4325
- margin: 0 0 8px;
4326
- text-transform: uppercase;
4327
- letter-spacing: 0.3px;
4328
- }
4329
- .welcome-action {
4330
- display: flex;
4331
- align-items: center;
4332
- gap: 8px;
4333
- width: 100%;
4334
- padding: 5px 8px;
4335
- margin: 0;
4336
- background: none;
4337
- border: none;
4338
- border-radius: var(--radius);
4339
- font: inherit;
4340
- font-size: 13px;
4341
- color: var(--accent);
4342
- cursor: pointer;
4343
- text-align: left;
4344
- }
4345
- .welcome-action:hover {
4346
- background: var(--hover-bg);
4347
- text-decoration: underline;
4348
- }
4349
- .welcome-action-icon {
4350
- flex-shrink: 0;
4351
- opacity: 0.8;
4352
- }
4353
- a.welcome-action {
4354
- text-decoration: none;
4355
- box-sizing: border-box;
4356
- }
4357
- .welcome-install-note {
4358
- margin: 4px 8px 0;
4359
- font-size: 12px;
4360
- color: var(--fg-dim);
4361
- }
4362
- .welcome-recent {
4363
- display: flex;
4364
- align-items: baseline;
4365
- gap: 12px;
4366
- width: 100%;
4367
- padding: 4px 8px;
4368
- margin: 0;
4369
- background: none;
4370
- border: none;
4371
- border-radius: var(--radius);
4372
- font: inherit;
4373
- font-size: 13px;
4374
- color: var(--fg);
4375
- cursor: pointer;
4376
- text-align: left;
4377
- }
4378
- .welcome-recent:hover {
4379
- background: var(--hover-bg);
4380
- }
4381
- .welcome-recent-name {
4382
- color: var(--accent);
4383
- flex-shrink: 0;
4384
- }
4385
- .welcome-recent-name:hover {
4386
- text-decoration: underline;
4387
- }
4388
- .welcome-recent-path {
4389
- color: var(--fg-dim);
4390
- font-size: var(--spectrum-font-size-75, 12px);
4391
- overflow: hidden;
4392
- text-overflow: ellipsis;
4393
- white-space: nowrap;
4394
- }
4395
- .welcome-section-header {
4396
- display: flex;
4397
- align-items: baseline;
4398
- justify-content: space-between;
4399
- gap: 12px;
4400
- }
4401
- .welcome-clear {
4402
- padding: 0 4px;
4403
- background: none;
4404
- border: none;
4405
- font: inherit;
4406
- font-size: var(--spectrum-font-size-75, 12px);
4407
- color: var(--fg-dim);
4408
- cursor: pointer;
4409
- }
4410
- .welcome-clear:hover {
4411
- color: var(--fg);
4412
- text-decoration: underline;
4413
- }
4414
- .welcome-recent-row {
4415
- display: flex;
4416
- align-items: center;
4417
- }
4418
- .welcome-recent-row .welcome-recent {
4419
- flex: 1;
4420
- min-width: 0;
4421
- }
4422
- .welcome-recent-remove {
4423
- flex-shrink: 0;
4424
- padding: 2px 6px;
4425
- background: none;
4426
- border: none;
4427
- font: inherit;
4428
- font-size: var(--spectrum-font-size-75, 12px);
4429
- color: var(--fg-dim);
4430
- cursor: pointer;
4431
- opacity: 0;
4432
- border-radius: var(--radius);
4433
- }
4434
- .welcome-recent-row:hover .welcome-recent-remove {
4435
- opacity: 1;
4436
- }
4437
- .welcome-recent-remove:hover {
4438
- color: var(--fg);
4439
- background: var(--hover-bg);
4440
- }
4441
-
4442
- /* ─── Grid editor (Tabulator theme over Spectrum tokens) ─────────────── */
4443
- .jx-grid {
4444
- display: flex;
4445
- flex-direction: column;
4446
- height: 100%;
4447
- min-height: 0;
4448
- background: var(--bg);
4449
- }
4450
- .jx-grid-toolbar {
4451
- display: flex;
4452
- align-items: center;
4453
- gap: 6px;
4454
- padding: 6px 10px;
4455
- border-bottom: 1px solid var(--border);
4456
- background: var(--bg-panel);
4457
- flex-shrink: 0;
4458
- }
4459
- .jx-grid-toolbar sp-search {
4460
- width: 200px;
4461
- }
4462
- .jx-grid-spacer {
4463
- flex: 1;
4464
- }
4465
- .jx-grid-note {
4466
- font-size: var(--spectrum-font-size-50, 11px);
4467
- color: var(--fg-dim);
4468
- border: 1px solid var(--border);
4469
- border-radius: var(--radius);
4470
- padding: 1px 6px;
4471
- cursor: help;
4472
- }
4473
- .jx-grid-count {
4474
- font-size: var(--spectrum-font-size-75, 12px);
4475
- color: var(--fg-dim);
4476
- white-space: nowrap;
4477
- }
4478
- .jx-grid-error-text {
4479
- color: var(--danger);
4480
- }
4481
- .jx-grid-host {
4482
- flex: 1;
4483
- min-height: 0;
4484
- }
4485
- .jx-grid-missing {
4486
- padding: 24px;
4487
- color: var(--fg-dim);
4488
- }
4489
-
4490
- /* Tabulator structural overrides — tokens only, scoped under .jx-grid. */
4491
- .jx-grid .tabulator {
4492
- background: var(--bg);
4493
- color: var(--fg);
4494
- border: none;
4495
- font-size: var(--spectrum-font-size-75, 12px);
4496
- height: 100%;
4497
- }
4498
- .jx-grid .tabulator .tabulator-header {
4499
- background: var(--bg-panel);
4500
- color: var(--fg);
4501
- border-bottom: 1px solid var(--border);
4502
- }
4503
- .jx-grid .tabulator .tabulator-header .tabulator-col {
4504
- background: var(--bg-panel);
4505
- border-right: 1px solid var(--border);
4506
- }
4507
- .jx-grid .tabulator .tabulator-header .tabulator-col .tabulator-col-title {
4508
- color: var(--fg);
4509
- font-weight: 600;
4510
- }
4511
- .jx-grid .tabulator .tabulator-header .tabulator-header-filter input {
4512
- background: var(--bg);
4513
- color: var(--fg);
4514
- border: 1px solid var(--border);
4515
- border-radius: var(--spectrum-corner-radius-75, 2px);
4516
- padding: 1px 4px;
4517
- font: inherit;
4518
- }
4519
- .jx-grid .tabulator .tabulator-tableholder {
4520
- background: var(--bg);
4521
- }
4522
- .jx-grid .tabulator .tabulator-row {
4523
- background: var(--bg);
4524
- color: var(--fg);
4525
- border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
4526
- min-height: 26px;
4527
- }
4528
- .jx-grid .tabulator .tabulator-row.tabulator-row-even {
4529
- background: color-mix(in srgb, var(--bg-panel) 45%, var(--bg));
4530
- }
4531
- .jx-grid .tabulator .tabulator-row.tabulator-selected {
4532
- background: color-mix(in srgb, var(--accent) 16%, var(--bg));
4533
- }
4534
- .jx-grid .tabulator .tabulator-row .tabulator-cell {
4535
- border-right: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
4536
- padding: 3px 8px;
4537
- }
4538
- .jx-grid .tabulator .tabulator-row .tabulator-cell.tabulator-frozen {
4539
- background: var(--bg-panel);
4540
- border-right: 1px solid var(--border);
4541
- }
4542
- .jx-grid .tabulator .tabulator-range {
4543
- border: 1px solid var(--accent);
4544
- background: color-mix(in srgb, var(--accent) 10%, transparent);
4545
- }
4546
- .jx-grid .tabulator .tabulator-range-overlay .tabulator-range-cell-active {
4547
- border: 2px solid var(--accent);
4548
- }
4549
- .jx-grid .tabulator .tabulator-placeholder .tabulator-placeholder-contents {
4550
- color: var(--fg-dim);
4551
- background: transparent;
4552
- }
4553
-
4554
- /* Buffer-state paint (dirty / error / stale / pending rows). */
4555
- .jx-grid .tabulator-cell.jx-grid-cell--dirty {
4556
- box-shadow: inset 2px 0 0 var(--accent);
4557
- background: color-mix(in srgb, var(--accent) 8%, transparent);
4558
- }
4559
- .jx-grid .tabulator-cell.jx-grid-cell--error {
4560
- box-shadow: inset 2px 0 0 var(--danger);
4561
- background: color-mix(in srgb, var(--danger) 12%, transparent);
4562
- }
4563
- .jx-grid .tabulator-cell.jx-grid-cell--stale {
4564
- opacity: 0.65;
4565
- }
4566
- .jx-grid .tabulator-row.jx-grid-row--pending-delete .tabulator-cell {
4567
- text-decoration: line-through;
4568
- opacity: 0.55;
4569
- }
4570
- .jx-grid .tabulator-row.jx-grid-row--pending-insert {
4571
- background: color-mix(in srgb, var(--success, var(--accent)) 10%, var(--bg));
4572
- }
4573
- .jx-grid .tabulator-row.jx-grid-row--stale {
4574
- outline: 1px dashed var(--fg-dim);
4575
- outline-offset: -1px;
4576
- }
4577
-
4578
- /* Cell content + in-cell editors. */
4579
- .jx-grid-cell-content {
4580
- overflow: hidden;
4581
- text-overflow: ellipsis;
4582
- white-space: nowrap;
4583
- }
4584
- .jx-grid-kind-number {
4585
- text-align: right;
4586
- font-variant-numeric: tabular-nums;
4587
- }
4588
- .jx-grid-kind-readonly {
4589
- color: var(--fg-dim);
4590
- font-family: var(--font-mono);
4591
- font-size: var(--spectrum-font-size-50, 11px);
4592
- }
4593
- .jx-grid-chip {
4594
- display: inline-block;
4595
- background: color-mix(in srgb, var(--accent) 18%, transparent);
4596
- border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
4597
- border-radius: 8px;
4598
- padding: 0 6px;
4599
- margin-right: 4px;
4600
- font-size: var(--spectrum-font-size-50, 11px);
4601
- line-height: 16px;
4602
- }
4603
- .jx-grid-editor {
4604
- width: 100%;
4605
- height: 100%;
4606
- display: flex;
4607
- align-items: center;
4608
- }
4609
- .jx-grid-editor .jx-grid-input,
4610
- .jx-grid-editor .jx-grid-select {
4611
- width: 100%;
4612
- background: var(--bg);
4613
- color: var(--fg);
4614
- border: 1px solid var(--accent);
4615
- border-radius: var(--spectrum-corner-radius-75, 2px);
4616
- padding: 2px 6px;
4617
- font: inherit;
4618
- outline: none;
4619
- }
4620
- .jx-grid-editor .jx-grid-checkbox {
4621
- margin: 0 auto;
4622
- accent-color: var(--accent);
4623
- }
4624
- .jx-grid-pill-editor .jx-grid-pills {
4625
- display: flex;
4626
- flex-wrap: wrap;
4627
- gap: 2px;
4628
- align-items: center;
4629
- width: 100%;
4630
- background: var(--bg);
4631
- border: 1px solid var(--accent);
4632
- border-radius: var(--spectrum-corner-radius-75, 2px);
4633
- padding: 1px 4px;
4634
- }
4635
- .jx-grid-pill-input {
4636
- flex: 1;
4637
- min-width: 60px;
4638
- background: transparent;
4639
- border: none;
4640
- outline: none;
4641
- color: var(--fg);
4642
- font: inherit;
4643
- }
4644
- .jx-grid-chip-x {
4645
- background: none;
4646
- border: none;
4647
- color: inherit;
4648
- cursor: pointer;
4649
- padding: 0 0 0 4px;
4650
- font: inherit;
4651
- line-height: 1;
4652
- }
4653
- .jx-grid-chip-x:hover {
4654
- color: var(--danger);
4655
- }
4656
- .jx-grid-cell-popover-body {
4657
- display: flex;
4658
- flex-direction: column;
4659
- gap: 8px;
4660
- padding: 10px;
4661
- min-width: 260px;
4662
- }
4663
- .jx-grid-cell-popover-title {
4664
- font-weight: 600;
4665
- font-size: var(--spectrum-font-size-75, 12px);
4666
- }
4667
- .jx-grid-cell-popover-hint {
4668
- color: var(--fg-dim);
4669
- font-size: var(--spectrum-font-size-50, 11px);
4670
- }
4671
- .jx-grid-cell-popover-actions {
4672
- display: flex;
4673
- justify-content: flex-end;
4674
- }
4675
- .jx-grid-cell-popover .jx-grid-select,
4676
- .jx-grid-cell-popover .jx-grid-input {
4677
- width: 100%;
4678
- background: var(--bg);
4679
- color: var(--fg);
4680
- border: 1px solid var(--border);
4681
- border-radius: var(--spectrum-corner-radius-75, 2px);
4682
- padding: 3px 6px;
4683
- font: inherit;
4684
- }
4685
- </style>
8
+ <link rel="stylesheet" href="./styles/tokens.css" />
9
+ <link rel="stylesheet" href="./styles/shell.css" />
10
+ <link rel="stylesheet" href="./styles/canvas.css" />
11
+ <link rel="stylesheet" href="./styles/panels.css" />
12
+ <link rel="stylesheet" href="./styles/inspector.css" />
13
+ <link rel="stylesheet" href="./styles/overlays.css" />
14
+ <!-- Last: forced colours redraws what Windows High Contrast deletes. -->
15
+ <link rel="stylesheet" href="./styles/forced-colors.css" />
4686
16
  </head>
4687
17
  <body>
4688
18
  <sp-theme color="dark" scale="medium" system="spectrum">
4689
19
  <div id="app">
4690
20
  <div id="toolbar"></div>
4691
- <div id="tab-strip"></div>
4692
- <div id="tab-bar"></div>
4693
- <div id="frontmatter-panel" hidden></div>
21
+ <!-- The PANE GRID (spec §18.1). One cell per pane, each holding that pane's own strip,
22
+ jump bar, chrome layer and stage — the four surfaces that used to be flat siblings of
23
+ THIS grid, which is to say application rows that only ever described one pane. There
24
+ is nothing to see here in markup: `panels/pane-grid.ts` reconciles the cells against
25
+ `workspace.panes`, because how many there are is a fact about the workspace and a
26
+ `<div id>` can only ever be one of them. -->
27
+ <div id="pane-grid"></div>
4694
28
  <div id="activity-bar"></div>
4695
29
  <div id="left-panel"></div>
4696
30
  <div id="resize-left" class="resize-handle"></div>
4697
- <div id="canvas-wrap"></div>
31
+ <!-- ⑪ The Bottom dock (⌘J). It sits in the PANE's column, under the stage and above the
32
+ status bar, so opening it never narrows the Navigator or the Inspector (spec §12
33
+ region ⑪). Its handle resizes on the other axis; `panels/bottom-dock.ts` stamps
34
+ `dock.bottom` on this host while it is open, and nothing while it is closed. -->
35
+ <div id="resize-bottom" class="resize-handle resize-handle-row"></div>
36
+ <div id="bottom-dock"></div>
4698
37
  <div id="resize-right" class="resize-handle"></div>
38
+ <!-- The Inspector dock. Four tabs — Content · Style · Logic · Assistant (spec §12 region
39
+ ⑨) — all inside this one host. The assistant's fifth grid column is gone. -->
4699
40
  <div id="right-panel"></div>
4700
- <div id="resize-chat" class="resize-handle"></div>
4701
- <div id="chat-panel"></div>
4702
- <div id="statusbar"></div>
41
+ <!-- The app's only status channel: announce what lands in it (spec §12 region ⑫). -->
42
+ <div id="statusbar" role="status" aria-live="polite"></div>
4703
43
  </div>
4704
44
  <div
4705
45
  id="layer-popover"
@@ -4713,6 +53,16 @@
4713
53
  id="layer-dialog"
4714
54
  style="position: fixed; inset: 0; pointer-events: none; z-index: 3000"
4715
55
  ></div>
56
+ <!-- The toast host: the fourth overlay layer (spec §12 region ④, §7.1). Above the dialog
57
+ layer, because an operation started from a dialog reports its outcome to the person
58
+ still looking at the dialog. `role="status"` sits on the HOST, so a stack of toasts is
59
+ announced as one live region rather than as one region per notification. -->
60
+ <div
61
+ id="layer-toast"
62
+ role="status"
63
+ aria-live="polite"
64
+ style="position: fixed; inset: 0; pointer-events: none; z-index: 4000"
65
+ ></div>
4716
66
  </sp-theme>
4717
67
  <script type="module" src="./dist/studio.js"></script>
4718
68
  </body>