@nocturnium/svelte-ide 1.0.0-rc.1

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 (330) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +251 -0
  3. package/dist/components/agents/AgentActivityPanel.svelte +565 -0
  4. package/dist/components/agents/AgentActivityPanel.svelte.d.ts +24 -0
  5. package/dist/components/agents/AgentAvatar.svelte +417 -0
  6. package/dist/components/agents/AgentAvatar.svelte.d.ts +23 -0
  7. package/dist/components/agents/AgentCursor.svelte +224 -0
  8. package/dist/components/agents/AgentCursor.svelte.d.ts +35 -0
  9. package/dist/components/agents/AgentPresenceBar.svelte +261 -0
  10. package/dist/components/agents/AgentPresenceBar.svelte.d.ts +20 -0
  11. package/dist/components/agents/index.d.ts +4 -0
  12. package/dist/components/agents/index.js +5 -0
  13. package/dist/components/ai/AIConversationList.svelte +524 -0
  14. package/dist/components/ai/AIConversationList.svelte.d.ts +17 -0
  15. package/dist/components/ai/AIEditPreview.svelte +132 -0
  16. package/dist/components/ai/AIEditPreview.svelte.d.ts +8 -0
  17. package/dist/components/ai/AIInlineEdit.svelte +155 -0
  18. package/dist/components/ai/AIInlineEdit.svelte.d.ts +10 -0
  19. package/dist/components/ai/AIMessage.svelte +239 -0
  20. package/dist/components/ai/AIMessage.svelte.d.ts +13 -0
  21. package/dist/components/ai/AIMessageActions.svelte +176 -0
  22. package/dist/components/ai/AIMessageActions.svelte.d.ts +12 -0
  23. package/dist/components/ai/AIMessageContent.svelte +355 -0
  24. package/dist/components/ai/AIMessageContent.svelte.d.ts +7 -0
  25. package/dist/components/ai/AIPanel.svelte +561 -0
  26. package/dist/components/ai/AIPanel.svelte.d.ts +7 -0
  27. package/dist/components/ai/AISuggestionWidget.svelte +132 -0
  28. package/dist/components/ai/AISuggestionWidget.svelte.d.ts +10 -0
  29. package/dist/components/ai/AIToolCallDisplay.svelte +317 -0
  30. package/dist/components/ai/AIToolCallDisplay.svelte.d.ts +12 -0
  31. package/dist/components/ai/index.d.ts +9 -0
  32. package/dist/components/ai/index.js +10 -0
  33. package/dist/components/core/Avatar.svelte +110 -0
  34. package/dist/components/core/Avatar.svelte.d.ts +12 -0
  35. package/dist/components/core/Badge.svelte +98 -0
  36. package/dist/components/core/Badge.svelte.d.ts +11 -0
  37. package/dist/components/core/Button.svelte +175 -0
  38. package/dist/components/core/Button.svelte.d.ts +18 -0
  39. package/dist/components/core/ConnectionStatus.svelte +294 -0
  40. package/dist/components/core/ConnectionStatus.svelte.d.ts +20 -0
  41. package/dist/components/core/ContextMenu.svelte +176 -0
  42. package/dist/components/core/ContextMenu.svelte.d.ts +19 -0
  43. package/dist/components/core/ErrorBoundary.svelte +277 -0
  44. package/dist/components/core/ErrorBoundary.svelte.d.ts +23 -0
  45. package/dist/components/core/Icon.svelte +107 -0
  46. package/dist/components/core/Icon.svelte.d.ts +8 -0
  47. package/dist/components/core/Input.svelte +138 -0
  48. package/dist/components/core/Input.svelte.d.ts +20 -0
  49. package/dist/components/core/Kbd.svelte +34 -0
  50. package/dist/components/core/Kbd.svelte.d.ts +7 -0
  51. package/dist/components/core/ResizeHandle.svelte +200 -0
  52. package/dist/components/core/ResizeHandle.svelte.d.ts +23 -0
  53. package/dist/components/core/Spinner.svelte +35 -0
  54. package/dist/components/core/Spinner.svelte.d.ts +7 -0
  55. package/dist/components/core/Textarea.svelte +112 -0
  56. package/dist/components/core/Textarea.svelte.d.ts +18 -0
  57. package/dist/components/core/Tooltip.svelte +103 -0
  58. package/dist/components/core/Tooltip.svelte.d.ts +11 -0
  59. package/dist/components/core/index.d.ts +13 -0
  60. package/dist/components/core/index.js +14 -0
  61. package/dist/components/editor/AIFocusLayer.svelte +430 -0
  62. package/dist/components/editor/AIFocusLayer.svelte.d.ts +32 -0
  63. package/dist/components/editor/Breadcrumbs.svelte +435 -0
  64. package/dist/components/editor/Breadcrumbs.svelte.d.ts +33 -0
  65. package/dist/components/editor/BreakpointLayer.svelte +642 -0
  66. package/dist/components/editor/BreakpointLayer.svelte.d.ts +20 -0
  67. package/dist/components/editor/CognitiveLoadMeter.svelte +324 -0
  68. package/dist/components/editor/CognitiveLoadMeter.svelte.d.ts +18 -0
  69. package/dist/components/editor/CollaborativeEditor.svelte +218 -0
  70. package/dist/components/editor/CollaborativeEditor.svelte.d.ts +32 -0
  71. package/dist/components/editor/CommandPalette.svelte +434 -0
  72. package/dist/components/editor/CommandPalette.svelte.d.ts +11 -0
  73. package/dist/components/editor/ComplexityLayer.svelte +293 -0
  74. package/dist/components/editor/ComplexityLayer.svelte.d.ts +23 -0
  75. package/dist/components/editor/ConflictZoneLayer.svelte +441 -0
  76. package/dist/components/editor/ConflictZoneLayer.svelte.d.ts +25 -0
  77. package/dist/components/editor/ContextLens.svelte +262 -0
  78. package/dist/components/editor/ContextLens.svelte.d.ts +27 -0
  79. package/dist/components/editor/CustomEditor.svelte +1242 -0
  80. package/dist/components/editor/CustomEditor.svelte.d.ts +37 -0
  81. package/dist/components/editor/DebugConsole.svelte +646 -0
  82. package/dist/components/editor/DebugConsole.svelte.d.ts +41 -0
  83. package/dist/components/editor/EchoCursorLayer.svelte +363 -0
  84. package/dist/components/editor/EchoCursorLayer.svelte.d.ts +24 -0
  85. package/dist/components/editor/Editor.svelte +61 -0
  86. package/dist/components/editor/Editor.svelte.d.ts +22 -0
  87. package/dist/components/editor/EditorGutter.svelte +119 -0
  88. package/dist/components/editor/EditorGutter.svelte.d.ts +19 -0
  89. package/dist/components/editor/EditorLines.svelte +182 -0
  90. package/dist/components/editor/EditorLines.svelte.d.ts +43 -0
  91. package/dist/components/editor/EditorPane.svelte +134 -0
  92. package/dist/components/editor/EditorPane.svelte.d.ts +9 -0
  93. package/dist/components/editor/EditorSelections.svelte +186 -0
  94. package/dist/components/editor/EditorSelections.svelte.d.ts +25 -0
  95. package/dist/components/editor/EditorTabs.svelte +170 -0
  96. package/dist/components/editor/EditorTabs.svelte.d.ts +12 -0
  97. package/dist/components/editor/FileExplorer.svelte +811 -0
  98. package/dist/components/editor/FileExplorer.svelte.d.ts +67 -0
  99. package/dist/components/editor/FileIcon.svelte +110 -0
  100. package/dist/components/editor/FileIcon.svelte.d.ts +10 -0
  101. package/dist/components/editor/FindReplace.svelte +448 -0
  102. package/dist/components/editor/FindReplace.svelte.d.ts +40 -0
  103. package/dist/components/editor/GhostBracketLayer.svelte +391 -0
  104. package/dist/components/editor/GhostBracketLayer.svelte.d.ts +24 -0
  105. package/dist/components/editor/GitBlameLayer.svelte +436 -0
  106. package/dist/components/editor/GitBlameLayer.svelte.d.ts +18 -0
  107. package/dist/components/editor/InlineDiagnosticsLayer.svelte +540 -0
  108. package/dist/components/editor/InlineDiagnosticsLayer.svelte.d.ts +35 -0
  109. package/dist/components/editor/InlineDiffLayer.svelte +337 -0
  110. package/dist/components/editor/InlineDiffLayer.svelte.d.ts +31 -0
  111. package/dist/components/editor/MinimalEditor.svelte +75 -0
  112. package/dist/components/editor/MinimalEditor.svelte.d.ts +6 -0
  113. package/dist/components/editor/MinimalEditor2.svelte +84 -0
  114. package/dist/components/editor/MinimalEditor2.svelte.d.ts +6 -0
  115. package/dist/components/editor/Minimap.svelte +327 -0
  116. package/dist/components/editor/Minimap.svelte.d.ts +34 -0
  117. package/dist/components/editor/PluginPreviewSandbox.svelte +793 -0
  118. package/dist/components/editor/PluginPreviewSandbox.svelte.d.ts +49 -0
  119. package/dist/components/editor/ProblemsPanel.svelte +628 -0
  120. package/dist/components/editor/ProblemsPanel.svelte.d.ts +25 -0
  121. package/dist/components/editor/QuickActionsMenu.svelte +403 -0
  122. package/dist/components/editor/QuickActionsMenu.svelte.d.ts +18 -0
  123. package/dist/components/editor/SnippetPalette.svelte +530 -0
  124. package/dist/components/editor/SnippetPalette.svelte.d.ts +16 -0
  125. package/dist/components/editor/StructureMap.svelte +431 -0
  126. package/dist/components/editor/StructureMap.svelte.d.ts +37 -0
  127. package/dist/components/editor/SymbolOutline.svelte +722 -0
  128. package/dist/components/editor/SymbolOutline.svelte.d.ts +44 -0
  129. package/dist/components/editor/TimelineScrubber.svelte +470 -0
  130. package/dist/components/editor/TimelineScrubber.svelte.d.ts +40 -0
  131. package/dist/components/editor/TokenRenderer.svelte +69 -0
  132. package/dist/components/editor/TokenRenderer.svelte.d.ts +15 -0
  133. package/dist/components/editor/constants.d.ts +32 -0
  134. package/dist/components/editor/constants.js +36 -0
  135. package/dist/components/editor/core/ai-awareness.d.ts +176 -0
  136. package/dist/components/editor/core/ai-awareness.js +210 -0
  137. package/dist/components/editor/core/bracket-healer.d.ts +189 -0
  138. package/dist/components/editor/core/bracket-healer.js +406 -0
  139. package/dist/components/editor/core/breakpoints.d.ts +203 -0
  140. package/dist/components/editor/core/breakpoints.js +414 -0
  141. package/dist/components/editor/core/commands.d.ts +108 -0
  142. package/dist/components/editor/core/commands.js +246 -0
  143. package/dist/components/editor/core/complexity-analyzer.d.ts +123 -0
  144. package/dist/components/editor/core/complexity-analyzer.js +376 -0
  145. package/dist/components/editor/core/conflict-predictor.d.ts +135 -0
  146. package/dist/components/editor/core/conflict-predictor.js +316 -0
  147. package/dist/components/editor/core/crdt-binding.d.ts +118 -0
  148. package/dist/components/editor/core/crdt-binding.js +286 -0
  149. package/dist/components/editor/core/diagnostics.d.ts +210 -0
  150. package/dist/components/editor/core/diagnostics.js +335 -0
  151. package/dist/components/editor/core/echo-cursor.d.ts +201 -0
  152. package/dist/components/editor/core/echo-cursor.js +267 -0
  153. package/dist/components/editor/core/folding.d.ts +124 -0
  154. package/dist/components/editor/core/folding.js +672 -0
  155. package/dist/components/editor/core/ghost-pair.d.ts +122 -0
  156. package/dist/components/editor/core/ghost-pair.js +221 -0
  157. package/dist/components/editor/core/git-blame.d.ts +170 -0
  158. package/dist/components/editor/core/git-blame.js +324 -0
  159. package/dist/components/editor/core/index.d.ts +26 -0
  160. package/dist/components/editor/core/index.js +24 -0
  161. package/dist/components/editor/core/keybindings.d.ts +79 -0
  162. package/dist/components/editor/core/keybindings.js +357 -0
  163. package/dist/components/editor/core/multi-cursor.d.ts +196 -0
  164. package/dist/components/editor/core/multi-cursor.js +521 -0
  165. package/dist/components/editor/core/navigation.d.ts +107 -0
  166. package/dist/components/editor/core/navigation.js +408 -0
  167. package/dist/components/editor/core/quick-actions.d.ts +189 -0
  168. package/dist/components/editor/core/quick-actions.js +427 -0
  169. package/dist/components/editor/core/search.d.ts +88 -0
  170. package/dist/components/editor/core/search.js +192 -0
  171. package/dist/components/editor/core/semantic-analyzer.d.ts +77 -0
  172. package/dist/components/editor/core/semantic-analyzer.js +424 -0
  173. package/dist/components/editor/core/snippet-manager.d.ts +202 -0
  174. package/dist/components/editor/core/snippet-manager.js +565 -0
  175. package/dist/components/editor/core/state.d.ts +367 -0
  176. package/dist/components/editor/core/state.js +900 -0
  177. package/dist/components/editor/core/timeline.d.ts +204 -0
  178. package/dist/components/editor/core/timeline.js +349 -0
  179. package/dist/components/editor/editor-find.d.ts +56 -0
  180. package/dist/components/editor/editor-find.js +148 -0
  181. package/dist/components/editor/editor-input.d.ts +77 -0
  182. package/dist/components/editor/editor-input.js +445 -0
  183. package/dist/components/editor/editor-multicursor.d.ts +21 -0
  184. package/dist/components/editor/editor-multicursor.js +196 -0
  185. package/dist/components/editor/editor-scroll.d.ts +14 -0
  186. package/dist/components/editor/editor-scroll.js +34 -0
  187. package/dist/components/editor/index.d.ts +15 -0
  188. package/dist/components/editor/index.js +21 -0
  189. package/dist/components/editor/languages.d.ts +62 -0
  190. package/dist/components/editor/languages.js +285 -0
  191. package/dist/components/editor/theme.d.ts +88 -0
  192. package/dist/components/editor/theme.js +139 -0
  193. package/dist/components/editor/tokenizer/base.d.ts +40 -0
  194. package/dist/components/editor/tokenizer/base.js +203 -0
  195. package/dist/components/editor/tokenizer/index.d.ts +56 -0
  196. package/dist/components/editor/tokenizer/index.js +215 -0
  197. package/dist/components/editor/tokenizer/languages/css.d.ts +17 -0
  198. package/dist/components/editor/tokenizer/languages/css.js +194 -0
  199. package/dist/components/editor/tokenizer/languages/go.d.ts +17 -0
  200. package/dist/components/editor/tokenizer/languages/go.js +220 -0
  201. package/dist/components/editor/tokenizer/languages/html.d.ts +24 -0
  202. package/dist/components/editor/tokenizer/languages/html.js +145 -0
  203. package/dist/components/editor/tokenizer/languages/javascript.d.ts +56 -0
  204. package/dist/components/editor/tokenizer/languages/javascript.js +452 -0
  205. package/dist/components/editor/tokenizer/languages/json.d.ts +12 -0
  206. package/dist/components/editor/tokenizer/languages/json.js +91 -0
  207. package/dist/components/editor/tokenizer/languages/markdown.d.ts +16 -0
  208. package/dist/components/editor/tokenizer/languages/markdown.js +156 -0
  209. package/dist/components/editor/tokenizer/languages/python.d.ts +20 -0
  210. package/dist/components/editor/tokenizer/languages/python.js +227 -0
  211. package/dist/components/editor/tokenizer/languages/svelte.d.ts +40 -0
  212. package/dist/components/editor/tokenizer/languages/svelte.js +326 -0
  213. package/dist/components/editor/tokenizer/types.d.ts +86 -0
  214. package/dist/components/editor/tokenizer/types.js +4 -0
  215. package/dist/components/layout/IDELayout.svelte +274 -0
  216. package/dist/components/layout/IDELayout.svelte.d.ts +29 -0
  217. package/dist/components/layout/StatusBar.svelte +511 -0
  218. package/dist/components/layout/StatusBar.svelte.d.ts +47 -0
  219. package/dist/components/layout/index.d.ts +2 -0
  220. package/dist/components/layout/index.js +3 -0
  221. package/dist/components/lsp/AutocompleteWidget.svelte +364 -0
  222. package/dist/components/lsp/AutocompleteWidget.svelte.d.ts +33 -0
  223. package/dist/components/lsp/DiagnosticMarker.svelte +166 -0
  224. package/dist/components/lsp/DiagnosticMarker.svelte.d.ts +19 -0
  225. package/dist/components/lsp/DiagnosticsPanel.svelte +388 -0
  226. package/dist/components/lsp/DiagnosticsPanel.svelte.d.ts +21 -0
  227. package/dist/components/lsp/HoverTooltip.svelte +274 -0
  228. package/dist/components/lsp/HoverTooltip.svelte.d.ts +24 -0
  229. package/dist/components/lsp/LSPEditor.svelte +486 -0
  230. package/dist/components/lsp/LSPEditor.svelte.d.ts +39 -0
  231. package/dist/components/lsp/SignatureHelpWidget.svelte +216 -0
  232. package/dist/components/lsp/SignatureHelpWidget.svelte.d.ts +22 -0
  233. package/dist/components/lsp/index.d.ts +6 -0
  234. package/dist/components/lsp/index.js +7 -0
  235. package/dist/components/plugins/PluginCard.svelte +153 -0
  236. package/dist/components/plugins/PluginCard.svelte.d.ts +19 -0
  237. package/dist/components/plugins/PluginPanel.svelte +280 -0
  238. package/dist/components/plugins/PluginPanel.svelte.d.ts +8 -0
  239. package/dist/components/plugins/PluginProposalForm.svelte +250 -0
  240. package/dist/components/plugins/PluginProposalForm.svelte.d.ts +6 -0
  241. package/dist/components/plugins/PluginStatusBadge.svelte +14 -0
  242. package/dist/components/plugins/PluginStatusBadge.svelte.d.ts +8 -0
  243. package/dist/components/plugins/index.d.ts +4 -0
  244. package/dist/components/plugins/index.js +5 -0
  245. package/dist/components/vfs/LockConflictDialog.svelte +705 -0
  246. package/dist/components/vfs/LockConflictDialog.svelte.d.ts +21 -0
  247. package/dist/components/vfs/LockIndicator.svelte +194 -0
  248. package/dist/components/vfs/LockIndicator.svelte.d.ts +29 -0
  249. package/dist/components/vfs/LockOverlay.svelte +344 -0
  250. package/dist/components/vfs/LockOverlay.svelte.d.ts +17 -0
  251. package/dist/components/vfs/VersionConflictDialog.svelte +549 -0
  252. package/dist/components/vfs/VersionConflictDialog.svelte.d.ts +24 -0
  253. package/dist/components/vfs/index.d.ts +4 -0
  254. package/dist/components/vfs/index.js +5 -0
  255. package/dist/crdt/awareness.d.ts +42 -0
  256. package/dist/crdt/awareness.js +109 -0
  257. package/dist/crdt/document.d.ts +101 -0
  258. package/dist/crdt/document.js +187 -0
  259. package/dist/crdt/index.d.ts +9 -0
  260. package/dist/crdt/index.js +8 -0
  261. package/dist/crdt/provider.d.ts +85 -0
  262. package/dist/crdt/provider.js +150 -0
  263. package/dist/crdt/types.d.ts +61 -0
  264. package/dist/crdt/types.js +4 -0
  265. package/dist/crdt/undo.d.ts +34 -0
  266. package/dist/crdt/undo.js +70 -0
  267. package/dist/index.d.ts +277 -0
  268. package/dist/index.js +280 -0
  269. package/dist/plugins/index.d.ts +103 -0
  270. package/dist/plugins/index.js +153 -0
  271. package/dist/services/error-handling.d.ts +95 -0
  272. package/dist/services/error-handling.js +413 -0
  273. package/dist/services/ide-integration.d.ts +83 -0
  274. package/dist/services/ide-integration.js +367 -0
  275. package/dist/services/lsp-client.d.ts +69 -0
  276. package/dist/services/lsp-client.js +667 -0
  277. package/dist/services/mock-ai.d.ts +37 -0
  278. package/dist/services/mock-ai.js +318 -0
  279. package/dist/services/optimistic.d.ts +141 -0
  280. package/dist/services/optimistic.js +367 -0
  281. package/dist/services/vfs-client.d.ts +81 -0
  282. package/dist/services/vfs-client.js +348 -0
  283. package/dist/stores/agents.svelte.d.ts +85 -0
  284. package/dist/stores/agents.svelte.js +459 -0
  285. package/dist/stores/ai-persistence.svelte.d.ts +76 -0
  286. package/dist/stores/ai-persistence.svelte.js +334 -0
  287. package/dist/stores/ai.svelte.d.ts +140 -0
  288. package/dist/stores/ai.svelte.js +383 -0
  289. package/dist/stores/collaboration.svelte.d.ts +164 -0
  290. package/dist/stores/collaboration.svelte.js +334 -0
  291. package/dist/stores/editor.svelte.d.ts +131 -0
  292. package/dist/stores/editor.svelte.js +250 -0
  293. package/dist/stores/index.d.ts +10 -0
  294. package/dist/stores/index.js +29 -0
  295. package/dist/stores/layout.svelte.d.ts +171 -0
  296. package/dist/stores/layout.svelte.js +351 -0
  297. package/dist/stores/plugin.svelte.d.ts +121 -0
  298. package/dist/stores/plugin.svelte.js +410 -0
  299. package/dist/stores/vfs.svelte.d.ts +123 -0
  300. package/dist/stores/vfs.svelte.js +680 -0
  301. package/dist/styles/theme.css +623 -0
  302. package/dist/types/agents.d.ts +127 -0
  303. package/dist/types/agents.js +5 -0
  304. package/dist/types/ai.d.ts +137 -0
  305. package/dist/types/ai.js +4 -0
  306. package/dist/types/crdt.d.ts +222 -0
  307. package/dist/types/crdt.js +5 -0
  308. package/dist/types/editor.d.ts +52 -0
  309. package/dist/types/editor.js +18 -0
  310. package/dist/types/events.d.ts +133 -0
  311. package/dist/types/events.js +4 -0
  312. package/dist/types/filesystem.d.ts +77 -0
  313. package/dist/types/filesystem.js +4 -0
  314. package/dist/types/index.d.ts +9 -0
  315. package/dist/types/index.js +12 -0
  316. package/dist/types/lsp.d.ts +691 -0
  317. package/dist/types/lsp.js +108 -0
  318. package/dist/types/plugin.d.ts +239 -0
  319. package/dist/types/plugin.js +5 -0
  320. package/dist/types/vfs.d.ts +191 -0
  321. package/dist/types/vfs.js +18 -0
  322. package/dist/utils/format.d.ts +55 -0
  323. package/dist/utils/format.js +152 -0
  324. package/dist/utils/index.d.ts +3 -0
  325. package/dist/utils/index.js +4 -0
  326. package/dist/utils/keybindings.d.ts +33 -0
  327. package/dist/utils/keybindings.js +171 -0
  328. package/dist/utils/language.d.ts +27 -0
  329. package/dist/utils/language.js +222 -0
  330. package/package.json +178 -0
