pmx-canvas 0.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 (226) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/Readme.md +865 -0
  4. package/dist/canvas/global.css +3173 -0
  5. package/dist/canvas/index.js +183 -0
  6. package/dist/json-render/index.css +2 -0
  7. package/dist/json-render/index.js +389 -0
  8. package/dist/types/cli/agent.d.ts +13 -0
  9. package/dist/types/cli/index.d.ts +2 -0
  10. package/dist/types/cli/watch.d.ts +5 -0
  11. package/dist/types/client/App.d.ts +1 -0
  12. package/dist/types/client/canvas/AttentionHistory.d.ts +1 -0
  13. package/dist/types/client/canvas/AttentionToast.d.ts +1 -0
  14. package/dist/types/client/canvas/CanvasNode.d.ts +8 -0
  15. package/dist/types/client/canvas/CanvasViewport.d.ts +8 -0
  16. package/dist/types/client/canvas/CommandPalette.d.ts +4 -0
  17. package/dist/types/client/canvas/ContextMenu.d.ts +24 -0
  18. package/dist/types/client/canvas/ContextPinBar.d.ts +1 -0
  19. package/dist/types/client/canvas/ContextPinHud.d.ts +1 -0
  20. package/dist/types/client/canvas/DockedNode.d.ts +4 -0
  21. package/dist/types/client/canvas/EdgeLayer.d.ts +8 -0
  22. package/dist/types/client/canvas/ExpandedNodeOverlay.d.ts +1 -0
  23. package/dist/types/client/canvas/FocusFieldLayer.d.ts +1 -0
  24. package/dist/types/client/canvas/Minimap.d.ts +23 -0
  25. package/dist/types/client/canvas/SelectionBar.d.ts +1 -0
  26. package/dist/types/client/canvas/ShortcutOverlay.d.ts +3 -0
  27. package/dist/types/client/canvas/SnapshotPanel.d.ts +7 -0
  28. package/dist/types/client/canvas/snap-guides.d.ts +23 -0
  29. package/dist/types/client/canvas/use-node-drag.d.ts +15 -0
  30. package/dist/types/client/canvas/use-node-resize.d.ts +15 -0
  31. package/dist/types/client/canvas/use-pan-zoom.d.ts +16 -0
  32. package/dist/types/client/ext-app/bridge.d.ts +161 -0
  33. package/dist/types/client/icons.d.ts +70 -0
  34. package/dist/types/client/index.d.ts +1 -0
  35. package/dist/types/client/nodes/ContextNode.d.ts +34 -0
  36. package/dist/types/client/nodes/ExtAppFrame.d.ts +18 -0
  37. package/dist/types/client/nodes/FileNode.d.ts +5 -0
  38. package/dist/types/client/nodes/GroupNode.d.ts +6 -0
  39. package/dist/types/client/nodes/ImageNode.d.ts +10 -0
  40. package/dist/types/client/nodes/InlineFormatBar.d.ts +7 -0
  41. package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +14 -0
  42. package/dist/types/client/nodes/LedgerNode.d.ts +4 -0
  43. package/dist/types/client/nodes/MarkdownNode.d.ts +6 -0
  44. package/dist/types/client/nodes/McpAppNode.d.ts +4 -0
  45. package/dist/types/client/nodes/MdFormatBar.d.ts +8 -0
  46. package/dist/types/client/nodes/PromptNode.d.ts +5 -0
  47. package/dist/types/client/nodes/ResponseNode.d.ts +5 -0
  48. package/dist/types/client/nodes/StatusNode.d.ts +4 -0
  49. package/dist/types/client/nodes/StatusSummary.d.ts +4 -0
  50. package/dist/types/client/nodes/TraceNode.d.ts +4 -0
  51. package/dist/types/client/nodes/WebpageNode.d.ts +5 -0
  52. package/dist/types/client/nodes/image-warnings.d.ts +6 -0
  53. package/dist/types/client/nodes/inline-editor-commands.d.ts +11 -0
  54. package/dist/types/client/nodes/md-format.d.ts +25 -0
  55. package/dist/types/client/state/attention-bridge.d.ts +3 -0
  56. package/dist/types/client/state/attention-store.d.ts +25 -0
  57. package/dist/types/client/state/canvas-store.d.ts +74 -0
  58. package/dist/types/client/state/intent-bridge.d.ts +158 -0
  59. package/dist/types/client/state/sse-bridge.d.ts +5 -0
  60. package/dist/types/client/theme/tokens.d.ts +27 -0
  61. package/dist/types/client/types.d.ts +40 -0
  62. package/dist/types/client/utils/ext-app-tool-result.d.ts +1 -0
  63. package/dist/types/client/utils/placement.d.ts +1 -0
  64. package/dist/types/client/utils/platform.d.ts +2 -0
  65. package/dist/types/json-render/catalog.d.ts +815 -0
  66. package/dist/types/json-render/charts/components.d.ts +54 -0
  67. package/dist/types/json-render/charts/definitions.d.ts +103 -0
  68. package/dist/types/json-render/charts/extra-components.d.ts +58 -0
  69. package/dist/types/json-render/charts/extra-definitions.d.ts +181 -0
  70. package/dist/types/json-render/renderer/index.d.ts +16 -0
  71. package/dist/types/json-render/schema.d.ts +46 -0
  72. package/dist/types/json-render/server.d.ts +55 -0
  73. package/dist/types/mcp/server.d.ts +22 -0
  74. package/dist/types/server/agent-context.d.ts +21 -0
  75. package/dist/types/server/artifact-paths.d.ts +3 -0
  76. package/dist/types/server/canvas-operations.d.ts +154 -0
  77. package/dist/types/server/canvas-provenance.d.ts +13 -0
  78. package/dist/types/server/canvas-schema.d.ts +49 -0
  79. package/dist/types/server/canvas-serialization.d.ts +25 -0
  80. package/dist/types/server/canvas-state.d.ts +174 -0
  81. package/dist/types/server/canvas-validation.d.ts +33 -0
  82. package/dist/types/server/chart-template.d.ts +29 -0
  83. package/dist/types/server/code-graph.d.ts +67 -0
  84. package/dist/types/server/context-cards.d.ts +24 -0
  85. package/dist/types/server/diagram-presets.d.ts +28 -0
  86. package/dist/types/server/ext-app-call-registry.d.ts +16 -0
  87. package/dist/types/server/ext-app-tool-result.d.ts +1 -0
  88. package/dist/types/server/file-watcher.d.ts +16 -0
  89. package/dist/types/server/index.d.ts +243 -0
  90. package/dist/types/server/mcp-app-candidate.d.ts +25 -0
  91. package/dist/types/server/mcp-app-host.d.ts +65 -0
  92. package/dist/types/server/mcp-app-runtime.d.ts +47 -0
  93. package/dist/types/server/mutation-history.d.ts +105 -0
  94. package/dist/types/server/placement.d.ts +37 -0
  95. package/dist/types/server/server.d.ts +103 -0
  96. package/dist/types/server/spatial-analysis.d.ts +87 -0
  97. package/dist/types/server/trace-manager.d.ts +48 -0
  98. package/dist/types/server/web-artifacts.d.ts +50 -0
  99. package/dist/types/server/webpage-node.d.ts +25 -0
  100. package/dist/types/shared/auto-arrange.d.ts +29 -0
  101. package/dist/types/shared/ext-app-tool-result.d.ts +9 -0
  102. package/dist/types/shared/placement.d.ts +26 -0
  103. package/dist/types/shared/semantic-attention.d.ts +97 -0
  104. package/package.json +109 -0
  105. package/skills/data-analysis/SKILL.md +324 -0
  106. package/skills/doc-coauthoring/SKILL.md +375 -0
  107. package/skills/frontend-design/SKILL.md +45 -0
  108. package/skills/json-render-codegen/SKILL.md +112 -0
  109. package/skills/json-render-core/SKILL.md +265 -0
  110. package/skills/json-render-ink/SKILL.md +273 -0
  111. package/skills/json-render-mcp/SKILL.md +132 -0
  112. package/skills/json-render-react/SKILL.md +264 -0
  113. package/skills/json-render-shadcn/SKILL.md +159 -0
  114. package/skills/playwright-cli/SKILL.md +67 -0
  115. package/skills/pmx-canvas/SKILL.md +668 -0
  116. package/skills/pmx-canvas/evals/evals.json +186 -0
  117. package/skills/pmx-canvas-testing/SKILL.md +78 -0
  118. package/skills/published-consumer-e2e/SKILL.md +43 -0
  119. package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +241 -0
  120. package/skills/web-artifacts-builder/SKILL.md +80 -0
  121. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +167 -0
  122. package/skills/web-artifacts-builder/scripts/init-artifact.sh +425 -0
  123. package/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  124. package/skills/web-design-guidelines/SKILL.md +39 -0
  125. package/src/cli/agent.ts +2144 -0
  126. package/src/cli/index.ts +622 -0
  127. package/src/cli/watch.ts +88 -0
  128. package/src/client/App.tsx +507 -0
  129. package/src/client/canvas/AttentionHistory.tsx +81 -0
  130. package/src/client/canvas/AttentionToast.tsx +19 -0
  131. package/src/client/canvas/CanvasNode.tsx +363 -0
  132. package/src/client/canvas/CanvasViewport.tsx +590 -0
  133. package/src/client/canvas/CommandPalette.tsx +302 -0
  134. package/src/client/canvas/ContextMenu.tsx +601 -0
  135. package/src/client/canvas/ContextPinBar.tsx +25 -0
  136. package/src/client/canvas/ContextPinHud.tsx +22 -0
  137. package/src/client/canvas/DockedNode.tsx +66 -0
  138. package/src/client/canvas/EdgeLayer.tsx +280 -0
  139. package/src/client/canvas/ExpandedNodeOverlay.tsx +260 -0
  140. package/src/client/canvas/FocusFieldLayer.tsx +107 -0
  141. package/src/client/canvas/Minimap.tsx +301 -0
  142. package/src/client/canvas/SelectionBar.tsx +69 -0
  143. package/src/client/canvas/ShortcutOverlay.tsx +69 -0
  144. package/src/client/canvas/SnapshotPanel.tsx +236 -0
  145. package/src/client/canvas/snap-guides.ts +170 -0
  146. package/src/client/canvas/use-node-drag.ts +51 -0
  147. package/src/client/canvas/use-node-resize.ts +59 -0
  148. package/src/client/canvas/use-pan-zoom.ts +191 -0
  149. package/src/client/ext-app/bridge.ts +542 -0
  150. package/src/client/icons.tsx +424 -0
  151. package/src/client/index.tsx +7 -0
  152. package/src/client/nodes/ContextNode.tsx +412 -0
  153. package/src/client/nodes/ExtAppFrame.tsx +509 -0
  154. package/src/client/nodes/FileNode.tsx +256 -0
  155. package/src/client/nodes/GroupNode.tsx +39 -0
  156. package/src/client/nodes/ImageNode.tsx +160 -0
  157. package/src/client/nodes/InlineFormatBar.tsx +169 -0
  158. package/src/client/nodes/InlineMarkdownEditor.tsx +123 -0
  159. package/src/client/nodes/LedgerNode.tsx +37 -0
  160. package/src/client/nodes/MarkdownNode.tsx +359 -0
  161. package/src/client/nodes/McpAppNode.tsx +85 -0
  162. package/src/client/nodes/MdFormatBar.tsx +109 -0
  163. package/src/client/nodes/PromptNode.tsx +597 -0
  164. package/src/client/nodes/ResponseNode.tsx +153 -0
  165. package/src/client/nodes/StatusNode.tsx +84 -0
  166. package/src/client/nodes/StatusSummary.tsx +38 -0
  167. package/src/client/nodes/TraceNode.tsx +120 -0
  168. package/src/client/nodes/WebpageNode.tsx +288 -0
  169. package/src/client/nodes/image-warnings.ts +95 -0
  170. package/src/client/nodes/inline-editor-commands.ts +37 -0
  171. package/src/client/nodes/md-format.ts +206 -0
  172. package/src/client/state/attention-bridge.ts +328 -0
  173. package/src/client/state/attention-store.ts +73 -0
  174. package/src/client/state/canvas-store.ts +631 -0
  175. package/src/client/state/intent-bridge.ts +315 -0
  176. package/src/client/state/sse-bridge.ts +965 -0
  177. package/src/client/theme/global.css +3173 -0
  178. package/src/client/theme/tokens.ts +72 -0
  179. package/src/client/types-shims.d.ts +5 -0
  180. package/src/client/types.ts +81 -0
  181. package/src/client/utils/ext-app-tool-result.ts +4 -0
  182. package/src/client/utils/placement.ts +4 -0
  183. package/src/client/utils/platform.ts +2 -0
  184. package/src/json-render/catalog.ts +256 -0
  185. package/src/json-render/charts/components.tsx +198 -0
  186. package/src/json-render/charts/definitions.ts +81 -0
  187. package/src/json-render/charts/extra-components.tsx +267 -0
  188. package/src/json-render/charts/extra-definitions.ts +145 -0
  189. package/src/json-render/renderer/index.css +174 -0
  190. package/src/json-render/renderer/index.tsx +86 -0
  191. package/src/json-render/schema.ts +62 -0
  192. package/src/json-render/server.ts +597 -0
  193. package/src/mcp/server.ts +1377 -0
  194. package/src/server/agent-context.ts +242 -0
  195. package/src/server/artifact-paths.ts +17 -0
  196. package/src/server/canvas-operations.ts +1279 -0
  197. package/src/server/canvas-provenance.ts +243 -0
  198. package/src/server/canvas-schema.ts +432 -0
  199. package/src/server/canvas-serialization.ts +95 -0
  200. package/src/server/canvas-state.ts +1134 -0
  201. package/src/server/canvas-validation.ts +114 -0
  202. package/src/server/chart-template.ts +449 -0
  203. package/src/server/code-graph.ts +370 -0
  204. package/src/server/context-cards.ts +31 -0
  205. package/src/server/diagram-presets.ts +71 -0
  206. package/src/server/ext-app-call-registry.ts +77 -0
  207. package/src/server/ext-app-tool-result.ts +4 -0
  208. package/src/server/file-watcher.ts +121 -0
  209. package/src/server/index.ts +647 -0
  210. package/src/server/mcp-app-candidate.ts +174 -0
  211. package/src/server/mcp-app-host.ts +814 -0
  212. package/src/server/mcp-app-runtime.ts +459 -0
  213. package/src/server/mutation-history.ts +350 -0
  214. package/src/server/placement.ts +125 -0
  215. package/src/server/server.ts +3846 -0
  216. package/src/server/spatial-analysis.ts +356 -0
  217. package/src/server/trace-manager.ts +333 -0
  218. package/src/server/web-artifacts/scripts/bundle-artifact.sh +167 -0
  219. package/src/server/web-artifacts/scripts/init-artifact.sh +426 -0
  220. package/src/server/web-artifacts/scripts/shadcn-components.tar.gz +0 -0
  221. package/src/server/web-artifacts.ts +442 -0
  222. package/src/server/webpage-node.ts +328 -0
  223. package/src/shared/auto-arrange.ts +439 -0
  224. package/src/shared/ext-app-tool-result.ts +76 -0
  225. package/src/shared/placement.ts +81 -0
  226. package/src/shared/semantic-attention.ts +598 -0
