symbiote-ui 0.3.0-alpha.4

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 (322) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +21 -0
  3. package/README.md +76 -0
  4. package/canvas/AutoLayout.js +731 -0
  5. package/canvas/Breadcrumb/Breadcrumb.css.js +75 -0
  6. package/canvas/Breadcrumb/Breadcrumb.js +96 -0
  7. package/canvas/Breadcrumb/Breadcrumb.tpl.js +7 -0
  8. package/canvas/CanvasConnectionRenderer.js +971 -0
  9. package/canvas/CanvasGraph/CanvasGraph.css.js +29 -0
  10. package/canvas/CanvasGraph/CanvasGraph.js +1697 -0
  11. package/canvas/CanvasGraph/CanvasGraphDrawState.js +280 -0
  12. package/canvas/CanvasGraph/CanvasGraphGeometry.js +194 -0
  13. package/canvas/CanvasViewport.js +550 -0
  14. package/canvas/ConnectionRenderer.js +1283 -0
  15. package/canvas/FlowSimulator.js +326 -0
  16. package/canvas/ForceLayout.js +226 -0
  17. package/canvas/ForceWorker.js +1303 -0
  18. package/canvas/FrameManager.js +223 -0
  19. package/canvas/GraphExplorerShell/GraphExplorerShell.css.js +136 -0
  20. package/canvas/GraphExplorerShell/GraphExplorerShell.js +129 -0
  21. package/canvas/GraphExplorerShell/GraphExplorerShell.tpl.js +12 -0
  22. package/canvas/GraphTabs/GraphTabs.css.js +101 -0
  23. package/canvas/GraphTabs/GraphTabs.js +189 -0
  24. package/canvas/GraphTabs/GraphTabs.tpl.js +12 -0
  25. package/canvas/LODManager.js +88 -0
  26. package/canvas/Minimap/Minimap.css.js +73 -0
  27. package/canvas/Minimap/Minimap.js +210 -0
  28. package/canvas/Minimap/Minimap.tpl.js +7 -0
  29. package/canvas/NodeCanvas/NodeCanvas.css.js +398 -0
  30. package/canvas/NodeCanvas/NodeCanvas.js +1499 -0
  31. package/canvas/NodeCanvas/NodeCanvas.tpl.js +22 -0
  32. package/canvas/NodeSearch/NodeSearch.css.js +97 -0
  33. package/canvas/NodeSearch/NodeSearch.js +140 -0
  34. package/canvas/NodeSearch/NodeSearch.tpl.js +25 -0
  35. package/canvas/NodeViewManager.js +748 -0
  36. package/canvas/PcbRouteDiagnostics.js +463 -0
  37. package/canvas/PcbRouter.js +1127 -0
  38. package/canvas/PinExpansion.js +134 -0
  39. package/canvas/PseudoConnection.js +84 -0
  40. package/canvas/SelectionSync.js +163 -0
  41. package/canvas/SubgraphManager.js +203 -0
  42. package/canvas/SubgraphRouter.js +452 -0
  43. package/canvas/ViewportActions.js +473 -0
  44. package/canvas/graph-explorer.js +339 -0
  45. package/canvas/graph-layout.js +148 -0
  46. package/canvas/graph-model.js +68 -0
  47. package/canvas/html-in-canvas.js +202 -0
  48. package/canvas/project-graph-builder.js +440 -0
  49. package/canvas/project-graph-model.js +183 -0
  50. package/chat/ChatComposer/ChatComposer.css.js +652 -0
  51. package/chat/ChatComposer/ChatComposer.js +304 -0
  52. package/chat/ChatList/ChatList.css.js +102 -0
  53. package/chat/ChatList/ChatList.js +99 -0
  54. package/chat/ChatList/ChatList.tpl.js +20 -0
  55. package/chat/ChatListItem/ChatListItem.css.js +117 -0
  56. package/chat/ChatListItem/ChatListItem.js +32 -0
  57. package/chat/ChatListItem/ChatListItem.tpl.js +17 -0
  58. package/chat/ChatMessageItem/ChatMessageItem.css.js +628 -0
  59. package/chat/ChatMessageItem/ChatMessageItem.js +156 -0
  60. package/chat/ChatSidebar/ChatSidebar.css.js +150 -0
  61. package/chat/ChatSidebar/ChatSidebar.js +230 -0
  62. package/chat/ChatSidebar/ChatSidebar.tpl.js +18 -0
  63. package/chat/ChatSidebar/constants.js +11 -0
  64. package/chat/ChatSidebarItem/ChatSidebarItem.css.js +445 -0
  65. package/chat/ChatSidebarItem/ChatSidebarItem.js +304 -0
  66. package/chat/ChatTranscript/ChatTranscript.css.js +90 -0
  67. package/chat/ChatTranscript/ChatTranscript.js +244 -0
  68. package/chat/chat-context.js +123 -0
  69. package/chat/message-model.js +156 -0
  70. package/cli.js +20 -0
  71. package/control/Button/Button.css.js +93 -0
  72. package/control/Button/Button.js +78 -0
  73. package/control/Button/Button.tpl.js +3 -0
  74. package/control/Field/Field.css.js +91 -0
  75. package/control/Field/Field.js +17 -0
  76. package/control/Field/Field.tpl.js +3 -0
  77. package/core/Connection.js +47 -0
  78. package/core/Editor.js +449 -0
  79. package/core/Frame.js +33 -0
  80. package/core/GraphMermaid.js +348 -0
  81. package/core/GraphText.js +228 -0
  82. package/core/Node.js +145 -0
  83. package/core/Portal.js +106 -0
  84. package/core/Socket.js +187 -0
  85. package/core/SubgraphNode.js +121 -0
  86. package/core/base-path.js +55 -0
  87. package/core/dom-utils.js +14 -0
  88. package/core/index.js +18 -0
  89. package/core/local-cache.js +26 -0
  90. package/core/state-sync.js +227 -0
  91. package/custom-elements.json +6380 -0
  92. package/discover.js +240 -0
  93. package/display/Badge/Badge.css.js +44 -0
  94. package/display/Badge/Badge.js +17 -0
  95. package/display/Badge/Badge.tpl.js +3 -0
  96. package/display/Banner/Banner.css.js +61 -0
  97. package/display/Banner/Banner.js +17 -0
  98. package/display/Banner/Banner.tpl.js +3 -0
  99. package/display/CodeBlock/CodeBlock.css.js +194 -0
  100. package/display/CodeBlock/CodeBlock.js +220 -0
  101. package/display/CodeBlock/CodeBlock.tpl.js +11 -0
  102. package/display/DataTable/DataTable.css.js +101 -0
  103. package/display/DataTable/DataTable.js +136 -0
  104. package/display/DataTable/DataTable.tpl.js +13 -0
  105. package/display/EmptyState/EmptyState.css.js +33 -0
  106. package/display/EmptyState/EmptyState.js +17 -0
  107. package/display/EmptyState/EmptyState.tpl.js +3 -0
  108. package/display/EventFeed/EventFeed.css.js +145 -0
  109. package/display/EventFeed/EventFeed.js +64 -0
  110. package/display/EventFeed/EventFeed.tpl.js +14 -0
  111. package/display/EventFeed/EventFeedItem.js +116 -0
  112. package/display/EventFeed/EventFeedItem.tpl.js +22 -0
  113. package/display/LoadingOverlay/LoadingOverlay.css.js +91 -0
  114. package/display/LoadingOverlay/LoadingOverlay.js +48 -0
  115. package/display/LoadingOverlay/LoadingOverlay.tpl.js +12 -0
  116. package/display/Metric/Metric.css.js +60 -0
  117. package/display/Metric/Metric.js +17 -0
  118. package/display/Metric/Metric.tpl.js +6 -0
  119. package/display/OutputGraphPreview/OutputGraphPreview.css.js +122 -0
  120. package/display/OutputGraphPreview/OutputGraphPreview.js +89 -0
  121. package/display/OutputGraphPreview/OutputGraphPreview.tpl.js +13 -0
  122. package/display/OutputListPreview/OutputListPreview.css.js +109 -0
  123. package/display/OutputListPreview/OutputListPreview.js +77 -0
  124. package/display/OutputListPreview/OutputListPreview.tpl.js +13 -0
  125. package/display/SourceEditor/SourceEditor.css.js +39 -0
  126. package/display/SourceEditor/SourceEditor.js +129 -0
  127. package/display/SourceEditor/SourceEditor.tpl.js +10 -0
  128. package/display/SourceViewer/SourceViewer.css.js +80 -0
  129. package/display/SourceViewer/SourceViewer.js +418 -0
  130. package/display/SourceViewer/SourceViewer.tpl.js +17 -0
  131. package/display/StatusRibbon/StatusRibbon.css.js +73 -0
  132. package/display/StatusRibbon/StatusRibbon.js +87 -0
  133. package/display/StatusRibbon/StatusRibbon.tpl.js +7 -0
  134. package/display/event-feed-adapter.js +72 -0
  135. package/display/format-utils.js +29 -0
  136. package/display/highlight.js +659 -0
  137. package/display/icons.js +37 -0
  138. package/display/markdown-formatter.js +60 -0
  139. package/display/network-approval-page.js +487 -0
  140. package/display/output-preview.js +261 -0
  141. package/effects/CellBg/CellBg.css.js +33 -0
  142. package/effects/CellBg/CellBg.js +410 -0
  143. package/effects/CellBg/CellBg.tpl.js +5 -0
  144. package/graph/canvas-adapter.js +223 -0
  145. package/graph/graph-algorithms.js +31 -0
  146. package/graph/index.js +46 -0
  147. package/graph/model.js +176 -0
  148. package/graph/project-graph-build.js +66 -0
  149. package/graph/project-graph-metadata.js +253 -0
  150. package/graph/project-package.js +128 -0
  151. package/graph/project-runtime.js +116 -0
  152. package/graph/project-transaction.js +284 -0
  153. package/graph/skeleton-utils.js +84 -0
  154. package/graph/theme-contract.js +36 -0
  155. package/graph/transaction-parser.js +56 -0
  156. package/icons/MaterialSymbols.js +69 -0
  157. package/icons/material-symbols-outlined-400.ttf +0 -0
  158. package/icons/material-symbols.css +24 -0
  159. package/index.js +95 -0
  160. package/inspector/InspectorPanel/InspectorPanel.css.js +375 -0
  161. package/inspector/InspectorPanel/InspectorPanel.js +368 -0
  162. package/inspector/InspectorPanel/InspectorPanel.tpl.js +96 -0
  163. package/inspector/TemplatePreview/TemplatePreview.css.js +104 -0
  164. package/inspector/TemplatePreview/TemplatePreview.js +145 -0
  165. package/inspector/TemplatePreview/TemplatePreview.tpl.js +33 -0
  166. package/interactions/ConnectFlow.js +304 -0
  167. package/interactions/Drag.js +104 -0
  168. package/interactions/Selector.js +133 -0
  169. package/interactions/SnapGrid.js +66 -0
  170. package/interactions/Zoom.js +139 -0
  171. package/layout/ActionZone/ActionZone.css.js +88 -0
  172. package/layout/ActionZone/ActionZone.js +261 -0
  173. package/layout/ActionZone/ActionZone.tpl.js +11 -0
  174. package/layout/CrossLayoutPortalBridge/CrossLayoutPortalBridge.js +255 -0
  175. package/layout/Layout/Layout.css.js +91 -0
  176. package/layout/Layout/Layout.js +637 -0
  177. package/layout/Layout/Layout.tpl.js +27 -0
  178. package/layout/LayoutNode/LayoutNode.css.js +302 -0
  179. package/layout/LayoutNode/LayoutNode.js +509 -0
  180. package/layout/LayoutNode/LayoutNode.tpl.js +39 -0
  181. package/layout/LayoutPreview/LayoutPreview.css.js +46 -0
  182. package/layout/LayoutPreview/LayoutPreview.js +102 -0
  183. package/layout/LayoutPreview/LayoutPreview.tpl.js +6 -0
  184. package/layout/LayoutRouter/LayoutRouter.js +274 -0
  185. package/layout/LayoutRouter/SectionRegistry.js +135 -0
  186. package/layout/LayoutRouter/routerSync.js +250 -0
  187. package/layout/LayoutSidebar/LayoutSidebar.css.js +411 -0
  188. package/layout/LayoutSidebar/LayoutSidebar.js +368 -0
  189. package/layout/LayoutSidebar/LayoutSidebar.tpl.js +26 -0
  190. package/layout/LayoutSidebar/SidebarSection.css.js +20 -0
  191. package/layout/LayoutSidebar/SidebarSection.js +184 -0
  192. package/layout/LayoutSidebar/SidebarSection.tpl.js +22 -0
  193. package/layout/LayoutTree.js +373 -0
  194. package/layout/PanelMenu/PanelMenu.css.js +43 -0
  195. package/layout/PanelMenu/PanelMenu.js +95 -0
  196. package/layout/PanelMenu/PanelMenu.tpl.js +17 -0
  197. package/layout/ProjectTabs/ProjectTabs.css.js +188 -0
  198. package/layout/ProjectTabs/ProjectTabs.js +77 -0
  199. package/layout/ProjectTabs/ProjectTabs.tpl.js +15 -0
  200. package/layout/index.js +40 -0
  201. package/list/ListDetailShell/ListDetailShell.css.js +128 -0
  202. package/list/ListDetailShell/ListDetailShell.js +72 -0
  203. package/list/ListDetailShell/ListDetailShell.tpl.js +36 -0
  204. package/list/ListItem/ListItem.css.js +111 -0
  205. package/list/ListItem/ListItem.js +66 -0
  206. package/list/ListItem/ListItem.tpl.js +18 -0
  207. package/locale/index.js +503 -0
  208. package/manifest/component-registry.js +2446 -0
  209. package/manifest/graph-schema.js +285 -0
  210. package/manifest/index.js +6 -0
  211. package/manifest/project-schema-catalog.js +246 -0
  212. package/manifest/rule-catalog.js +201 -0
  213. package/manifest/theme-catalog.js +2149 -0
  214. package/manifest/ui-schema-catalog.js +334 -0
  215. package/menu/ContextMenu/ContextMenu.css.js +61 -0
  216. package/menu/ContextMenu/ContextMenu.js +82 -0
  217. package/menu/ContextMenu/ContextMenu.tpl.js +19 -0
  218. package/navigation/QuickOpen/QuickOpen.css.js +92 -0
  219. package/navigation/QuickOpen/QuickOpen.js +185 -0
  220. package/navigation/QuickOpen/QuickOpen.tpl.js +15 -0
  221. package/navigation/quick-open-utils.js +101 -0
  222. package/node/CtrlItem/CtrlItem.css.js +41 -0
  223. package/node/CtrlItem/CtrlItem.js +24 -0
  224. package/node/CtrlItem/CtrlItem.tpl.js +17 -0
  225. package/node/GraphFrame/GraphFrame.css.js +66 -0
  226. package/node/GraphFrame/GraphFrame.js +32 -0
  227. package/node/GraphFrame/GraphFrame.tpl.js +13 -0
  228. package/node/GraphNode/GraphNode.css.js +815 -0
  229. package/node/GraphNode/GraphNode.js +173 -0
  230. package/node/GraphNode/GraphNode.tpl.js +33 -0
  231. package/node/NodeCallout/NodeCallout.css.js +91 -0
  232. package/node/NodeCallout/NodeCallout.js +281 -0
  233. package/node/NodeCallout/NodeCallout.tpl.js +8 -0
  234. package/node/NodeSocket/NodeSocket.css.js +68 -0
  235. package/node/NodeSocket/NodeSocket.js +26 -0
  236. package/node/NodeSocket/NodeSocket.tpl.js +7 -0
  237. package/node/PortItem/PortItem.css.js +93 -0
  238. package/node/PortItem/PortItem.js +87 -0
  239. package/node/PortItem/PortItem.tpl.js +10 -0
  240. package/package.json +165 -0
  241. package/palette/PaletteBrowser/PaletteBrowser.css.js +143 -0
  242. package/palette/PaletteBrowser/PaletteBrowser.js +152 -0
  243. package/palette/PaletteBrowser/PaletteBrowser.tpl.js +23 -0
  244. package/plugins/History.js +408 -0
  245. package/plugins/Readonly.js +60 -0
  246. package/rules/symbiote-3x.json +170 -0
  247. package/schemas/component-descriptor-v1.json +91 -0
  248. package/schemas/component-descriptor-v2.json +145 -0
  249. package/schemas/graph-model-v1.json +179 -0
  250. package/schemas/graph-v1.json +91 -0
  251. package/schemas/project-package-v1.json +102 -0
  252. package/schemas/project-transaction-v1.json +114 -0
  253. package/schemas/runtime-ui-v1.json +80 -0
  254. package/schemas/theme-rule-block-v1.json +73 -0
  255. package/shapes/CircleShape.js +79 -0
  256. package/shapes/CommentShape.js +35 -0
  257. package/shapes/DiamondShape.js +130 -0
  258. package/shapes/NodeShape.js +79 -0
  259. package/shapes/PillShape.js +91 -0
  260. package/shapes/RectShape.js +84 -0
  261. package/shapes/SVGShape.js +525 -0
  262. package/shapes/index.js +63 -0
  263. package/surface/Card/Card.css.js +57 -0
  264. package/surface/Card/Card.js +17 -0
  265. package/surface/Card/Card.tpl.js +3 -0
  266. package/themes/Palette.js +30 -0
  267. package/themes/Skin.js +113 -0
  268. package/themes/Theme.js +82 -0
  269. package/themes/carbon.js +135 -0
  270. package/themes/dark.js +140 -0
  271. package/themes/default-dark.js +714 -0
  272. package/themes/default-provider.css +635 -0
  273. package/themes/default-provider.js +718 -0
  274. package/themes/ebook.js +136 -0
  275. package/themes/grey.js +137 -0
  276. package/themes/light.js +139 -0
  277. package/themes/neon.js +138 -0
  278. package/themes/pcb.js +273 -0
  279. package/themes/synthwave.js +138 -0
  280. package/tokens/base.json +29 -0
  281. package/tokens/themes/carbon.json +11 -0
  282. package/tokens/themes/dark.json +12 -0
  283. package/tokens/themes/default-dark.json +1543 -0
  284. package/tokens/themes/default-provider.json +1543 -0
  285. package/tokens/themes/ebook.json +11 -0
  286. package/tokens/themes/grey.json +11 -0
  287. package/tokens/themes/light.json +12 -0
  288. package/tokens/themes/neon.json +11 -0
  289. package/tokens/themes/pcb.json +11 -0
  290. package/tokens/themes/synthwave.json +11 -0
  291. package/toolbar/QuickToolbar/QuickToolbar.css.js +152 -0
  292. package/toolbar/QuickToolbar/QuickToolbar.js +529 -0
  293. package/toolbar/QuickToolbar/QuickToolbar.tpl.js +34 -0
  294. package/tree/TreePanel/TreePanel.css.js +112 -0
  295. package/tree/TreePanel/TreePanel.js +147 -0
  296. package/tree/TreePanel/TreePanel.tpl.js +18 -0
  297. package/tree/TreeView/TreeView.css.js +122 -0
  298. package/tree/TreeView/TreeView.js +365 -0
  299. package/tree/TreeView/TreeView.tpl.js +10 -0
  300. package/ui/dialogs.js +221 -0
  301. package/ui/host-adapters.js +114 -0
  302. package/ui/index.js +660 -0
  303. package/ui/locale.js +50 -0
  304. package/ui/overlay-stack.js +89 -0
  305. package/ui/shared-styles.js +26 -0
  306. package/webmcp.js +37 -0
  307. package/xr/deep-graph.js +646 -0
  308. package/xr/emulation.js +198 -0
  309. package/xr/gesture.js +228 -0
  310. package/xr/html-canvas-renderer.js +472 -0
  311. package/xr/index.js +15 -0
  312. package/xr/layout-projection.js +1046 -0
  313. package/xr/panel-frame.js +128 -0
  314. package/xr/panel-host.js +267 -0
  315. package/xr/pointer.js +258 -0
  316. package/xr/scene-controller.js +242 -0
  317. package/xr/spatial-scene.js +212 -0
  318. package/xr/theme-bridge.js +105 -0
  319. package/xr/three-webxr-adapter.js +3439 -0
  320. package/xr/webgl-layer-renderer.js +419 -0
  321. package/xr/webxr.js +679 -0
  322. package/xr/workbench.js +516 -0