@@ -0,0 +1,326 @@
1
+ /**
2
+ * Svelte tokenizer for syntax highlighting
3
+ *
4
+ * Supports:
5
+ * - Template directives: {#if}, {#each}, {@html}, etc.
6
+ * - JavaScript expressions in curly braces
7
+ * - Svelte-specific attributes: bind:, on:, use:, transition:, etc.
8
+ * - Script and style sections
9
+ * - HTML template parts
10
+ */
11
+ import { createTypeScriptTokenizer } from './javascript';
12
+ import { createCSSTokenizer } from './css';
13
+ /**
14
+ * Assign sequential start/end positions to tokens in document order.
15
+ * Token N starts where token N-1 ended, since tokens render left-to-right.
16
+ */
17
+ function reindexTokens(tokens) {
18
+ let cursor = 0;
19
+ return tokens.map((t) => {
20
+ const start = cursor;
21
+ const end = start + t.text.length;
22
+ cursor = end;
23
+ return { type: t.type, text: t.text, start, end };
24
+ });
25
+ }
26
+ /**
27
+ * Svelte keywords and directives
28
+ */
29
+ const SVELTE_BLOCK_KEYWORDS = new Set([
30
+ 'if', 'else', 'each', 'await', 'then', 'catch', 'key', 'snippet'
31
+ ]);
32
+ const SVELTE_TAG_KEYWORDS = new Set([
33
+ 'html', 'debug', 'const', 'render'
34
+ ]);
35
+ const SVELTE_ATTRIBUTE_PREFIXES = [
36
+ 'bind:', 'on:', 'use:', 'transition:', 'in:', 'out:', 'animate:', 'let:', 'class:'
37
+ ];
38
+ /**
39
+ * Svelte tokenizer
40
+ */
41
+ export class SvelteTokenizer {
42
+ language = 'svelte';
43
+ tsTokenizer;
44
+ cssTokenizer;
45
+ constructor() {
46
+ this.tsTokenizer = createTypeScriptTokenizer();
47
+ this.cssTokenizer = createCSSTokenizer();
48
+ }
49
+ getInitialState() {
50
+ return {
51
+ context: 'template',
52
+ tagDepth: 0
53
+ };
54
+ }
55
+ tokenizeLine(line, lineNumber, state) {
56
+ const tokens = [];
57
+ let pos = 0;
58
+ // Handle script context
59
+ if (state.context === 'script') {
60
+ const closeScriptMatch = line.match(/<\/script>/i);
61
+ if (closeScriptMatch) {
62
+ // Tokenize JavaScript part
63
+ const scriptPart = line.substring(0, closeScriptMatch.index);
64
+ if (scriptPart) {
65
+ const result = this.tsTokenizer.tokenizeLine(scriptPart, lineNumber, state.innerState || this.tsTokenizer.getInitialState());
66
+ tokens.push(...result.tokens);
67
+ state.innerState = result.state;
68
+ }
69
+ // Add closing tag
70
+ tokens.push({ type: 'tag.punctuation', text: '</' });
71
+ tokens.push({ type: 'tag.name', text: 'script' });
72
+ tokens.push({ type: 'tag.punctuation', text: '>' });
73
+ // Continue with template for remainder
74
+ state.context = 'template';
75
+ state.innerState = undefined;
76
+ pos = closeScriptMatch.index + closeScriptMatch[0].length;
77
+ if (pos < line.length) {
78
+ const remaining = this.tokenizeTemplate(line.substring(pos), state);
79
+ tokens.push(...remaining);
80
+ }
81
+ }
82
+ else {
83
+ // Entire line is JavaScript
84
+ const result = this.tsTokenizer.tokenizeLine(line, lineNumber, state.innerState || this.tsTokenizer.getInitialState());
85
+ tokens.push(...result.tokens);
86
+ state.innerState = result.state;
87
+ }
88
+ return { lineNumber, tokens: reindexTokens(tokens), text: line, state };
89
+ }
90
+ // Handle style context
91
+ if (state.context === 'style') {
92
+ const closeStyleMatch = line.match(/<\/style>/i);
93
+ if (closeStyleMatch) {
94
+ // Tokenize CSS part
95
+ const cssPart = line.substring(0, closeStyleMatch.index);
96
+ if (cssPart) {
97
+ const result = this.cssTokenizer.tokenizeLine(cssPart, lineNumber, state.innerState || this.cssTokenizer.getInitialState());
98
+ tokens.push(...result.tokens);
99
+ state.innerState = result.state;
100
+ }
101
+ // Add closing tag
102
+ tokens.push({ type: 'tag.punctuation', text: '</' });
103
+ tokens.push({ type: 'tag.name', text: 'style' });
104
+ tokens.push({ type: 'tag.punctuation', text: '>' });
105
+ // Continue with template for remainder
106
+ state.context = 'template';
107
+ state.innerState = undefined;
108
+ pos = closeStyleMatch.index + closeStyleMatch[0].length;
109
+ if (pos < line.length) {
110
+ const remaining = this.tokenizeTemplate(line.substring(pos), state);
111
+ tokens.push(...remaining);
112
+ }
113
+ }
114
+ else {
115
+ // Entire line is CSS
116
+ const result = this.cssTokenizer.tokenizeLine(line, lineNumber, state.innerState || this.cssTokenizer.getInitialState());
117
+ tokens.push(...result.tokens);
118
+ state.innerState = result.state;
119
+ }
120
+ return { lineNumber, tokens: reindexTokens(tokens), text: line, state };
121
+ }
122
+ // Template context
123
+ const templateTokens = this.tokenizeTemplate(line, state);
124
+ tokens.push(...templateTokens);
125
+ return { lineNumber, tokens: reindexTokens(tokens), text: line, state };
126
+ }
127
+ tokenizeTemplate(line, state) {
128
+ const tokens = [];
129
+ let pos = 0;
130
+ while (pos < line.length) {
131
+ const char = line[pos];
132
+ // Check for <script> tag
133
+ if (line.substring(pos).match(/^<script(?:\s|>)/i)) {
134
+ const scriptMatch = line.substring(pos).match(/^<script(?:\s+[^>]*)?>?/i);
135
+ if (scriptMatch) {
136
+ tokens.push(...this.tokenizeTag(scriptMatch[0]));
137
+ pos += scriptMatch[0].length;
138
+ if (scriptMatch[0].endsWith('>')) {
139
+ state.context = 'script';
140
+ state.innerState = this.tsTokenizer.getInitialState();
141
+ }
142
+ continue;
143
+ }
144
+ }
145
+ // Check for <style> tag
146
+ if (line.substring(pos).match(/^<style(?:\s|>)/i)) {
147
+ const styleMatch = line.substring(pos).match(/^<style(?:\s+[^>]*)?>?/i);
148
+ if (styleMatch) {
149
+ tokens.push(...this.tokenizeTag(styleMatch[0]));
150
+ pos += styleMatch[0].length;
151
+ if (styleMatch[0].endsWith('>')) {
152
+ state.context = 'style';
153
+ state.innerState = this.cssTokenizer.getInitialState();
154
+ }
155
+ continue;
156
+ }
157
+ }
158
+ // Svelte template directives: {#if}, {@html}, etc.
159
+ if (char === '{' && pos + 1 < line.length) {
160
+ const nextChar = line[pos + 1];
161
+ if (nextChar === '#' || nextChar === '/' || nextChar === ':' || nextChar === '@') {
162
+ const directiveMatch = line.substring(pos).match(/^\{([#\/:@])(\w+)(?:\s+([^}]+))?\}/);
163
+ if (directiveMatch) {
164
+ const [full, prefix, keyword, expression] = directiveMatch;
165
+ // Opening brace
166
+ tokens.push({ type: 'punctuation.brace', text: '{' });
167
+ // Prefix (#, /, :, @)
168
+ tokens.push({ type: 'keyword.control', text: prefix });
169
+ // Keyword
170
+ const isBlockKeyword = SVELTE_BLOCK_KEYWORDS.has(keyword);
171
+ const isTagKeyword = SVELTE_TAG_KEYWORDS.has(keyword);
172
+ if (isBlockKeyword || isTagKeyword) {
173
+ tokens.push({ type: 'keyword.control', text: keyword });
174
+ }
175
+ else {
176
+ tokens.push({ type: 'text', text: keyword });
177
+ }
178
+ // Expression (if any)
179
+ if (expression) {
180
+ tokens.push({ type: 'text', text: ' ' });
181
+ tokens.push(...this.tokenizeJSExpression(expression));
182
+ }
183
+ // Closing brace
184
+ tokens.push({ type: 'punctuation.brace', text: '}' });
185
+ pos += full.length;
186
+ continue;
187
+ }
188
+ }
189
+ // Regular JavaScript expression
190
+ const exprMatch = line.substring(pos).match(/^\{([^}]+)\}/);
191
+ if (exprMatch) {
192
+ const [full, expression] = exprMatch;
193
+ tokens.push({ type: 'punctuation.brace', text: '{' });
194
+ tokens.push(...this.tokenizeJSExpression(expression));
195
+ tokens.push({ type: 'punctuation.brace', text: '}' });
196
+ pos += full.length;
197
+ continue;
198
+ }
199
+ }
200
+ // HTML tags
201
+ if (char === '<') {
202
+ const tagMatch = line.substring(pos).match(/^<\/?[\w-]+(?:\s+[^>]*)?>?/);
203
+ if (tagMatch) {
204
+ tokens.push(...this.tokenizeTag(tagMatch[0]));
205
+ pos += tagMatch[0].length;
206
+ continue;
207
+ }
208
+ }
209
+ // HTML comments
210
+ if (line.substring(pos).startsWith('<!--')) {
211
+ const commentMatch = line.substring(pos).match(/^<!--.*?(?:-->|$)/);
212
+ if (commentMatch) {
213
+ tokens.push({ type: 'comment', text: commentMatch[0] });
214
+ pos += commentMatch[0].length;
215
+ continue;
216
+ }
217
+ }
218
+ // Regular text
219
+ const textMatch = line.substring(pos).match(/^[^<{]+/);
220
+ if (textMatch) {
221
+ tokens.push({ type: 'text', text: textMatch[0] });
222
+ pos += textMatch[0].length;
223
+ continue;
224
+ }
225
+ // Fallback: single character
226
+ tokens.push({ type: 'text', text: char });
227
+ pos++;
228
+ }
229
+ return tokens;
230
+ }
231
+ tokenizeTag(tag) {
232
+ const tokens = [];
233
+ let pos = 0;
234
+ // Opening bracket
235
+ if (tag.startsWith('</')) {
236
+ tokens.push({ type: 'tag.punctuation', text: '</' });
237
+ pos = 2;
238
+ }
239
+ else {
240
+ tokens.push({ type: 'tag.punctuation', text: '<' });
241
+ pos = 1;
242
+ }
243
+ // Tag name
244
+ const nameMatch = tag.substring(pos).match(/^[\w-]+/);
245
+ if (nameMatch) {
246
+ const tagName = nameMatch[0];
247
+ tokens.push({ type: 'tag.name', text: tagName });
248
+ pos += tagName.length;
249
+ }
250
+ // Attributes
251
+ while (pos < tag.length) {
252
+ // Skip whitespace
253
+ const wsMatch = tag.substring(pos).match(/^\s+/);
254
+ if (wsMatch) {
255
+ tokens.push({ type: 'text', text: wsMatch[0] });
256
+ pos += wsMatch[0].length;
257
+ continue;
258
+ }
259
+ // Closing bracket
260
+ if (tag[pos] === '>' || tag.substring(pos).startsWith('/>')) {
261
+ const closing = tag.substring(pos);
262
+ tokens.push({ type: 'tag.punctuation', text: closing });
263
+ break;
264
+ }
265
+ // Attribute name
266
+ const attrMatch = tag.substring(pos).match(/^([\w:-]+)(?:=)?/);
267
+ if (attrMatch) {
268
+ const attrName = attrMatch[1];
269
+ const isSvelteAttr = SVELTE_ATTRIBUTE_PREFIXES.some(prefix => attrName.startsWith(prefix));
270
+ if (isSvelteAttr) {
271
+ // Highlight Svelte-specific attributes
272
+ const prefixMatch = SVELTE_ATTRIBUTE_PREFIXES.find(p => attrName.startsWith(p));
273
+ if (prefixMatch) {
274
+ tokens.push({ type: 'keyword.control', text: prefixMatch });
275
+ tokens.push({ type: 'tag.attribute', text: attrName.substring(prefixMatch.length) });
276
+ }
277
+ else {
278
+ tokens.push({ type: 'tag.attribute', text: attrName });
279
+ }
280
+ }
281
+ else {
282
+ tokens.push({ type: 'tag.attribute', text: attrName });
283
+ }
284
+ pos += attrName.length;
285
+ // Equals sign
286
+ if (attrMatch[0].endsWith('=')) {
287
+ tokens.push({ type: 'punctuation', text: '=' });
288
+ pos++;
289
+ // Attribute value
290
+ const valueMatch = tag.substring(pos).match(/^(?:"([^"]*)"|'([^']*)'|\{([^}]+)\})/);
291
+ if (valueMatch) {
292
+ if (valueMatch[0].startsWith('{')) {
293
+ // JavaScript expression
294
+ tokens.push({ type: 'punctuation.brace', text: '{' });
295
+ tokens.push(...this.tokenizeJSExpression(valueMatch[3]));
296
+ tokens.push({ type: 'punctuation.brace', text: '}' });
297
+ }
298
+ else {
299
+ // String value
300
+ const quote = valueMatch[0][0];
301
+ const value = valueMatch[1] || valueMatch[2];
302
+ tokens.push({ type: 'string', text: quote + value + quote });
303
+ }
304
+ pos += valueMatch[0].length;
305
+ }
306
+ }
307
+ continue;
308
+ }
309
+ // Shouldn't reach here, but just in case
310
+ tokens.push({ type: 'text', text: tag[pos] });
311
+ pos++;
312
+ }
313
+ return tokens;
314
+ }
315
+ tokenizeJSExpression(expression) {
316
+ // Simple JavaScript expression tokenization
317
+ const result = this.tsTokenizer.tokenizeLine(expression, 1, this.tsTokenizer.getInitialState());
318
+ return result.tokens;
319
+ }
320
+ }
321
+ /**
322
+ * Create a Svelte tokenizer
323
+ */
324
+ export function createSvelteTokenizer() {
325
+ return new SvelteTokenizer();
326
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Token types for syntax highlighting
3
+ */
4
+ export type TokenType = 'comment' | 'comment.line' | 'comment.block' | 'comment.doc' | 'string' | 'string.template' | 'string.regex' | 'string.escape' | 'number' | 'number.integer' | 'number.float' | 'number.hex' | 'number.binary' | 'keyword' | 'keyword.control' | 'keyword.operator' | 'keyword.definition' | 'keyword.module' | 'keyword.storage' | 'operator' | 'operator.arithmetic' | 'operator.comparison' | 'operator.logical' | 'operator.assignment' | 'variable' | 'variable.definition' | 'variable.parameter' | 'function' | 'function.definition' | 'function.call' | 'property' | 'property.definition' | 'type' | 'type.class' | 'type.interface' | 'type.namespace' | 'type.builtin' | 'constant' | 'constant.boolean' | 'constant.null' | 'constant.builtin' | 'punctuation' | 'punctuation.bracket' | 'punctuation.brace' | 'punctuation.paren' | 'punctuation.separator' | 'punctuation.accessor' | 'tag' | 'tag.name' | 'tag.attribute' | 'tag.attribute.value' | 'tag.punctuation' | 'markup.heading' | 'markup.bold' | 'markup.italic' | 'markup.link' | 'markup.code' | 'markup.quote' | 'markup.list' | 'invalid' | 'text';
5
+ /**
6
+ * A single token in the tokenized output
7
+ */
8
+ export interface Token {
9
+ /** Token type for styling */
10
+ type: TokenType;
11
+ /** The actual text content */
12
+ text: string;
13
+ /** Starting position in the line */
14
+ start: number;
15
+ /** Ending position in the line */
16
+ end: number;
17
+ }
18
+ /**
19
+ * A tokenized line
20
+ */
21
+ export interface TokenizedLine {
22
+ /** Line number (1-based) */
23
+ lineNumber: number;
24
+ /** Array of tokens in the line */
25
+ tokens: Token[];
26
+ /** Raw text of the line */
27
+ text: string;
28
+ /** State to carry forward to next line (for multi-line constructs) */
29
+ state?: TokenizerState;
30
+ }
31
+ /**
32
+ * State carried between lines for multi-line constructs
33
+ */
34
+ export interface TokenizerState {
35
+ /** Currently in a multi-line comment */
36
+ inBlockComment?: boolean;
37
+ /** Currently in a template literal */
38
+ inTemplateLiteral?: boolean;
39
+ /** Currently in a multi-line string */
40
+ inMultilineString?: boolean;
41
+ /** String delimiter if in string */
42
+ stringDelimiter?: string;
43
+ /** Nesting depth for template literals */
44
+ templateDepth?: number;
45
+ /** Custom state data */
46
+ custom?: Record<string, unknown>;
47
+ }
48
+ /**
49
+ * Language tokenizer interface
50
+ */
51
+ export interface LanguageTokenizer {
52
+ /** Language identifier */
53
+ language: string;
54
+ /** Tokenize a single line */
55
+ tokenizeLine(line: string, lineNumber: number, state?: TokenizerState): TokenizedLine;
56
+ /** Get initial state */
57
+ getInitialState(): TokenizerState;
58
+ }
59
+ /**
60
+ * Token rule for regex-based tokenization
61
+ */
62
+ export interface TokenRule {
63
+ /** Token type to assign */
64
+ type: TokenType;
65
+ /** Regex pattern to match */
66
+ pattern: RegExp;
67
+ /** Optional: next state after matching */
68
+ nextState?: string;
69
+ /** Optional: pop state after matching */
70
+ popState?: boolean;
71
+ }
72
+ /**
73
+ * Grammar definition for a language
74
+ */
75
+ export interface LanguageGrammar {
76
+ /** Language identifier */
77
+ language: string;
78
+ /** File extensions */
79
+ extensions: string[];
80
+ /** Line comment prefix */
81
+ lineComment?: string;
82
+ /** Block comment start/end */
83
+ blockComment?: [string, string];
84
+ /** Token rules by state */
85
+ rules: Record<string, TokenRule[]>;
86
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Token types for syntax highlighting
3
+ */
4
+ export {};
@@ -0,0 +1,274 @@
1
+ <script lang="ts">
2
+ /**
3
+ * IDELayout - Main IDE layout with resizable panels
4
+ *
5
+ * Provides a VS Code-like layout with:
6
+ * - Activity bar (left icons)
7
+ * - Resizable left sidebar (file explorer, search, etc.)
8
+ * - Main editor area
9
+ * - Resizable right sidebar (AI panel, etc.)
10
+ * - Resizable bottom panel (terminal, output, etc.)
11
+ * - Status bar
12
+ */
13
+
14
+ import { ResizeHandle } from '../core';
15
+ import {
16
+ getLeftSidebarVisible,
17
+ getLeftSidebarWidth,
18
+ setLeftSidebarWidth,
19
+ getRightSidebarVisible,
20
+ getRightSidebarWidth,
21
+ setRightSidebarWidth,
22
+ getBottomPanelVisible,
23
+ getBottomPanelHeight,
24
+ setBottomPanelHeight,
25
+ getStatusBarVisible,
26
+ constraints
27
+ } from '../../stores/layout.svelte';
28
+
29
+ interface Props {
30
+ /** Additional CSS class */
31
+ class?: string;
32
+ }
33
+
34
+ let { class: className = '' }: Props = $props();
35
+
36
+ // Track resize state for visual feedback
37
+ let isResizingLeft = $state(false);
38
+ let isResizingRight = $state(false);
39
+ let isResizingBottom = $state(false);
40
+ </script>
41
+
42
+ <div
43
+ class="ide-layout {className}"
44
+ class:ide-layout--resizing={isResizingLeft || isResizingRight || isResizingBottom}
45
+ >
46
+ <!-- Top Row: Activity Bar + Content -->
47
+ <div class="ide-layout__row">
48
+ <!-- Activity Bar -->
49
+ <aside class="ide-layout__activity-bar">
50
+ <slot name="activity-bar" />
51
+ </aside>
52
+
53
+ <!-- Content Area: Left Sidebar + Main + Right Sidebar -->
54
+ <div class="ide-layout__content">
55
+ <!-- Left Sidebar -->
56
+ {#if getLeftSidebarVisible()}
57
+ <aside
58
+ class="ide-layout__sidebar ide-layout__sidebar--left"
59
+ class:ide-layout__sidebar--resizing={isResizingLeft}
60
+ style="width: {getLeftSidebarWidth()}px;"
61
+ >
62
+ <slot name="left-sidebar" />
63
+ </aside>
64
+ <ResizeHandle
65
+ direction="vertical"
66
+ position="end"
67
+ size={getLeftSidebarWidth()}
68
+ min={constraints.sidebarMinWidth}
69
+ max={constraints.sidebarMaxWidth}
70
+ onResize={setLeftSidebarWidth}
71
+ onResizeStart={() => (isResizingLeft = true)}
72
+ onResizeEnd={() => (isResizingLeft = false)}
73
+ />
74
+ {/if}
75
+
76
+ <!-- Main Content Area -->
77
+ <main class="ide-layout__main">
78
+ <!-- Editor Area -->
79
+ <div class="ide-layout__editor">
80
+ <slot name="editor" />
81
+ </div>
82
+
83
+ <!-- Bottom Panel -->
84
+ {#if getBottomPanelVisible()}
85
+ <ResizeHandle
86
+ direction="horizontal"
87
+ position="start"
88
+ size={getBottomPanelHeight()}
89
+ min={constraints.panelMinHeight}
90
+ max={constraints.panelMaxHeight}
91
+ onResize={setBottomPanelHeight}
92
+ onResizeStart={() => (isResizingBottom = true)}
93
+ onResizeEnd={() => (isResizingBottom = false)}
94
+ />
95
+ <aside
96
+ class="ide-layout__panel ide-layout__panel--bottom"
97
+ class:ide-layout__panel--resizing={isResizingBottom}
98
+ style="height: {getBottomPanelHeight()}px;"
99
+ >
100
+ <slot name="bottom-panel" />
101
+ </aside>
102
+ {/if}
103
+ </main>
104
+
105
+ <!-- Right Sidebar -->
106
+ {#if getRightSidebarVisible()}
107
+ <ResizeHandle
108
+ direction="vertical"
109
+ position="start"
110
+ size={getRightSidebarWidth()}
111
+ min={constraints.sidebarMinWidth}
112
+ max={constraints.sidebarMaxWidth}
113
+ onResize={setRightSidebarWidth}
114
+ onResizeStart={() => (isResizingRight = true)}
115
+ onResizeEnd={() => (isResizingRight = false)}
116
+ />
117
+ <aside
118
+ class="ide-layout__sidebar ide-layout__sidebar--right"
119
+ class:ide-layout__sidebar--resizing={isResizingRight}
120
+ style="width: {getRightSidebarWidth()}px;"
121
+ >
122
+ <slot name="right-sidebar" />
123
+ </aside>
124
+ {/if}
125
+ </div>
126
+ </div>
127
+
128
+ <!-- Status Bar -->
129
+ {#if getStatusBarVisible()}
130
+ <footer class="ide-layout__status-bar">
131
+ <slot name="status-bar" />
132
+ </footer>
133
+ {/if}
134
+ </div>
135
+
136
+ <style>
137
+ .ide-layout {
138
+ display: flex;
139
+ flex-direction: column;
140
+ height: 100vh;
141
+ width: 100vw;
142
+ overflow: hidden;
143
+ background: var(--ide-bg-primary);
144
+ }
145
+
146
+ /* Optimize during resize - reduce reflows */
147
+ .ide-layout--resizing {
148
+ contain: layout;
149
+ }
150
+
151
+ /* Disable pointer events on content during resize for smoother performance */
152
+ .ide-layout--resizing .ide-layout__editor,
153
+ .ide-layout--resizing .ide-layout__panel--bottom {
154
+ pointer-events: none;
155
+ }
156
+
157
+ /* Top row: activity bar + content area */
158
+ .ide-layout__row {
159
+ display: flex;
160
+ flex-direction: row;
161
+ flex: 1;
162
+ min-height: 0;
163
+ overflow: hidden;
164
+ }
165
+
166
+ .ide-layout__activity-bar {
167
+ display: flex;
168
+ flex-direction: column;
169
+ flex-shrink: 0;
170
+ width: 48px;
171
+ background: var(--ide-bg-secondary);
172
+ border-right: 1px solid var(--ide-border);
173
+ }
174
+
175
+ /* Content area: sidebars + main in a row */
176
+ .ide-layout__content {
177
+ display: flex;
178
+ flex-direction: row;
179
+ flex: 1;
180
+ min-width: 0;
181
+ overflow: hidden;
182
+ }
183
+
184
+ .ide-layout__sidebar {
185
+ display: flex;
186
+ flex-direction: column;
187
+ flex-shrink: 0;
188
+ background: var(--ide-bg-secondary);
189
+ overflow: hidden;
190
+ /* Smooth transition when size is applied on mouse up */
191
+ transition: width 0.08s ease-out;
192
+ }
193
+
194
+ .ide-layout__sidebar--left {
195
+ border-right: 1px solid var(--ide-border);
196
+ }
197
+
198
+ .ide-layout__sidebar--right {
199
+ border-left: 1px solid var(--ide-border);
200
+ }
201
+
202
+ .ide-layout__sidebar--resizing {
203
+ /* Disable transition during drag for instant ghost line feedback */
204
+ transition: none;
205
+ will-change: width;
206
+ contain: layout style;
207
+ }
208
+
209
+ /* Fade/blur content during resize to hide ugly text reflow */
210
+ .ide-layout--resizing .ide-layout__sidebar > :global(*) {
211
+ opacity: 0.5;
212
+ filter: blur(1px);
213
+ transition: opacity 0.1s ease, filter 0.1s ease;
214
+ }
215
+
216
+ .ide-layout__main {
217
+ display: flex;
218
+ flex-direction: column;
219
+ flex: 1;
220
+ min-width: 0;
221
+ min-height: 0;
222
+ overflow: hidden;
223
+ }
224
+
225
+ .ide-layout__editor {
226
+ flex: 1;
227
+ min-height: 0;
228
+ overflow: hidden;
229
+ }
230
+
231
+ /* Fade editor during resize */
232
+ .ide-layout--resizing .ide-layout__editor > :global(*) {
233
+ opacity: 0.7;
234
+ transition: opacity 0.1s ease;
235
+ }
236
+
237
+ .ide-layout__panel {
238
+ flex-shrink: 0;
239
+ background: var(--ide-bg-secondary);
240
+ overflow: hidden;
241
+ /* Smooth transition when size is applied on mouse up */
242
+ transition: height 0.08s ease-out;
243
+ }
244
+
245
+ .ide-layout__panel--bottom {
246
+ border-top: 1px solid var(--ide-border);
247
+ }
248
+
249
+ .ide-layout__panel--resizing {
250
+ /* Disable transition during drag */
251
+ transition: none;
252
+ will-change: height;
253
+ contain: layout style;
254
+ }
255
+
256
+ /* Fade panel content during resize */
257
+ .ide-layout--resizing .ide-layout__panel > :global(*) {
258
+ opacity: 0.5;
259
+ filter: blur(1px);
260
+ transition: opacity 0.1s ease, filter 0.1s ease;
261
+ }
262
+
263
+ .ide-layout__status-bar {
264
+ flex-shrink: 0;
265
+ height: 24px;
266
+ display: flex;
267
+ align-items: center;
268
+ padding: 0 var(--ide-spacing-sm);
269
+ background: var(--ide-bg-tertiary);
270
+ border-top: 1px solid var(--ide-border);
271
+ font-size: var(--ide-font-size-xs);
272
+ color: var(--ide-text-secondary);
273
+ }
274
+ </style>