@@ -0,0 +1,3173 @@
1
+ :root {
2
+ /* ── Core palette (dark · ink + cyan) ────────────────────── */
3
+ --c-bg: #081524;
4
+ --c-panel: #0f1d31;
5
+ --c-panel-soft: #0a1729;
6
+ --c-line: #1b2c44;
7
+ --c-text: #e6eef7;
8
+ --c-text-soft: #c7d3ea;
9
+ --c-muted: #8ea3bd;
10
+ --c-dim: #5c6b80;
11
+ --c-accent: #4BBCFF;
12
+ --c-ok: #2fd07f;
13
+ --c-warn: #f4c542;
14
+ --c-warn-alt: #FFB300;
15
+ --c-danger: #ff6a7f;
16
+ --c-purple: #b07aff;
17
+ --c-thinking: #B388FF;
18
+ --c-subagent: #00E5FF;
19
+ --c-input-bg: #0a1729;
20
+ --c-dot-grid: rgba(75, 188, 255, 0.08);
21
+ --c-panel-overlay: rgba(8, 21, 36, 0.6);
22
+ --c-panel-glass: rgba(15, 29, 49, 0.92);
23
+ --c-shadow: rgba(0, 0, 0, 0.3);
24
+ --c-shadow-heavy: rgba(0, 0, 0, 0.5);
25
+ --c-glow-accent: rgba(75, 188, 255, 0.15);
26
+ --c-surface-hover: rgba(255, 255, 255, 0.06);
27
+ --c-surface-subtle: rgba(255, 255, 255, 0.03);
28
+ --c-surface-th: rgba(255, 255, 255, 0.04);
29
+ --c-accent-8: rgba(75, 188, 255, 0.08);
30
+ --c-accent-10: rgba(75, 188, 255, 0.1);
31
+ --c-accent-12: rgba(75, 188, 255, 0.12);
32
+ --c-accent-15: rgba(75, 188, 255, 0.15);
33
+ --c-accent-25: rgba(75, 188, 255, 0.25);
34
+ --c-accent-30: rgba(75, 188, 255, 0.3);
35
+ --c-accent-40: rgba(75, 188, 255, 0.4);
36
+ --c-ok-10: rgba(47, 208, 127, 0.1);
37
+ --c-ok-12: rgba(47, 208, 127, 0.12);
38
+ --c-ok-20: rgba(47, 208, 127, 0.2);
39
+ --c-ok-25: rgba(47, 208, 127, 0.25);
40
+ --c-warn-10: rgba(244, 197, 66, 0.1);
41
+ --c-warn-12: rgba(244, 197, 66, 0.12);
42
+ --c-warn-15: rgba(244, 197, 66, 0.15);
43
+ --c-warn-20: rgba(244, 197, 66, 0.2);
44
+ --c-warn-22: rgba(244, 197, 66, 0.22);
45
+ --c-warn-30: rgba(244, 197, 66, 0.3);
46
+ --c-warn-60: rgba(244, 197, 66, 0.6);
47
+ --c-danger-12: rgba(255, 106, 127, 0.12);
48
+ --c-line-30: rgba(27, 44, 68, 0.3);
49
+ --c-contrast-fg: #081524;
50
+ --c-accent-hover: #6ECAFF;
51
+ --c-warn-hover: #f5d06b;
52
+ --c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0));
53
+ /* ── Non-color tokens ────────────────────────────────────── */
54
+ --font: "IBM Plex Sans", "SF Pro Text", "Avenir Next", system-ui, sans-serif;
55
+ --mono: "IBM Plex Mono", "SF Mono", "Fira Code", monospace;
56
+ --radius: 10px;
57
+ --radius-sm: 6px;
58
+ }
59
+
60
+ :root[data-theme="light"] {
61
+ /* ── Core palette (light · paper + ink) ──────────────────── */
62
+ --c-bg: #F4EFE6;
63
+ --c-panel: #EFE7D4;
64
+ --c-panel-soft: #ECE4D0;
65
+ --c-line: #D6CBB4;
66
+ --c-text: #081524;
67
+ --c-text-soft: #3d4d63;
68
+ --c-muted: #5c6b80;
69
+ --c-dim: #8794a6;
70
+ --c-accent: #1A7ABF;
71
+ --c-ok: #1a9f55;
72
+ --c-warn: #c89b2a;
73
+ --c-warn-alt: #b8860b;
74
+ --c-danger: #d32f2f;
75
+ --c-purple: #7c4dff;
76
+ --c-thinking: #7C4DFF;
77
+ --c-subagent: #00838F;
78
+ --c-input-bg: #FAF6EE;
79
+ --c-dot-grid: rgba(8, 21, 36, 0.08);
80
+ --c-panel-overlay: rgba(244, 239, 230, 0.88);
81
+ --c-panel-glass: rgba(239, 231, 212, 0.88);
82
+ --c-shadow: rgba(8, 21, 36, 0.08);
83
+ --c-shadow-heavy: rgba(8, 21, 36, 0.16);
84
+ --c-glow-accent: rgba(26, 122, 191, 0.12);
85
+ --c-surface-hover: rgba(8, 21, 36, 0.06);
86
+ --c-surface-subtle: rgba(8, 21, 36, 0.03);
87
+ --c-surface-th: rgba(8, 21, 36, 0.04);
88
+ --c-accent-8: rgba(26, 122, 191, 0.08);
89
+ --c-accent-10: rgba(26, 122, 191, 0.1);
90
+ --c-accent-12: rgba(26, 122, 191, 0.12);
91
+ --c-accent-15: rgba(26, 122, 191, 0.15);
92
+ --c-accent-25: rgba(26, 122, 191, 0.25);
93
+ --c-accent-30: rgba(26, 122, 191, 0.3);
94
+ --c-accent-40: rgba(26, 122, 191, 0.4);
95
+ --c-ok-10: rgba(26, 159, 85, 0.1);
96
+ --c-ok-12: rgba(26, 159, 85, 0.12);
97
+ --c-ok-20: rgba(26, 159, 85, 0.2);
98
+ --c-ok-25: rgba(26, 159, 85, 0.25);
99
+ --c-warn-10: rgba(200, 155, 42, 0.1);
100
+ --c-warn-12: rgba(200, 155, 42, 0.12);
101
+ --c-warn-15: rgba(200, 155, 42, 0.15);
102
+ --c-warn-20: rgba(200, 155, 42, 0.2);
103
+ --c-warn-22: rgba(200, 155, 42, 0.22);
104
+ --c-warn-30: rgba(200, 155, 42, 0.3);
105
+ --c-warn-60: rgba(200, 155, 42, 0.6);
106
+ --c-danger-12: rgba(211, 47, 47, 0.12);
107
+ --c-line-30: rgba(214, 203, 180, 0.5);
108
+ --c-contrast-fg: #F4EFE6;
109
+ --c-accent-hover: #1588CE;
110
+ --c-warn-hover: #dab040;
111
+ --c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(8, 21, 36, 0.02));
112
+ }
113
+
114
+ :root[data-theme="high-contrast"] {
115
+ --c-bg: #000000;
116
+ --c-panel: #0a0a0a;
117
+ --c-panel-soft: #0a0a0a;
118
+ --c-line: #ffffff;
119
+ --c-text: #ffffff;
120
+ --c-text-soft: #dddddd;
121
+ --c-muted: #aaaaaa;
122
+ --c-dim: #888888;
123
+ --c-accent: #00ffff;
124
+ --c-ok: #00ff00;
125
+ --c-warn: #ffff00;
126
+ --c-warn-alt: #ffcc00;
127
+ --c-danger: #ff0000;
128
+ --c-purple: #e040fb;
129
+ --c-thinking: #E040FB;
130
+ --c-subagent: #18FFFF;
131
+ --c-input-bg: #111111;
132
+ --c-dot-grid: rgba(255, 255, 255, 0.12);
133
+ --c-panel-overlay: rgba(0, 0, 0, 0.85);
134
+ --c-panel-glass: rgba(0, 0, 0, 0.95);
135
+ --c-shadow: rgba(0, 0, 0, 0.5);
136
+ --c-shadow-heavy: rgba(0, 0, 0, 0.7);
137
+ --c-glow-accent: rgba(0, 255, 255, 0.2);
138
+ --c-surface-hover: rgba(255, 255, 255, 0.1);
139
+ --c-surface-subtle: rgba(255, 255, 255, 0.05);
140
+ --c-surface-th: rgba(255, 255, 255, 0.08);
141
+ --c-accent-8: rgba(0, 255, 255, 0.08);
142
+ --c-accent-10: rgba(0, 255, 255, 0.1);
143
+ --c-accent-12: rgba(0, 255, 255, 0.12);
144
+ --c-accent-15: rgba(0, 255, 255, 0.15);
145
+ --c-accent-25: rgba(0, 255, 255, 0.25);
146
+ --c-accent-30: rgba(0, 255, 255, 0.3);
147
+ --c-accent-40: rgba(0, 255, 255, 0.4);
148
+ --c-ok-10: rgba(0, 255, 0, 0.1);
149
+ --c-ok-12: rgba(0, 255, 0, 0.12);
150
+ --c-ok-20: rgba(0, 255, 0, 0.2);
151
+ --c-ok-25: rgba(0, 255, 0, 0.25);
152
+ --c-warn-10: rgba(255, 255, 0, 0.1);
153
+ --c-warn-12: rgba(255, 255, 0, 0.12);
154
+ --c-warn-15: rgba(255, 255, 0, 0.15);
155
+ --c-warn-20: rgba(255, 255, 0, 0.2);
156
+ --c-warn-22: rgba(255, 255, 0, 0.22);
157
+ --c-warn-30: rgba(255, 255, 0, 0.3);
158
+ --c-warn-60: rgba(255, 255, 0, 0.6);
159
+ --c-danger-12: rgba(255, 0, 0, 0.12);
160
+ --c-line-30: rgba(255, 255, 255, 0.3);
161
+ --c-contrast-fg: #000000;
162
+ --c-accent-hover: #33ffff;
163
+ --c-warn-hover: #ffff33;
164
+ --c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0));
165
+ }
166
+
167
+ * {
168
+ box-sizing: border-box;
169
+ margin: 0;
170
+ padding: 0;
171
+ }
172
+
173
+ html,
174
+ body,
175
+ #app {
176
+ width: 100%;
177
+ height: 100%;
178
+ overflow: hidden;
179
+ background: var(--c-bg);
180
+ color: var(--c-text);
181
+ font: 14px / 1.55 var(--font);
182
+ -webkit-font-smoothing: antialiased;
183
+ }
184
+
185
+ /* Dot-grid canvas background */
186
+ #app {
187
+ background-image:
188
+ var(--c-canvas-wash),
189
+ radial-gradient(circle, var(--c-dot-grid) 1px, transparent 1px);
190
+ background-size: auto, 24px 24px;
191
+ }
192
+
193
+ /* Scrollbar styling */
194
+ ::-webkit-scrollbar {
195
+ width: 6px;
196
+ height: 6px;
197
+ }
198
+ ::-webkit-scrollbar-track {
199
+ background: transparent;
200
+ }
201
+ ::-webkit-scrollbar-thumb {
202
+ background: var(--c-line);
203
+ border-radius: 3px;
204
+ }
205
+ ::-webkit-scrollbar-thumb:hover {
206
+ background: var(--c-muted);
207
+ }
208
+
209
+ /* Node card shared styles */
210
+ .canvas-node {
211
+ position: absolute;
212
+ background: var(--c-panel);
213
+ border: 1px solid var(--c-line);
214
+ border-radius: var(--radius);
215
+ box-shadow: 0 4px 24px var(--c-shadow);
216
+ display: flex;
217
+ flex-direction: column;
218
+ overflow: hidden;
219
+ transition: box-shadow 0.15s ease;
220
+ contain: layout style paint;
221
+ }
222
+
223
+ .canvas-node:hover {
224
+ box-shadow: 0 6px 32px var(--c-shadow);
225
+ }
226
+
227
+ .canvas-node.active {
228
+ border-color: var(--c-accent);
229
+ box-shadow: 0 0 0 1px var(--c-accent), 0 6px 32px var(--c-glow-accent);
230
+ }
231
+
232
+ .canvas-node.neighbor {
233
+ border-color: var(--c-accent-40);
234
+ box-shadow: 0 0 0 1px var(--c-accent-30), 0 4px 20px var(--c-accent-15);
235
+ transition: border-color 0.2s, box-shadow 0.2s;
236
+ }
237
+
238
+ /* Spatial search highlighting — canvas lights up as you type in Cmd+K */
239
+ .canvas-node.search-match {
240
+ border-color: var(--c-accent);
241
+ box-shadow: 0 0 0 2px var(--c-accent), 0 0 20px var(--c-accent-30), 0 0 40px var(--c-accent-15);
242
+ animation: search-pulse 1.5s ease-in-out infinite;
243
+ }
244
+ @keyframes search-pulse {
245
+ 0%, 100% { box-shadow: 0 0 0 2px var(--c-accent), 0 0 20px var(--c-accent-30), 0 0 40px var(--c-accent-15); }
246
+ 50% { box-shadow: 0 0 0 2px var(--c-accent), 0 0 30px var(--c-accent-40), 0 0 60px var(--c-accent-25); }
247
+ }
248
+ .canvas-node.search-dimmed {
249
+ opacity: 0.25;
250
+ transition: opacity 0.2s;
251
+ }
252
+
253
+ /* ── Connection port handles (drag-to-connect) ───────────── */
254
+ .node-port {
255
+ position: absolute;
256
+ width: 10px;
257
+ height: 10px;
258
+ border-radius: 50%;
259
+ background: var(--c-accent);
260
+ border: 2px solid var(--c-panel);
261
+ opacity: 0;
262
+ cursor: crosshair;
263
+ z-index: 10;
264
+ transition: opacity 0.15s, transform 0.15s;
265
+ transform: translate(-50%, -50%) scale(0.6);
266
+ pointer-events: auto;
267
+ }
268
+ .canvas-node:hover .node-port {
269
+ opacity: 1;
270
+ transform: translate(-50%, -50%) scale(1);
271
+ }
272
+ .node-port:hover {
273
+ background: var(--c-accent-hover);
274
+ transform: translate(-50%, -50%) scale(1.3);
275
+ }
276
+ .node-port-top { top: 0; left: 50%; }
277
+ .node-port-bottom { bottom: 0; left: 50%; transform: translate(-50%, 50%) scale(0.6); }
278
+ .node-port-left { left: 0; top: 50%; }
279
+ .node-port-right { right: 0; top: 50%; transform: translate(50%, -50%) scale(0.6); }
280
+ .canvas-node:hover .node-port-bottom { transform: translate(-50%, 50%) scale(1); }
281
+ .canvas-node:hover .node-port-right { transform: translate(50%, -50%) scale(1); }
282
+ .node-port-bottom:hover { transform: translate(-50%, 50%) scale(1.3); }
283
+ .node-port-right:hover { transform: translate(50%, -50%) scale(1.3); }
284
+
285
+ .canvas-node .node-titlebar {
286
+ display: flex;
287
+ align-items: center;
288
+ gap: calc(8px * var(--node-chrome-scale, 1));
289
+ padding: calc(8px * var(--node-chrome-scale, 1)) calc(12px * var(--node-chrome-scale, 1));
290
+ background: var(--c-panel-overlay);
291
+ border-bottom: 1px solid var(--c-line);
292
+ cursor: grab;
293
+ user-select: none;
294
+ flex-shrink: 0;
295
+ }
296
+
297
+ .canvas-node .node-titlebar:active {
298
+ cursor: grabbing;
299
+ }
300
+
301
+ .canvas-node .node-title {
302
+ font-size: calc(12px * var(--node-chrome-scale, 1));
303
+ font-weight: 600;
304
+ color: var(--c-muted);
305
+ white-space: nowrap;
306
+ overflow: hidden;
307
+ text-overflow: ellipsis;
308
+ flex: 1;
309
+ min-width: 0;
310
+ }
311
+
312
+ .canvas-node .node-type-icon {
313
+ display: inline-flex;
314
+ align-items: center;
315
+ justify-content: center;
316
+ width: calc(18px * var(--node-chrome-scale, 1));
317
+ height: calc(18px * var(--node-chrome-scale, 1));
318
+ border-radius: calc(4px * var(--node-chrome-scale, 1));
319
+ color: var(--c-accent);
320
+ background: var(--c-accent-10);
321
+ flex-shrink: 0;
322
+ }
323
+
324
+ .canvas-node .node-type-badge {
325
+ font-size: calc(10px * var(--node-chrome-scale, 1));
326
+ padding: calc(1px * var(--node-chrome-scale, 1)) calc(6px * var(--node-chrome-scale, 1));
327
+ border-radius: calc(4px * var(--node-chrome-scale, 1));
328
+ background: var(--c-accent-12);
329
+ color: var(--c-accent);
330
+ text-transform: uppercase;
331
+ letter-spacing: 0.04em;
332
+ flex-shrink: 0;
333
+ }
334
+
335
+ .canvas-node .node-controls {
336
+ display: flex;
337
+ align-items: center;
338
+ gap: calc(4px * var(--node-chrome-scale, 1));
339
+ flex-shrink: 0;
340
+ }
341
+
342
+ .canvas-node .node-controls button {
343
+ background: none;
344
+ border: none;
345
+ color: var(--c-muted);
346
+ cursor: pointer;
347
+ display: inline-flex;
348
+ align-items: center;
349
+ justify-content: center;
350
+ min-width: calc(22px * var(--node-chrome-scale, 1));
351
+ min-height: calc(22px * var(--node-chrome-scale, 1));
352
+ padding: calc(2px * var(--node-chrome-scale, 1)) calc(4px * var(--node-chrome-scale, 1));
353
+ font-size: calc(14px * var(--node-chrome-scale, 1));
354
+ line-height: 1;
355
+ border-radius: calc(3px * var(--node-chrome-scale, 1));
356
+ }
357
+
358
+ .canvas-node .node-controls button:hover {
359
+ background: var(--c-surface-hover);
360
+ color: var(--c-text);
361
+ }
362
+
363
+ .canvas-node .node-body {
364
+ flex: 1;
365
+ overflow: auto;
366
+ padding: 12px;
367
+ min-height: 0;
368
+ }
369
+
370
+ /* Markdown rendered content inside nodes */
371
+ .canvas-node .node-body h1,
372
+ .canvas-node .node-body h2,
373
+ .canvas-node .node-body h3 {
374
+ margin: 0.6em 0 0.3em;
375
+ color: var(--c-text);
376
+ }
377
+
378
+ .canvas-node .node-body h1 {
379
+ font-size: 1.4em;
380
+ }
381
+ .canvas-node .node-body h2 {
382
+ font-size: 1.15em;
383
+ }
384
+ .canvas-node .node-body h3 {
385
+ font-size: 1em;
386
+ }
387
+
388
+ .canvas-node .node-body p {
389
+ margin: 0.4em 0;
390
+ color: var(--c-muted);
391
+ }
392
+ .canvas-node .node-body a {
393
+ color: var(--c-accent);
394
+ text-decoration: none;
395
+ }
396
+ .canvas-node .node-body a:hover {
397
+ text-decoration: underline;
398
+ }
399
+
400
+ .canvas-node .node-body code {
401
+ font-family: var(--mono);
402
+ font-size: 0.9em;
403
+ background: var(--c-surface-hover);
404
+ padding: 2px 5px;
405
+ border-radius: 4px;
406
+ }
407
+
408
+ .canvas-node .node-body pre {
409
+ background: var(--c-shadow);
410
+ padding: 10px 12px;
411
+ border-radius: var(--radius-sm);
412
+ overflow-x: auto;
413
+ margin: 0.5em 0;
414
+ }
415
+
416
+ .canvas-node .node-body pre code {
417
+ background: none;
418
+ padding: 0;
419
+ }
420
+
421
+ .canvas-node .node-body table {
422
+ width: 100%;
423
+ border-collapse: collapse;
424
+ margin: 0.5em 0;
425
+ }
426
+
427
+ .canvas-node .node-body th,
428
+ .canvas-node .node-body td {
429
+ border: 1px solid var(--c-line);
430
+ padding: 6px 10px;
431
+ text-align: left;
432
+ font-size: 0.9em;
433
+ }
434
+
435
+ .canvas-node .node-body th {
436
+ background: var(--c-surface-th);
437
+ font-weight: 600;
438
+ }
439
+
440
+ /* HUD layer — fixed row: [left-dock] [toolbar] [right-dock] */
441
+ .hud-layer {
442
+ position: fixed;
443
+ top: 12px;
444
+ left: 12px;
445
+ right: 12px;
446
+ display: flex;
447
+ align-items: flex-start;
448
+ justify-content: center;
449
+ gap: 8px;
450
+ z-index: 9999;
451
+ pointer-events: none;
452
+ }
453
+ .hud-layer > * {
454
+ pointer-events: auto;
455
+ }
456
+ .hud-left,
457
+ .hud-right {
458
+ display: flex;
459
+ gap: 8px;
460
+ }
461
+
462
+ /* Toolbar */
463
+ .canvas-toolbar {
464
+ display: flex;
465
+ align-items: center;
466
+ gap: 6px;
467
+ padding: 6px 10px;
468
+ background: var(--c-panel-glass);
469
+ backdrop-filter: blur(12px);
470
+ border: 1px solid var(--c-line);
471
+ border-radius: var(--radius);
472
+ flex-shrink: 0;
473
+ }
474
+
475
+ .toolbar-tooltip-anchor {
476
+ position: relative;
477
+ display: inline-flex;
478
+ align-items: center;
479
+ }
480
+
481
+ .toolbar-tooltip-anchor-start .toolbar-tooltip {
482
+ left: 0;
483
+ transform: translateX(0) translateY(6px);
484
+ }
485
+
486
+ .toolbar-tooltip-anchor-end .toolbar-tooltip {
487
+ left: auto;
488
+ right: 0;
489
+ transform: translateX(0) translateY(6px);
490
+ }
491
+
492
+ .toolbar-tooltip {
493
+ position: absolute;
494
+ left: 50%;
495
+ top: calc(100% + 10px);
496
+ transform: translateX(-50%) translateY(6px);
497
+ display: flex;
498
+ flex-direction: column;
499
+ gap: 4px;
500
+ min-width: 168px;
501
+ max-width: 240px;
502
+ padding: 10px 12px;
503
+ background: color-mix(in srgb, var(--c-panel) 92%, black 8%);
504
+ border: 1px solid color-mix(in srgb, var(--c-line) 78%, var(--c-accent) 22%);
505
+ border-radius: 10px;
506
+ box-shadow: 0 14px 36px var(--c-shadow-heavy), 0 0 0 1px var(--c-accent-8);
507
+ backdrop-filter: blur(14px);
508
+ color: var(--c-text);
509
+ font-size: 12px;
510
+ line-height: 1.35;
511
+ white-space: normal;
512
+ opacity: 0;
513
+ pointer-events: none;
514
+ z-index: 10010;
515
+ transition: opacity 0.14s ease, transform 0.14s ease;
516
+ }
517
+
518
+ .toolbar-tooltip::after {
519
+ content: '';
520
+ position: absolute;
521
+ left: 50%;
522
+ top: -5px;
523
+ width: 10px;
524
+ height: 10px;
525
+ background: inherit;
526
+ border-top: 1px solid color-mix(in srgb, var(--c-line) 78%, var(--c-accent) 22%);
527
+ border-left: 1px solid color-mix(in srgb, var(--c-line) 78%, var(--c-accent) 22%);
528
+ transform: translateX(-50%) rotate(45deg);
529
+ }
530
+
531
+ .toolbar-tooltip-anchor-start .toolbar-tooltip::after {
532
+ left: 18px;
533
+ transform: rotate(45deg);
534
+ }
535
+
536
+ .toolbar-tooltip-anchor-end .toolbar-tooltip::after {
537
+ left: auto;
538
+ right: 18px;
539
+ transform: rotate(45deg);
540
+ }
541
+
542
+ .toolbar-tooltip-anchor:hover .toolbar-tooltip,
543
+ .toolbar-tooltip-anchor > :focus-visible + .toolbar-tooltip {
544
+ opacity: 1;
545
+ transform: translateX(-50%) translateY(0);
546
+ }
547
+
548
+ .toolbar-tooltip-anchor-start:hover .toolbar-tooltip,
549
+ .toolbar-tooltip-anchor-start > :focus-visible + .toolbar-tooltip,
550
+ .toolbar-tooltip-anchor-end:hover .toolbar-tooltip,
551
+ .toolbar-tooltip-anchor-end > :focus-visible + .toolbar-tooltip {
552
+ transform: translateX(0) translateY(0);
553
+ }
554
+
555
+ .toolbar-tooltip-label {
556
+ font-size: 13px;
557
+ font-weight: 600;
558
+ letter-spacing: 0.01em;
559
+ color: var(--c-text);
560
+ }
561
+
562
+ .toolbar-tooltip-meta {
563
+ display: flex;
564
+ align-items: center;
565
+ justify-content: space-between;
566
+ gap: 10px;
567
+ color: var(--c-text-soft);
568
+ }
569
+
570
+ .toolbar-tooltip-shortcut {
571
+ display: inline-flex;
572
+ align-items: center;
573
+ justify-content: center;
574
+ min-height: 20px;
575
+ padding: 2px 7px;
576
+ border-radius: 999px;
577
+ border: 1px solid var(--c-accent-25);
578
+ background: var(--c-accent-10);
579
+ color: var(--c-accent);
580
+ font: 11px/1 var(--mono);
581
+ white-space: nowrap;
582
+ }
583
+
584
+ .canvas-toolbar button {
585
+ background: none;
586
+ border: 1px solid transparent;
587
+ color: var(--c-muted);
588
+ padding: 6px 10px;
589
+ border-radius: var(--radius-sm);
590
+ font: inherit;
591
+ font-size: 14px;
592
+ cursor: pointer;
593
+ }
594
+
595
+ .canvas-toolbar button:hover {
596
+ background: var(--c-surface-hover);
597
+ color: var(--c-text);
598
+ border-color: var(--c-line);
599
+ }
600
+
601
+ .canvas-toolbar .separator {
602
+ width: 1px;
603
+ height: 20px;
604
+ background: var(--c-line);
605
+ }
606
+
607
+ .canvas-toolbar .canvas-brand {
608
+ display: inline-flex;
609
+ align-items: center;
610
+ justify-content: center;
611
+ width: 28px;
612
+ height: 28px;
613
+ color: var(--c-accent);
614
+ flex-shrink: 0;
615
+ }
616
+
617
+ .canvas-toolbar .connection-dot {
618
+ width: 8px;
619
+ height: 8px;
620
+ border-radius: 50%;
621
+ flex-shrink: 0;
622
+ }
623
+
624
+ .canvas-toolbar .connection-dot.connected {
625
+ background: var(--c-ok);
626
+ }
627
+ .canvas-toolbar .connection-dot.connecting {
628
+ background: var(--c-warn);
629
+ animation: pulse 1.5s infinite;
630
+ }
631
+ .canvas-toolbar .connection-dot.disconnected {
632
+ background: var(--c-danger);
633
+ }
634
+
635
+ @keyframes pulse {
636
+ 0%,
637
+ 100% {
638
+ opacity: 1;
639
+ }
640
+ 50% {
641
+ opacity: 0.4;
642
+ }
643
+ }
644
+
645
+ .toolbar-group {
646
+ display: flex;
647
+ align-items: center;
648
+ gap: 6px;
649
+ flex-shrink: 0;
650
+ }
651
+
652
+ .canvas-toolbar button svg {
653
+ display: block;
654
+ }
655
+
656
+ @media (max-width: 900px) {
657
+ .toolbar-tooltip {
658
+ min-width: 150px;
659
+ max-width: 200px;
660
+ padding: 9px 10px;
661
+ font-size: 11px;
662
+ }
663
+
664
+ .toolbar-tooltip-label {
665
+ font-size: 12px;
666
+ }
667
+
668
+ .toolbar-tooltip-meta {
669
+ gap: 8px;
670
+ }
671
+ }
672
+
673
+ /* Raw markdown source editor */
674
+ .md-editor-split {
675
+ display: flex;
676
+ height: 100%;
677
+ gap: 1px;
678
+ background: var(--c-line);
679
+ }
680
+
681
+ .md-editor-split textarea {
682
+ flex: 1;
683
+ resize: none;
684
+ border: none;
685
+ background: var(--c-panel-soft);
686
+ color: var(--c-text);
687
+ font: 13px / 1.6 var(--mono);
688
+ padding: 12px;
689
+ outline: none;
690
+ }
691
+
692
+ .md-editor-split .md-preview {
693
+ flex: 1;
694
+ overflow: auto;
695
+ padding: 12px;
696
+ background: var(--c-panel);
697
+ }
698
+
699
+ /* ── Expanded editor layout ────────────────────────────────── */
700
+ .md-editor-expanded {
701
+ display: flex;
702
+ flex-direction: column;
703
+ height: 100%;
704
+ }
705
+
706
+ .md-editor-toolbar {
707
+ display: flex;
708
+ align-items: center;
709
+ justify-content: space-between;
710
+ padding: 6px 12px;
711
+ border-bottom: 1px solid var(--c-line);
712
+ background: var(--c-panel-overlay);
713
+ flex-shrink: 0;
714
+ }
715
+
716
+ .md-toolbar-btn {
717
+ padding: 4px 12px;
718
+ font-size: 12px;
719
+ font-weight: 500;
720
+ background: var(--c-surface-hover);
721
+ border: 1px solid var(--c-line);
722
+ border-radius: var(--radius-sm);
723
+ color: var(--c-muted);
724
+ cursor: pointer;
725
+ font-family: var(--font);
726
+ transition: all 0.12s ease;
727
+ }
728
+
729
+ .md-toolbar-btn:hover {
730
+ background: var(--c-surface-hover);
731
+ color: var(--c-text);
732
+ border-color: var(--c-muted);
733
+ }
734
+
735
+ .md-toolbar-btn-primary {
736
+ background: var(--c-accent-15);
737
+ border-color: var(--c-accent-40);
738
+ color: var(--c-accent);
739
+ }
740
+
741
+ .md-toolbar-btn-primary:hover {
742
+ background: var(--c-accent-25);
743
+ border-color: var(--c-accent);
744
+ }
745
+
746
+ .md-toolbar-btn:disabled {
747
+ opacity: 0.5;
748
+ cursor: default;
749
+ }
750
+
751
+ .md-toolbar-path {
752
+ font-size: 11px;
753
+ color: var(--c-muted);
754
+ }
755
+
756
+ .md-editor-expanded .md-editor-split {
757
+ flex: 1;
758
+ min-height: 0;
759
+ }
760
+
761
+ /* ── Markdown reader mode (expanded view) ──────────────────── */
762
+ .md-reader {
763
+ height: 100%;
764
+ overflow-y: auto;
765
+ display: flex;
766
+ justify-content: center;
767
+ }
768
+
769
+ .md-reader-content {
770
+ max-width: 760px;
771
+ width: 100%;
772
+ padding: 8px 24px 48px;
773
+ font-size: 15px;
774
+ line-height: 1.75;
775
+ color: var(--c-text);
776
+ }
777
+
778
+ .md-reader-content h1 {
779
+ font-size: 1.7em;
780
+ margin: 1em 0 0.5em;
781
+ padding-bottom: 0.3em;
782
+ border-bottom: 1px solid var(--c-line);
783
+ color: var(--c-text);
784
+ font-weight: 700;
785
+ }
786
+
787
+ .md-reader-content h2 {
788
+ font-size: 1.35em;
789
+ margin: 0.9em 0 0.4em;
790
+ color: var(--c-text);
791
+ font-weight: 600;
792
+ }
793
+
794
+ .md-reader-content h3 {
795
+ font-size: 1.1em;
796
+ margin: 0.7em 0 0.3em;
797
+ color: var(--c-text);
798
+ font-weight: 600;
799
+ }
800
+
801
+ .md-reader-content p {
802
+ margin: 0.6em 0;
803
+ color: var(--c-text);
804
+ }
805
+
806
+ .md-reader-content ul,
807
+ .md-reader-content ol {
808
+ margin: 0.5em 0;
809
+ padding-left: 1.5em;
810
+ color: var(--c-text);
811
+ }
812
+
813
+ .md-reader-content li {
814
+ margin: 0.25em 0;
815
+ }
816
+
817
+ .md-reader-content li::marker {
818
+ color: var(--c-muted);
819
+ }
820
+
821
+ .md-reader-content blockquote {
822
+ border-left: 3px solid var(--c-accent);
823
+ padding: 0.5em 1em;
824
+ margin: 0.8em 0;
825
+ background: var(--c-accent-8);
826
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
827
+ }
828
+
829
+ .md-reader-content blockquote p {
830
+ color: var(--c-muted);
831
+ }
832
+
833
+ .md-reader-content strong {
834
+ color: var(--c-text);
835
+ font-weight: 600;
836
+ }
837
+
838
+ .md-reader-content a {
839
+ color: var(--c-accent);
840
+ text-decoration: none;
841
+ }
842
+
843
+ .md-reader-content a:hover {
844
+ text-decoration: underline;
845
+ }
846
+
847
+ .md-reader-content code {
848
+ font-family: var(--mono);
849
+ font-size: 0.88em;
850
+ background: var(--c-surface-hover);
851
+ padding: 2px 6px;
852
+ border-radius: 4px;
853
+ }
854
+
855
+ .md-reader-content pre {
856
+ background: var(--c-shadow);
857
+ padding: 14px 16px;
858
+ border-radius: var(--radius-sm);
859
+ overflow-x: auto;
860
+ margin: 0.8em 0;
861
+ border: 1px solid var(--c-line-30);
862
+ }
863
+
864
+ .md-reader-content pre code {
865
+ background: none;
866
+ padding: 0;
867
+ }
868
+
869
+ .md-reader-content hr {
870
+ border: none;
871
+ border-top: 1px solid var(--c-line);
872
+ margin: 1.5em 0;
873
+ }
874
+
875
+ /* Reader-mode tables — polished with rounded container */
876
+ .md-reader-content table {
877
+ width: 100%;
878
+ border-collapse: separate;
879
+ border-spacing: 0;
880
+ border: 1px solid var(--c-line);
881
+ border-radius: var(--radius-sm);
882
+ overflow: hidden;
883
+ margin: 1em 0;
884
+ }
885
+
886
+ .md-reader-content th {
887
+ background: var(--c-accent-8);
888
+ font-weight: 600;
889
+ color: var(--c-text);
890
+ padding: 10px 14px;
891
+ border-bottom: 2px solid var(--c-line);
892
+ text-align: left;
893
+ font-size: 0.85em;
894
+ text-transform: uppercase;
895
+ letter-spacing: 0.03em;
896
+ }
897
+
898
+ .md-reader-content td {
899
+ padding: 10px 14px;
900
+ border-bottom: 1px solid var(--c-line-30);
901
+ color: var(--c-text);
902
+ }
903
+
904
+ .md-reader-content th + th,
905
+ .md-reader-content td + td {
906
+ border-left: 1px solid var(--c-line-30);
907
+ }
908
+
909
+ .md-reader-content tr:last-child td {
910
+ border-bottom: none;
911
+ }
912
+
913
+ .md-reader-content tbody tr:hover td {
914
+ background: var(--c-surface-subtle);
915
+ }
916
+
917
+ /* Source-mode FAB in expanded document view */
918
+ .md-edit-fab {
919
+ position: absolute;
920
+ bottom: 16px;
921
+ right: 16px;
922
+ padding: 8px 18px;
923
+ font-size: 13px;
924
+ font-weight: 600;
925
+ background: var(--c-panel-glass);
926
+ backdrop-filter: blur(12px);
927
+ border: 1px solid var(--c-line);
928
+ border-radius: var(--radius);
929
+ color: var(--c-muted);
930
+ cursor: pointer;
931
+ font-family: var(--font);
932
+ transition: all 0.15s ease;
933
+ z-index: 1;
934
+ box-shadow: 0 4px 16px var(--c-shadow);
935
+ }
936
+
937
+ .md-edit-fab:hover {
938
+ background: var(--c-accent-12);
939
+ border-color: var(--c-accent);
940
+ color: var(--c-accent);
941
+ box-shadow: 0 4px 20px var(--c-glow-accent);
942
+ }
943
+
944
+ /* ── Inline WYSIWYG editor (contentEditable on the rendered HTML) ─
945
+ The .md-reader-content styles above already give us the reading
946
+ typography; we just need to strip the browser's contentEditable chrome
947
+ and make the caret visible. */
948
+ .md-reader-editable {
949
+ outline: none;
950
+ caret-color: var(--c-accent);
951
+ cursor: text;
952
+ }
953
+
954
+ .md-reader-editable:focus {
955
+ outline: none;
956
+ }
957
+
958
+ .md-reader-editable::selection,
959
+ .md-reader-editable *::selection {
960
+ background: var(--c-accent-25);
961
+ }
962
+
963
+ /* ── Inline selection toolbar (contentEditable WYSIWYG) ────────── */
964
+ .md-inline-format-bar {
965
+ position: fixed;
966
+ z-index: 10002; /* above the expanded overlay (z-index 10001) */
967
+ display: flex;
968
+ align-items: center;
969
+ gap: 2px;
970
+ padding: 4px 6px;
971
+ background: var(--c-panel-glass);
972
+ backdrop-filter: blur(16px);
973
+ border: 1px solid var(--c-line);
974
+ border-radius: 8px;
975
+ box-shadow: 0 4px 16px var(--c-shadow), 0 0 0 1px var(--c-line-30);
976
+ font-family: var(--font);
977
+ animation: md-inline-format-bar-in 0.1s ease-out;
978
+ }
979
+
980
+ @keyframes md-inline-format-bar-in {
981
+ from { opacity: 0; transform: translateY(4px); }
982
+ to { opacity: 1; transform: translateY(0); }
983
+ }
984
+
985
+ .md-inline-format-btn {
986
+ display: inline-flex;
987
+ align-items: center;
988
+ justify-content: center;
989
+ min-width: 28px;
990
+ height: 28px;
991
+ padding: 0 7px;
992
+ background: none;
993
+ border: 1px solid transparent;
994
+ border-radius: var(--radius-sm);
995
+ font: 600 12px var(--font);
996
+ color: var(--c-text-soft);
997
+ cursor: pointer;
998
+ white-space: nowrap;
999
+ transition: background 0.1s, color 0.1s, border-color 0.1s;
1000
+ }
1001
+
1002
+ .md-inline-format-btn:hover {
1003
+ background: var(--c-surface-hover);
1004
+ color: var(--c-text);
1005
+ border-color: var(--c-line);
1006
+ }
1007
+
1008
+ .md-inline-format-btn:active {
1009
+ background: var(--c-accent-12);
1010
+ color: var(--c-accent);
1011
+ }
1012
+
1013
+ .md-inline-format-divider {
1014
+ width: 1px;
1015
+ height: 18px;
1016
+ background: var(--c-line);
1017
+ margin: 0 3px;
1018
+ flex-shrink: 0;
1019
+ }
1020
+
1021
+ /* ── Markdown Format Bar (floating) ─────────────────────────── */
1022
+ .md-format-bar {
1023
+ position: fixed;
1024
+ z-index: 9999;
1025
+ display: flex;
1026
+ align-items: center;
1027
+ gap: 2px;
1028
+ padding: 4px 6px;
1029
+ background: var(--c-panel-glass);
1030
+ backdrop-filter: blur(16px);
1031
+ border: 1px solid var(--c-line);
1032
+ border-radius: 8px;
1033
+ box-shadow: 0 4px 16px var(--c-shadow), 0 0 0 1px var(--c-line-30);
1034
+ animation: md-format-bar-in 0.12s ease-out;
1035
+ }
1036
+
1037
+ @keyframes md-format-bar-in {
1038
+ from { opacity: 0; transform: translateY(4px); }
1039
+ to { opacity: 1; transform: translateY(0); }
1040
+ }
1041
+
1042
+ .md-format-btn {
1043
+ display: inline-flex;
1044
+ align-items: center;
1045
+ justify-content: center;
1046
+ min-width: 26px;
1047
+ height: 26px;
1048
+ padding: 0 5px;
1049
+ background: none;
1050
+ border: 1px solid transparent;
1051
+ border-radius: var(--radius-sm);
1052
+ font-family: var(--mono);
1053
+ font-size: 12px;
1054
+ font-weight: 600;
1055
+ color: var(--c-muted);
1056
+ cursor: pointer;
1057
+ white-space: nowrap;
1058
+ transition: background 0.1s, color 0.1s, border-color 0.1s;
1059
+ }
1060
+
1061
+ .md-format-btn:hover {
1062
+ background: var(--c-surface-hover);
1063
+ color: var(--c-text);
1064
+ border-color: var(--c-line);
1065
+ }
1066
+
1067
+ .md-format-btn:active {
1068
+ background: var(--c-accent-12);
1069
+ color: var(--c-accent);
1070
+ }
1071
+
1072
+ .md-format-btn-bold { font-weight: 800; }
1073
+ .md-format-btn-italic { font-style: italic; }
1074
+ .md-format-btn-strike { text-decoration: line-through; }
1075
+
1076
+ .md-format-divider {
1077
+ width: 1px;
1078
+ height: 18px;
1079
+ background: var(--c-line);
1080
+ margin: 0 3px;
1081
+ flex-shrink: 0;
1082
+ }
1083
+
1084
+ /* Auto-fit transition */
1085
+ .canvas-node {
1086
+ transition: height 0.2s ease, box-shadow 0.15s ease;
1087
+ }
1088
+
1089
+ /* Node resize handle */
1090
+ .canvas-node .node-resize-handle {
1091
+ position: absolute;
1092
+ bottom: 0;
1093
+ right: 0;
1094
+ width: 16px;
1095
+ height: 16px;
1096
+ cursor: nwse-resize;
1097
+ z-index: 2;
1098
+ }
1099
+
1100
+ .canvas-node .node-resize-handle::after {
1101
+ content: "";
1102
+ position: absolute;
1103
+ bottom: 3px;
1104
+ right: 3px;
1105
+ width: 8px;
1106
+ height: 8px;
1107
+ border-right: 2px solid var(--c-line);
1108
+ border-bottom: 2px solid var(--c-line);
1109
+ opacity: 0.5;
1110
+ }
1111
+
1112
+ .canvas-node:hover .node-resize-handle::after {
1113
+ border-color: var(--c-muted);
1114
+ opacity: 1;
1115
+ }
1116
+
1117
+ /* Pinned node indicator */
1118
+ .canvas-node.pinned {
1119
+ border-style: dashed;
1120
+ }
1121
+
1122
+ .canvas-node .pin-indicator {
1123
+ color: var(--c-accent);
1124
+ font-size: calc(11px * var(--node-chrome-scale, 1));
1125
+ opacity: 0.6;
1126
+ }
1127
+
1128
+ /* Rename input inside title bar */
1129
+ .canvas-node .node-title-input {
1130
+ flex: 1;
1131
+ min-width: 0;
1132
+ font-size: calc(12px * var(--node-chrome-scale, 1));
1133
+ font-weight: 600;
1134
+ color: var(--c-text);
1135
+ background: var(--c-surface-hover);
1136
+ border: 1px solid var(--c-accent);
1137
+ border-radius: calc(3px * var(--node-chrome-scale, 1));
1138
+ padding: calc(1px * var(--node-chrome-scale, 1)) calc(6px * var(--node-chrome-scale, 1));
1139
+ outline: none;
1140
+ font-family: inherit;
1141
+ }
1142
+
1143
+ /* Context menu */
1144
+ .context-menu {
1145
+ background: var(--c-panel-glass);
1146
+ backdrop-filter: blur(12px);
1147
+ border: 1px solid var(--c-line);
1148
+ border-radius: var(--radius-sm);
1149
+ padding: 4px 0;
1150
+ min-width: 220px;
1151
+ box-shadow: 0 8px 32px var(--c-shadow-heavy);
1152
+ }
1153
+
1154
+ .context-menu-item {
1155
+ display: flex;
1156
+ align-items: center;
1157
+ justify-content: space-between;
1158
+ width: 100%;
1159
+ padding: 6px 12px;
1160
+ background: none;
1161
+ border: none;
1162
+ color: var(--c-text);
1163
+ font: inherit;
1164
+ font-size: 12px;
1165
+ cursor: pointer;
1166
+ text-align: left;
1167
+ }
1168
+
1169
+ .context-menu-item:hover {
1170
+ background: var(--c-accent-10);
1171
+ color: var(--c-accent);
1172
+ }
1173
+
1174
+ .context-menu-shortcut {
1175
+ color: var(--c-muted);
1176
+ font-size: 10px;
1177
+ margin-left: 16px;
1178
+ }
1179
+
1180
+ .context-menu-separator {
1181
+ height: 1px;
1182
+ background: var(--c-line);
1183
+ margin: 4px 0;
1184
+ }
1185
+
1186
+ .context-menu-custom {
1187
+ padding: 0;
1188
+ }
1189
+
1190
+ .context-menu-section {
1191
+ display: flex;
1192
+ flex-direction: column;
1193
+ gap: 8px;
1194
+ padding: 8px 12px 10px;
1195
+ }
1196
+
1197
+ .context-menu-section-header {
1198
+ display: flex;
1199
+ align-items: center;
1200
+ justify-content: space-between;
1201
+ gap: 12px;
1202
+ }
1203
+
1204
+ .context-menu-section-label {
1205
+ color: var(--c-muted);
1206
+ font-size: 10px;
1207
+ font-weight: 600;
1208
+ letter-spacing: 0.08em;
1209
+ text-transform: uppercase;
1210
+ }
1211
+
1212
+ .context-menu-reset {
1213
+ background: none;
1214
+ border: none;
1215
+ color: var(--c-muted);
1216
+ cursor: pointer;
1217
+ font: inherit;
1218
+ font-size: 11px;
1219
+ padding: 0;
1220
+ }
1221
+
1222
+ .context-menu-reset:hover {
1223
+ color: var(--c-accent);
1224
+ }
1225
+
1226
+ .context-menu-color-grid {
1227
+ display: grid;
1228
+ gap: 6px;
1229
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1230
+ }
1231
+
1232
+ .context-menu-color-swatch {
1233
+ align-items: center;
1234
+ background: var(--c-surface-subtle);
1235
+ border: 1px solid var(--c-line);
1236
+ border-radius: var(--radius-sm);
1237
+ color: var(--c-text);
1238
+ cursor: pointer;
1239
+ display: inline-flex;
1240
+ font: inherit;
1241
+ font-size: 11px;
1242
+ gap: 8px;
1243
+ justify-content: flex-start;
1244
+ padding: 6px 8px;
1245
+ width: 100%;
1246
+ }
1247
+
1248
+ .context-menu-color-swatch:hover {
1249
+ background: var(--c-accent-8);
1250
+ border-color: var(--c-accent-30);
1251
+ }
1252
+
1253
+ .context-menu-color-swatch.active {
1254
+ border-color: var(--swatch-color, var(--c-accent));
1255
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--swatch-color, var(--c-accent)) 45%, transparent);
1256
+ }
1257
+
1258
+ .context-menu-color-dot {
1259
+ background: var(--swatch-color);
1260
+ border-radius: 999px;
1261
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--swatch-color) 60%, #000 40%);
1262
+ flex: 0 0 auto;
1263
+ height: 10px;
1264
+ width: 10px;
1265
+ }
1266
+
1267
+ .context-menu-color-custom {
1268
+ align-items: center;
1269
+ color: var(--c-muted);
1270
+ display: flex;
1271
+ font-size: 11px;
1272
+ justify-content: space-between;
1273
+ gap: 12px;
1274
+ }
1275
+
1276
+ .context-menu-color-input {
1277
+ appearance: none;
1278
+ background: none;
1279
+ border: none;
1280
+ cursor: pointer;
1281
+ height: 26px;
1282
+ padding: 0;
1283
+ width: 42px;
1284
+ }
1285
+
1286
+ .context-menu-color-input::-webkit-color-swatch-wrapper {
1287
+ padding: 0;
1288
+ }
1289
+
1290
+ .context-menu-color-input::-webkit-color-swatch {
1291
+ border: 1px solid var(--c-line);
1292
+ border-radius: 999px;
1293
+ }
1294
+
1295
+ /* Edge labels */
1296
+ .edge-label {
1297
+ font-family: var(--font);
1298
+ font-size: 11px;
1299
+ pointer-events: none;
1300
+ user-select: none;
1301
+ }
1302
+
1303
+ .edge-label-bg {
1304
+ fill: var(--c-panel-glass);
1305
+ stroke: var(--c-line);
1306
+ stroke-width: 0.5;
1307
+ }
1308
+
1309
+ /* Trace nodes — compact pills for agent tool/subagent visualization */
1310
+ .canvas-node.trace-node {
1311
+ border-radius: 28px;
1312
+ min-height: 0;
1313
+ }
1314
+
1315
+ .canvas-node.trace-node .node-titlebar {
1316
+ display: none;
1317
+ }
1318
+
1319
+ .canvas-node.trace-node .node-resize-handle {
1320
+ display: none;
1321
+ }
1322
+
1323
+ .canvas-node.trace-node .node-body {
1324
+ padding: 0;
1325
+ display: flex;
1326
+ align-items: center;
1327
+ }
1328
+
1329
+ .canvas-node.trace-node.trace-running {
1330
+ border-color: var(--c-accent);
1331
+ animation: trace-pulse 2s ease-in-out infinite;
1332
+ }
1333
+
1334
+ @keyframes trace-pulse {
1335
+ 0%,
1336
+ 100% {
1337
+ box-shadow: 0 0 0 0 var(--c-accent-30);
1338
+ }
1339
+ 50% {
1340
+ box-shadow: 0 0 0 4px var(--c-accent-15);
1341
+ }
1342
+ }
1343
+
1344
+ /* Docked node — compact toolbar-flanking panel */
1345
+ .docked-node {
1346
+ min-width: 200px;
1347
+ max-width: 360px;
1348
+ background: var(--c-panel-glass);
1349
+ backdrop-filter: blur(16px);
1350
+ border: 1px solid var(--c-line);
1351
+ border-radius: var(--radius);
1352
+ box-shadow: 0 12px 40px var(--c-shadow-heavy), 0 0 0 1px rgba(255, 255, 255, 0.04);
1353
+ display: flex;
1354
+ flex-direction: column;
1355
+ overflow: hidden;
1356
+ }
1357
+
1358
+ .docked-node:has(.context-body) {
1359
+ width: 320px;
1360
+ max-width: 320px;
1361
+ }
1362
+
1363
+ .docked-node-header {
1364
+ display: flex;
1365
+ align-items: center;
1366
+ gap: 6px;
1367
+ padding: 6px 10px;
1368
+ border-bottom: 1px solid var(--c-line);
1369
+ user-select: none;
1370
+ flex-shrink: 0;
1371
+ }
1372
+
1373
+ .docked-node-header .node-type-badge {
1374
+ font-size: 10px;
1375
+ padding: 1px 6px;
1376
+ border-radius: 4px;
1377
+ background: var(--c-accent-12);
1378
+ color: var(--c-accent);
1379
+ text-transform: uppercase;
1380
+ letter-spacing: 0.04em;
1381
+ flex-shrink: 0;
1382
+ }
1383
+
1384
+ .docked-node-controls {
1385
+ display: flex;
1386
+ gap: 4px;
1387
+ margin-left: auto;
1388
+ flex-shrink: 0;
1389
+ }
1390
+
1391
+ .docked-node-controls button {
1392
+ background: none;
1393
+ border: none;
1394
+ color: var(--c-muted);
1395
+ cursor: pointer;
1396
+ padding: 2px 4px;
1397
+ font-size: 14px;
1398
+ line-height: 1;
1399
+ border-radius: 3px;
1400
+ }
1401
+
1402
+ .docked-node-controls button:hover {
1403
+ background: var(--c-surface-hover);
1404
+ color: var(--c-text);
1405
+ }
1406
+
1407
+ .docked-node-body {
1408
+ padding: 8px 10px;
1409
+ max-height: 200px;
1410
+ overflow-y: auto;
1411
+ }
1412
+
1413
+ .docked-node-body.context-body {
1414
+ max-height: 420px;
1415
+ padding: 10px 14px;
1416
+ }
1417
+
1418
+ /* MCP app iframe */
1419
+ .mcp-app-frame {
1420
+ width: 100%;
1421
+ height: 100%;
1422
+ border: none;
1423
+ background: var(--c-panel-soft);
1424
+ border-radius: 0 0 calc(var(--radius) - 1px) calc(var(--radius) - 1px);
1425
+ }
1426
+
1427
+ /* ── Prompt nodes ──────────────────────────────────────────── */
1428
+ .canvas-node:has(.prompt-node-inner) {
1429
+ border-color: var(--c-accent-30);
1430
+ }
1431
+
1432
+ .canvas-node:has(.prompt-node-inner) .node-type-badge {
1433
+ background: var(--c-accent-15);
1434
+ color: var(--c-accent);
1435
+ }
1436
+
1437
+ /* ── Response nodes ────────────────────────────────────────── */
1438
+ .canvas-node:has(.response-node-inner) {
1439
+ border-color: var(--c-ok-25);
1440
+ }
1441
+
1442
+ .canvas-node:has(.response-node-inner) .node-type-badge {
1443
+ background: var(--c-ok-12);
1444
+ color: var(--c-ok);
1445
+ }
1446
+
1447
+ /* Streaming pulse animation for response nodes */
1448
+ @keyframes response-stream-pulse {
1449
+ 0%,
1450
+ 100% {
1451
+ opacity: 0.3;
1452
+ transform: translateX(-100%);
1453
+ }
1454
+ 50% {
1455
+ opacity: 1;
1456
+ transform: translateX(100%);
1457
+ }
1458
+ }
1459
+
1460
+ /* ── Multi-node selection ─────────────────────────────────── */
1461
+ .canvas-node.selected {
1462
+ border-color: var(--c-accent);
1463
+ box-shadow: 0 0 0 2px var(--c-accent), 0 6px 32px var(--c-accent-25);
1464
+ }
1465
+
1466
+ /* Lasso rectangle overlay */
1467
+ .lasso-rect {
1468
+ background: var(--c-accent-8);
1469
+ border: 1px solid var(--c-accent);
1470
+ border-radius: 2px;
1471
+ z-index: 9998;
1472
+ }
1473
+
1474
+ /* ── Drop Zone (file drag-and-drop) ─────────────────────────── */
1475
+ .drop-zone-overlay {
1476
+ position: absolute;
1477
+ inset: 0;
1478
+ z-index: 9997;
1479
+ pointer-events: none;
1480
+ border: 2px dashed var(--c-accent);
1481
+ border-radius: 8px;
1482
+ background: var(--c-accent-8);
1483
+ animation: drop-zone-pulse 1.5s ease-in-out infinite;
1484
+ }
1485
+
1486
+ @keyframes drop-zone-pulse {
1487
+ 0%, 100% { background: var(--c-accent-8); }
1488
+ 50% { background: var(--c-accent-12); }
1489
+ }
1490
+
1491
+ .drop-zone-indicator {
1492
+ position: absolute;
1493
+ top: 50%;
1494
+ left: 50%;
1495
+ transform: translate(-50%, -50%);
1496
+ display: flex;
1497
+ flex-direction: column;
1498
+ align-items: center;
1499
+ gap: 8px;
1500
+ padding: 20px 32px;
1501
+ background: var(--c-panel-glass);
1502
+ backdrop-filter: blur(16px);
1503
+ border: 1px solid var(--c-accent-30);
1504
+ border-radius: 12px;
1505
+ box-shadow: 0 4px 24px var(--c-shadow), 0 0 24px var(--c-glow-accent);
1506
+ }
1507
+
1508
+ .drop-zone-icon {
1509
+ font-size: 28px;
1510
+ font-weight: 300;
1511
+ color: var(--c-accent);
1512
+ width: 44px;
1513
+ height: 44px;
1514
+ display: flex;
1515
+ align-items: center;
1516
+ justify-content: center;
1517
+ border: 2px dashed var(--c-accent-40);
1518
+ border-radius: 50%;
1519
+ }
1520
+
1521
+ .drop-zone-label {
1522
+ font-size: 13px;
1523
+ color: var(--c-text-soft);
1524
+ white-space: nowrap;
1525
+ }
1526
+
1527
+ /* ── Snap Alignment Guides ──────────────────────────────────── */
1528
+ .snap-guide-line {
1529
+ stroke: var(--c-accent);
1530
+ stroke-width: 1;
1531
+ stroke-dasharray: 4 3;
1532
+ opacity: 0.7;
1533
+ }
1534
+
1535
+ .snap-guides-svg {
1536
+ z-index: 9999;
1537
+ }
1538
+
1539
+ /* Selection action bar — fixed bottom-center */
1540
+ .selection-bar {
1541
+ position: fixed;
1542
+ bottom: 60px;
1543
+ left: 50%;
1544
+ transform: translateX(-50%);
1545
+ display: flex;
1546
+ align-items: center;
1547
+ gap: 8px;
1548
+ padding: 8px 14px;
1549
+ background: var(--c-panel-glass);
1550
+ backdrop-filter: blur(12px);
1551
+ border: 1px solid var(--c-accent);
1552
+ border-radius: var(--radius);
1553
+ box-shadow: 0 8px 32px var(--c-shadow), 0 0 0 1px var(--c-accent-15);
1554
+ z-index: 10001;
1555
+ white-space: nowrap;
1556
+ }
1557
+
1558
+ .selection-bar-count {
1559
+ font-size: 12px;
1560
+ font-weight: 600;
1561
+ color: var(--c-accent);
1562
+ }
1563
+
1564
+ .selection-bar-btn {
1565
+ padding: 5px 12px;
1566
+ font-size: 12px;
1567
+ font-weight: 600;
1568
+ background: var(--c-accent-10);
1569
+ border: 1px solid var(--c-accent-30);
1570
+ border-radius: var(--radius-sm);
1571
+ color: var(--c-accent);
1572
+ cursor: pointer;
1573
+ font-family: var(--font);
1574
+ }
1575
+
1576
+ .selection-bar-btn:hover {
1577
+ background: var(--c-accent-25);
1578
+ border-color: var(--c-accent);
1579
+ }
1580
+
1581
+ .selection-bar-ask {
1582
+ background: var(--c-accent);
1583
+ color: var(--c-contrast-fg);
1584
+ border-color: var(--c-accent);
1585
+ }
1586
+
1587
+ .selection-bar-ask:hover {
1588
+ background: var(--c-accent-hover);
1589
+ border-color: var(--c-accent-hover);
1590
+ }
1591
+
1592
+ .selection-bar-clear {
1593
+ background: none;
1594
+ border: none;
1595
+ color: var(--c-muted);
1596
+ font-size: 16px;
1597
+ padding: 2px 6px;
1598
+ line-height: 1;
1599
+ }
1600
+
1601
+ .selection-bar-clear:hover {
1602
+ color: var(--c-text);
1603
+ background: var(--c-surface-hover);
1604
+ }
1605
+
1606
+ /* "Pin as context" button in selection bar */
1607
+ .selection-bar-pin-ctx {
1608
+ background: var(--c-warn-12);
1609
+ border-color: var(--c-warn-30);
1610
+ color: var(--c-warn);
1611
+ }
1612
+
1613
+ .selection-bar-pin-ctx:hover {
1614
+ background: var(--c-warn-22);
1615
+ border-color: var(--c-warn);
1616
+ }
1617
+
1618
+ /* ── Context-pinned nodes — amber glow ───────────────────────── */
1619
+ .canvas-node.context-pinned {
1620
+ border-color: var(--c-warn-60);
1621
+ box-shadow: 0 0 0 2px var(--c-warn), 0 0 8px var(--c-warn-30);
1622
+ }
1623
+
1624
+ .canvas-node.context-pinned .node-type-badge {
1625
+ background: var(--c-warn-15);
1626
+ color: var(--c-warn);
1627
+ }
1628
+
1629
+ :root[data-theme="light"] .canvas-node.context-pinned {
1630
+ border-color: #4BBCFF;
1631
+ box-shadow: 0 0 0 2px #4BBCFF, 0 0 12px rgba(75, 188, 255, 0.28);
1632
+ }
1633
+
1634
+ :root[data-theme="light"] .canvas-node.context-pinned .node-type-badge {
1635
+ background: rgba(75, 188, 255, 0.14);
1636
+ color: #1588CE;
1637
+ }
1638
+
1639
+ /* ── Attention layer — human-facing semantic feedback ───────── */
1640
+ .canvas-node.attention-focus-primary {
1641
+ box-shadow:
1642
+ 0 0 0 1px color-mix(in srgb, var(--c-warn) 72%, transparent),
1643
+ 0 12px 34px color-mix(in srgb, var(--c-warn) 18%, transparent),
1644
+ inset 0 0 0 1px color-mix(in srgb, var(--c-warn) 28%, transparent);
1645
+ }
1646
+
1647
+ .canvas-node.attention-focus-primary .node-titlebar {
1648
+ background:
1649
+ linear-gradient(90deg, color-mix(in srgb, var(--c-warn) 12%, transparent), transparent 68%),
1650
+ var(--c-panel-soft);
1651
+ }
1652
+
1653
+ :root[data-theme="light"] .canvas-node.attention-focus-primary {
1654
+ box-shadow:
1655
+ 0 0 0 1px rgba(75, 188, 255, 0.72),
1656
+ 0 12px 34px rgba(75, 188, 255, 0.2),
1657
+ inset 0 0 0 1px rgba(75, 188, 255, 0.18);
1658
+ }
1659
+
1660
+ :root[data-theme="light"] .canvas-node.attention-focus-primary .node-titlebar {
1661
+ background:
1662
+ linear-gradient(90deg, rgba(75, 188, 255, 0.14), transparent 68%),
1663
+ var(--c-panel-soft);
1664
+ }
1665
+
1666
+ .canvas-node.attention-focus-secondary {
1667
+ box-shadow:
1668
+ 0 0 0 1px color-mix(in srgb, var(--c-warn) 30%, transparent),
1669
+ 0 8px 24px color-mix(in srgb, var(--c-warn) 10%, transparent);
1670
+ }
1671
+
1672
+ .canvas-node.attention-focus-secondary .node-type-badge {
1673
+ background: color-mix(in srgb, var(--c-warn) 10%, transparent);
1674
+ color: color-mix(in srgb, var(--c-warn) 88%, var(--c-text) 12%);
1675
+ }
1676
+
1677
+ :root[data-theme="light"] .canvas-node.attention-focus-secondary {
1678
+ box-shadow:
1679
+ 0 0 0 1px rgba(75, 188, 255, 0.32),
1680
+ 0 8px 24px rgba(75, 188, 255, 0.12);
1681
+ }
1682
+
1683
+ :root[data-theme="light"] .canvas-node.attention-focus-secondary .node-type-badge {
1684
+ background: rgba(75, 188, 255, 0.12);
1685
+ color: #1588CE;
1686
+ }
1687
+
1688
+ .canvas-node.attention-pulse {
1689
+ animation: attention-node-pulse 0.9s ease;
1690
+ }
1691
+
1692
+ :root[data-theme="light"] .canvas-node.attention-pulse {
1693
+ animation-name: attention-node-pulse-light;
1694
+ }
1695
+
1696
+ @keyframes attention-node-pulse {
1697
+ 0% {
1698
+ transform: translateZ(0) scale(1);
1699
+ box-shadow:
1700
+ 0 0 0 0 color-mix(in srgb, var(--c-warn) 0%, transparent),
1701
+ 0 4px 24px var(--c-shadow);
1702
+ }
1703
+ 38% {
1704
+ transform: translateZ(0) scale(1.012);
1705
+ box-shadow:
1706
+ 0 0 0 3px color-mix(in srgb, var(--c-warn) 35%, transparent),
1707
+ 0 16px 34px color-mix(in srgb, var(--c-warn) 16%, transparent);
1708
+ }
1709
+ 100% {
1710
+ transform: translateZ(0) scale(1);
1711
+ }
1712
+ }
1713
+
1714
+ @keyframes attention-node-pulse-light {
1715
+ 0% {
1716
+ transform: translateZ(0) scale(1);
1717
+ box-shadow:
1718
+ 0 0 0 0 rgba(75, 188, 255, 0),
1719
+ 0 4px 24px var(--c-shadow);
1720
+ }
1721
+ 38% {
1722
+ transform: translateZ(0) scale(1.012);
1723
+ box-shadow:
1724
+ 0 0 0 3px rgba(75, 188, 255, 0.32),
1725
+ 0 16px 34px rgba(75, 188, 255, 0.18);
1726
+ }
1727
+ 100% {
1728
+ transform: translateZ(0) scale(1);
1729
+ }
1730
+ }
1731
+
1732
+ .attention-field-layer {
1733
+ position: absolute;
1734
+ inset: 0;
1735
+ pointer-events: none;
1736
+ z-index: 0;
1737
+ }
1738
+
1739
+ .attention-field-region,
1740
+ .attention-field-node {
1741
+ position: absolute;
1742
+ pointer-events: none;
1743
+ }
1744
+
1745
+ .attention-field-region {
1746
+ background:
1747
+ radial-gradient(circle at 25% 30%, color-mix(in srgb, var(--c-warn) 16%, transparent), transparent 62%),
1748
+ linear-gradient(135deg, color-mix(in srgb, var(--c-warn) 10%, transparent), color-mix(in srgb, var(--c-accent) 5%, transparent));
1749
+ border: 1px solid color-mix(in srgb, var(--c-warn) 22%, transparent);
1750
+ opacity: 0.8;
1751
+ filter: blur(18px);
1752
+ }
1753
+
1754
+ .attention-field-node.attention-field-primary {
1755
+ border: 1px solid color-mix(in srgb, var(--c-warn) 38%, transparent);
1756
+ background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--c-warn) 16%, transparent), transparent 72%);
1757
+ box-shadow: 0 0 38px color-mix(in srgb, var(--c-warn) 18%, transparent);
1758
+ }
1759
+
1760
+ .attention-field-node.attention-field-secondary {
1761
+ border: 1px solid color-mix(in srgb, var(--c-warn) 18%, transparent);
1762
+ background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--c-warn) 9%, transparent), transparent 74%);
1763
+ box-shadow: 0 0 24px color-mix(in srgb, var(--c-warn) 10%, transparent);
1764
+ }
1765
+
1766
+ :root[data-theme="light"] .attention-field-region {
1767
+ background:
1768
+ radial-gradient(circle at 25% 30%, rgba(75, 188, 255, 0.16), transparent 62%),
1769
+ linear-gradient(135deg, rgba(75, 188, 255, 0.1), rgba(75, 188, 255, 0.05));
1770
+ border: 1px solid rgba(75, 188, 255, 0.22);
1771
+ }
1772
+
1773
+ :root[data-theme="light"] .attention-field-node.attention-field-primary {
1774
+ border: 1px solid rgba(75, 188, 255, 0.4);
1775
+ background: radial-gradient(circle at 50% 50%, rgba(75, 188, 255, 0.18), transparent 72%);
1776
+ box-shadow: 0 0 38px rgba(75, 188, 255, 0.2);
1777
+ }
1778
+
1779
+ :root[data-theme="light"] .attention-field-node.attention-field-secondary {
1780
+ border: 1px solid rgba(75, 188, 255, 0.18);
1781
+ background: radial-gradient(circle at 50% 50%, rgba(75, 188, 255, 0.1), transparent 74%);
1782
+ box-shadow: 0 0 24px rgba(75, 188, 255, 0.12);
1783
+ }
1784
+
1785
+ .attention-toast {
1786
+ position: fixed;
1787
+ top: 76px;
1788
+ right: 18px;
1789
+ max-width: min(260px, calc(100vw - 24px));
1790
+ display: inline-flex;
1791
+ align-items: center;
1792
+ gap: 8px;
1793
+ padding: 6px 12px 6px 10px;
1794
+ background: color-mix(in srgb, var(--c-panel-glass) 96%, transparent);
1795
+ backdrop-filter: blur(14px);
1796
+ border: 1px solid color-mix(in srgb, var(--c-line) 76%, var(--c-warn) 24%);
1797
+ border-radius: 999px;
1798
+ box-shadow: 0 8px 22px var(--c-shadow);
1799
+ color: var(--c-text);
1800
+ font: inherit;
1801
+ cursor: pointer;
1802
+ z-index: 10003;
1803
+ animation: attention-toast-in 180ms ease-out;
1804
+ }
1805
+
1806
+ .attention-toast:hover {
1807
+ background: color-mix(in srgb, var(--c-panel-glass) 100%, transparent);
1808
+ box-shadow: 0 10px 28px var(--c-shadow-heavy);
1809
+ }
1810
+
1811
+ .attention-toast:focus-visible {
1812
+ outline: 2px solid var(--c-accent);
1813
+ outline-offset: 2px;
1814
+ }
1815
+
1816
+ @keyframes attention-toast-in {
1817
+ from {
1818
+ opacity: 0;
1819
+ transform: translateY(-6px);
1820
+ }
1821
+ to {
1822
+ opacity: 1;
1823
+ transform: translateY(0);
1824
+ }
1825
+ }
1826
+
1827
+ .attention-toast-dot {
1828
+ width: 8px;
1829
+ height: 8px;
1830
+ border-radius: 50%;
1831
+ background: currentColor;
1832
+ flex-shrink: 0;
1833
+ box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 28%, transparent);
1834
+ }
1835
+
1836
+ .attention-toast-title {
1837
+ font-size: 12px;
1838
+ font-weight: 600;
1839
+ line-height: 1.2;
1840
+ letter-spacing: -0.005em;
1841
+ white-space: nowrap;
1842
+ overflow: hidden;
1843
+ text-overflow: ellipsis;
1844
+ max-width: 200px;
1845
+ }
1846
+
1847
+ .attention-history {
1848
+ position: fixed;
1849
+ top: 146px;
1850
+ right: 18px;
1851
+ width: min(320px, calc(100vw - 24px));
1852
+ display: flex;
1853
+ flex-direction: column;
1854
+ gap: 10px;
1855
+ padding: 14px;
1856
+ background: color-mix(in srgb, var(--c-panel-glass) 96%, transparent);
1857
+ backdrop-filter: blur(16px);
1858
+ border: 1px solid color-mix(in srgb, var(--c-line) 82%, var(--c-warn) 18%);
1859
+ border-radius: 18px;
1860
+ box-shadow: 0 14px 36px var(--c-shadow), 0 0 0 1px color-mix(in srgb, var(--c-warn) 8%, transparent);
1861
+ z-index: 10002;
1862
+ }
1863
+
1864
+ .attention-history-tab {
1865
+ position: fixed;
1866
+ top: 146px;
1867
+ right: 0;
1868
+ display: flex;
1869
+ align-items: center;
1870
+ gap: 8px;
1871
+ padding: 8px 12px 8px 14px;
1872
+ background: color-mix(in srgb, var(--c-panel-glass) 96%, transparent);
1873
+ backdrop-filter: blur(16px);
1874
+ border: 1px solid color-mix(in srgb, var(--c-line) 82%, var(--c-warn) 18%);
1875
+ border-right: 0;
1876
+ border-radius: 14px 0 0 14px;
1877
+ box-shadow: 0 12px 36px var(--c-shadow);
1878
+ color: var(--c-text);
1879
+ cursor: pointer;
1880
+ font: inherit;
1881
+ font-size: 11px;
1882
+ font-weight: 600;
1883
+ letter-spacing: 0.08em;
1884
+ text-transform: uppercase;
1885
+ z-index: 60;
1886
+ }
1887
+
1888
+ .attention-history-tab:hover {
1889
+ border-color: color-mix(in srgb, var(--c-accent) 40%, var(--c-line) 60%);
1890
+ color: var(--c-accent);
1891
+ }
1892
+
1893
+ .attention-history-tab svg {
1894
+ display: block;
1895
+ color: var(--c-accent);
1896
+ flex-shrink: 0;
1897
+ }
1898
+
1899
+ .attention-history-tab-label {
1900
+ white-space: nowrap;
1901
+ }
1902
+
1903
+ .attention-history-tab-badge {
1904
+ min-width: 18px;
1905
+ height: 18px;
1906
+ padding: 0 5px;
1907
+ display: inline-flex;
1908
+ align-items: center;
1909
+ justify-content: center;
1910
+ border-radius: 9px;
1911
+ background: var(--c-warn);
1912
+ color: var(--c-contrast-fg);
1913
+ font-size: 10px;
1914
+ font-weight: 700;
1915
+ letter-spacing: 0;
1916
+ text-transform: none;
1917
+ }
1918
+
1919
+ .attention-history-header {
1920
+ display: flex;
1921
+ align-items: flex-start;
1922
+ justify-content: space-between;
1923
+ gap: 8px;
1924
+ padding: 2px 2px 4px;
1925
+ }
1926
+
1927
+ .attention-history-header-text {
1928
+ display: flex;
1929
+ flex-direction: column;
1930
+ gap: 2px;
1931
+ min-width: 0;
1932
+ }
1933
+
1934
+ .attention-history-close {
1935
+ flex-shrink: 0;
1936
+ width: 22px;
1937
+ height: 22px;
1938
+ border: 0;
1939
+ border-radius: 6px;
1940
+ background: transparent;
1941
+ color: var(--c-dim);
1942
+ font-size: 18px;
1943
+ line-height: 1;
1944
+ cursor: pointer;
1945
+ display: grid;
1946
+ place-items: center;
1947
+ padding: 0;
1948
+ }
1949
+
1950
+ .attention-history-close:hover {
1951
+ color: var(--c-text);
1952
+ background: var(--c-surface-hover);
1953
+ }
1954
+
1955
+ .attention-history-title {
1956
+ font-size: 12px;
1957
+ font-weight: 700;
1958
+ letter-spacing: 0.08em;
1959
+ text-transform: uppercase;
1960
+ color: var(--c-text);
1961
+ }
1962
+
1963
+ .attention-history-subtitle {
1964
+ font-size: 11px;
1965
+ color: var(--c-dim);
1966
+ }
1967
+
1968
+ .attention-history-list {
1969
+ display: flex;
1970
+ flex-direction: column;
1971
+ gap: 8px;
1972
+ }
1973
+
1974
+ .attention-history-entry {
1975
+ display: flex;
1976
+ flex-direction: column;
1977
+ gap: 6px;
1978
+ padding: 10px 11px;
1979
+ border-radius: 14px;
1980
+ background: color-mix(in srgb, var(--c-panel-soft) 78%, transparent);
1981
+ border: 1px solid transparent;
1982
+ }
1983
+
1984
+ .attention-history-meta {
1985
+ display: flex;
1986
+ align-items: baseline;
1987
+ justify-content: space-between;
1988
+ gap: 12px;
1989
+ }
1990
+
1991
+ .attention-history-kind {
1992
+ font-size: 12px;
1993
+ font-weight: 700;
1994
+ color: var(--c-text);
1995
+ }
1996
+
1997
+ .attention-history-time {
1998
+ font-size: 10px;
1999
+ color: var(--c-dim);
2000
+ white-space: nowrap;
2001
+ }
2002
+
2003
+ .attention-history-detail {
2004
+ font-size: 12px;
2005
+ line-height: 1.45;
2006
+ color: var(--c-text-soft);
2007
+ }
2008
+
2009
+ .attention-tone-context {
2010
+ border-color: color-mix(in srgb, var(--c-warn) 26%, transparent);
2011
+ }
2012
+
2013
+ .attention-toast.attention-tone-context {
2014
+ color: color-mix(in srgb, var(--c-warn) 82%, var(--c-text) 18%);
2015
+ }
2016
+
2017
+ .attention-tone-context .attention-history-kind,
2018
+ .attention-tone-context .attention-toast-title {
2019
+ color: color-mix(in srgb, var(--c-warn) 82%, var(--c-text) 18%);
2020
+ }
2021
+
2022
+ .attention-tone-relationship {
2023
+ border-color: color-mix(in srgb, var(--c-accent) 24%, transparent);
2024
+ }
2025
+
2026
+ .attention-toast.attention-tone-relationship {
2027
+ color: color-mix(in srgb, var(--c-accent) 78%, var(--c-text) 22%);
2028
+ }
2029
+
2030
+ .attention-tone-relationship .attention-history-kind,
2031
+ .attention-tone-relationship .attention-toast-title {
2032
+ color: color-mix(in srgb, var(--c-accent) 78%, var(--c-text) 22%);
2033
+ }
2034
+
2035
+ .attention-tone-group {
2036
+ border-color: color-mix(in srgb, var(--c-purple) 24%, transparent);
2037
+ }
2038
+
2039
+ .attention-toast.attention-tone-group {
2040
+ color: color-mix(in srgb, var(--c-purple) 78%, var(--c-text) 22%);
2041
+ }
2042
+
2043
+ .attention-tone-group .attention-history-kind,
2044
+ .attention-tone-group .attention-toast-title {
2045
+ color: color-mix(in srgb, var(--c-purple) 78%, var(--c-text) 22%);
2046
+ }
2047
+
2048
+ .attention-tone-cluster,
2049
+ .attention-tone-neighborhood {
2050
+ border-color: color-mix(in srgb, var(--c-warn-alt) 22%, transparent);
2051
+ }
2052
+
2053
+ .attention-toast.attention-tone-cluster,
2054
+ .attention-toast.attention-tone-neighborhood {
2055
+ color: color-mix(in srgb, var(--c-warn-alt) 78%, var(--c-text) 22%);
2056
+ }
2057
+
2058
+ .attention-tone-cluster .attention-history-kind,
2059
+ .attention-tone-cluster .attention-toast-title,
2060
+ .attention-tone-neighborhood .attention-history-kind,
2061
+ .attention-tone-neighborhood .attention-toast-title {
2062
+ color: color-mix(in srgb, var(--c-warn-alt) 78%, var(--c-text) 22%);
2063
+ }
2064
+
2065
+ .attention-tone-remove {
2066
+ border-color: color-mix(in srgb, var(--c-danger) 24%, transparent);
2067
+ }
2068
+
2069
+ .attention-toast.attention-tone-remove {
2070
+ color: color-mix(in srgb, var(--c-danger) 78%, var(--c-text) 22%);
2071
+ }
2072
+
2073
+ .attention-tone-remove .attention-history-kind,
2074
+ .attention-tone-remove .attention-toast-title {
2075
+ color: color-mix(in srgb, var(--c-danger) 78%, var(--c-text) 22%);
2076
+ }
2077
+
2078
+ /* ── Group node — spatial container/frame ─────────────────────── */
2079
+ .canvas-node.group-node {
2080
+ background: transparent;
2081
+ border: 2px dashed var(--group-color, var(--c-accent));
2082
+ border-radius: 12px;
2083
+ box-shadow: none;
2084
+ overflow: visible;
2085
+ min-width: 200px;
2086
+ min-height: 120px;
2087
+ }
2088
+
2089
+ .canvas-node.group-node .node-titlebar {
2090
+ background: color-mix(in srgb, var(--group-color, var(--c-accent)) 12%, transparent);
2091
+ border-bottom: 1px solid color-mix(in srgb, var(--group-color, var(--c-accent)) 25%, transparent);
2092
+ border-radius: 10px 10px 0 0;
2093
+ }
2094
+
2095
+ .canvas-node.group-node .node-type-badge {
2096
+ background: color-mix(in srgb, var(--group-color, var(--c-accent)) 20%, transparent);
2097
+ color: var(--group-color, var(--c-accent));
2098
+ }
2099
+
2100
+ .canvas-node.group-node .node-body {
2101
+ background: color-mix(in srgb, var(--group-color, var(--c-accent)) 4%, transparent);
2102
+ padding: 12px;
2103
+ }
2104
+
2105
+ .canvas-node.group-node:hover {
2106
+ border-style: solid;
2107
+ box-shadow: 0 0 0 1px color-mix(in srgb, var(--group-color, var(--c-accent)) 30%, transparent);
2108
+ }
2109
+
2110
+ .canvas-node.group-node.active {
2111
+ border-style: solid;
2112
+ border-color: var(--group-color, var(--c-accent));
2113
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--group-color, var(--c-accent)) 40%, transparent);
2114
+ }
2115
+
2116
+ .group-node-body {
2117
+ display: flex;
2118
+ flex-direction: column;
2119
+ gap: 8px;
2120
+ height: 100%;
2121
+ }
2122
+
2123
+ .group-summary {
2124
+ display: flex;
2125
+ align-items: center;
2126
+ gap: 10px;
2127
+ flex-wrap: wrap;
2128
+ }
2129
+
2130
+ .group-child-count {
2131
+ font-size: 13px;
2132
+ font-weight: 600;
2133
+ color: var(--group-color, var(--c-accent));
2134
+ }
2135
+
2136
+ .group-type-summary {
2137
+ font-size: 12px;
2138
+ color: var(--c-text-muted);
2139
+ }
2140
+
2141
+ .group-empty-hint {
2142
+ font-size: 12px;
2143
+ color: var(--c-text-muted);
2144
+ font-style: italic;
2145
+ padding: 12px 0;
2146
+ text-align: center;
2147
+ opacity: 0.7;
2148
+ }
2149
+
2150
+ /* ── Context pin bar — persistent floating indicator ─────────── */
2151
+ .context-pin-bar {
2152
+ position: fixed;
2153
+ bottom: 20px;
2154
+ left: 50%;
2155
+ transform: translateX(-50%);
2156
+ display: flex;
2157
+ align-items: center;
2158
+ gap: 8px;
2159
+ padding: 8px 14px;
2160
+ background: var(--c-panel-glass);
2161
+ backdrop-filter: blur(12px);
2162
+ border: 1px solid var(--c-warn);
2163
+ border-radius: var(--radius);
2164
+ box-shadow: 0 8px 32px var(--c-shadow), 0 0 0 1px var(--c-warn-15);
2165
+ z-index: 10000;
2166
+ white-space: nowrap;
2167
+ }
2168
+
2169
+ .context-pin-bar-count {
2170
+ font-size: 12px;
2171
+ font-weight: 600;
2172
+ color: var(--c-warn);
2173
+ }
2174
+
2175
+ .context-pin-bar-btn {
2176
+ padding: 5px 12px;
2177
+ font-size: 12px;
2178
+ font-weight: 600;
2179
+ background: var(--c-warn-10);
2180
+ border: 1px solid var(--c-warn-30);
2181
+ border-radius: var(--radius-sm);
2182
+ color: var(--c-warn);
2183
+ cursor: pointer;
2184
+ font-family: var(--font);
2185
+ }
2186
+
2187
+ .context-pin-bar-btn:hover {
2188
+ background: var(--c-warn-20);
2189
+ border-color: var(--c-warn);
2190
+ }
2191
+
2192
+ .context-pin-bar-ask {
2193
+ background: var(--c-warn);
2194
+ color: var(--c-contrast-fg);
2195
+ border-color: var(--c-warn);
2196
+ }
2197
+
2198
+ .context-pin-bar-ask:hover {
2199
+ background: var(--c-warn-hover);
2200
+ border-color: var(--c-warn-hover);
2201
+ }
2202
+
2203
+ .context-pin-bar-clear {
2204
+ background: none;
2205
+ border: none;
2206
+ color: var(--c-muted);
2207
+ font-size: 16px;
2208
+ padding: 2px 6px;
2209
+ line-height: 1;
2210
+ }
2211
+
2212
+ .context-pin-bar-clear:hover {
2213
+ color: var(--c-text);
2214
+ background: var(--c-surface-hover);
2215
+ }
2216
+
2217
+ /* ── Expanded overlay actions ────────────────────────────────── */
2218
+ .expanded-actions {
2219
+ display: flex;
2220
+ align-items: center;
2221
+ gap: 6px;
2222
+ }
2223
+
2224
+ .expanded-action-btn {
2225
+ padding: 3px 10px;
2226
+ font-size: 11px;
2227
+ font-weight: 600;
2228
+ background: var(--c-panel-soft);
2229
+ border: 1px solid var(--c-line);
2230
+ border-radius: var(--radius-sm);
2231
+ color: var(--c-text-soft);
2232
+ cursor: pointer;
2233
+ font-family: var(--font);
2234
+ }
2235
+
2236
+ .expanded-action-btn:hover {
2237
+ background: var(--c-surface-hover);
2238
+ color: var(--c-text);
2239
+ border-color: var(--c-muted);
2240
+ }
2241
+
2242
+ .expanded-action-btn.expanded-action-active {
2243
+ background: var(--c-warn-12);
2244
+ border-color: var(--c-warn-30);
2245
+ color: var(--c-warn);
2246
+ }
2247
+
2248
+ .expanded-action-btn.expanded-action-active:hover {
2249
+ background: var(--c-warn-20);
2250
+ border-color: var(--c-warn);
2251
+ }
2252
+
2253
+ .expanded-meta {
2254
+ font-size: 10px;
2255
+ color: var(--c-muted);
2256
+ padding: 0 4px;
2257
+ }
2258
+
2259
+ /* ── Context pin button on node title bar ────────────────────── */
2260
+ .node-controls .ctx-pin-btn {
2261
+ color: var(--c-muted);
2262
+ opacity: 0;
2263
+ transition: opacity 0.15s;
2264
+ }
2265
+
2266
+ .canvas-node:hover .ctx-pin-btn {
2267
+ opacity: 0.7;
2268
+ }
2269
+
2270
+ .ctx-pin-btn.ctx-pin-active {
2271
+ color: var(--c-warn);
2272
+ opacity: 1 !important;
2273
+ }
2274
+
2275
+ :root[data-theme="light"] .ctx-pin-btn.ctx-pin-active {
2276
+ color: #4BBCFF;
2277
+ }
2278
+
2279
+ /* ── Context pin HUD — top-right pill ────────────────────────── */
2280
+ .context-pin-hud {
2281
+ display: flex;
2282
+ align-items: center;
2283
+ gap: 6px;
2284
+ padding: 5px 10px;
2285
+ background: var(--c-panel-glass);
2286
+ backdrop-filter: blur(12px);
2287
+ border: 1px solid var(--c-warn-30);
2288
+ border-radius: var(--radius);
2289
+ white-space: nowrap;
2290
+ }
2291
+
2292
+ .context-pin-hud-label {
2293
+ font-size: 11px;
2294
+ font-weight: 600;
2295
+ color: var(--c-warn);
2296
+ }
2297
+
2298
+ .context-pin-hud-clear {
2299
+ background: none;
2300
+ border: none;
2301
+ color: var(--c-muted);
2302
+ font-size: 14px;
2303
+ padding: 0 2px;
2304
+ cursor: pointer;
2305
+ line-height: 1;
2306
+ }
2307
+
2308
+ .context-pin-hud-clear:hover {
2309
+ color: var(--c-text);
2310
+ }
2311
+
2312
+ /* ── Thread turn styles ──────────────────────────────────────── */
2313
+ .thread-turn-user {
2314
+ padding: 8px 0;
2315
+ }
2316
+
2317
+ .thread-turn-assistant {
2318
+ padding: 6px 0;
2319
+ border-left: 2px solid var(--c-ok-20);
2320
+ padding-left: 10px;
2321
+ margin-left: 2px;
2322
+ overflow: hidden;
2323
+ }
2324
+
2325
+ /* Keep list markers inside the content box so they don't overlap the green border */
2326
+ .thread-turn-assistant ol,
2327
+ .thread-turn-assistant ul {
2328
+ list-style-position: inside;
2329
+ padding-left: 0;
2330
+ }
2331
+
2332
+ .thread-turn-assistant li {
2333
+ padding-left: 4px;
2334
+ }
2335
+
2336
+ .thread-turn-role {
2337
+ font-size: 10px;
2338
+ font-weight: 700;
2339
+ text-transform: uppercase;
2340
+ letter-spacing: 0.04em;
2341
+ margin-bottom: 3px;
2342
+ display: flex;
2343
+ align-items: center;
2344
+ gap: 6px;
2345
+ }
2346
+
2347
+ .thread-turn-role .status-dot {
2348
+ width: 8px;
2349
+ height: 8px;
2350
+ border-radius: 50%;
2351
+ flex-shrink: 0;
2352
+ }
2353
+
2354
+ .thread-turn-user .thread-turn-role {
2355
+ color: var(--c-accent);
2356
+ }
2357
+
2358
+ .thread-turn-user .status-dot {
2359
+ background: var(--c-accent);
2360
+ }
2361
+
2362
+ .thread-turn-assistant .thread-turn-role {
2363
+ color: var(--c-ok);
2364
+ }
2365
+
2366
+ .thread-turn-assistant .status-dot {
2367
+ background: var(--c-ok);
2368
+ }
2369
+
2370
+ .thread-turn-assistant .status-dot.pulsing {
2371
+ animation: status-dot-pulse 2s ease-in-out infinite;
2372
+ }
2373
+
2374
+ @keyframes status-dot-pulse {
2375
+ 0%, 100% { opacity: 1; transform: scale(1); }
2376
+ 50% { opacity: 0.35; transform: scale(0.8); }
2377
+ }
2378
+
2379
+ .thread-turn-divider {
2380
+ height: 1px;
2381
+ background: var(--c-line);
2382
+ margin: 6px 0;
2383
+ opacity: 0.35;
2384
+ }
2385
+
2386
+ /* Blinking cursor shown at the end of streaming text */
2387
+ .streaming-cursor {
2388
+ display: inline-block;
2389
+ width: 6px;
2390
+ height: 14px;
2391
+ background: var(--c-ok);
2392
+ border-radius: 1px;
2393
+ margin-left: 2px;
2394
+ vertical-align: text-bottom;
2395
+ animation: cursor-blink 0.8s step-end infinite;
2396
+ }
2397
+
2398
+ @keyframes cursor-blink {
2399
+ 0%, 100% { opacity: 1; }
2400
+ 50% { opacity: 0; }
2401
+ }
2402
+
2403
+ .thread-reply-area {
2404
+ margin-top: 2px;
2405
+ }
2406
+
2407
+ /* ── Snapshot Panel ───────────────────────────────────────── */
2408
+
2409
+ .snapshot-panel {
2410
+ position: fixed;
2411
+ width: 320px;
2412
+ max-height: 420px;
2413
+ display: flex;
2414
+ flex-direction: column;
2415
+ background: var(--c-panel-glass);
2416
+ backdrop-filter: blur(16px);
2417
+ border: 1px solid var(--c-line);
2418
+ border-radius: var(--radius);
2419
+ box-shadow: 0 12px 40px var(--c-shadow-heavy), 0 0 0 1px rgba(255,255,255,0.04);
2420
+ z-index: 10001;
2421
+ overflow: hidden;
2422
+ animation: snapshot-panel-in 0.15s ease-out;
2423
+ }
2424
+
2425
+ @keyframes snapshot-panel-in {
2426
+ from { opacity: 0; transform: translateY(-6px); }
2427
+ to { opacity: 1; transform: translateY(0); }
2428
+ }
2429
+
2430
+ .snapshot-panel-header {
2431
+ display: flex;
2432
+ align-items: center;
2433
+ justify-content: space-between;
2434
+ padding: 10px 14px;
2435
+ border-bottom: 1px solid var(--c-line);
2436
+ }
2437
+
2438
+ .snapshot-panel-title {
2439
+ font-size: 11px;
2440
+ font-weight: 600;
2441
+ text-transform: uppercase;
2442
+ letter-spacing: 0.06em;
2443
+ color: var(--c-muted);
2444
+ }
2445
+
2446
+ .snapshot-panel-close {
2447
+ background: none;
2448
+ border: none;
2449
+ color: var(--c-dim);
2450
+ font-size: 16px;
2451
+ cursor: pointer;
2452
+ padding: 0 2px;
2453
+ line-height: 1;
2454
+ }
2455
+ .snapshot-panel-close:hover {
2456
+ color: var(--c-text);
2457
+ }
2458
+
2459
+ .snapshot-save-form {
2460
+ display: flex;
2461
+ gap: 6px;
2462
+ padding: 10px 14px;
2463
+ border-bottom: 1px solid var(--c-line);
2464
+ }
2465
+
2466
+ .snapshot-name-input {
2467
+ flex: 1;
2468
+ background: var(--c-input-bg);
2469
+ border: 1px solid var(--c-line);
2470
+ border-radius: var(--radius-sm);
2471
+ color: var(--c-text);
2472
+ font-family: var(--font);
2473
+ font-size: 12px;
2474
+ padding: 6px 10px;
2475
+ outline: none;
2476
+ transition: border-color 0.15s;
2477
+ }
2478
+ .snapshot-name-input:focus {
2479
+ border-color: var(--c-accent);
2480
+ }
2481
+ .snapshot-name-input::placeholder {
2482
+ color: var(--c-dim);
2483
+ }
2484
+
2485
+ .snapshot-save-btn {
2486
+ background: var(--c-accent);
2487
+ border: none;
2488
+ color: var(--c-contrast-fg);
2489
+ font-family: var(--font);
2490
+ font-size: 11px;
2491
+ font-weight: 600;
2492
+ padding: 6px 14px;
2493
+ border-radius: var(--radius-sm);
2494
+ cursor: pointer;
2495
+ white-space: nowrap;
2496
+ transition: background 0.15s;
2497
+ }
2498
+ .snapshot-save-btn:hover:not(:disabled) {
2499
+ background: var(--c-accent-hover);
2500
+ }
2501
+ .snapshot-save-btn:disabled {
2502
+ opacity: 0.4;
2503
+ cursor: default;
2504
+ }
2505
+
2506
+ .snapshot-restore-note {
2507
+ padding: 0 12px 10px;
2508
+ font-size: 10px;
2509
+ color: var(--c-dim);
2510
+ }
2511
+
2512
+ .snapshot-list {
2513
+ overflow-y: auto;
2514
+ flex: 1;
2515
+ padding: 4px 0;
2516
+ }
2517
+
2518
+ .snapshot-empty {
2519
+ padding: 20px 14px;
2520
+ color: var(--c-dim);
2521
+ font-size: 12px;
2522
+ text-align: center;
2523
+ line-height: 1.5;
2524
+ }
2525
+
2526
+ .snapshot-item {
2527
+ display: flex;
2528
+ align-items: center;
2529
+ justify-content: space-between;
2530
+ gap: 8px;
2531
+ padding: 8px 14px;
2532
+ transition: background 0.1s;
2533
+ }
2534
+ .snapshot-item:hover {
2535
+ background: var(--c-surface-hover);
2536
+ }
2537
+
2538
+ .snapshot-item-info {
2539
+ display: flex;
2540
+ flex-direction: column;
2541
+ gap: 2px;
2542
+ min-width: 0;
2543
+ flex: 1;
2544
+ }
2545
+
2546
+ .snapshot-item-name {
2547
+ font-size: 12px;
2548
+ font-weight: 500;
2549
+ color: var(--c-text);
2550
+ white-space: nowrap;
2551
+ overflow: hidden;
2552
+ text-overflow: ellipsis;
2553
+ }
2554
+
2555
+ .snapshot-item-meta {
2556
+ font-size: 10px;
2557
+ color: var(--c-dim);
2558
+ }
2559
+
2560
+ .snapshot-item-actions {
2561
+ display: flex;
2562
+ gap: 4px;
2563
+ flex-shrink: 0;
2564
+ opacity: 0;
2565
+ transition: opacity 0.1s;
2566
+ }
2567
+ .snapshot-item:hover .snapshot-item-actions {
2568
+ opacity: 1;
2569
+ }
2570
+
2571
+ .snapshot-action-btn {
2572
+ background: none;
2573
+ border: 1px solid var(--c-line);
2574
+ color: var(--c-muted);
2575
+ font-family: var(--font);
2576
+ font-size: 10px;
2577
+ padding: 3px 8px;
2578
+ border-radius: var(--radius-sm);
2579
+ cursor: pointer;
2580
+ transition: all 0.1s;
2581
+ }
2582
+
2583
+ .snapshot-action-restore {
2584
+ color: var(--c-accent);
2585
+ border-color: var(--c-accent-25);
2586
+ }
2587
+ .snapshot-action-restore:hover {
2588
+ background: var(--c-accent-12);
2589
+ border-color: var(--c-accent);
2590
+ }
2591
+
2592
+ .snapshot-action-delete {
2593
+ color: var(--c-dim);
2594
+ border-color: transparent;
2595
+ padding: 3px 5px;
2596
+ }
2597
+ .snapshot-action-delete:hover {
2598
+ color: var(--c-danger);
2599
+ border-color: var(--c-danger-12);
2600
+ }
2601
+
2602
+ .snapshot-action-confirm {
2603
+ color: var(--c-danger);
2604
+ border-color: var(--c-danger);
2605
+ }
2606
+ .snapshot-action-confirm:hover {
2607
+ background: var(--c-danger-12);
2608
+ }
2609
+
2610
+ /* ── Command Palette (Cmd/Ctrl+K) ──────────────────────────── */
2611
+
2612
+ .command-palette-backdrop {
2613
+ position: fixed;
2614
+ inset: 0;
2615
+ z-index: 10002;
2616
+ background: rgba(0, 0, 0, 0.25);
2617
+ display: flex;
2618
+ justify-content: center;
2619
+ padding-top: 18vh;
2620
+ }
2621
+
2622
+ .command-palette {
2623
+ width: 500px;
2624
+ max-height: 440px;
2625
+ display: flex;
2626
+ flex-direction: column;
2627
+ background: var(--c-panel-glass);
2628
+ backdrop-filter: blur(16px);
2629
+ border: 1px solid var(--c-line);
2630
+ border-radius: var(--radius);
2631
+ box-shadow: 0 12px 40px var(--c-shadow-heavy), 0 0 0 1px rgba(255,255,255,0.04);
2632
+ overflow: hidden;
2633
+ animation: command-palette-in 0.12s ease-out;
2634
+ align-self: flex-start;
2635
+ }
2636
+
2637
+ @keyframes command-palette-in {
2638
+ from { opacity: 0; transform: translateY(-8px) scale(0.98); }
2639
+ to { opacity: 1; transform: translateY(0) scale(1); }
2640
+ }
2641
+
2642
+ .command-palette-input {
2643
+ background: var(--c-input-bg);
2644
+ border: none;
2645
+ border-bottom: 1px solid var(--c-line);
2646
+ color: var(--c-text);
2647
+ font-family: var(--font);
2648
+ font-size: 14px;
2649
+ padding: 14px 16px;
2650
+ outline: none;
2651
+ width: 100%;
2652
+ box-sizing: border-box;
2653
+ }
2654
+ .command-palette-input:focus {
2655
+ border-bottom-color: var(--c-accent);
2656
+ }
2657
+ .command-palette-input::placeholder {
2658
+ color: var(--c-dim);
2659
+ }
2660
+
2661
+ .command-palette-hint {
2662
+ display: flex;
2663
+ gap: 12px;
2664
+ padding: 6px 16px;
2665
+ font-size: 10px;
2666
+ color: var(--c-dim);
2667
+ border-bottom: 1px solid var(--c-line);
2668
+ }
2669
+ .command-palette-hint kbd {
2670
+ display: inline-block;
2671
+ background: var(--c-surface-hover);
2672
+ border: 1px solid var(--c-line);
2673
+ border-radius: 3px;
2674
+ padding: 0 4px;
2675
+ font-family: var(--font);
2676
+ font-size: 9px;
2677
+ line-height: 1.6;
2678
+ margin-right: 2px;
2679
+ }
2680
+
2681
+ .command-palette-results {
2682
+ overflow-y: auto;
2683
+ flex: 1;
2684
+ padding: 4px 0;
2685
+ }
2686
+
2687
+ .command-palette-empty {
2688
+ padding: 24px 16px;
2689
+ text-align: center;
2690
+ color: var(--c-dim);
2691
+ font-size: 12px;
2692
+ }
2693
+
2694
+ .command-palette-item {
2695
+ display: flex;
2696
+ align-items: center;
2697
+ gap: 10px;
2698
+ width: 100%;
2699
+ padding: 8px 16px;
2700
+ background: none;
2701
+ border: none;
2702
+ color: var(--c-text);
2703
+ font-family: var(--font);
2704
+ font-size: 12px;
2705
+ cursor: pointer;
2706
+ text-align: left;
2707
+ transition: background 0.06s;
2708
+ }
2709
+
2710
+ .command-palette-item.selected {
2711
+ background: var(--c-accent-10);
2712
+ }
2713
+
2714
+ .command-palette-item:hover {
2715
+ background: var(--c-surface-hover);
2716
+ }
2717
+
2718
+ .command-palette-item.selected:hover {
2719
+ background: var(--c-accent-10);
2720
+ }
2721
+
2722
+ .command-palette-badge {
2723
+ font-size: 9px;
2724
+ padding: 1px 6px;
2725
+ border-radius: 4px;
2726
+ background: var(--c-accent-12);
2727
+ color: var(--c-accent);
2728
+ flex-shrink: 0;
2729
+ font-weight: 600;
2730
+ letter-spacing: 0.04em;
2731
+ text-transform: uppercase;
2732
+ min-width: 32px;
2733
+ text-align: center;
2734
+ }
2735
+
2736
+ .command-palette-badge--action {
2737
+ background: rgba(176, 122, 255, 0.12);
2738
+ color: var(--c-purple);
2739
+ }
2740
+
2741
+ .command-palette-label {
2742
+ flex: 1;
2743
+ white-space: nowrap;
2744
+ overflow: hidden;
2745
+ text-overflow: ellipsis;
2746
+ }
2747
+ .command-palette-label mark {
2748
+ background: none;
2749
+ color: var(--c-accent);
2750
+ font-weight: 600;
2751
+ }
2752
+
2753
+ .command-palette-desc {
2754
+ font-size: 11px;
2755
+ color: var(--c-dim);
2756
+ white-space: nowrap;
2757
+ overflow: hidden;
2758
+ text-overflow: ellipsis;
2759
+ max-width: 180px;
2760
+ flex-shrink: 0;
2761
+ }
2762
+
2763
+ /* ── Shortcut Overlay (Press ?) ────────────────────────────── */
2764
+
2765
+ .shortcut-overlay-backdrop {
2766
+ position: fixed;
2767
+ inset: 0;
2768
+ z-index: 10003;
2769
+ background: rgba(0, 0, 0, 0.5);
2770
+ display: flex;
2771
+ justify-content: center;
2772
+ align-items: center;
2773
+ }
2774
+
2775
+ .shortcut-overlay {
2776
+ width: 540px;
2777
+ max-height: 80vh;
2778
+ display: flex;
2779
+ flex-direction: column;
2780
+ background: var(--c-panel-glass);
2781
+ backdrop-filter: blur(16px);
2782
+ border: 1px solid var(--c-line);
2783
+ border-radius: var(--radius);
2784
+ box-shadow: 0 12px 40px var(--c-shadow-heavy), 0 0 0 1px rgba(255,255,255,0.04);
2785
+ overflow: hidden;
2786
+ animation: command-palette-in 0.12s ease-out;
2787
+ }
2788
+
2789
+ .shortcut-overlay-header {
2790
+ display: flex;
2791
+ align-items: center;
2792
+ justify-content: space-between;
2793
+ padding: 14px 20px;
2794
+ border-bottom: 1px solid var(--c-line);
2795
+ }
2796
+
2797
+ .shortcut-overlay-title {
2798
+ font-size: 13px;
2799
+ font-weight: 600;
2800
+ color: var(--c-text);
2801
+ }
2802
+
2803
+ .shortcut-overlay-hint {
2804
+ font-size: 10px;
2805
+ color: var(--c-dim);
2806
+ }
2807
+ .shortcut-overlay-hint kbd {
2808
+ display: inline-block;
2809
+ background: var(--c-surface-hover);
2810
+ border: 1px solid var(--c-line);
2811
+ border-radius: 3px;
2812
+ padding: 0 4px;
2813
+ font-family: var(--font);
2814
+ font-size: 9px;
2815
+ line-height: 1.6;
2816
+ margin: 0 2px;
2817
+ }
2818
+
2819
+ .shortcut-overlay-body {
2820
+ overflow-y: auto;
2821
+ padding: 8px 20px 16px;
2822
+ display: grid;
2823
+ grid-template-columns: 1fr 1fr;
2824
+ gap: 16px;
2825
+ }
2826
+
2827
+ .shortcut-group {
2828
+ display: flex;
2829
+ flex-direction: column;
2830
+ gap: 6px;
2831
+ }
2832
+
2833
+ .shortcut-group-title {
2834
+ font-size: 10px;
2835
+ font-weight: 600;
2836
+ text-transform: uppercase;
2837
+ letter-spacing: 0.06em;
2838
+ color: var(--c-accent);
2839
+ margin-bottom: 2px;
2840
+ }
2841
+
2842
+ .shortcut-row {
2843
+ display: flex;
2844
+ align-items: baseline;
2845
+ gap: 10px;
2846
+ }
2847
+
2848
+ .shortcut-keys {
2849
+ display: inline-block;
2850
+ background: var(--c-input-bg);
2851
+ border: 1px solid var(--c-line);
2852
+ border-radius: 4px;
2853
+ padding: 2px 7px;
2854
+ font-family: var(--mono);
2855
+ font-size: 11px;
2856
+ color: var(--c-text);
2857
+ white-space: nowrap;
2858
+ min-width: 60px;
2859
+ text-align: center;
2860
+ flex-shrink: 0;
2861
+ }
2862
+
2863
+ .shortcut-desc {
2864
+ font-size: 11px;
2865
+ color: var(--c-muted);
2866
+ line-height: 1.4;
2867
+ }
2868
+
2869
+ /* ── Welcome Card (empty canvas) ────────────────────────── */
2870
+ .welcome-card {
2871
+ position: absolute;
2872
+ top: 50%;
2873
+ left: 50%;
2874
+ transform: translate(-50%, -50%);
2875
+ z-index: 5;
2876
+ display: flex;
2877
+ flex-direction: column;
2878
+ align-items: center;
2879
+ gap: 12px;
2880
+ padding: 36px 44px;
2881
+ background: var(--c-panel-glass);
2882
+ backdrop-filter: blur(16px);
2883
+ border: 1px solid var(--c-line);
2884
+ border-radius: 16px;
2885
+ box-shadow: 0 8px 32px var(--c-shadow), 0 0 0 1px var(--c-line-30);
2886
+ animation: welcome-fade-in 0.5s ease-out;
2887
+ pointer-events: auto;
2888
+ max-width: 380px;
2889
+ text-align: center;
2890
+ }
2891
+
2892
+ @keyframes welcome-fade-in {
2893
+ from { opacity: 0; transform: translate(-50%, -48%); }
2894
+ to { opacity: 1; transform: translate(-50%, -50%); }
2895
+ }
2896
+
2897
+ .welcome-icon {
2898
+ font-size: 32px;
2899
+ color: var(--c-accent);
2900
+ opacity: 0.7;
2901
+ line-height: 1;
2902
+ }
2903
+
2904
+ .welcome-title {
2905
+ font-size: 18px;
2906
+ font-weight: 600;
2907
+ color: var(--c-text);
2908
+ letter-spacing: -0.3px;
2909
+ }
2910
+
2911
+ .welcome-subtitle {
2912
+ font-size: 12px;
2913
+ color: var(--c-dim);
2914
+ margin-bottom: 8px;
2915
+ line-height: 1.55;
2916
+ }
2917
+
2918
+ .welcome-hints {
2919
+ display: flex;
2920
+ flex-direction: column;
2921
+ gap: 6px;
2922
+ width: 100%;
2923
+ }
2924
+
2925
+ .welcome-hint {
2926
+ display: flex;
2927
+ align-items: center;
2928
+ gap: 12px;
2929
+ padding: 8px 12px;
2930
+ background: var(--c-surface-subtle);
2931
+ border: 1px solid transparent;
2932
+ border-radius: var(--radius-sm);
2933
+ text-align: left;
2934
+ cursor: default;
2935
+ font: inherit;
2936
+ color: inherit;
2937
+ }
2938
+
2939
+ button.welcome-hint {
2940
+ cursor: pointer;
2941
+ }
2942
+
2943
+ button.welcome-hint:hover {
2944
+ background: var(--c-surface-hover);
2945
+ border-color: var(--c-line);
2946
+ }
2947
+
2948
+ @media (max-width: 980px) {
2949
+ .attention-toast {
2950
+ top: 70px;
2951
+ left: 12px;
2952
+ right: 12px;
2953
+ width: auto;
2954
+ }
2955
+
2956
+ .attention-history {
2957
+ top: auto;
2958
+ left: 12px;
2959
+ right: 12px;
2960
+ bottom: 84px;
2961
+ width: auto;
2962
+ }
2963
+
2964
+ .welcome-card {
2965
+ width: calc(100vw - 24px);
2966
+ max-width: 420px;
2967
+ padding: 28px 24px;
2968
+ }
2969
+ }
2970
+
2971
+ @media (prefers-reduced-motion: reduce) {
2972
+ .attention-toast,
2973
+ .welcome-card,
2974
+ .canvas-node.attention-pulse {
2975
+ animation: none !important;
2976
+ }
2977
+
2978
+ .attention-field-region,
2979
+ .attention-field-node,
2980
+ .canvas-node {
2981
+ transition: none !important;
2982
+ }
2983
+ }
2984
+
2985
+ .welcome-hint kbd {
2986
+ display: inline-block;
2987
+ background: var(--c-input-bg);
2988
+ border: 1px solid var(--c-line);
2989
+ border-radius: 4px;
2990
+ padding: 2px 7px;
2991
+ font-family: var(--mono);
2992
+ font-size: 10px;
2993
+ color: var(--c-accent);
2994
+ white-space: nowrap;
2995
+ min-width: 70px;
2996
+ text-align: center;
2997
+ flex-shrink: 0;
2998
+ }
2999
+
3000
+ .welcome-hint span {
3001
+ font-size: 12px;
3002
+ color: var(--c-muted);
3003
+ }
3004
+
3005
+ .welcome-footer {
3006
+ font-size: 11px;
3007
+ color: var(--c-dim);
3008
+ margin-top: 4px;
3009
+ line-height: 1.4;
3010
+ }
3011
+
3012
+ /* ── Image Node ─────────────────────────────────────────────── */
3013
+ .image-node {
3014
+ display: flex;
3015
+ flex-direction: column;
3016
+ height: 100%;
3017
+ overflow: hidden;
3018
+ }
3019
+
3020
+ .image-node-warning-stack {
3021
+ display: flex;
3022
+ flex-direction: column;
3023
+ gap: 6px;
3024
+ padding: 8px 8px 0;
3025
+ }
3026
+
3027
+ .image-node-warning {
3028
+ display: flex;
3029
+ flex-direction: column;
3030
+ gap: 3px;
3031
+ padding: 8px 10px;
3032
+ border-radius: 10px;
3033
+ border: 1px solid color-mix(in srgb, var(--c-warn) 42%, var(--c-line) 58%);
3034
+ background: color-mix(in srgb, var(--c-warn) 12%, var(--c-panel-soft) 88%);
3035
+ color: var(--c-text);
3036
+ }
3037
+
3038
+ .image-node-warning-title {
3039
+ font-size: 10px;
3040
+ font-weight: 700;
3041
+ letter-spacing: 0.06em;
3042
+ text-transform: uppercase;
3043
+ color: color-mix(in srgb, var(--c-warn) 88%, var(--c-text) 12%);
3044
+ }
3045
+
3046
+ .image-node-warning-detail {
3047
+ font-size: 11px;
3048
+ line-height: 1.35;
3049
+ color: var(--c-text-soft);
3050
+ }
3051
+
3052
+ .image-node-viewport {
3053
+ flex: 1;
3054
+ overflow: hidden;
3055
+ display: flex;
3056
+ align-items: center;
3057
+ justify-content: center;
3058
+ background: repeating-conic-gradient(
3059
+ var(--c-surface-subtle) 0% 25%,
3060
+ transparent 0% 50%
3061
+ ) 50% / 16px 16px;
3062
+ position: relative;
3063
+ min-height: 80px;
3064
+ border-radius: var(--radius-sm);
3065
+ }
3066
+
3067
+ .image-node-viewport img {
3068
+ max-width: 100%;
3069
+ max-height: 100%;
3070
+ object-fit: contain;
3071
+ transition: opacity 0.2s ease;
3072
+ transform-origin: center center;
3073
+ user-select: none;
3074
+ -webkit-user-drag: none;
3075
+ }
3076
+
3077
+ .image-node-expanded .image-node-viewport img {
3078
+ max-width: none;
3079
+ max-height: none;
3080
+ width: auto;
3081
+ height: auto;
3082
+ }
3083
+
3084
+ .image-node-loading,
3085
+ .image-node-error {
3086
+ display: flex;
3087
+ flex-direction: column;
3088
+ align-items: center;
3089
+ justify-content: center;
3090
+ gap: 8px;
3091
+ padding: 24px;
3092
+ color: var(--c-dim);
3093
+ font-size: 12px;
3094
+ position: absolute;
3095
+ inset: 0;
3096
+ }
3097
+
3098
+ .image-node-error-icon {
3099
+ font-size: 24px;
3100
+ opacity: 0.5;
3101
+ }
3102
+
3103
+ .image-node-error-path {
3104
+ font-family: var(--mono);
3105
+ font-size: 10px;
3106
+ color: var(--c-muted);
3107
+ word-break: break-all;
3108
+ max-width: 250px;
3109
+ text-align: center;
3110
+ }
3111
+
3112
+ .image-node-empty {
3113
+ display: flex;
3114
+ flex-direction: column;
3115
+ align-items: center;
3116
+ justify-content: center;
3117
+ gap: 8px;
3118
+ height: 100%;
3119
+ color: var(--c-dim);
3120
+ }
3121
+
3122
+ .image-node-empty-icon {
3123
+ font-size: 32px;
3124
+ opacity: 0.4;
3125
+ }
3126
+
3127
+ .image-node-empty-text {
3128
+ font-size: 12px;
3129
+ }
3130
+
3131
+ .image-node-footer {
3132
+ display: flex;
3133
+ align-items: center;
3134
+ justify-content: space-between;
3135
+ padding: 4px 10px;
3136
+ border-top: 1px solid var(--c-line);
3137
+ background: var(--c-panel-soft);
3138
+ font-size: 10px;
3139
+ color: var(--c-dim);
3140
+ gap: 8px;
3141
+ min-height: 24px;
3142
+ margin-top: 8px;
3143
+ }
3144
+
3145
+ .image-node-caption {
3146
+ color: var(--c-muted);
3147
+ overflow: hidden;
3148
+ text-overflow: ellipsis;
3149
+ white-space: nowrap;
3150
+ flex: 1;
3151
+ }
3152
+
3153
+ .image-node-meta {
3154
+ display: flex;
3155
+ align-items: center;
3156
+ gap: 8px;
3157
+ flex-shrink: 0;
3158
+ }
3159
+
3160
+ .image-node-zoom-reset {
3161
+ background: none;
3162
+ border: 1px solid var(--c-line);
3163
+ border-radius: 3px;
3164
+ padding: 1px 6px;
3165
+ font: inherit;
3166
+ font-size: 10px;
3167
+ color: var(--c-accent);
3168
+ cursor: pointer;
3169
+ }
3170
+
3171
+ .image-node-zoom-reset:hover {
3172
+ background: var(--c-surface-hover);
3173
+ }