vortx-gl 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,225 @@
1
+ import { vec2 } from "gl-matrix";
2
+ /**
3
+ * Visual properties applicable to nodes or edges via classes.
4
+ */
5
+ export interface GraphStyle {
6
+ /** Fill color: CSS hex string ("#ff6b6b") or [r,g,b,a] components in 0–1 range. */
7
+ color?: string | [number, number, number, number?];
8
+ /** Node diameter or edge weight. */
9
+ size?: number;
10
+ /** Display label. */
11
+ label?: string;
12
+ /** Emoji or text icon. */
13
+ icon?: string;
14
+ /** URI of an image. */
15
+ image?: string;
16
+ }
17
+ /**
18
+ * A dictionary of class names to style properties.
19
+ */
20
+ export type Stylesheet = Record<string, GraphStyle>;
21
+ /**
22
+ * Input format for creating or updating a node via `engine.addNode()`.
23
+ */
24
+ export interface NodeInput {
25
+ /** Unique identifier. String or number. Auto-generated if omitted. */
26
+ id?: string | number;
27
+ /** Initial world position. */
28
+ position?: {
29
+ x: number;
30
+ y: number;
31
+ };
32
+ /** Fill color: CSS hex string ("#ff6b6b") or [r,g,b,a] components in 0–1 range. */
33
+ color?: string | [number, number, number, number?];
34
+ /** Display label shown above or below the node. */
35
+ label?: string;
36
+ /** Emoji or text icon rendered inside the node. */
37
+ icon?: string;
38
+ /** URI of an image to render inside the node circle. */
39
+ image?: string;
40
+ /** Arbitrary application data attached to the node. */
41
+ data?: Record<string, unknown>;
42
+ /** Node diameter in pixels. */
43
+ size?: number;
44
+ /** Class names for shared styling. */
45
+ classes?: string[];
46
+ }
47
+ /**
48
+ * Input format for creating or updating an edge via `engine.addEdge()`.
49
+ */
50
+ export interface EdgeInput {
51
+ /** Unique identifier. Auto-generated if omitted. */
52
+ id?: string;
53
+ /** ID of the source node. */
54
+ source: string | number;
55
+ /** ID of the target node. */
56
+ target: string | number;
57
+ /** Display label for the edge. */
58
+ label?: string;
59
+ /** Arbitrary application data attached to the edge. */
60
+ data?: Record<string, unknown>;
61
+ /** Class names for shared styling. */
62
+ classes?: string[];
63
+ }
64
+ /**
65
+ * Plain data object returned by `engine.getAllNodes()`.
66
+ */
67
+ export interface NodeData {
68
+ /** The original ID provided by the user. */
69
+ id: string | number;
70
+ /** Internal buffer index — used for direct GPU operations. */
71
+ _index: number;
72
+ /** Current world positions. */
73
+ position: {
74
+ x: number;
75
+ y: number;
76
+ };
77
+ label?: string;
78
+ icon?: string;
79
+ image?: string;
80
+ /** Arbitrary application data. */
81
+ data?: Record<string, unknown>;
82
+ /** Visual radius of the node. */
83
+ size?: number;
84
+ /** Applied class names. */
85
+ classes?: string[];
86
+ }
87
+ /**
88
+ * Plain data object returned by `engine.getAllEdges()`.
89
+ */
90
+ export interface EdgeData {
91
+ /** Unique edge ID. */
92
+ id: string;
93
+ /** ID of the source node. */
94
+ source: string | number;
95
+ /** ID of the target node. */
96
+ target: string | number;
97
+ label?: string;
98
+ /** Arbitrary application data. */
99
+ data?: Record<string, unknown>;
100
+ /** Applied class names. */
101
+ classes?: string[];
102
+ }
103
+ /**
104
+ * Engine-internal metadata for a node.
105
+ */
106
+ export interface NodeMetadata {
107
+ label?: string;
108
+ icon?: string;
109
+ image?: string;
110
+ imageElement?: HTMLImageElement;
111
+ processedImageElement?: HTMLCanvasElement | HTMLImageElement;
112
+ link?: string;
113
+ width?: number;
114
+ height?: number;
115
+ /** Arbitrary application data. */
116
+ data?: Record<string, unknown>;
117
+ classes?: string[];
118
+ }
119
+ /**
120
+ * Engine-internal metadata for an edge.
121
+ */
122
+ export interface EdgeMetadata {
123
+ label?: string;
124
+ width?: number;
125
+ /** Arbitrary application data. */
126
+ data?: Record<string, unknown>;
127
+ classes?: string[];
128
+ }
129
+ /**
130
+ * Configuration for the Energy Flow animation.
131
+ */
132
+ export interface FlowConfig {
133
+ enabled: boolean;
134
+ /** Particle movement speed (0-0.01) */
135
+ velocity: number;
136
+ /** Particle radius in pixels */
137
+ size: number;
138
+ /** Optional custom color */
139
+ color?: string;
140
+ /** Opacity (0-1) */
141
+ opacity?: number;
142
+ /** Enable pulse effect */
143
+ pulse?: boolean;
144
+ /** Optional property filter (metadata.data field) */
145
+ filterProp?: string | null;
146
+ /** Value to match for the filterProp */
147
+ filterValue?: unknown;
148
+ /** If true, only run flow on edges connected to selected nodes. */
149
+ selectedOnly?: boolean;
150
+ }
151
+ /**
152
+ * Represents a group of nodes that can be managed together.
153
+ */
154
+ export interface Combo {
155
+ /** Unique group ID. */
156
+ id: string;
157
+ /** Display label. */
158
+ label: string;
159
+ /** Set of internal node indices belonging to this group. */
160
+ nodeIds: Set<number>;
161
+ /** Optional hull color. */
162
+ color?: string;
163
+ /** Whether the group is currently collapsed into a summary node. */
164
+ collapsed?: boolean;
165
+ /** Stored positions of nodes before they were collapsed. */
166
+ originalPositions?: Map<number, {
167
+ x: number;
168
+ y: number;
169
+ }>;
170
+ /** The index of the node that remains visible to represent the group when collapsed. */
171
+ representativeId?: number;
172
+ }
173
+ /**
174
+ * An item in the radial (circular) context menu.
175
+ */
176
+ export interface RadialMenuItem {
177
+ /** Label shown in the menu segment. */
178
+ label: string;
179
+ /** Lucide icon name. */
180
+ icon: string;
181
+ /** Action ID emitted when clicked. */
182
+ action: string;
183
+ /** Optional arbitrary data. */
184
+ data?: any;
185
+ }
186
+ /**
187
+ * Temporary edge drawn during relation creation.
188
+ */
189
+ export interface PhantomEdge {
190
+ /** Internal index of the source node. */
191
+ sourceNodeId: number;
192
+ /** World-space target position (usually mouse position). */
193
+ targetPos: vec2;
194
+ }
195
+ /**
196
+ * Captures the current state of viewport interaction.
197
+ */
198
+ export interface InteractionState {
199
+ /** Viewport zoom level. */
200
+ zoom: number;
201
+ /** Screen-space offset (pan). */
202
+ offset: vec2;
203
+ /** Set of currently selected internal node indices. */
204
+ selectedNodeIds: Set<number>;
205
+ /** ID of the currently selected edge. */
206
+ selectedEdgeId: string | null;
207
+ /** ID of the currently selected combo. */
208
+ selectedComboId: string | null;
209
+ /** Index of the node currently under the mouse. */
210
+ hoveredNodeId: number | null;
211
+ /** Whether a box selection is currently active. */
212
+ isBoxSelecting: boolean;
213
+ /** Starting screen-space coordinate of the selection marquee. */
214
+ selectionStart: vec2;
215
+ /** Current screen-space coordinate of the selection marquee. */
216
+ selectionEnd: vec2;
217
+ /** Whether multiple nodes are being dragged. */
218
+ isMultiDragging: boolean;
219
+ /** Index of a single node currently being dragged. */
220
+ draggedNodeId: number | null;
221
+ /** Current energy flow configuration. */
222
+ flow: FlowConfig;
223
+ /** Temporary edge drawn during relation creation. */
224
+ phantomEdge: PhantomEdge | null;
225
+ }
package/dist/index.d.ts CHANGED
@@ -1 +1,8 @@
1
- export {}
1
+ import './style.css';
2
+ export { GraphEngine } from './engine/renderer';
3
+ export * from './engine/types';
4
+ export { default as GraphCanvas } from './components/GraphCanvas.vue';
5
+ export declare const createGraphData: (nodes: any[], edges: any[]) => {
6
+ nodes: any[];
7
+ edges: any[];
8
+ };
package/dist/vortx-gl.css CHANGED
@@ -1 +1 @@
1
- .vortx-gl-root{--vortx-primary: hsl(190, 100%, 50%);--vortx-primary-glow: hsla(190, 100%, 50%, .3);--vortx-primary-hover: hsl(190, 100%, 40%);--vortx-secondary: hsl(260, 100%, 65%);--vortx-secondary-glow: hsla(260, 100%, 65%, .3);--vortx-success: hsl(145, 80%, 45%);--vortx-warning: hsl(35, 100%, 55%);--vortx-danger: hsl(0, 85%, 60%);--vortx-bg-dark: hsl(230, 20%, 5%);--vortx-surface-dark: hsla(230, 15%, 15%, .6);--vortx-border-dark: hsla(0, 0%, 100%, .12);--vortx-text-dark: hsl(0, 0%, 98%);--vortx-text-dim-dark: hsl(230, 10%, 75%);--vortx-bg-light: hsl(220, 20%, 97%);--vortx-surface-light: hsla(0, 0%, 100%, .7);--vortx-border-light: hsla(230, 20%, 0%, .08);--vortx-text-light: hsl(230, 20%, 10%);--vortx-text-dim-light: hsl(230, 15%, 45%);--vortx-bg: var(--vortx-bg-dark);--vortx-surface: var(--vortx-surface-dark);--vortx-border: var(--vortx-border-dark);--vortx-text: var(--vortx-text-dark);--vortx-text-dim: var(--vortx-text-dim-dark);--vortx-glass-blur: 24px;--vortx-glass-border: 1px solid var(--vortx-border);--vortx-glass-shadow: 0 4px 12px 0 rgba(0, 0, 0, .4), 0 1px 3px 0 rgba(0, 0, 0, .2);--vortx-radius-sm: 8px;--vortx-radius-md: 12px;--vortx-radius-lg: 24px;--vortx-radius-full: 9999px;--vortx-space-xs: 4px;--vortx-space-sm: 8px;--vortx-space-md: 16px;--vortx-space-lg: 32px;--vortx-space-xl: 48px;font-family:Outfit,Inter,system-ui,-apple-system,sans-serif;line-height:1.6;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.vortx-gl-root.light{--vortx-bg: var(--vortx-bg-light);--vortx-surface: var(--vortx-surface-light);--vortx-border: var(--vortx-border-light);--vortx-text: var(--vortx-text-light);--vortx-text-dim: var(--vortx-text-dim-light);--vortx-glass-shadow: 0 4px 12px 0 rgba(0, 0, 0, .1), 0 1px 3px 0 rgba(0, 0, 0, .05)}.vortx-gl-root *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}.vortx-gl-root .glass{background:var(--vortx-surface);backdrop-filter:blur(var(--vortx-glass-blur));-webkit-backdrop-filter:blur(var(--vortx-glass-blur));border:var(--vortx-glass-border);box-shadow:var(--vortx-glass-shadow);color:var(--vortx-text)}.vortx-gl-root .glass-interactive{background:var(--vortx-surface);backdrop-filter:blur(var(--vortx-glass-blur));-webkit-backdrop-filter:blur(var(--vortx-glass-blur));border:var(--vortx-glass-border);box-shadow:var(--vortx-glass-shadow);transition:all .3s cubic-bezier(.4,0,.2,1);color:var(--vortx-text)}.vortx-gl-root .glass-interactive:hover{background:#3d425c4d;border-color:#00d4ff66;transform:translateY(-2px);box-shadow:0 8px 24px #00000080}.vortx-gl-root.light .glass-interactive:hover{background:#fffc;border-color:#00d4ff66;box-shadow:0 8px 24px #0000001a}.vortx-gl-root ::-webkit-scrollbar{width:8px;height:8px}.vortx-gl-root ::-webkit-scrollbar-track{background:transparent}.vortx-gl-root ::-webkit-scrollbar-thumb{background:var(--vortx-border);border-radius:var(--vortx-radius-full)}.vortx-gl-root ::-webkit-scrollbar-thumb:hover{background:var(--vortx-text-dim)}@keyframes vortxFadeIn{0%{opacity:0}to{opacity:1}}@keyframes vortxSlideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes vortxScaleIn{0%{transform:scale(.95);opacity:0}to{transform:scale(1);opacity:1}}@media(max-width:768px){.vortx-gl-root{--vortx-space-md: 12px;--vortx-space-lg: 24px;--vortx-glass-blur: 16px}}.lucide-icon[data-v-6aa14fad]{display:inline-block;vertical-align:middle}.radial-menu[data-v-9d75fdc7]{position:fixed;width:0;height:0;z-index:2000;pointer-events:none}.radial-center[data-v-9d75fdc7]{position:absolute;width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;transform:translate(-50%,-50%);animation:popIn-9d75fdc7 .4s cubic-bezier(.34,1.56,.64,1);pointer-events:auto;font-size:24px;border-color:var(--vortx-primary);box-shadow:0 0 20px #00ffd533}.radial-item[data-v-9d75fdc7]{position:absolute;width:64px;height:64px;pointer-events:none;animation:itemIn-9d75fdc7 .5s cubic-bezier(.34,1.56,.64,1) backwards;z-index:2001}.radial-item-inner[data-v-9d75fdc7]{width:100%;height:100%;border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;pointer-events:auto;transition:all .3s cubic-bezier(.175,.885,.32,1.275);border:1px solid var(--vortx-border);color:var(--vortx-text);outline:none;padding:0}.radial-item-inner[data-v-9d75fdc7]:hover{background:var(--vortx-primary);color:#fff;transform:scale(1.15);border-color:#fff;box-shadow:0 0 25px #00ffd580}.radial-icon[data-v-9d75fdc7]{font-size:20px}.radial-label[data-v-9d75fdc7]{font-size:9px;text-transform:uppercase;margin-top:2px;font-weight:700;letter-spacing:.5px}@keyframes popIn-9d75fdc7{0%{transform:translate(-50%,-50%) scale(0);opacity:0}to{transform:translate(-50%,-50%) scale(1);opacity:1}}@keyframes itemIn-9d75fdc7{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}to{opacity:1}}@media(max-width:768px){.radial-item[data-v-9d75fdc7]{width:72px;height:72px}.radial-icon[data-v-9d75fdc7]{font-size:24px}.radial-label[data-v-9d75fdc7]{font-size:10px}}.top-right-controls[data-v-f90ff709]{position:absolute;top:var(--vortx-space-md);right:var(--vortx-space-md);display:flex;flex-direction:column;gap:var(--vortx-space-xs);padding:var(--vortx-space-xs);border-radius:var(--vortx-radius-md);z-index:1000;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.control-btn[data-v-f90ff709]{width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:all .2s cubic-bezier(.4,0,.2,1);font-size:20px;background:transparent;border:none;color:var(--vortx-text);outline:none;position:relative;overflow:hidden}.control-btn[data-v-f90ff709]:hover{background:var(--vortx-border);transform:translateY(-2px)}.control-btn[data-v-f90ff709]:active{transform:scale(.9)}.stress-btn[data-v-f90ff709]{color:var(--vortx-warning)}.divider[data-v-f90ff709]{width:24px;height:1px;background:var(--vortx-border);align-self:center;margin:4px 0}@media(max-width:768px){.top-right-controls[data-v-f90ff709]{flex-direction:row;top:auto;bottom:var(--vortx-space-xl);right:50%;transform:translate(50%);gap:var(--vortx-space-sm);padding:var(--vortx-space-sm)}.divider[data-v-f90ff709]{width:1px;height:24px;margin:0 4px}.control-btn[data-v-f90ff709]{width:48px;height:48px;font-size:22px}}.layout-controls[data-v-2650a643]{position:absolute;bottom:var(--vortx-space-lg);left:50%;transform:translate(-50%);width:auto;max-width:90vw;padding:6px;border-radius:var(--vortx-radius-lg);z-index:1000;overflow:hidden}.scroll-container[data-v-2650a643]{display:flex;gap:var(--vortx-space-xs);overflow-x:auto;padding:2px;scrollbar-width:none;-ms-overflow-style:none}.scroll-container[data-v-2650a643]::-webkit-scrollbar{display:none}.layout-btn[data-v-2650a643]{padding:10px 18px;border-radius:var(--vortx-radius-md);cursor:pointer;font-size:14px;font-weight:500;transition:all .3s cubic-bezier(.4,0,.2,1);background:transparent;border:none;display:flex;align-items:center;gap:8px;color:var(--vortx-text-dim);white-space:nowrap;outline:none}.layout-btn[data-v-2650a643]:hover{background:var(--vortx-border);color:var(--vortx-text);transform:translateY(-2px)}.layout-btn.active[data-v-2650a643]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 15px var(--vortx-primary-glow);border-color:var(--vortx-primary)}.btn-icon[data-v-2650a643]{font-size:18px}@media(max-width:768px){.layout-controls[data-v-2650a643]{bottom:calc(var(--vortx-space-xl) + 80px);max-width:95vw;border-radius:var(--vortx-radius-md)}.layout-btn[data-v-2650a643]{padding:12px 20px;font-size:15px}}.property-panel[data-v-205cc0b7]{position:absolute;top:var(--vortx-space-md);left:var(--vortx-space-md);width:320px;max-height:calc(100vh - var(--vortx-space-xl) * 2);border-radius:var(--vortx-radius-lg);z-index:1100;display:flex;flex-direction:column;animation:slideIn-205cc0b7 .4s cubic-bezier(.16,1,.3,1);overflow:hidden}@keyframes slideIn-205cc0b7{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}.panel-header[data-v-205cc0b7]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.panel-header h3[data-v-205cc0b7]{margin:0;font-size:16px;font-weight:600;color:var(--vortx-primary);text-transform:uppercase;letter-spacing:.5px}.close-btn[data-v-205cc0b7]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer;padding:4px;font-size:18px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn[data-v-205cc0b7]:hover{color:var(--vortx-text)}.panel-content[data-v-205cc0b7]{padding:var(--vortx-space-md);overflow-y:auto;flex:1}.prop-group[data-v-205cc0b7]{margin-bottom:var(--vortx-space-md)}.prop-row[data-v-205cc0b7]{display:grid;grid-template-columns:1fr 1fr;gap:var(--vortx-space-sm)}.prop-group label[data-v-205cc0b7]{display:block;font-size:11px;font-weight:600;color:var(--vortx-text-dim);text-transform:uppercase;margin-bottom:var(--vortx-space-xs)}.id-badge[data-v-205cc0b7]{display:inline-block;background:var(--vortx-border);padding:4px 8px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:13px}.val-container[data-v-205cc0b7]{font-size:14px}input[data-v-205cc0b7]{width:100%;background:var(--vortx-border);border:1px solid transparent;padding:8px 12px;border-radius:var(--vortx-radius-sm);color:var(--vortx-text);font-family:monospace;font-size:14px;transition:all .2s}input[data-v-205cc0b7]:focus{outline:none;border-color:var(--vortx-primary);background:transparent}.json-prop[data-v-205cc0b7]{font-size:11px;background:#0003;padding:8px;border-radius:var(--vortx-radius-sm);margin:0;max-height:150px;overflow:auto;white-space:pre-wrap;word-break:break-all;border:1px solid var(--vortx-border)}.member-list[data-v-205cc0b7]{background:var(--vortx-border);border-radius:var(--vortx-radius-sm);padding:var(--vortx-space-xs);max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.member-item[data-v-205cc0b7]{display:flex;justify-content:space-between;align-items:center;padding:4px 8px;font-size:12px;border-radius:4px}.member-item[data-v-205cc0b7]:hover{background:var(--vortx-border)}.remove-btn[data-v-205cc0b7]{background:#ff00001a;border:none;color:var(--vortx-danger);width:20px;height:20px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px}.prop-image[data-v-205cc0b7]{width:64px;height:64px;object-fit:contain;padding:8px;background:var(--vortx-surface);border-radius:50%;border:1px solid var(--vortx-border);margin-top:4px;box-shadow:0 2px 8px #0003}.edge-panel .panel-header h3[data-v-205cc0b7]{color:var(--vortx-secondary)}.combo-panel .panel-header h3[data-v-205cc0b7]{color:var(--vortx-success)}@media(max-width:768px){.property-panel[data-v-205cc0b7]{inset:auto 0 0;width:100%;height:50vh;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;animation:vortxSlideUp .4s cubic-bezier(.16,1,.3,1)}}.search-wrapper[data-v-283de02c]{position:absolute;top:var(--vortx-space-md);left:50%;transform:translate(-50%);z-index:1200;transition:all .3s ease}.search-container[data-v-283de02c]{width:240px;max-width:90vw;border-radius:var(--vortx-radius-full);transition:all .3s cubic-bezier(.4,0,.2,1);padding:4px}.search-container.expanded[data-v-283de02c]{width:320px;border-radius:var(--vortx-radius-md)}.search-input-wrapper[data-v-283de02c]{display:flex;align-items:center;gap:8px;padding:4px 12px}.search-icon[data-v-283de02c]{opacity:.6}input[data-v-283de02c]{flex:1;background:transparent;border:none;border-radius:999px;padding:8px 4px;font-size:14px;color:var(--vortx-text);outline:none}.clear-btn[data-v-283de02c]{cursor:pointer;opacity:.5;padding:4px;display:flex;align-items:center}.results-panel[data-v-283de02c]{margin-top:4px;border-top:1px solid var(--vortx-border);padding:4px;max-height:250px;overflow-y:auto}.result-item[data-v-283de02c]{display:flex;align-items:center;gap:12px;padding:10px 12px;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:background .2s}.result-item[data-v-283de02c]:hover{background:var(--vortx-border)}.node-icon[data-v-283de02c]{color:var(--vortx-primary)}.node-info[data-v-283de02c]{display:flex;flex-direction:column}.node-label[data-v-283de02c]{font-size:13px;font-weight:500}.node-id[data-v-283de02c]{font-size:11px;opacity:.6}.no-results[data-v-283de02c]{padding:12px;text-align:center;font-size:13px;color:var(--vortx-text-dim);border-top:1px solid var(--vortx-border)}.search-wrapper.is-mobile[data-v-283de02c]{top:auto;bottom:var(--vortx-space-md);left:var(--vortx-space-md);transform:none}.is-mobile .search-container[data-v-283de02c]{width:52px;height:52px;overflow:hidden;padding:0;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px #0000004d;border-color:var(--vortx-primary)}.is-mobile .search-input-wrapper[data-v-283de02c]{padding:0;width:100%;height:100%;justify-content:center}.is-mobile .search-icon[data-v-283de02c]{margin:0}.is-mobile input[data-v-283de02c]{display:none}.is-mobile .search-container.expanded[data-v-283de02c]{position:fixed;bottom:0;left:0;width:100vw;height:auto;max-width:none;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;transform:none;padding:var(--vortx-space-md);display:block}.is-mobile .search-wrapper.mobile-expanded[data-v-283de02c]{left:0;bottom:0;width:100%}.is-mobile .search-container.expanded .search-input-wrapper[data-v-283de02c]{height:auto;padding:4px 0;margin-bottom:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.is-mobile .search-container.expanded input[data-v-283de02c]{display:block;font-size:16px}.is-mobile .search-container.expanded .results-panel[data-v-283de02c]{max-height:60vh}.mobile-backdrop[data-v-283de02c]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:-1}.container[data-v-d6f5f92c]{position:relative;width:100%;height:100%;transition:background-color .4s cubic-bezier(.4,0,.2,1);background:var(--vortx-bg);color:var(--vortx-text);overflow:hidden}.main-canvas[data-v-d6f5f92c],.overlay-canvas[data-v-d6f5f92c]{position:absolute;top:0;left:0;width:100%;height:100%;display:block}.overlay-canvas[data-v-d6f5f92c]{pointer-events:none}.mobile-menu[data-v-d6f5f92c]{position:fixed;bottom:var(--vortx-space-md);left:50%;transform:translate(-50%);display:flex;align-items:center;padding:6px;border-radius:var(--vortx-radius-full);z-index:1000;gap:4px}.menu-btn[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 16px;border-radius:var(--vortx-radius-full);cursor:pointer;transition:all .2s;min-width:70px}.menu-btn span[data-v-d6f5f92c]{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.menu-btn.active[data-v-d6f5f92c]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 12px var(--vortx-primary-glow)}.menu-divider[data-v-d6f5f92c]{width:1px;height:24px;background:var(--vortx-border);margin:0 4px}.drawer-overlay[data-v-d6f5f92c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1300}.mobile-drawer[data-v-d6f5f92c]{position:absolute;bottom:0;left:0;width:100%;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;padding:var(--vortx-space-md);padding-bottom:env(safe-area-inset-bottom,var(--vortx-space-lg));animation:vortxSlideUp .3s cubic-bezier(.16,1,.3,1)}.drawer-handle[data-v-d6f5f92c]{width:40px;height:4px;background:var(--vortx-border);border-radius:2px;margin:0 auto var(--vortx-space-md)}.drawer-header[data-v-d6f5f92c]{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--vortx-space-md)}.drawer-header h3[data-v-d6f5f92c]{margin:0;font-size:16px;font-weight:700}.drawer-close[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer}.drawer-content[data-v-d6f5f92c]{padding:var(--vortx-space-sm) 0}.drawer-content[data-v-d6f5f92c] .layout-controls,.drawer-content[data-v-d6f5f92c] .top-right-controls{position:static;transform:none;width:100%;max-width:none;padding:0;background:transparent;box-shadow:none;border:none;flex-direction:row;flex-wrap:wrap;justify-content:center}.drawer-content[data-v-d6f5f92c] .divider{display:none}.help-trigger[data-v-d6f5f92c]{position:absolute;bottom:var(--vortx-space-md);right:var(--vortx-space-md);width:32px;height:32px;background:var(--vortx-surface);border:1px solid var(--vortx-border);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;font-weight:700;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);z-index:1000;transition:all .2s;color:var(--vortx-text-dim)}.help-trigger[data-v-d6f5f92c]:hover{background:var(--vortx-primary);color:#fff;border-color:#fff;transform:scale(1.1)}.help-modal-overlay[data-v-d6f5f92c]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2000;display:flex;align-items:center;justify-content:center}.help-modal[data-v-d6f5f92c]{width:340px;border-radius:var(--vortx-radius-lg);overflow:hidden;animation:vortxScaleIn .3s cubic-bezier(.34,1.56,.64,1)}.help-header[data-v-d6f5f92c]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.help-header h3[data-v-d6f5f92c]{margin:0;font-size:16px}.shortcut-row[data-v-d6f5f92c]{display:flex;justify-content:space-between;align-items:center;padding:12px var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.shortcut-row[data-v-d6f5f92c]:last-child{border-bottom:none}.key-badge[data-v-d6f5f92c]{background:var(--vortx-border);padding:4px 10px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:12px}.action-desc[data-v-d6f5f92c]{font-size:13px;color:var(--vortx-text-dim)}.close-btn[data-v-d6f5f92c]{background:transparent;border:none;color:var(--vortx-text-dim);font-size:20px;cursor:pointer}@media(max-width:768px){.help-trigger[data-v-d6f5f92c]{display:none}}
1
+ .vortx-gl-root{--vortx-primary: hsl(190, 100%, 50%);--vortx-primary-glow: hsla(190, 100%, 50%, .3);--vortx-primary-hover: hsl(190, 100%, 40%);--vortx-secondary: hsl(260, 100%, 65%);--vortx-secondary-glow: hsla(260, 100%, 65%, .3);--vortx-success: hsl(145, 80%, 45%);--vortx-warning: hsl(35, 100%, 55%);--vortx-danger: hsl(0, 85%, 60%);--vortx-bg-dark: hsl(230, 20%, 5%);--vortx-surface-dark: hsla(230, 15%, 15%, .6);--vortx-border-dark: hsla(0, 0%, 100%, .12);--vortx-text-dark: hsl(0, 0%, 98%);--vortx-text-dim-dark: hsl(230, 10%, 75%);--vortx-bg-light: hsl(220, 20%, 97%);--vortx-surface-light: hsla(0, 0%, 100%, .7);--vortx-border-light: hsla(230, 20%, 0%, .08);--vortx-text-light: hsl(230, 20%, 10%);--vortx-text-dim-light: hsl(230, 15%, 45%);--vortx-bg: var(--vortx-bg-dark);--vortx-surface: var(--vortx-surface-dark);--vortx-border: var(--vortx-border-dark);--vortx-text: var(--vortx-text-dark);--vortx-text-dim: var(--vortx-text-dim-dark);--vortx-glass-blur: 24px;--vortx-glass-border: 1px solid var(--vortx-border);--vortx-glass-shadow: 0 4px 12px 0 rgba(0, 0, 0, .4), 0 1px 3px 0 rgba(0, 0, 0, .2);--vortx-radius-sm: 8px;--vortx-radius-md: 12px;--vortx-radius-lg: 24px;--vortx-radius-full: 9999px;--vortx-space-xs: 4px;--vortx-space-sm: 8px;--vortx-space-md: 16px;--vortx-space-lg: 32px;--vortx-space-xl: 48px;font-family:Outfit,Inter,system-ui,-apple-system,sans-serif;line-height:1.6;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.vortx-gl-root.light{--vortx-bg: var(--vortx-bg-light);--vortx-surface: var(--vortx-surface-light);--vortx-border: var(--vortx-border-light);--vortx-text: var(--vortx-text-light);--vortx-text-dim: var(--vortx-text-dim-light);--vortx-glass-shadow: 0 4px 12px 0 rgba(0, 0, 0, .1), 0 1px 3px 0 rgba(0, 0, 0, .05)}.vortx-gl-root *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}.vortx-gl-root .glass{background:var(--vortx-surface);backdrop-filter:blur(var(--vortx-glass-blur));-webkit-backdrop-filter:blur(var(--vortx-glass-blur));border:var(--vortx-glass-border);box-shadow:var(--vortx-glass-shadow);color:var(--vortx-text)}.vortx-gl-root .glass-interactive{background:var(--vortx-surface);backdrop-filter:blur(var(--vortx-glass-blur));-webkit-backdrop-filter:blur(var(--vortx-glass-blur));border:var(--vortx-glass-border);box-shadow:var(--vortx-glass-shadow);transition:all .3s cubic-bezier(.4,0,.2,1);color:var(--vortx-text)}.vortx-gl-root .glass-interactive:hover{background:#3d425c4d;border-color:#00d4ff66;transform:translateY(-2px);box-shadow:0 8px 24px #00000080}.vortx-gl-root.light .glass-interactive:hover{background:#fffc;border-color:#00d4ff66;box-shadow:0 8px 24px #0000001a}.vortx-gl-root ::-webkit-scrollbar{width:8px;height:8px}.vortx-gl-root ::-webkit-scrollbar-track{background:transparent}.vortx-gl-root ::-webkit-scrollbar-thumb{background:var(--vortx-border);border-radius:var(--vortx-radius-full)}.vortx-gl-root ::-webkit-scrollbar-thumb:hover{background:var(--vortx-text-dim)}@keyframes vortxFadeIn{0%{opacity:0}to{opacity:1}}@keyframes vortxSlideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes vortxScaleIn{0%{transform:scale(.95);opacity:0}to{transform:scale(1);opacity:1}}@media(max-width:768px){.vortx-gl-root{--vortx-space-md: 12px;--vortx-space-lg: 24px;--vortx-glass-blur: 16px}}.lucide-icon[data-v-6aa14fad]{display:inline-block;vertical-align:middle}.radial-menu[data-v-31b4eac1]{position:fixed;width:0;height:0;z-index:2000;pointer-events:none}.radial-center[data-v-31b4eac1]{position:absolute;width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;transform:translate(-50%,-50%);animation:popIn-31b4eac1 .4s cubic-bezier(.34,1.56,.64,1);pointer-events:auto;font-size:24px;border-color:var(--vortx-primary);box-shadow:0 0 20px #00ffd533}.radial-item[data-v-31b4eac1]{position:absolute;width:58px;height:58px;pointer-events:none;animation:itemIn-31b4eac1 .5s cubic-bezier(.34,1.56,.64,1) backwards;z-index:2001}.radial-item-inner[data-v-31b4eac1]{width:100%;height:100%;border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer;pointer-events:auto;transition:all .3s cubic-bezier(.175,.885,.32,1.275);border:1px solid var(--vortx-border);color:var(--vortx-text);outline:none;padding:0}.radial-item-inner[data-v-31b4eac1]:hover{background:var(--vortx-primary);color:#fff;transform:scale(1.15);border-color:#fff;box-shadow:0 0 25px #00ffd580}.radial-icon[data-v-31b4eac1]{font-size:20px}.radial-label[data-v-31b4eac1]{font-size:9px;text-transform:uppercase;margin-top:2px;font-weight:700;letter-spacing:.5px}@keyframes popIn-31b4eac1{0%{transform:translate(-50%,-50%) scale(0);opacity:0}to{transform:translate(-50%,-50%) scale(1);opacity:1}}@keyframes itemIn-31b4eac1{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}to{opacity:1}}@media(max-width:768px){.radial-item[data-v-31b4eac1]{width:72px;height:72px}.radial-icon[data-v-31b4eac1]{font-size:24px}.radial-label[data-v-31b4eac1]{font-size:10px}}.top-right-controls[data-v-08b2ffb9]{position:absolute;top:var(--vortx-space-md);right:var(--vortx-space-md);display:flex;flex-direction:column;gap:var(--vortx-space-xs);padding:var(--vortx-space-xs);border-radius:var(--vortx-radius-md);z-index:1000;transition:transform .3s cubic-bezier(.34,1.56,.64,1)}.control-btn[data-v-08b2ffb9]{width:44px;height:44px;display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:all .2s cubic-bezier(.4,0,.2,1);font-size:20px;background:transparent;border:none;color:var(--vortx-text);outline:none;position:relative;overflow:hidden}.control-btn[data-v-08b2ffb9]:hover{background:var(--vortx-border);transform:translateY(-2px)}.control-btn[data-v-08b2ffb9]:active{transform:scale(.9)}.stress-btn[data-v-08b2ffb9]{color:var(--vortx-warning)}.flow-active[data-v-08b2ffb9]{color:var(--vortx-primary);background:var(--vortx-primary-glow)!important;box-shadow:0 0 15px var(--vortx-primary-glow)}.divider[data-v-08b2ffb9]{width:24px;height:1px;background:var(--vortx-border);align-self:center;margin:4px 0}@media(max-width:768px){.top-right-controls[data-v-08b2ffb9]{flex-direction:row;top:auto;bottom:var(--vortx-space-xl);right:50%;transform:translate(50%);gap:var(--vortx-space-sm);padding:var(--vortx-space-sm)}.divider[data-v-08b2ffb9]{width:1px;height:24px;margin:0 4px}.control-btn[data-v-08b2ffb9]{width:48px;height:48px;font-size:22px}}.layout-controls[data-v-503d31c7]{position:absolute;bottom:var(--vortx-space-lg);left:50%;transform:translate(-50%);width:auto;max-width:90vw;padding:6px;border-radius:var(--vortx-radius-lg);z-index:1000;overflow:hidden}.scroll-container[data-v-503d31c7]{display:flex;gap:var(--vortx-space-xs);overflow-x:auto;padding:2px;scrollbar-width:none;-ms-overflow-style:none}.scroll-container[data-v-503d31c7]::-webkit-scrollbar{display:none}.layout-btn[data-v-503d31c7]{padding:8px 14px;border-radius:var(--vortx-radius-md);cursor:pointer;font-size:13px;font-weight:500;transition:all .2s cubic-bezier(.4,0,.2,1);background:transparent;border:none;display:flex;align-items:center;gap:6px;color:var(--vortx-text-dim);white-space:nowrap;outline:none}.layout-btn[data-v-503d31c7]:hover{background:var(--vortx-border);color:var(--vortx-text);transform:translateY(-2px)}.layout-btn.active[data-v-503d31c7]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 15px var(--vortx-primary-glow);border-color:var(--vortx-primary)}.btn-icon[data-v-503d31c7]{font-size:18px}@media(max-width:768px){.layout-controls[data-v-503d31c7]{bottom:calc(var(--vortx-space-xl) + 80px);max-width:95vw;border-radius:var(--vortx-radius-md)}.layout-btn[data-v-503d31c7]{padding:10px 16px}.layout-btn .btn-name[data-v-503d31c7]{display:inline}}.property-panel[data-v-acd191f9]{position:absolute;top:var(--vortx-space-md);right:var(--vortx-space-md);width:320px;max-height:calc(100vh - var(--vortx-space-xl) * 2);border-radius:var(--vortx-radius-lg);z-index:1100;display:flex;flex-direction:column;animation:slideIn-acd191f9 .4s cubic-bezier(.16,1,.3,1);overflow:hidden}@keyframes slideIn-acd191f9{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}.panel-header[data-v-acd191f9]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.panel-header h3[data-v-acd191f9]{margin:0;font-size:16px;font-weight:600;color:var(--vortx-primary);text-transform:uppercase;letter-spacing:.5px}.close-btn[data-v-acd191f9]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer;padding:4px;font-size:18px;display:flex;align-items:center;justify-content:center;transition:color .2s}.close-btn[data-v-acd191f9]:hover{color:var(--vortx-text)}.panel-content[data-v-acd191f9]{padding:var(--vortx-space-md);overflow-y:auto;flex:1}.prop-group[data-v-acd191f9]{margin-bottom:var(--vortx-space-md)}.prop-row[data-v-acd191f9]{display:grid;grid-template-columns:1fr 1fr;gap:var(--vortx-space-sm)}.prop-group label[data-v-acd191f9]{display:block;font-size:11px;font-weight:600;color:var(--vortx-text-dim);text-transform:uppercase;margin-bottom:var(--vortx-space-xs)}.id-badge[data-v-acd191f9]{display:inline-block;background:var(--vortx-border);padding:4px 8px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:13px}.val-container[data-v-acd191f9]{font-size:14px}input[data-v-acd191f9]{width:100%;background:var(--vortx-border);border:1px solid transparent;padding:8px 12px;border-radius:var(--vortx-radius-sm);color:var(--vortx-text);font-family:monospace;font-size:14px;transition:all .2s}input[data-v-acd191f9]:focus{outline:none;border-color:var(--vortx-primary);background:transparent}.json-prop[data-v-acd191f9]{font-size:11px;background:#0003;padding:8px;border-radius:var(--vortx-radius-sm);margin:0;max-height:150px;overflow:auto;white-space:pre-wrap;word-break:break-all;border:1px solid var(--vortx-border)}.member-list[data-v-acd191f9]{background:var(--vortx-border);border-radius:var(--vortx-radius-sm);padding:var(--vortx-space-xs);max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.member-item[data-v-acd191f9]{display:flex;justify-content:space-between;align-items:center;padding:4px 8px;font-size:12px;border-radius:4px}.member-item[data-v-acd191f9]:hover{background:var(--vortx-border)}.remove-btn[data-v-acd191f9]{background:#ff00001a;border:none;color:var(--vortx-danger);width:20px;height:20px;border-radius:4px;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:10px}.prop-image[data-v-acd191f9]{width:64px;height:64px;object-fit:contain;padding:8px;background:var(--vortx-surface);border-radius:50%;border:1px solid var(--vortx-border);margin-top:4px;box-shadow:0 2px 8px #0003}.edge-panel .panel-header h3[data-v-acd191f9]{color:var(--vortx-secondary)}.combo-panel .panel-header h3[data-v-acd191f9]{color:var(--vortx-success)}@media(max-width:768px){.property-panel[data-v-acd191f9]{inset:auto 0 0;width:100%;height:50vh;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;animation:vortxSlideUp .4s cubic-bezier(.16,1,.3,1)}}.search-wrapper[data-v-283de02c]{position:absolute;top:var(--vortx-space-md);left:50%;transform:translate(-50%);z-index:1200;transition:all .3s ease}.search-container[data-v-283de02c]{width:240px;max-width:90vw;border-radius:var(--vortx-radius-full);transition:all .3s cubic-bezier(.4,0,.2,1);padding:4px}.search-container.expanded[data-v-283de02c]{width:320px;border-radius:var(--vortx-radius-md)}.search-input-wrapper[data-v-283de02c]{display:flex;align-items:center;gap:8px;padding:4px 12px}.search-icon[data-v-283de02c]{opacity:.6}input[data-v-283de02c]{flex:1;background:transparent;border:none;border-radius:999px;padding:8px 4px;font-size:14px;color:var(--vortx-text);outline:none}.clear-btn[data-v-283de02c]{cursor:pointer;opacity:.5;padding:4px;display:flex;align-items:center}.results-panel[data-v-283de02c]{margin-top:4px;border-top:1px solid var(--vortx-border);padding:4px;max-height:250px;overflow-y:auto}.result-item[data-v-283de02c]{display:flex;align-items:center;gap:12px;padding:10px 12px;cursor:pointer;border-radius:var(--vortx-radius-sm);transition:background .2s}.result-item[data-v-283de02c]:hover{background:var(--vortx-border)}.node-icon[data-v-283de02c]{color:var(--vortx-primary)}.node-info[data-v-283de02c]{display:flex;flex-direction:column}.node-label[data-v-283de02c]{font-size:13px;font-weight:500}.node-id[data-v-283de02c]{font-size:11px;opacity:.6}.no-results[data-v-283de02c]{padding:12px;text-align:center;font-size:13px;color:var(--vortx-text-dim);border-top:1px solid var(--vortx-border)}.search-wrapper.is-mobile[data-v-283de02c]{top:auto;bottom:var(--vortx-space-md);left:var(--vortx-space-md);transform:none}.is-mobile .search-container[data-v-283de02c]{width:52px;height:52px;overflow:hidden;padding:0;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px #0000004d;border-color:var(--vortx-primary)}.is-mobile .search-input-wrapper[data-v-283de02c]{padding:0;width:100%;height:100%;justify-content:center}.is-mobile .search-icon[data-v-283de02c]{margin:0}.is-mobile input[data-v-283de02c]{display:none}.is-mobile .search-container.expanded[data-v-283de02c]{position:fixed;bottom:0;left:0;width:100vw;height:auto;max-width:none;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;transform:none;padding:var(--vortx-space-md);display:block}.is-mobile .search-wrapper.mobile-expanded[data-v-283de02c]{left:0;bottom:0;width:100%}.is-mobile .search-container.expanded .search-input-wrapper[data-v-283de02c]{height:auto;padding:4px 0;margin-bottom:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.is-mobile .search-container.expanded input[data-v-283de02c]{display:block;font-size:16px}.is-mobile .search-container.expanded .results-panel[data-v-283de02c]{max-height:60vh}.mobile-backdrop[data-v-283de02c]{position:fixed;inset:0;background:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:-1}:root{--vortx-bg: #09090b;--vortx-surface: rgba(18, 18, 22, .7);--vortx-primary: #00ffcc;--vortx-primary-glow: hsla(170, 100%, 50%, .3);--vortx-border: rgba(255, 255, 255, .08);--vortx-text: #f4f4f5;--vortx-text-dim: #a1a1aa;--vortx-radius-sm: 8px;--vortx-radius-md: 12px;--vortx-radius-lg: 20px;--vortx-radius-full: 9999px;--vortx-space-xs: 4px;--vortx-space-sm: 8px;--vortx-space-md: 16px;--vortx-space-lg: 24px}::-webkit-scrollbar{display:none!important}*{-ms-overflow-style:none!important;scrollbar-width:none!important}.glass{background:var(--vortx-surface);backdrop-filter:blur(12px) saturate(180%);-webkit-backdrop-filter:blur(12px) saturate(180%);border:1px solid var(--vortx-border)}.glass-interactive{background:var(--vortx-surface);-webkit-backdrop-filter:blur(12px) saturate(180%);backdrop-filter:blur(12px) saturate(180%);border:1px solid var(--vortx-border);transition:all .2s cubic-bezier(.4,0,.2,1)}.glass-interactive:hover{background:#ffffff0d;border-color:#fff3;transform:translateY(-1px)}.shadow-glow{box-shadow:0 8px 32px #0006,0 0 15px var(--vortx-primary-glow)}.container[data-v-0b4073a8]{position:relative;width:100vw;height:100vh;transition:background-color .4s cubic-bezier(.4,0,.2,1);background:var(--vortx-bg);color:var(--vortx-text);overflow:hidden;-webkit-user-select:none;user-select:none}.main-canvas[data-v-0b4073a8],.overlay-canvas[data-v-0b4073a8]{position:absolute;top:0;left:0;width:100%;height:100%;display:block}.overlay-canvas[data-v-0b4073a8]{pointer-events:none}.mobile-menu[data-v-0b4073a8]{position:fixed;bottom:var(--vortx-space-md);left:50%;transform:translate(-50%);display:flex;align-items:center;padding:6px;border-radius:var(--vortx-radius-full);z-index:1000;gap:4px}.menu-btn[data-v-0b4073a8]{background:transparent;border:none;color:var(--vortx-text-dim);display:flex;flex-direction:column;align-items:center;gap:4px;padding:8px 16px;border-radius:var(--vortx-radius-full);cursor:pointer;transition:all .2s;min-width:70px}.menu-btn span[data-v-0b4073a8]{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px}.menu-btn.active[data-v-0b4073a8]{background:var(--vortx-primary);color:#fff;box-shadow:0 4px 12px var(--vortx-primary-glow)}.menu-divider[data-v-0b4073a8]{width:1px;height:24px;background:var(--vortx-border);margin:0 4px}.drawer-overlay[data-v-0b4073a8]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1300}.mobile-drawer[data-v-0b4073a8]{position:absolute;bottom:0;left:0;width:100%;border-radius:var(--vortx-radius-lg) var(--vortx-radius-lg) 0 0;padding:var(--vortx-space-md);padding-bottom:env(safe-area-inset-bottom,var(--vortx-space-lg));animation:vortxSlideUp .3s cubic-bezier(.16,1,.3,1)}.drawer-handle[data-v-0b4073a8]{width:40px;height:4px;background:var(--vortx-border);border-radius:2px;margin:0 auto var(--vortx-space-md)}.drawer-header[data-v-0b4073a8]{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--vortx-space-md)}.drawer-header h3[data-v-0b4073a8]{margin:0;font-size:16px;font-weight:700}.drawer-close[data-v-0b4073a8]{background:transparent;border:none;color:var(--vortx-text-dim);cursor:pointer}.drawer-content[data-v-0b4073a8]{padding:var(--vortx-space-sm) 0}.drawer-content[data-v-0b4073a8] .layout-controls,.drawer-content[data-v-0b4073a8] .top-right-controls{position:static;transform:none;width:100%;max-width:none;padding:0;background:transparent;box-shadow:none;border:none;flex-direction:row;flex-wrap:wrap;justify-content:center}.drawer-content[data-v-0b4073a8] .divider{display:none}.help-trigger[data-v-0b4073a8]{position:absolute;bottom:var(--vortx-space-md);right:var(--vortx-space-md);width:32px;height:32px;background:var(--vortx-surface);border:1px solid var(--vortx-border);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;font-weight:700;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);z-index:1000;transition:all .2s;color:var(--vortx-text-dim)}.help-trigger[data-v-0b4073a8]:hover{background:var(--vortx-primary);color:#fff;border-color:#fff;transform:scale(1.1)}.help-modal-overlay[data-v-0b4073a8]{position:fixed;inset:0;background:#0006;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2000;display:flex;align-items:center;justify-content:center}.help-modal[data-v-0b4073a8]{width:340px;border-radius:var(--vortx-radius-lg);overflow:hidden;animation:vortxScaleIn .3s cubic-bezier(.34,1.56,.64,1)}.help-header[data-v-0b4073a8]{padding:var(--vortx-space-md);border-bottom:1px solid var(--vortx-border);display:flex;justify-content:space-between;align-items:center}.help-header h3[data-v-0b4073a8]{margin:0;font-size:16px}.shortcut-row[data-v-0b4073a8]{display:flex;justify-content:space-between;align-items:center;padding:12px var(--vortx-space-md);border-bottom:1px solid var(--vortx-border)}.shortcut-row[data-v-0b4073a8]:last-child{border-bottom:none}.key-badge[data-v-0b4073a8]{background:var(--vortx-border);padding:4px 10px;border-radius:var(--vortx-radius-sm);font-family:monospace;font-size:12px}.action-desc[data-v-0b4073a8]{font-size:13px;color:var(--vortx-text-dim)}.close-btn[data-v-0b4073a8]{background:transparent;border:none;color:var(--vortx-text-dim);font-size:20px;cursor:pointer}@media(max-width:768px){.help-trigger[data-v-0b4073a8]{display:none}}.connecting-toast[data-v-0b4073a8]{position:fixed;top:var(--vortx-space-lg);left:50%;transform:translate(-50%);z-index:3000;display:flex;align-items:center;gap:var(--vortx-space-md);padding:8px 16px;border-radius:var(--vortx-radius-lg);border:1px solid var(--vortx-primary);animation:vortxSlideDown-0b4073a8 .3s cubic-bezier(.16,1,.3,1);min-width:500px}.edge-config-group[data-v-0b4073a8]{display:flex;align-items:center;gap:12px}.vortx-input-sm[data-v-0b4073a8]{background:#ffffff0d;border:1px solid var(--vortx-border);border-radius:var(--vortx-radius-sm);padding:6px 12px;color:#fff;font-size:13px;width:140px;height:32px}.vortx-input-sm.narrow[data-v-0b4073a8]{width:60px}.color-presets[data-v-0b4073a8]{display:flex;gap:6px}.color-dot[data-v-0b4073a8]{width:18px;height:18px;border-radius:50%;cursor:pointer;transition:transform .2s}.color-dot[data-v-0b4073a8]:hover{transform:scale(1.2)}.size-config[data-v-0b4073a8]{display:flex;align-items:center;gap:6px}.divider-v[data-v-0b4073a8]{width:1px;height:24px;background:var(--vortx-border)}.instruction-text[data-v-0b4073a8]{font-size:13px;font-weight:700;color:var(--vortx-primary);white-space:nowrap}.toast-content[data-v-0b4073a8]{display:flex;align-items:center;gap:16px;flex:1}.dim[data-v-0b4073a8]{opacity:.5}.pulse-icon[data-v-0b4073a8]{color:var(--vortx-primary);animation:vortxPulse-0b4073a8 2s infinite}.toast-cancel[data-v-0b4073a8]{background:#ffffff1a;border:none;color:var(--vortx-text-dim);width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s}.toast-cancel[data-v-0b4073a8]:hover{background:#f003;color:#fff}@keyframes vortxPulse-0b4073a8{0%{transform:scale(1);opacity:1}50%{transform:scale(1.2);opacity:.7}to{transform:scale(1);opacity:1}}@keyframes vortxSlideDown-0b4073a8{0%{transform:translate(-50%,-20px);opacity:0}to{transform:translate(-50%);opacity:1}}