@@ -0,0 +1,815 @@
1
+ import { css } from '@symbiotejs/symbiote';
2
+
3
+ export let styles = css`
4
+ graph-node {
5
+ display: block;
6
+ min-width: var(--sn-node-min-width);
7
+ max-width: var(--sn-node-max-width);
8
+ border-radius: var(--sn-node-radius);
9
+ background: var(--sn-node-bg);
10
+ border: var(--sn-node-border-width) solid var(--sn-node-border);
11
+ box-shadow: var(--sn-node-shadow);
12
+ user-select: none;
13
+ cursor: move;
14
+ transition:
15
+ border-color 0.2s ease-out,
16
+ box-shadow 0.2s ease-out,
17
+ opacity 0.2s ease-out;
18
+ overflow: visible;
19
+ font-family: var(--sn-font);
20
+ font-size: var(--sn-node-font-size);
21
+ -webkit-font-smoothing: antialiased;
22
+ --sn-node-items-max-height: 420px;
23
+ --sn-svg-shape-media-clip: circle(50% at 50% 50%);
24
+ --sn-node-category-accent: var(--sn-cat-default);
25
+ --sn-node-accent: var(--sn-node-type-accent, var(--sn-node-category-accent));
26
+
27
+ /* Symbiote animateOut: CSS-driven exit transition */
28
+ &[leaving] {
29
+ opacity: 0;
30
+ transform: scale(0.92);
31
+ transition:
32
+ border-color 0.2s ease-out,
33
+ box-shadow 0.2s ease-out,
34
+ opacity 0.2s ease-out,
35
+ transform 0.2s ease-out;
36
+ }
37
+
38
+ &[data-selected] {
39
+ border-color: var(--sn-node-selected);
40
+ box-shadow: 0 0 20px color-mix(in srgb, var(--sn-node-selected) 30%, transparent);
41
+ }
42
+
43
+ &[data-collapsed] {
44
+ & .controls {
45
+ display: none;
46
+ }
47
+ & .sn-node-body {
48
+ padding: 4px 0;
49
+ }
50
+ & .port-label {
51
+ display: none;
52
+ }
53
+ }
54
+
55
+ &[data-muted] {
56
+ opacity: 0.45;
57
+ filter: saturate(0.3);
58
+
59
+ & .sn-node-label {
60
+ text-decoration: line-through;
61
+ }
62
+ }
63
+
64
+ &[data-header-hidden] .sn-node-header {
65
+ display: none !important;
66
+ }
67
+
68
+ &[data-content-hidden] {
69
+ & .sn-node-content,
70
+ & .sn-node-items {
71
+ display: none !important;
72
+ }
73
+ }
74
+
75
+ &[data-readonly]:not([data-readonly-node-dragging]),
76
+ node-canvas[data-readonly] &:not([data-readonly-node-dragging]) {
77
+ cursor: default;
78
+ }
79
+
80
+ /* Compact mode — hide node body (ports & controls).
81
+ Activated by canvas.setCompactMode(true) which sets data-compact on the canvas.
82
+ SubgraphNodes (node-type="subgraph") keep body visible for inner graph preview. */
83
+ node-canvas[data-compact] &:not([node-type='subgraph']) .sn-node-body {
84
+ display: none;
85
+ }
86
+
87
+ /* LOD: medium — strip heavy rendering for performance */
88
+ &[data-lod='medium'] {
89
+ box-shadow: none;
90
+ transition: none;
91
+ will-change: auto;
92
+ pointer-events: auto;
93
+
94
+ &:hover {
95
+ border-color: var(--sn-node-border);
96
+ }
97
+
98
+ &[data-selected] {
99
+ box-shadow: none;
100
+ }
101
+
102
+ &[data-processing] {
103
+ box-shadow: none;
104
+ animation: none;
105
+ }
106
+
107
+ &[data-completed] {
108
+ box-shadow: none;
109
+ }
110
+
111
+ &[data-muted] {
112
+ filter: none;
113
+ opacity: 0.5;
114
+ }
115
+
116
+ & .controls,
117
+ & .port-label,
118
+ & .sn-subgraph-preview,
119
+ & .error-frame,
120
+ & .sn-quick-toolbar {
121
+ display: none;
122
+ }
123
+
124
+ & .sn-node-body {
125
+ padding: 2px 0;
126
+ }
127
+
128
+ & node-socket {
129
+ transition: none;
130
+ cursor: default;
131
+
132
+ &:hover {
133
+ transform: none;
134
+ box-shadow: none;
135
+ }
136
+ }
137
+ }
138
+
139
+ &[node-type='subgraph'] .sn-subgraph-preview {
140
+ display: block;
141
+ width: 100%;
142
+ height: 80px;
143
+ border-top: 1px solid color-mix(in srgb, currentColor 6%, transparent);
144
+ opacity: 0.7;
145
+ }
146
+
147
+ &[data-processing] {
148
+ border-color: var(--sn-node-accent, var(--sn-node-selected));
149
+ box-shadow:
150
+ 0 0 16px color-mix(in srgb, var(--sn-node-accent) 40%, transparent),
151
+ 0 0 4px color-mix(in srgb, var(--sn-node-accent) 60%, transparent);
152
+ animation: sn-node-pulse 1s ease-in-out infinite;
153
+ }
154
+
155
+ &[data-completed] {
156
+ border-color: var(--sn-success-color);
157
+ box-shadow: 0 0 8px color-mix(in srgb, var(--sn-success-color) 30%, transparent);
158
+ }
159
+
160
+ &[data-error] {
161
+ border-color: color-mix(in srgb, var(--sn-danger-color) 60%, transparent);
162
+ position: relative;
163
+ }
164
+
165
+ &[data-error] .sn-node-header {
166
+ background: color-mix(in srgb, var(--sn-danger-color) 10%, transparent);
167
+ }
168
+
169
+ & .error-frame {
170
+ position: absolute;
171
+ bottom: calc(100% + var(--sn-node-error-frame-offset));
172
+ left: 50%;
173
+ transform: translateX(-50%);
174
+ min-width: var(--sn-node-error-frame-min-width);
175
+ max-width: var(--sn-node-error-frame-max-width);
176
+ border: var(--sn-node-error-frame-border-width) solid color-mix(in srgb, var(--sn-danger-color) 60%, transparent);
177
+ border-radius: var(--sn-node-error-frame-radius);
178
+ background: color-mix(in srgb, var(--sn-danger-color) 8%, transparent);
179
+ pointer-events: none;
180
+ z-index: 10;
181
+ transition: bottom 0.15s ease;
182
+ }
183
+
184
+ & .error-frame-header {
185
+ display: flex;
186
+ align-items: center;
187
+ gap: 6px;
188
+ padding: 5px 10px;
189
+ font-size: 12px;
190
+ font-weight: 600;
191
+ color: color-mix(in srgb, var(--sn-danger-color) 90%, white);
192
+ border-bottom: 1px solid color-mix(in srgb, var(--sn-danger-color) 20%, transparent);
193
+ user-select: none;
194
+ }
195
+
196
+ & .error-frame-header .material-symbols-outlined {
197
+ font-size: 14px;
198
+ opacity: 0.8;
199
+ }
200
+
201
+ & .error-frame-body {
202
+ padding: 6px 10px;
203
+ font-size: 11px;
204
+ line-height: 1.4;
205
+ color: color-mix(in srgb, var(--sn-danger-color) 75%, white);
206
+ word-wrap: break-word;
207
+ }
208
+
209
+ & .sn-node-media {
210
+ inline-size: 100%;
211
+ overflow: hidden;
212
+ border-bottom: 1px solid color-mix(in srgb, currentColor 8%, transparent);
213
+ background: color-mix(in srgb, var(--sn-node-accent) 10%, transparent);
214
+ }
215
+
216
+ & .sn-node-media-img {
217
+ display: block;
218
+ inline-size: 100%;
219
+ aspect-ratio: 16 / 9;
220
+ object-fit: cover;
221
+ pointer-events: none;
222
+ user-select: none;
223
+ -webkit-user-drag: none;
224
+ }
225
+
226
+ & .sn-node-content {
227
+ padding: 8px 12px 10px;
228
+ min-width: 0;
229
+ }
230
+
231
+ & .sn-node-summary {
232
+ margin: 0;
233
+ color: var(--sn-text-dim);
234
+ font-size: 12px;
235
+ line-height: 1.45;
236
+ }
237
+
238
+ & .sn-node-link {
239
+ display: inline-flex;
240
+ align-items: center;
241
+ gap: 5px;
242
+ margin-top: 8px;
243
+ color: var(--sn-node-selected);
244
+ font-size: 12px;
245
+ font-weight: 700;
246
+ text-decoration: none;
247
+ }
248
+
249
+ & .sn-node-link:not([href]) {
250
+ display: none;
251
+ }
252
+
253
+ & .sn-node-link .material-symbols-outlined {
254
+ font-size: 15px;
255
+ }
256
+
257
+ & .sn-node-items {
258
+ display: flex;
259
+ flex-direction: column;
260
+ padding: 6px;
261
+ gap: 6px;
262
+ max-block-size: var(--sn-node-items-max-height);
263
+ overflow-y: auto;
264
+ }
265
+
266
+ & .sn-node-item {
267
+ display: flex;
268
+ flex-direction: column;
269
+ gap: 3px;
270
+ padding: 8px 9px;
271
+ border: 1px solid color-mix(in srgb, currentColor 8%, transparent);
272
+ border-radius: 6px;
273
+ background: color-mix(in srgb, var(--sn-node-accent) 8%, transparent);
274
+ color: inherit;
275
+ text-decoration: none;
276
+ }
277
+
278
+ & .sn-node-item:hover {
279
+ border-color: color-mix(in srgb, var(--sn-node-accent) 44%, transparent);
280
+ background: color-mix(in srgb, var(--sn-node-accent) 14%, transparent);
281
+ }
282
+
283
+ & .sn-node-item-kicker {
284
+ color: var(--sn-node-accent);
285
+ font-size: 10px;
286
+ font-weight: 800;
287
+ letter-spacing: 0.04em;
288
+ text-transform: uppercase;
289
+ }
290
+
291
+ & .sn-node-item-title {
292
+ color: var(--sn-text);
293
+ font-size: 13px;
294
+ font-weight: 700;
295
+ line-height: 1.25;
296
+ }
297
+
298
+ & .sn-node-item-summary {
299
+ display: -webkit-box;
300
+ overflow: hidden;
301
+ color: var(--sn-text-dim);
302
+ font-size: 11px;
303
+ line-height: 1.35;
304
+ -webkit-box-orient: vertical;
305
+ -webkit-line-clamp: 2;
306
+ }
307
+
308
+ &[data-selected] .error-frame {
309
+ bottom: calc(100% + 46px);
310
+ }
311
+
312
+ &:hover {
313
+ border-color: var(--sn-node-hover);
314
+ }
315
+
316
+ &[node-category='server'] {
317
+ --sn-node-category-accent: var(--sn-cat-server);
318
+ }
319
+ &[node-category='instance'] {
320
+ --sn-node-category-accent: var(--sn-cat-instance);
321
+ }
322
+ &[node-category='control'] {
323
+ --sn-node-category-accent: var(--sn-cat-control);
324
+ }
325
+ &[node-category='data'] {
326
+ --sn-node-category-accent: var(--sn-cat-data);
327
+ }
328
+ &[node-category='default'] {
329
+ --sn-node-category-accent: var(--sn-cat-default);
330
+ }
331
+ /* Codebase categories */
332
+ &[node-category='directory'] {
333
+ --sn-node-category-accent: var(--sn-cat-directory);
334
+ }
335
+ &[node-category='file'] {
336
+ --sn-node-category-accent: var(--sn-cat-file);
337
+ }
338
+ &[node-category='function'] {
339
+ --sn-node-category-accent: var(--sn-cat-function);
340
+ }
341
+ &[node-category='class'] {
342
+ --sn-node-category-accent: var(--sn-cat-class);
343
+ }
344
+ &[node-category='module'] {
345
+ --sn-node-category-accent: var(--sn-cat-module);
346
+ }
347
+
348
+ /* Shape: pill — compact horizontal capsule */
349
+ &[node-shape='pill'] {
350
+ min-width: 100px;
351
+ max-width: 200px;
352
+ border-radius: 999px;
353
+
354
+ & .sn-node-header {
355
+ display: none;
356
+ }
357
+ & .sn-node-body {
358
+ padding: 8px 20px;
359
+ align-items: center;
360
+ justify-content: center;
361
+ flex-direction: row;
362
+ gap: 8px;
363
+ }
364
+ & .inputs,
365
+ & .outputs {
366
+ padding: 0;
367
+ }
368
+ & .sn-port-in node-socket {
369
+ margin-left: -26px;
370
+ }
371
+ & .sn-port-out node-socket {
372
+ margin-right: -26px;
373
+ }
374
+ & .controls {
375
+ display: none;
376
+ }
377
+ }
378
+
379
+ /* Shape: circle — hub/connector node */
380
+ &[node-shape='circle'] {
381
+ min-width: 100px;
382
+ min-height: 100px;
383
+ border-radius: 50%;
384
+ aspect-ratio: 1;
385
+ display: flex;
386
+ flex-direction: column;
387
+ align-items: center;
388
+ justify-content: center;
389
+
390
+ & .sn-node-header {
391
+ background: transparent;
392
+ border-bottom: none;
393
+ justify-content: center;
394
+ padding: 6px;
395
+ }
396
+ & .sn-node-body {
397
+ padding: 0 8px 8px;
398
+ flex-direction: row;
399
+ align-items: center;
400
+ gap: 0;
401
+ }
402
+ & .inputs {
403
+ position: absolute;
404
+ left: -6px;
405
+ top: 50%;
406
+ transform: translateY(-50%);
407
+ }
408
+ & .outputs {
409
+ position: absolute;
410
+ right: -6px;
411
+ top: 50%;
412
+ transform: translateY(-50%);
413
+ }
414
+ & .port-label {
415
+ display: none;
416
+ }
417
+ & .controls {
418
+ display: none;
419
+ }
420
+ }
421
+
422
+ /* Shape: diamond — condition/decision */
423
+ &[node-shape='diamond'] {
424
+ min-width: 100px;
425
+ min-height: 100px;
426
+ border-radius: 4px;
427
+ transform-origin: center;
428
+ clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
429
+ display: flex;
430
+ align-items: center;
431
+ justify-content: center;
432
+
433
+ & .sn-node-header {
434
+ display: none;
435
+ }
436
+ & .sn-node-body {
437
+ text-align: center;
438
+ padding: 25% 10%;
439
+ }
440
+ & .controls {
441
+ display: none;
442
+ }
443
+ }
444
+
445
+ /* Shape: comment — annotation banner */
446
+ &[node-shape='comment'] {
447
+ min-width: 200px;
448
+ max-width: 400px;
449
+ border-radius: var(--sn-comment-radius);
450
+ background: var(--sn-comment-bg);
451
+ border-color: var(--sn-comment-border);
452
+ cursor: default;
453
+ box-shadow: none;
454
+
455
+ & .sn-node-header {
456
+ display: none;
457
+ }
458
+ & .sn-node-body {
459
+ padding: 12px 16px;
460
+ }
461
+ & .inputs,
462
+ & .outputs {
463
+ display: none;
464
+ }
465
+ }
466
+
467
+ /* Shape: SVG custom — node with SVG background path */
468
+ &[data-svg-shape] {
469
+ position: relative;
470
+ min-width: 100px;
471
+ min-height: 100px;
472
+ background: transparent;
473
+ border: none;
474
+ box-shadow: none;
475
+ border-radius: 0;
476
+ overflow: visible;
477
+ cursor: default;
478
+
479
+ /* Move cursor only over SVG path fill area */
480
+ & > svg {
481
+ pointer-events: none;
482
+ & > path {
483
+ pointer-events: visibleFill;
484
+ cursor: move;
485
+ transition: stroke 0.2s ease;
486
+ }
487
+ }
488
+
489
+ &[data-readonly]:not([data-readonly-node-dragging]) > svg > path,
490
+ node-canvas[data-readonly] &:not([data-readonly-node-dragging]) > svg > path {
491
+ cursor: default;
492
+ }
493
+
494
+ & .sn-node-header {
495
+ display: none;
496
+ }
497
+ & .sn-node-body {
498
+ padding: 4px 0;
499
+ align-items: center;
500
+ }
501
+ & .controls {
502
+ display: none;
503
+ }
504
+ & .sn-shape-watermark {
505
+ position: absolute;
506
+ top: 50%;
507
+ left: 50%;
508
+ transform: translate(-50%, -50%);
509
+ font-size: 40px;
510
+ color: var(--sn-node-accent, var(--sn-text-dim));
511
+ pointer-events: none;
512
+ z-index: 0;
513
+ }
514
+ /* Hide DOM port items — ConnectionRenderer computes positions mathematically */
515
+ & .inputs,
516
+ & .outputs {
517
+ display: none;
518
+ }
519
+
520
+ &[data-has-media] {
521
+ overflow: visible !important;
522
+ border-radius: 0 !important;
523
+
524
+ & > svg {
525
+ z-index: 1;
526
+ }
527
+
528
+ & > svg > path {
529
+ fill: transparent;
530
+ }
531
+
532
+ & .sn-node-media {
533
+ position: absolute !important;
534
+ inset: var(--sn-svg-shape-media-top, 0%) auto auto var(--sn-svg-shape-media-left, 0%);
535
+ inline-size: var(--sn-svg-shape-media-width, 100%);
536
+ block-size: var(--sn-svg-shape-media-height, 100%);
537
+ z-index: 0;
538
+ border: 0;
539
+ margin: 0;
540
+ clip-path: var(--sn-svg-shape-media-clip);
541
+ }
542
+
543
+ & .sn-node-media-img {
544
+ inline-size: 100%;
545
+ block-size: 100%;
546
+ aspect-ratio: 1;
547
+ object-fit: cover;
548
+ }
549
+
550
+ & .sn-node-body {
551
+ padding: 0;
552
+ }
553
+
554
+ & .sn-node-icon,
555
+ & .sn-shape-watermark {
556
+ display: none;
557
+ }
558
+ }
559
+ }
560
+
561
+ &[data-svg-shape][data-node-tone='inverse'] {
562
+ --sn-shape-fill: var(--sn-node-accent);
563
+ --sn-shape-stroke: var(--sn-node-accent);
564
+
565
+ & .sn-shape-watermark {
566
+ color: var(--sn-node-bg);
567
+ }
568
+ }
569
+
570
+ /* SVG shape states — target inline svg > path directly.
571
+ border/box-shadow have no effect on SVG nodes (border: none).
572
+ Only stroke COLOR changes on state — width stays the same as inactive,
573
+ matching HTML nodes where border-width stays 1px on selection. */
574
+ &[data-svg-shape][data-selected] > svg > path {
575
+ stroke: var(--sn-node-selected);
576
+ transition: stroke 0.2s ease;
577
+ }
578
+
579
+ &[data-svg-shape][data-error] > svg > path {
580
+ stroke: var(--sn-danger-color);
581
+ transition: stroke 0.2s ease;
582
+ }
583
+
584
+ &[data-svg-shape][data-muted] > svg > path {
585
+ opacity: 0.35;
586
+ filter: saturate(0.2);
587
+ transition:
588
+ opacity 0.2s ease,
589
+ filter 0.2s ease;
590
+ }
591
+
592
+ &[data-svg-shape][data-processing] > svg > path {
593
+ stroke: var(--sn-node-accent, var(--sn-node-selected));
594
+ animation: sn-svg-pulse 1s ease-in-out infinite;
595
+ }
596
+
597
+ &[data-svg-shape][data-completed] > svg > path {
598
+ stroke: var(--sn-success-color);
599
+ transition: stroke 0.2s ease;
600
+ }
601
+
602
+ & .sn-node-header {
603
+ display: flex;
604
+ align-items: center;
605
+ gap: 6px;
606
+ padding: 8px 12px;
607
+ background: var(
608
+ --sn-node-header-bg,
609
+ color-mix(in srgb, var(--sn-node-accent) 15%, transparent)
610
+ );
611
+ border-bottom: 1px solid color-mix(in srgb, currentColor 6%, transparent);
612
+ border-radius: var(--sn-node-radius) var(--sn-node-radius) 0 0;
613
+ }
614
+
615
+ & .sn-node-icon {
616
+ font-size: 18px;
617
+ color: var(--sn-node-accent);
618
+ opacity: 1;
619
+ }
620
+
621
+ & .sn-node-label {
622
+ font-weight: 600;
623
+ font-size: var(--sn-node-label-size, inherit);
624
+ color: var(--sn-text);
625
+ opacity: 1;
626
+ white-space: nowrap;
627
+ overflow: hidden;
628
+ text-overflow: ellipsis;
629
+ }
630
+
631
+ & .sn-node-body {
632
+ padding: 8px 0;
633
+ display: flex;
634
+ flex-direction: column;
635
+ gap: 4px;
636
+ }
637
+
638
+ & .inputs,
639
+ & .outputs {
640
+ display: flex;
641
+ flex-direction: column;
642
+ transition: transform 0.15s ease;
643
+ }
644
+
645
+ /* Port hint: slide ports to nearest side during connector drag */
646
+ &[data-port-hint='right'] .inputs {
647
+ transform: translateX(calc(100% - 12px));
648
+ }
649
+
650
+ &[data-port-hint='left'] .outputs {
651
+ transform: translateX(calc(-100% + 12px));
652
+ }
653
+
654
+ /* Compatible SVG node during drag: subtle outline hint only — dots handle highlight */
655
+ &[data-svg-shape][data-port-hint] > svg > path {
656
+ stroke: var(--sn-node-selected);
657
+ stroke-width: 0.5;
658
+ opacity: 0.8;
659
+ transition:
660
+ stroke 0.15s ease,
661
+ opacity 0.15s ease;
662
+ }
663
+
664
+ /* Incompatible dimming for nodes without compatible ports */
665
+ &[data-port-hint='none'] {
666
+ opacity: 0.4;
667
+ pointer-events: none;
668
+ }
669
+
670
+ & .sn-port {
671
+ display: flex;
672
+ align-items: center;
673
+ gap: 6px;
674
+ padding: 3px 12px;
675
+ min-height: 24px;
676
+ }
677
+
678
+ & .sn-port-in {
679
+ flex-direction: row;
680
+
681
+ & node-socket {
682
+ margin-left: -18px;
683
+ }
684
+ }
685
+
686
+ & .sn-port-out {
687
+ flex-direction: row;
688
+ justify-content: flex-end;
689
+
690
+ & node-socket {
691
+ margin-right: -18px;
692
+ }
693
+ }
694
+
695
+ & .port-label {
696
+ color: var(--sn-text-dim);
697
+ font-size: 12px;
698
+ white-space: nowrap;
699
+ }
700
+
701
+ & .controls {
702
+ padding: 0 12px;
703
+ }
704
+
705
+ & .sn-control-item {
706
+ display: flex;
707
+ flex-direction: column;
708
+ gap: 2px;
709
+ margin: 4px 0;
710
+ }
711
+
712
+ & .sn-control-label {
713
+ font-size: 10px;
714
+ text-transform: uppercase;
715
+ color: var(--sn-text-dim);
716
+ letter-spacing: 0.5px;
717
+ }
718
+
719
+ & .sn-control-input {
720
+ background: color-mix(in srgb, var(--sn-bg) 70%, transparent);
721
+ border: 1px solid color-mix(in srgb, currentColor 10%, transparent);
722
+ border-radius: 4px;
723
+ padding: 4px 8px;
724
+ color: var(--sn-text);
725
+ font-size: 12px;
726
+ outline: none;
727
+ font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', monospace;
728
+
729
+ &:focus {
730
+ border-color: var(--sn-node-accent);
731
+ }
732
+
733
+ &[readonly] {
734
+ opacity: 0.6;
735
+ cursor: default;
736
+ }
737
+ }
738
+ }
739
+
740
+ /* Preview Area — image/text preview at bottom of node */
741
+ .sn-preview {
742
+ border-top: 1px solid var(--sn-node-border);
743
+ border-radius: 0 0 8px 8px;
744
+ overflow: hidden;
745
+ max-height: 120px;
746
+ background: color-mix(in srgb, var(--sn-bg) 55%, transparent);
747
+
748
+ &[hidden] {
749
+ display: none;
750
+ }
751
+
752
+ & img {
753
+ width: 100%;
754
+ height: auto;
755
+ display: block;
756
+ object-fit: cover;
757
+ max-height: 120px;
758
+ }
759
+
760
+ & .sn-preview-text {
761
+ padding: 6px 10px;
762
+ font-size: 11px;
763
+ color: var(--sn-text-dim);
764
+ font-family: 'JetBrains Mono', 'Fira Code', monospace;
765
+ white-space: pre-wrap;
766
+ word-break: break-all;
767
+ line-height: 1.4;
768
+ }
769
+ }
770
+
771
+
772
+ @keyframes sn-node-pulse {
773
+ 0%,
774
+ 100% {
775
+ opacity: 1;
776
+ }
777
+ 50% {
778
+ opacity: 0.7;
779
+ }
780
+ }
781
+
782
+ @keyframes sn-node-error-pulse {
783
+ 0%,
784
+ 100% {
785
+ box-shadow:
786
+ 0 0 16px color-mix(in srgb, var(--sn-danger-color) 35%, transparent),
787
+ 0 0 4px color-mix(in srgb, var(--sn-danger-color) 50%, transparent);
788
+ }
789
+ 50% {
790
+ box-shadow:
791
+ 0 0 24px color-mix(in srgb, var(--sn-danger-color) 50%, transparent),
792
+ 0 0 8px color-mix(in srgb, var(--sn-danger-color) 70%, transparent);
793
+ }
794
+ }
795
+
796
+ @keyframes sn-svg-pulse {
797
+ 0%,
798
+ 100% {
799
+ opacity: 0.7;
800
+ transform: scale(1);
801
+ }
802
+ 50% {
803
+ opacity: 1;
804
+ transform: scale(1.05);
805
+ }
806
+ }
807
+
808
+ /* Accessibility: reduced motion */
809
+ @media (prefers-reduced-motion: reduce) {
810
+ graph-node {
811
+ transition: none;
812
+ animation: none;
813
+ }
814
+ }
815
+ `;