@goplasmatic/datalogic-ui 4.0.21 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +35 -15
  2. package/dist/components/logic-editor/AutoFitView.d.ts +7 -0
  3. package/dist/components/logic-editor/AutoFitView.d.ts.map +1 -1
  4. package/dist/components/logic-editor/DataLogicEditor.d.ts +1 -1
  5. package/dist/components/logic-editor/DataLogicEditor.d.ts.map +1 -1
  6. package/dist/components/logic-editor/EditorToolbar.d.ts +6 -3
  7. package/dist/components/logic-editor/EditorToolbar.d.ts.map +1 -1
  8. package/dist/components/logic-editor/UndoRedoToolbar.d.ts +1 -1
  9. package/dist/components/logic-editor/UndoRedoToolbar.d.ts.map +1 -1
  10. package/dist/components/logic-editor/config/operators/utility.d.ts.map +1 -1
  11. package/dist/components/logic-editor/constants/index.d.ts +1 -1
  12. package/dist/components/logic-editor/constants/index.d.ts.map +1 -1
  13. package/dist/components/logic-editor/constants/layout.d.ts +13 -4
  14. package/dist/components/logic-editor/constants/layout.d.ts.map +1 -1
  15. package/dist/components/logic-editor/context/ConnectedHandlesContext.d.ts +1 -1
  16. package/dist/components/logic-editor/context/ConnectedHandlesContext.d.ts.map +1 -1
  17. package/dist/components/logic-editor/context/DirectionContextDef.d.ts +11 -0
  18. package/dist/components/logic-editor/context/DirectionContextDef.d.ts.map +1 -0
  19. package/dist/components/logic-editor/context/debugger/DebuggerProvider.d.ts +1 -1
  20. package/dist/components/logic-editor/context/debugger/DebuggerProvider.d.ts.map +1 -1
  21. package/dist/components/logic-editor/context/editor/EditorContext.d.ts +1 -1
  22. package/dist/components/logic-editor/context/editor/EditorContext.d.ts.map +1 -1
  23. package/dist/components/logic-editor/context/editor/useClipboardState.d.ts.map +1 -1
  24. package/dist/components/logic-editor/context/editor/useHistoryState.d.ts.map +1 -1
  25. package/dist/components/logic-editor/context/index.d.ts +2 -0
  26. package/dist/components/logic-editor/context/index.d.ts.map +1 -1
  27. package/dist/components/logic-editor/context/useDirection.d.ts +6 -0
  28. package/dist/components/logic-editor/context/useDirection.d.ts.map +1 -0
  29. package/dist/components/logic-editor/context-menu/CanvasContextMenu.d.ts +1 -1
  30. package/dist/components/logic-editor/context-menu/CanvasContextMenu.d.ts.map +1 -1
  31. package/dist/components/logic-editor/context-menu/ContextMenu.d.ts +1 -1
  32. package/dist/components/logic-editor/context-menu/ContextMenu.d.ts.map +1 -1
  33. package/dist/components/logic-editor/debugger-controls/DebuggerControls.d.ts +2 -2
  34. package/dist/components/logic-editor/debugger-controls/DebuggerControls.d.ts.map +1 -1
  35. package/dist/components/logic-editor/edges/EdgeOperatorPicker.d.ts +1 -1
  36. package/dist/components/logic-editor/edges/EdgeOperatorPicker.d.ts.map +1 -1
  37. package/dist/components/logic-editor/edges/EditableEdge.d.ts +1 -1
  38. package/dist/components/logic-editor/edges/EditableEdge.d.ts.map +1 -1
  39. package/dist/components/logic-editor/edges/index.d.ts +1 -1
  40. package/dist/components/logic-editor/hooks/index.d.ts +1 -1
  41. package/dist/components/logic-editor/hooks/index.d.ts.map +1 -1
  42. package/dist/components/logic-editor/hooks/useLogicEditor.d.ts +6 -3
  43. package/dist/components/logic-editor/hooks/useLogicEditor.d.ts.map +1 -1
  44. package/dist/components/logic-editor/hooks/useWasmEvaluator.d.ts +8 -3
  45. package/dist/components/logic-editor/hooks/useWasmEvaluator.d.ts.map +1 -1
  46. package/dist/components/logic-editor/nodes/CellHandles.d.ts +1 -1
  47. package/dist/components/logic-editor/nodes/CellHandles.d.ts.map +1 -1
  48. package/dist/components/logic-editor/nodes/CellRow.d.ts +1 -1
  49. package/dist/components/logic-editor/nodes/CellRow.d.ts.map +1 -1
  50. package/dist/components/logic-editor/nodes/DebugInfoBubble.d.ts +1 -1
  51. package/dist/components/logic-editor/nodes/DebugInfoBubble.d.ts.map +1 -1
  52. package/dist/components/logic-editor/nodes/LiteralNode.d.ts +1 -1
  53. package/dist/components/logic-editor/nodes/LiteralNode.d.ts.map +1 -1
  54. package/dist/components/logic-editor/nodes/StructureNode.d.ts +1 -1
  55. package/dist/components/logic-editor/nodes/StructureNode.d.ts.map +1 -1
  56. package/dist/components/logic-editor/nodes/UnifiedOperatorNode.d.ts +1 -1
  57. package/dist/components/logic-editor/nodes/UnifiedOperatorNode.d.ts.map +1 -1
  58. package/dist/components/logic-editor/nodes/shared/CollapseToggleButton.d.ts +1 -1
  59. package/dist/components/logic-editor/nodes/shared/CollapseToggleButton.d.ts.map +1 -1
  60. package/dist/components/logic-editor/nodes/shared/NodeDebugBubble.d.ts +1 -1
  61. package/dist/components/logic-editor/nodes/shared/NodeDebugBubble.d.ts.map +1 -1
  62. package/dist/components/logic-editor/nodes/shared/NodeInputHandles.d.ts +6 -3
  63. package/dist/components/logic-editor/nodes/shared/NodeInputHandles.d.ts.map +1 -1
  64. package/dist/components/logic-editor/panel-inputs/BooleanInput.d.ts +1 -1
  65. package/dist/components/logic-editor/panel-inputs/BooleanInput.d.ts.map +1 -1
  66. package/dist/components/logic-editor/panel-inputs/ExpressionInput.d.ts +1 -1
  67. package/dist/components/logic-editor/panel-inputs/ExpressionInput.d.ts.map +1 -1
  68. package/dist/components/logic-editor/panel-inputs/JsonInput.d.ts +1 -1
  69. package/dist/components/logic-editor/panel-inputs/JsonInput.d.ts.map +1 -1
  70. package/dist/components/logic-editor/panel-inputs/NumberInput.d.ts +1 -1
  71. package/dist/components/logic-editor/panel-inputs/NumberInput.d.ts.map +1 -1
  72. package/dist/components/logic-editor/panel-inputs/PathArrayInput.d.ts +1 -1
  73. package/dist/components/logic-editor/panel-inputs/PathArrayInput.d.ts.map +1 -1
  74. package/dist/components/logic-editor/panel-inputs/PathInput.d.ts +1 -1
  75. package/dist/components/logic-editor/panel-inputs/PathInput.d.ts.map +1 -1
  76. package/dist/components/logic-editor/panel-inputs/SelectInput.d.ts +1 -1
  77. package/dist/components/logic-editor/panel-inputs/SelectInput.d.ts.map +1 -1
  78. package/dist/components/logic-editor/panel-inputs/TextAreaInput.d.ts +1 -1
  79. package/dist/components/logic-editor/panel-inputs/TextAreaInput.d.ts.map +1 -1
  80. package/dist/components/logic-editor/panel-inputs/TextInput.d.ts +1 -1
  81. package/dist/components/logic-editor/panel-inputs/TextInput.d.ts.map +1 -1
  82. package/dist/components/logic-editor/properties-panel/ArgumentItem.d.ts +1 -1
  83. package/dist/components/logic-editor/properties-panel/ArgumentItem.d.ts.map +1 -1
  84. package/dist/components/logic-editor/properties-panel/ArgumentsSection.d.ts +1 -1
  85. package/dist/components/logic-editor/properties-panel/ArgumentsSection.d.ts.map +1 -1
  86. package/dist/components/logic-editor/properties-panel/HelpSection.d.ts +1 -1
  87. package/dist/components/logic-editor/properties-panel/HelpSection.d.ts.map +1 -1
  88. package/dist/components/logic-editor/properties-panel/PropertiesPanel.d.ts +1 -1
  89. package/dist/components/logic-editor/properties-panel/PropertiesPanel.d.ts.map +1 -1
  90. package/dist/components/logic-editor/types/editor.d.ts +18 -6
  91. package/dist/components/logic-editor/types/editor.d.ts.map +1 -1
  92. package/dist/components/logic-editor/types/index.d.ts +1 -1
  93. package/dist/components/logic-editor/types/index.d.ts.map +1 -1
  94. package/dist/components/logic-editor/types/trace.d.ts +22 -0
  95. package/dist/components/logic-editor/types/trace.d.ts.map +1 -1
  96. package/dist/components/logic-editor/utils/ExpressionSyntax.d.ts +1 -1
  97. package/dist/components/logic-editor/utils/ExpressionSyntax.d.ts.map +1 -1
  98. package/dist/components/logic-editor/utils/converters/if-else-converter.d.ts +6 -0
  99. package/dist/components/logic-editor/utils/converters/if-else-converter.d.ts.map +1 -1
  100. package/dist/components/logic-editor/utils/converters/operator-converter.d.ts.map +1 -1
  101. package/dist/components/logic-editor/utils/converters/types.d.ts +2 -2
  102. package/dist/components/logic-editor/utils/converters/types.d.ts.map +1 -1
  103. package/dist/components/logic-editor/utils/edge-builder.d.ts +5 -4
  104. package/dist/components/logic-editor/utils/edge-builder.d.ts.map +1 -1
  105. package/dist/components/logic-editor/utils/formatting/arg-summary.d.ts +7 -0
  106. package/dist/components/logic-editor/utils/formatting/arg-summary.d.ts.map +1 -1
  107. package/dist/components/logic-editor/utils/formatting/index.d.ts +1 -1
  108. package/dist/components/logic-editor/utils/formatting/index.d.ts.map +1 -1
  109. package/dist/components/logic-editor/utils/inline-vars.d.ts +15 -0
  110. package/dist/components/logic-editor/utils/inline-vars.d.ts.map +1 -0
  111. package/dist/components/logic-editor/utils/jsonlogic-to-nodes.d.ts +2 -2
  112. package/dist/components/logic-editor/utils/jsonlogic-to-nodes.d.ts.map +1 -1
  113. package/dist/components/logic-editor/utils/layout.d.ts +2 -1
  114. package/dist/components/logic-editor/utils/layout.d.ts.map +1 -1
  115. package/dist/components/logic-editor/utils/node-factory.d.ts.map +1 -1
  116. package/dist/components/logic-editor/utils/nodeShape.d.ts +23 -0
  117. package/dist/components/logic-editor/utils/nodeShape.d.ts.map +1 -0
  118. package/dist/components/logic-editor/utils/signal.d.ts +10 -0
  119. package/dist/components/logic-editor/utils/signal.d.ts.map +1 -0
  120. package/dist/components/logic-editor/utils/trace/node-creators/if-else.d.ts +4 -2
  121. package/dist/components/logic-editor/utils/trace/node-creators/if-else.d.ts.map +1 -1
  122. package/dist/components/logic-editor/utils/trace/node-creators/variable.d.ts.map +1 -1
  123. package/dist/components/logic-editor/utils/trace/node-creators/vertical-cell.d.ts.map +1 -1
  124. package/dist/components/logic-editor/utils/trace/node-type.d.ts +1 -1
  125. package/dist/components/logic-editor/utils/trace/node-type.d.ts.map +1 -1
  126. package/dist/components/logic-editor/utils/trace/types.d.ts +3 -3
  127. package/dist/components/logic-editor/utils/trace/types.d.ts.map +1 -1
  128. package/dist/datalogic_wasm-BOuSyKtI.cjs +1148 -0
  129. package/dist/datalogic_wasm-Dloh5u2g.js +1145 -0
  130. package/dist/index.cjs +3296 -2323
  131. package/dist/index.js +3298 -2325
  132. package/dist/styles.css +1380 -474
  133. package/package.json +50 -41
  134. package/dist/datalogic_wasm-Ckkdrc0z.cjs +0 -383
  135. package/dist/datalogic_wasm-daWVf40b.js +0 -380
package/dist/styles.css CHANGED
@@ -1,88 +1,171 @@
1
1
  /*
2
- * DataLogic UI - Scoped Theme Variables
2
+ * DataLogic UI "Signal Board" theme tokens
3
+ * ============================================================
4
+ * Every design decision in this component is expressed as a CSS custom
5
+ * property, all scoped to `.logic-editor` so nothing leaks into the host app.
3
6
  *
4
- * All variables are scoped to .logic-editor to avoid leaking into consumer apps.
5
- * The library component applies this class to its root element.
7
+ * OVERRIDING FROM A CONSUMER APP
8
+ * ------------------------------
9
+ * Import the stylesheet once, then redefine any token with equal-or-greater
10
+ * specificity. Two supported patterns:
11
+ *
12
+ * 1. Re-tune the whole component:
13
+ * .logic-editor { --sig-number: #0ea5e9; --board: #f7f7f8; }
14
+ * .logic-editor[data-theme="dark"] { --board: #0b0b0f; }
15
+ *
16
+ * 2. Scope an override to one instance (pass className to DataLogicEditor):
17
+ * .my-editor.logic-editor { --accent: #db2777; }
18
+ *
19
+ * The SIGNAL palette (`--sig-*`) is the primary colour axis: a node is
20
+ * coloured by the *type of value it produces*. The neutral board tokens
21
+ * (`--board`, `--ink`, `--hairline`) set the calm substrate everything sits on.
22
+ * Legacy aliases (`--bg-primary`, `--node-bg`, `--syntax-*`, `--debug-*`) are
23
+ * kept and mapped onto the new system so existing consumer overrides keep working.
6
24
  */
7
25
 
8
26
  .logic-editor {
9
- /* Light theme (default) */
10
- --bg-primary: #f5f5f5;
11
- --bg-secondary: #ffffff;
12
- --bg-tertiary: #fafafa;
13
- --bg-hover: #f0f0f0;
14
- --bg-active: #e8e8e8;
15
-
16
- --text-primary: #333333;
17
- --text-secondary: #555555;
18
- --text-tertiary: #666666;
19
- --text-muted: #999999;
20
- --text-placeholder: #aaaaaa;
21
-
22
- --border-primary: #e0e0e0;
23
- --border-secondary: #dddddd;
24
- --border-light: #eeeeee;
25
-
26
- --accent-blue: #3b82f6;
27
- --accent-blue-light: #dbeafe;
28
-
29
- --accent-amber: #f59e0b;
30
- --accent-amber-light: #fef3c7;
31
-
32
- /* Status colors */
33
- --success-bg: #d1fae5;
34
- --success-text: #059669;
35
- --success-border: #a7f3d0;
36
-
37
- --error-bg: #fee2e2;
38
- --error-bg-light: #fef2f2;
39
- --error-bg-lighter: #fff5f5;
40
- --error-text: #dc2626;
41
- --error-border: #fecaca;
42
-
43
- --warning-bg: #fef3c7;
44
- --warning-text: #d97706;
45
- --warning-border: #fde68a;
46
-
47
- /* Syntax highlighting */
48
- --syntax-key: #0550ae;
49
- --syntax-string: #0a3069;
50
- --syntax-number: #0550ae;
51
- --syntax-boolean: #cf222e;
52
- --syntax-null: #6e7781;
53
- --syntax-bracket: #24292f;
54
- --syntax-punctuation: #24292f;
55
-
56
- /* Node colors - these stay consistent */
57
- --node-bg: #ffffff;
58
- --node-shadow: rgba(0, 0, 0, 0.1);
59
- --node-shadow-hover: rgba(0, 0, 0, 0.15);
60
-
61
- /* Code background */
62
- --code-bg: #f8f9fa;
63
-
64
- /* Debug popover colors */
65
- --debug-popover-bg: #ffffff;
66
- --debug-popover-text: #1f2937;
67
- --debug-popover-error-bg: #fef2f2;
68
- --debug-popover-shadow: rgba(0, 0, 0, 0.15);
69
- --debug-popover-value-bg: rgba(0, 0, 0, 0.05);
70
- --debug-iteration-color: #b45309;
71
- --debug-label-color: #6b7280;
72
- --debug-border-color: rgba(0, 0, 0, 0.1);
73
-
74
- /* Debug value type colors */
75
- --debug-value-true: #059669;
76
- --debug-value-false: #dc2626;
77
- --debug-value-number: #2563eb;
78
- --debug-value-string: #059669;
79
- --debug-value-array: #7c3aed;
80
- --debug-value-null: #6b7280;
81
-
82
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
27
+ /* ---- Fonts ------------------------------------------------------ */
28
+ --font-ui: 'Space Grotesk', ui-sans-serif, -apple-system, BlinkMacSystemFont,
29
+ 'Segoe UI', Roboto, sans-serif;
30
+ --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', 'Cascadia Code',
31
+ 'Consolas', monospace;
32
+
33
+ /* ---- Substrate — cool paper (light default) -------------------- */
34
+ --board: #eef1f5;
35
+ --board-grid: rgba(20, 40, 70, 0.05);
36
+ --surface: #ffffff;
37
+ --surface-2: #f6f8fb;
38
+ --chip: #ffffff;
39
+ --hairline: #d6dde6;
40
+ --hairline-2: #e6ebf1;
41
+
42
+ --ink: #0e1826;
43
+ --ink-2: #33475e;
44
+ --muted: #5b6a7d;
45
+ --faint: #9aa9ba; /* NON-TEXT only: idle wires, dot-grid, dashed slots */
46
+
47
+ /* ---- Structural accent — used ONLY for selection/root/focus ----- */
48
+ --accent: #4b56d6;
49
+ --accent-soft: #e7e9fb;
50
+ --accent-hover: #3a44c0;
51
+
52
+ /* ---- SIGNAL palette — colour = the value that flows OUT --------- */
53
+ --sig-bool-true: #1a7f37;
54
+ --sig-bool-false: #cf222e;
55
+ --sig-bool-rest: #57708a;
56
+ --sig-number: #0959c0;
57
+ --sig-string: #8a5a00;
58
+ --sig-collection: #8250df;
59
+ --sig-data: #1b7c83;
60
+ --sig-temporal: #bf3989;
61
+ --sig-null: #6e7781;
62
+
63
+ --sig-bool-true-bg: rgba(26, 127, 55, 0.10);
64
+ --sig-bool-false-bg: rgba(207, 34, 46, 0.10);
65
+ --sig-number-bg: rgba(9, 105, 218, 0.10);
66
+ --sig-string-bg: rgba(154, 103, 0, 0.12);
67
+ --sig-collection-bg: rgba(130, 80, 223, 0.10);
68
+ --sig-data-bg: rgba(27, 124, 131, 0.10);
69
+ --sig-temporal-bg: rgba(191, 57, 137, 0.10);
70
+ --sig-null-bg: rgba(110, 119, 129, 0.10);
71
+
72
+ /* ---- Radius & spacing scales ----------------------------------- */
73
+ --radius-sm: 7px;
74
+ --radius-md: 10px;
75
+ --radius-lg: 14px;
76
+
77
+ --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
78
+ --sp-5: 20px; --sp-6: 24px; --sp-8: 32px;
79
+
80
+ /* ---- Elevation ------------------------------------------------- */
81
+ --shadow-sm: 0 1px 2px rgba(16, 30, 54, 0.05);
82
+ --shadow-md: 0 1px 2px rgba(16, 30, 54, 0.06), 0 2px 6px rgba(16, 30, 54, 0.06);
83
+ --shadow-lg: 0 8px 30px rgba(16, 30, 54, 0.14), 0 2px 8px rgba(16, 30, 54, 0.08);
84
+
85
+ /* ---- Motion ---------------------------------------------------- */
86
+ --motion-fast: 120ms;
87
+ --motion-base: 180ms;
88
+ --motion-slow: 260ms;
89
+ --ease-out: cubic-bezier(0.4, 0, 0.2, 1);
90
+
91
+ /* ============================================================
92
+ LEGACY ALIASES mapped onto the Signal Board system so existing
93
+ consumer overrides (e.g. dataflow-rs redefines --node-bg / --node-shadow)
94
+ keep working. Prefer the tokens above for new overrides.
95
+ ============================================================ */
96
+ --bg-primary: var(--board);
97
+ --bg-secondary: var(--surface);
98
+ --bg-tertiary: var(--surface-2);
99
+ --bg-hover: var(--surface-2);
100
+ --bg-active: var(--hairline-2);
101
+
102
+ --text-primary: var(--ink);
103
+ --text-secondary: var(--ink-2);
104
+ --text-tertiary: var(--muted);
105
+ --text-muted: var(--muted);
106
+ --text-placeholder: var(--faint);
107
+
108
+ --border-primary: var(--hairline);
109
+ --border-secondary: var(--hairline-2);
110
+ --border-light: var(--hairline-2);
111
+
112
+ --accent-blue: var(--accent);
113
+ --accent-blue-light: var(--accent-soft);
114
+ --accent-blue-hover: var(--accent-hover);
115
+
116
+ --accent-amber: var(--sig-string);
117
+ --accent-amber-light: var(--sig-string-bg);
118
+
119
+ --success-bg: var(--sig-bool-true-bg);
120
+ --success-text: var(--sig-bool-true);
121
+ --success-border: color-mix(in srgb, var(--sig-bool-true) 30%, transparent);
122
+
123
+ --error-bg: var(--sig-bool-false-bg);
124
+ --error-bg-light: color-mix(in srgb, var(--sig-bool-false) 6%, var(--surface));
125
+ --error-bg-lighter: color-mix(in srgb, var(--sig-bool-false) 3%, var(--surface));
126
+ --error-text: var(--sig-bool-false);
127
+ --error-border: color-mix(in srgb, var(--sig-bool-false) 30%, transparent);
128
+
129
+ --warning-bg: var(--sig-string-bg);
130
+ --warning-text: var(--sig-string);
131
+ --warning-border: color-mix(in srgb, var(--sig-string) 30%, transparent);
132
+
133
+ --syntax-key: var(--sig-data);
134
+ --syntax-string: var(--sig-string);
135
+ --syntax-number: var(--sig-number);
136
+ --syntax-boolean: var(--sig-bool-false);
137
+ --syntax-null: var(--sig-null);
138
+ --syntax-bracket: var(--ink-2);
139
+ --syntax-punctuation: var(--muted);
140
+
141
+ --node-bg: var(--chip);
142
+ --node-shadow: var(--shadow-sm);
143
+ --node-shadow-hover: var(--shadow-md);
144
+
145
+ --code-bg: var(--surface-2);
146
+
147
+ --debug-popover-bg: var(--chip);
148
+ --debug-popover-text: var(--ink);
149
+ --debug-popover-error-bg: var(--sig-bool-false-bg);
150
+ --debug-popover-shadow: rgba(16, 30, 54, 0.15);
151
+ --debug-popover-value-bg: var(--surface-2);
152
+ --debug-iteration-color: var(--sig-collection);
153
+ --debug-label-color: var(--muted);
154
+ --debug-border-color: var(--hairline-2);
155
+
156
+ --debug-value-true: var(--sig-bool-true);
157
+ --debug-value-false: var(--sig-bool-false);
158
+ --debug-value-number: var(--sig-number);
159
+ --debug-value-string: var(--sig-string);
160
+ --debug-value-array: var(--sig-collection);
161
+ --debug-value-null: var(--sig-null);
162
+
163
+ --focus-ring: 0 0 0 2px var(--accent);
164
+
165
+ font-family: var(--font-ui);
83
166
  line-height: 1.5;
84
167
  font-weight: 400;
85
- color: var(--text-primary);
168
+ color: var(--ink);
86
169
  font-synthesis: none;
87
170
  text-rendering: optimizeLegibility;
88
171
  -webkit-font-smoothing: antialiased;
@@ -99,78 +182,51 @@
99
182
  font-family: inherit;
100
183
  }
101
184
 
185
+ /* ============================================================
186
+ DARK — "lit logic board"
187
+ ============================================================ */
102
188
  .logic-editor[data-theme="dark"] {
103
- --bg-primary: #1a1a1a;
104
- --bg-secondary: #242424;
105
- --bg-tertiary: #2a2a2a;
106
- --bg-hover: #333333;
107
- --bg-active: #404040;
108
-
109
- --text-primary: #e5e5e5;
110
- --text-secondary: #cccccc;
111
- --text-tertiary: #b3b3b3;
112
- --text-muted: #888888;
113
- --text-placeholder: #666666;
114
-
115
- --border-primary: #404040;
116
- --border-secondary: #4a4a4a;
117
- --border-light: #333333;
118
-
119
- --accent-blue: #60a5fa;
120
- --accent-blue-light: #1e3a5f;
121
-
122
- --accent-amber: #fbbf24;
123
- --accent-amber-light: #451a03;
124
-
125
- /* Status colors - darker variants */
126
- --success-bg: #064e3b;
127
- --success-text: #6ee7b7;
128
- --success-border: #065f46;
129
-
130
- --error-bg: #450a0a;
131
- --error-bg-light: #3f0a0a;
132
- --error-bg-lighter: #350a0a;
133
- --error-text: #fca5a5;
134
- --error-border: #7f1d1d;
135
-
136
- --warning-bg: #451a03;
137
- --warning-text: #fcd34d;
138
- --warning-border: #78350f;
139
-
140
- /* Syntax highlighting - dark theme */
141
- --syntax-key: #79c0ff;
142
- --syntax-string: #a5d6ff;
143
- --syntax-number: #79c0ff;
144
- --syntax-boolean: #ff7b72;
145
- --syntax-null: #8b949e;
146
- --syntax-bracket: #c9d1d9;
147
- --syntax-punctuation: #c9d1d9;
148
-
149
- /* Node colors */
150
- --node-bg: #2d2d2d;
151
- --node-shadow: rgba(0, 0, 0, 0.3);
152
- --node-shadow-hover: rgba(0, 0, 0, 0.4);
153
-
154
- /* Code background */
155
- --code-bg: #1f1f1f;
156
-
157
- /* Debug popover colors */
158
- --debug-popover-bg: #1f2937;
159
- --debug-popover-text: #f3f4f6;
160
- --debug-popover-error-bg: #7f1d1d;
161
- --debug-popover-shadow: rgba(0, 0, 0, 0.4);
162
- --debug-popover-value-bg: rgba(0, 0, 0, 0.2);
163
- --debug-iteration-color: #fbbf24;
164
- --debug-label-color: #9ca3af;
165
- --debug-border-color: rgba(255, 255, 255, 0.1);
166
-
167
- /* Debug value type colors */
168
- --debug-value-true: #86efac;
169
- --debug-value-false: #fca5a5;
170
- --debug-value-number: #93c5fd;
171
- --debug-value-string: #86efac;
172
- --debug-value-array: #d8b4fe;
173
- --debug-value-null: #9ca3af;
189
+ --board: #0a0f16;
190
+ --board-grid: rgba(120, 170, 255, 0.06);
191
+ --surface: #10161f;
192
+ --surface-2: #141b26;
193
+ --chip: #161d28;
194
+ --hairline: #263140;
195
+ --hairline-2: #1d2632;
196
+
197
+ --ink: #e6edf5;
198
+ --ink-2: #b3c1d1;
199
+ --muted: #8a9cb0;
200
+ --faint: #566172;
201
+
202
+ --accent: #7c86f5;
203
+ --accent-soft: #1b2140;
204
+ --accent-hover: #9aa2f8;
205
+
206
+ --sig-bool-true: #3fb950;
207
+ --sig-bool-false: #f85149;
208
+ --sig-bool-rest: #8098b0;
209
+ --sig-number: #58a6ff;
210
+ --sig-string: #e3b341;
211
+ --sig-collection: #bc8cff;
212
+ --sig-data: #39c5cf;
213
+ --sig-temporal: #db61a2;
214
+ --sig-null: #8b949e;
215
+
216
+ --sig-bool-true-bg: rgba(63, 185, 80, 0.13);
217
+ --sig-bool-false-bg: rgba(248, 81, 73, 0.13);
218
+ --sig-number-bg: rgba(88, 166, 255, 0.13);
219
+ --sig-string-bg: rgba(227, 179, 65, 0.14);
220
+ --sig-collection-bg: rgba(188, 140, 255, 0.13);
221
+ --sig-data-bg: rgba(57, 197, 207, 0.13);
222
+ --sig-temporal-bg: rgba(219, 97, 162, 0.14);
223
+ --sig-null-bg: rgba(139, 148, 158, 0.14);
224
+
225
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
226
+ --shadow-md: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.4);
227
+ --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.6), 0 2px 10px rgba(0, 0, 0, 0.4);
228
+
229
+ --debug-popover-shadow: rgba(0, 0, 0, 0.5);
174
230
  }
175
231
  /*
176
232
  * ReactFlow base styles - bundled locally so they're included in the library's styles.css
@@ -1075,7 +1131,7 @@ svg.react-flow__connectionline {
1075
1131
  }
1076
1132
 
1077
1133
  .dl-edge-picker-operator-name {
1078
- font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
1134
+ font-family: var(--font-mono);
1079
1135
  font-weight: 600;
1080
1136
  min-width: 50px;
1081
1137
  }
@@ -1095,27 +1151,60 @@ svg.react-flow__connectionline {
1095
1151
  color: var(--text-tertiary, #888);
1096
1152
  text-align: center;
1097
1153
  }
1098
- /* Inline variant (used in toolbar) */
1099
- .dl-debugger-controls--inline {
1100
- display: flex;
1154
+ .dl-tooltip-wrap {
1155
+ display: inline-flex;
1101
1156
  align-items: center;
1102
- flex-shrink: 0;
1103
1157
  }
1104
1158
 
1105
- .dl-debugger-controls--inline .dl-debugger-controls-inner {
1106
- display: flex;
1159
+ .dl-tooltip {
1160
+ pointer-events: none;
1161
+ z-index: 9999;
1162
+ display: inline-flex;
1107
1163
  align-items: center;
1108
- gap: 12px;
1109
- padding: 0;
1110
- background: none;
1111
- border: none;
1112
- border-radius: 0;
1113
- box-shadow: none;
1114
- backdrop-filter: none;
1115
- flex-shrink: 0;
1164
+ gap: 6px;
1165
+ max-width: 280px;
1166
+ padding: 5px 8px;
1167
+ font-family: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', Roboto, sans-serif;
1168
+ font-size: 11px;
1169
+ font-weight: 500;
1170
+ line-height: 1.3;
1171
+ letter-spacing: 0.1px;
1172
+ white-space: nowrap;
1173
+ color: #fafafa;
1174
+ background: rgba(20, 20, 22, 0.95);
1175
+ border: 1px solid rgba(255, 255, 255, 0.06);
1176
+ border-radius: var(--radius-sm, 6px);
1177
+ box-shadow:
1178
+ 0 2px 4px rgba(0, 0, 0, 0.08),
1179
+ 0 4px 12px rgba(0, 0, 0, 0.16);
1180
+ transition: opacity 120ms cubic-bezier(0.4, 0, 0.2, 1);
1181
+ }
1182
+
1183
+ .dl-tooltip-label {
1184
+ color: inherit;
1185
+ }
1186
+
1187
+ .dl-tooltip-shortcut {
1188
+ display: inline-flex;
1189
+ align-items: center;
1190
+ padding: 0 5px;
1191
+ height: 16px;
1192
+ font-size: 10px;
1193
+ font-weight: 600;
1194
+ color: rgba(250, 250, 250, 0.65);
1195
+ background: rgba(255, 255, 255, 0.08);
1196
+ border-radius: 3px;
1197
+ }
1198
+
1199
+ /* Don't show tooltips on touch / no-hover devices */
1200
+ @media (hover: none), (pointer: coarse) {
1201
+ .dl-tooltip {
1202
+ display: none;
1203
+ }
1116
1204
  }
1205
+ /* Transport bar — floating over the board, or chrome-stripped inline in the toolbar.
1206
+ Mirrors the design-system .transport. */
1117
1207
 
1118
- /* Floating overlay variant (legacy, used inside ReactFlow) */
1119
1208
  .dl-debugger-controls--floating {
1120
1209
  position: absolute;
1121
1210
  top: 12px;
@@ -1125,188 +1214,205 @@ svg.react-flow__connectionline {
1125
1214
  pointer-events: auto;
1126
1215
  }
1127
1216
 
1128
- .dl-debugger-controls--floating .dl-debugger-controls-inner {
1129
- display: flex;
1217
+ .dl-debugger-controls-inner {
1218
+ position: relative;
1219
+ display: inline-flex;
1130
1220
  align-items: center;
1131
- gap: 16px;
1132
- padding: 8px 16px;
1133
- background: var(--bg-secondary);
1134
- border: 1px solid var(--border-primary);
1135
- border-radius: 8px;
1136
- box-shadow: 0 4px 12px var(--node-shadow);
1137
- backdrop-filter: blur(8px);
1221
+ gap: 12px;
1222
+ height: 48px;
1223
+ padding: 0 12px 0 15px;
1224
+ border-radius: 13px;
1225
+ background: color-mix(in srgb, var(--surface) 92%, transparent);
1226
+ backdrop-filter: blur(14px);
1227
+ border: 1px solid var(--hairline);
1228
+ box-shadow: var(--shadow-lg);
1229
+ font-family: var(--font-ui);
1230
+ }
1231
+
1232
+ /* left rail — resting slate, accent while playing */
1233
+ .dl-debugger-controls-inner::before {
1234
+ content: "";
1235
+ position: absolute;
1236
+ left: 0;
1237
+ top: 10px;
1238
+ bottom: 10px;
1239
+ width: 3px;
1240
+ border-radius: 3px;
1241
+ background: var(--sig-bool-rest);
1242
+ }
1243
+ .dl-debugger-controls-inner.is-playing::before {
1244
+ background: var(--accent);
1138
1245
  }
1139
1246
 
1140
- /* Bug icon indicator */
1141
1247
  .dl-debugger-icon {
1142
- display: flex;
1248
+ display: inline-flex;
1143
1249
  align-items: center;
1144
- justify-content: center;
1145
- color: var(--accent-amber);
1250
+ color: var(--sig-string);
1146
1251
  }
1147
1252
 
1148
- /* Navigation buttons */
1149
1253
  .dl-debugger-buttons {
1150
- display: flex;
1254
+ display: inline-flex;
1151
1255
  align-items: center;
1152
- gap: 4px;
1256
+ gap: 6px;
1153
1257
  flex-shrink: 0;
1154
1258
  }
1155
1259
 
1156
1260
  .dl-debugger-btn {
1157
- display: flex;
1158
- align-items: center;
1159
- justify-content: center;
1160
- width: 32px;
1161
- height: 32px;
1261
+ width: 34px;
1262
+ height: 34px;
1162
1263
  padding: 0;
1163
- border: none;
1164
- border-radius: 6px;
1165
- background: var(--bg-hover);
1166
- color: var(--text-secondary);
1264
+ border-radius: 8px;
1265
+ display: grid;
1266
+ place-items: center;
1167
1267
  cursor: pointer;
1168
- transition: background-color 0.15s, color 0.15s, transform 0.1s;
1268
+ background: var(--surface-2);
1269
+ border: 1px solid var(--hairline);
1270
+ color: var(--ink-2);
1271
+ transition: border-color 0.15s ease, transform 0.1s ease, background 0.15s ease, color 0.15s ease;
1169
1272
  }
1170
-
1171
1273
  .dl-debugger-btn:hover:not(:disabled) {
1172
- background: var(--bg-tertiary);
1173
- color: var(--text-primary);
1274
+ border-color: color-mix(in srgb, var(--accent) 55%, var(--hairline));
1275
+ color: var(--ink);
1174
1276
  }
1175
-
1176
1277
  .dl-debugger-btn:active:not(:disabled) {
1177
- transform: scale(0.95);
1278
+ transform: scale(0.94);
1178
1279
  }
1179
-
1180
1280
  .dl-debugger-btn:disabled {
1181
- opacity: 0.4;
1182
- cursor: not-allowed;
1281
+ opacity: 0.35;
1282
+ cursor: default;
1183
1283
  }
1184
-
1185
1284
  .dl-debugger-btn-primary {
1186
- width: 36px;
1187
- height: 36px;
1188
- background: var(--accent-blue);
1189
- color: white;
1285
+ width: 40px;
1286
+ height: 40px;
1287
+ background: var(--accent);
1288
+ border-color: var(--accent);
1289
+ color: #fff;
1290
+ box-shadow: 0 0 0 3px var(--accent-soft);
1190
1291
  }
1191
-
1192
1292
  .dl-debugger-btn-primary:hover:not(:disabled) {
1193
- background: var(--accent-blue-hover);
1194
- color: white;
1293
+ filter: brightness(1.08);
1294
+ color: #fff;
1295
+ border-color: var(--accent);
1195
1296
  }
1196
1297
 
1197
- /* Step counter */
1298
+ /* step counter — a mono readout whose underline fills with progress */
1198
1299
  .dl-debugger-step-counter {
1199
- display: flex;
1300
+ position: relative;
1301
+ display: inline-flex;
1200
1302
  align-items: baseline;
1201
- gap: 2px;
1202
- font-family: 'SF Mono', 'Consolas', monospace;
1203
- font-size: 13px;
1204
- min-width: 60px;
1303
+ gap: 3px;
1304
+ min-width: 58px;
1205
1305
  justify-content: center;
1306
+ padding: 6px 12px 8px;
1307
+ border-radius: 8px;
1308
+ overflow: hidden;
1206
1309
  flex-shrink: 0;
1310
+ font-family: var(--font-mono);
1311
+ background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 8%, var(--surface-2)), var(--surface-2));
1312
+ border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--hairline));
1207
1313
  }
1208
-
1209
1314
  .dl-step-current {
1210
- color: var(--text-primary);
1211
- font-weight: 600;
1315
+ font-size: 15px;
1316
+ font-weight: 700;
1317
+ color: var(--ink);
1212
1318
  }
1213
-
1214
- .dl-step-separator {
1215
- color: var(--text-muted);
1216
- margin: 0 2px;
1319
+ .dl-debugger-controls-inner.is-playing .dl-step-current {
1320
+ color: var(--accent);
1217
1321
  }
1218
-
1322
+ .dl-step-separator,
1219
1323
  .dl-step-total {
1220
- color: var(--text-secondary);
1324
+ color: var(--muted);
1325
+ font-size: 12px;
1326
+ }
1327
+ .dl-step-progress {
1328
+ position: absolute;
1329
+ left: 0;
1330
+ bottom: 0;
1331
+ height: 2px;
1332
+ background: var(--accent);
1333
+ border-radius: 2px;
1334
+ transition: width 0.2s ease;
1221
1335
  }
1222
1336
 
1223
- /* Speed control */
1337
+ /* speed slider */
1224
1338
  .dl-debugger-speed {
1225
- display: flex;
1339
+ display: inline-flex;
1226
1340
  align-items: center;
1227
1341
  gap: 8px;
1228
1342
  flex-shrink: 0;
1229
1343
  }
1230
-
1231
1344
  .dl-speed-label {
1232
- font-size: 12px;
1233
- color: var(--text-tertiary);
1345
+ font-family: var(--font-mono);
1346
+ font-size: 9.5px;
1347
+ font-weight: 700;
1348
+ letter-spacing: 0.1em;
1349
+ text-transform: uppercase;
1350
+ color: var(--muted);
1234
1351
  white-space: nowrap;
1235
1352
  }
1236
-
1237
1353
  .dl-speed-slider {
1238
- width: 80px;
1239
- height: 4px;
1240
1354
  -webkit-appearance: none;
1241
1355
  appearance: none;
1242
- background: var(--bg-tertiary);
1243
- border-radius: 2px;
1356
+ width: 84px;
1357
+ height: 4px;
1358
+ border-radius: 3px;
1359
+ background: var(--hairline);
1244
1360
  cursor: pointer;
1245
1361
  }
1246
-
1247
1362
  .dl-speed-slider::-webkit-slider-thumb {
1248
1363
  -webkit-appearance: none;
1249
1364
  appearance: none;
1250
1365
  width: 14px;
1251
1366
  height: 14px;
1252
- background: var(--accent-blue);
1253
1367
  border-radius: 50%;
1368
+ background: var(--chip);
1369
+ border: 2px solid var(--sig-number);
1254
1370
  cursor: pointer;
1255
- transition: transform 0.1s;
1256
- }
1257
-
1258
- .dl-speed-slider::-webkit-slider-thumb:hover {
1259
- transform: scale(1.15);
1260
1371
  }
1261
-
1262
1372
  .dl-speed-slider::-moz-range-thumb {
1263
1373
  width: 14px;
1264
1374
  height: 14px;
1265
- background: var(--accent-blue);
1266
1375
  border-radius: 50%;
1267
- border: none;
1376
+ background: var(--chip);
1377
+ border: 2px solid var(--sig-number);
1268
1378
  cursor: pointer;
1269
1379
  }
1270
1380
 
1271
- /* Dark mode adjustments */
1272
- .logic-editor[data-theme="dark"] .dl-debugger-controls--floating .dl-debugger-controls-inner {
1273
- background: rgba(31, 41, 55, 0.95);
1274
- border-color: var(--border-light);
1381
+ /* inline variant chrome stripped, lives in the toolbar strip */
1382
+ .dl-debugger-controls--inline {
1383
+ display: flex;
1384
+ align-items: center;
1385
+ flex-shrink: 0;
1275
1386
  }
1276
-
1277
- .logic-editor[data-theme="dark"] .dl-debugger-btn {
1278
- background: rgba(55, 65, 81, 0.8);
1387
+ .dl-debugger-controls--inline .dl-debugger-controls-inner {
1388
+ background: none;
1389
+ backdrop-filter: none;
1390
+ border: none;
1391
+ box-shadow: none;
1392
+ height: auto;
1393
+ padding: 0;
1394
+ gap: 10px;
1279
1395
  }
1280
-
1281
- .logic-editor[data-theme="dark"] .dl-debugger-btn:hover:not(:disabled) {
1282
- background: rgba(75, 85, 99, 0.9);
1396
+ .dl-debugger-controls--inline .dl-debugger-controls-inner::before {
1397
+ display: none;
1283
1398
  }
1284
-
1285
- .logic-editor[data-theme="dark"] .dl-speed-slider {
1286
- background: rgba(75, 85, 99, 0.8);
1399
+ .dl-debugger-controls--inline .dl-debugger-icon,
1400
+ .dl-debugger-controls--inline .dl-debugger-speed {
1401
+ display: none;
1402
+ }
1403
+ .dl-debugger-controls--inline .dl-debugger-btn {
1404
+ width: 30px;
1405
+ height: 30px;
1406
+ }
1407
+ .dl-debugger-controls--inline .dl-debugger-btn-primary {
1408
+ width: 34px;
1409
+ height: 34px;
1287
1410
  }
1288
1411
 
1289
- /* Mobile adjustments */
1290
1412
  @media (max-width: 1024px) {
1291
1413
  .dl-debugger-controls--inline .dl-debugger-controls-inner {
1292
1414
  gap: 8px;
1293
1415
  }
1294
-
1295
- .dl-debugger-btn {
1296
- width: 36px;
1297
- height: 36px;
1298
- }
1299
-
1300
- .dl-debugger-btn-primary {
1301
- width: 40px;
1302
- height: 40px;
1303
- }
1304
-
1305
- .dl-debugger-step-counter {
1306
- min-width: 50px;
1307
- font-size: 12px;
1308
- }
1309
-
1310
1416
  .dl-speed-slider {
1311
1417
  width: 60px;
1312
1418
  }
@@ -1325,20 +1431,13 @@ svg.react-flow__connectionline {
1325
1431
  bottom: 8px;
1326
1432
  width: 280px;
1327
1433
  z-index: 50;
1328
- background: var(--bg-secondary, #ffffff);
1329
- border: 1px solid var(--border-color, #e0e0e0);
1330
- border-radius: 8px;
1331
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
1434
+ background: var(--bg-secondary);
1435
+ border: 1px solid var(--border-primary);
1436
+ border-radius: var(--radius-md);
1437
+ box-shadow: var(--shadow-lg);
1332
1438
  overflow: hidden;
1333
1439
  }
1334
1440
 
1335
- /* Dark mode */
1336
- .logic-editor[data-theme="dark"] .properties-panel {
1337
- background: var(--bg-secondary, #1e1e1e);
1338
- border-color: var(--border-color, #3e3e3e);
1339
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35), 0 2px 4px rgba(0, 0, 0, 0.2);
1340
- }
1341
-
1342
1441
  .properties-panel-content {
1343
1442
  display: flex;
1344
1443
  flex-direction: column;
@@ -1397,10 +1496,17 @@ svg.react-flow__connectionline {
1397
1496
  padding: 0;
1398
1497
  background: transparent;
1399
1498
  border: none;
1400
- border-radius: 6px;
1499
+ border-radius: var(--radius-sm);
1401
1500
  color: var(--text-tertiary, #999);
1402
1501
  cursor: pointer;
1403
- transition: background 0.15s, color 0.15s;
1502
+ transition: background var(--motion-fast) var(--ease-out),
1503
+ color var(--motion-fast) var(--ease-out),
1504
+ box-shadow var(--motion-fast) var(--ease-out);
1505
+ }
1506
+
1507
+ .properties-panel-close:focus-visible {
1508
+ outline: none;
1509
+ box-shadow: var(--focus-ring);
1404
1510
  }
1405
1511
 
1406
1512
  .properties-panel-close:hover {
@@ -1519,7 +1625,7 @@ svg.react-flow__connectionline {
1519
1625
  }
1520
1626
 
1521
1627
  .help-badge code {
1522
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
1628
+ font-family: var(--font-mono);
1523
1629
  }
1524
1630
 
1525
1631
  .help-badge-arity {
@@ -1634,7 +1740,7 @@ svg.react-flow__connectionline {
1634
1740
  .help-example-code {
1635
1741
  margin: 0;
1636
1742
  padding: 8px;
1637
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
1743
+ font-family: var(--font-mono);
1638
1744
  font-size: 11px;
1639
1745
  line-height: 1.5;
1640
1746
  background: var(--dl-bg-code, #fff);
@@ -1671,7 +1777,7 @@ svg.react-flow__connectionline {
1671
1777
 
1672
1778
  .help-example-data code,
1673
1779
  .help-example-result code {
1674
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
1780
+ font-family: var(--font-mono);
1675
1781
  color: var(--dl-text-primary, #1a1a1a);
1676
1782
  }
1677
1783
 
@@ -1681,7 +1787,7 @@ svg.react-flow__connectionline {
1681
1787
  }
1682
1788
 
1683
1789
  .help-example-error code {
1684
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
1790
+ font-family: var(--font-mono);
1685
1791
  color: var(--dl-error, #ef4444);
1686
1792
  }
1687
1793
 
@@ -1746,26 +1852,24 @@ svg.react-flow__connectionline {
1746
1852
  padding: 10px 16px;
1747
1853
  font-size: 13px;
1748
1854
  font-weight: 500;
1749
- color: #ef4444;
1750
- background: #fef2f2;
1751
- border: 1px solid #fecaca;
1752
- border-radius: 6px;
1855
+ color: var(--error-text);
1856
+ background: var(--error-bg);
1857
+ border: 1px solid var(--error-border);
1858
+ border-radius: var(--radius-sm);
1753
1859
  cursor: pointer;
1754
- transition: background 0.15s, border-color 0.15s;
1755
- }
1756
-
1757
- .logic-editor[data-theme="dark"] .properties-panel-delete {
1758
- background: #451a1a;
1759
- border-color: #7f1d1d;
1860
+ transition: background var(--motion-fast) var(--ease-out),
1861
+ border-color var(--motion-fast) var(--ease-out),
1862
+ box-shadow var(--motion-fast) var(--ease-out);
1760
1863
  }
1761
1864
 
1762
1865
  .properties-panel-delete:hover {
1763
- background: #fee2e2;
1764
- border-color: #ef4444;
1866
+ background: var(--error-bg-light);
1867
+ border-color: var(--error-text);
1765
1868
  }
1766
1869
 
1767
- .logic-editor[data-theme="dark"] .properties-panel-delete:hover {
1768
- background: #5c2424;
1870
+ .properties-panel-delete:focus-visible {
1871
+ outline: none;
1872
+ box-shadow: 0 0 0 2px var(--bg-secondary), 0 0 0 4px var(--error-text);
1769
1873
  }
1770
1874
 
1771
1875
  /* ==========================================================================
@@ -1902,7 +2006,7 @@ svg.react-flow__connectionline {
1902
2006
  flex: 1;
1903
2007
  padding: 4px 8px;
1904
2008
  font-size: 12px;
1905
- font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
2009
+ font-family: var(--font-mono);
1906
2010
  color: var(--text-primary, #1a1a1a);
1907
2011
  background: transparent;
1908
2012
  border: none;
@@ -2020,7 +2124,7 @@ svg.react-flow__connectionline {
2020
2124
  width: 100%;
2021
2125
  padding: 6px 8px;
2022
2126
  font-size: 12px;
2023
- font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
2127
+ font-family: var(--font-mono);
2024
2128
  color: var(--text-primary, #1a1a1a);
2025
2129
  background: var(--bg-primary, #ffffff);
2026
2130
  border: 1px solid var(--border-color, #d0d0d0);
@@ -2102,7 +2206,7 @@ svg.react-flow__connectionline {
2102
2206
  flex: 1;
2103
2207
  padding: 6px 8px;
2104
2208
  font-size: 12px;
2105
- font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
2209
+ font-family: var(--font-mono);
2106
2210
  color: var(--color-primary, #2563eb);
2107
2211
  background: var(--bg-primary, #ffffff);
2108
2212
  border: 1px solid var(--border-color, #d0d0d0);
@@ -2142,7 +2246,7 @@ svg.react-flow__connectionline {
2142
2246
  width: 100%;
2143
2247
  padding: 6px 8px;
2144
2248
  font-size: 12px;
2145
- font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
2249
+ font-family: var(--font-mono);
2146
2250
  color: var(--text-secondary, #666);
2147
2251
  background: var(--bg-tertiary, #f5f5f5);
2148
2252
  border: 1px solid var(--border-color, #e0e0e0);
@@ -2182,17 +2286,18 @@ svg.react-flow__connectionline {
2182
2286
  width: 100%;
2183
2287
  padding: 8px 12px 8px 32px;
2184
2288
  font-size: 13px;
2185
- color: var(--text-primary, #1a1a1a);
2186
- background: var(--bg-tertiary, #f8f9fa);
2187
- border: 1px solid var(--border-color, #e0e0e0);
2188
- border-radius: 6px;
2289
+ color: var(--text-primary);
2290
+ background: var(--bg-tertiary);
2291
+ border: 1px solid var(--border-secondary);
2292
+ border-radius: var(--radius-sm);
2189
2293
  outline: none;
2190
- transition: border-color 0.15s, box-shadow 0.15s;
2294
+ transition: border-color var(--motion-fast) var(--ease-out),
2295
+ box-shadow var(--motion-fast) var(--ease-out);
2191
2296
  }
2192
2297
 
2193
2298
  .properties-panel-search-input:focus {
2194
- border-color: var(--color-primary, #2563eb);
2195
- box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
2299
+ border-color: var(--accent-blue);
2300
+ box-shadow: var(--focus-ring);
2196
2301
  }
2197
2302
 
2198
2303
  .properties-panel-search-input::placeholder {
@@ -2316,7 +2421,7 @@ svg.react-flow__connectionline {
2316
2421
  }
2317
2422
 
2318
2423
  .properties-panel-operator-symbol {
2319
- font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
2424
+ font-family: var(--font-mono);
2320
2425
  font-size: 11px;
2321
2426
  color: var(--text-tertiary, #999);
2322
2427
  padding: 2px 6px;
@@ -2449,18 +2554,19 @@ svg.react-flow__connectionline {
2449
2554
  padding: 8px 10px;
2450
2555
  font-size: 13px;
2451
2556
  font-family: inherit;
2452
- color: var(--dl-text-primary, #1a1a1a);
2453
- background: var(--dl-bg-input, #fff);
2454
- border: 1px solid var(--dl-border, #e0e0e0);
2455
- border-radius: 6px;
2557
+ color: var(--text-primary);
2558
+ background: var(--bg-secondary);
2559
+ border: 1px solid var(--border-secondary);
2560
+ border-radius: var(--radius-sm);
2456
2561
  outline: none;
2457
- transition: border-color 0.15s, box-shadow 0.15s;
2562
+ transition: border-color var(--motion-fast) var(--ease-out),
2563
+ box-shadow var(--motion-fast) var(--ease-out);
2458
2564
  box-sizing: border-box;
2459
2565
  }
2460
2566
 
2461
2567
  .panel-input:focus {
2462
- border-color: var(--dl-primary, #3b82f6);
2463
- box-shadow: 0 0 0 3px var(--dl-primary-alpha, rgba(59, 130, 246, 0.15));
2568
+ border-color: var(--accent-blue);
2569
+ box-shadow: var(--focus-ring);
2464
2570
  }
2465
2571
 
2466
2572
  .panel-input:disabled {
@@ -2502,7 +2608,7 @@ svg.react-flow__connectionline {
2502
2608
  .panel-input-textarea {
2503
2609
  resize: vertical;
2504
2610
  min-height: 60px;
2505
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2611
+ font-family: var(--font-mono);
2506
2612
  }
2507
2613
 
2508
2614
  /* ==========================================================================
@@ -2559,15 +2665,15 @@ svg.react-flow__connectionline {
2559
2665
  }
2560
2666
 
2561
2667
  .panel-input-checkbox:checked + .panel-input-toggle {
2562
- background: var(--dl-primary, #3b82f6);
2668
+ background: var(--accent-blue);
2563
2669
  }
2564
2670
 
2565
2671
  .panel-input-checkbox:checked + .panel-input-toggle::after {
2566
2672
  transform: translateX(16px);
2567
2673
  }
2568
2674
 
2569
- .panel-input-checkbox:focus + .panel-input-toggle {
2570
- box-shadow: 0 0 0 3px var(--dl-primary-alpha, rgba(59, 130, 246, 0.15));
2675
+ .panel-input-checkbox:focus-visible + .panel-input-toggle {
2676
+ box-shadow: var(--focus-ring);
2571
2677
  }
2572
2678
 
2573
2679
  .panel-input-checkbox:disabled + .panel-input-toggle {
@@ -2610,22 +2716,23 @@ svg.react-flow__connectionline {
2610
2716
  .panel-input-path-wrapper {
2611
2717
  display: flex;
2612
2718
  align-items: center;
2613
- background: var(--dl-bg-input, #fff);
2614
- border: 1px solid var(--dl-border, #e0e0e0);
2615
- border-radius: 6px;
2719
+ background: var(--bg-secondary);
2720
+ border: 1px solid var(--border-secondary);
2721
+ border-radius: var(--radius-sm);
2616
2722
  overflow: hidden;
2617
- transition: border-color 0.15s, box-shadow 0.15s;
2723
+ transition: border-color var(--motion-fast) var(--ease-out),
2724
+ box-shadow var(--motion-fast) var(--ease-out);
2618
2725
  }
2619
2726
 
2620
2727
  .panel-input-path-wrapper:focus-within {
2621
- border-color: var(--dl-primary, #3b82f6);
2622
- box-shadow: 0 0 0 3px var(--dl-primary-alpha, rgba(59, 130, 246, 0.15));
2728
+ border-color: var(--accent-blue);
2729
+ box-shadow: var(--focus-ring);
2623
2730
  }
2624
2731
 
2625
2732
  .panel-input-path-prefix {
2626
2733
  padding: 8px 0 8px 10px;
2627
2734
  font-size: 13px;
2628
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2735
+ font-family: var(--font-mono);
2629
2736
  color: var(--dl-text-tertiary, #999);
2630
2737
  user-select: none;
2631
2738
  }
@@ -2633,7 +2740,7 @@ svg.react-flow__connectionline {
2633
2740
  .panel-input-path {
2634
2741
  border: none;
2635
2742
  padding-left: 4px;
2636
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2743
+ font-family: var(--font-mono);
2637
2744
  }
2638
2745
 
2639
2746
  .panel-input-path:focus {
@@ -2658,7 +2765,7 @@ svg.react-flow__connectionline {
2658
2765
 
2659
2766
  .panel-input-segment {
2660
2767
  flex: 1;
2661
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2768
+ font-family: var(--font-mono);
2662
2769
  }
2663
2770
 
2664
2771
  .panel-input-segment-remove {
@@ -2712,7 +2819,7 @@ svg.react-flow__connectionline {
2712
2819
 
2713
2820
  .panel-input-path-preview {
2714
2821
  font-size: 11px;
2715
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2822
+ font-family: var(--font-mono);
2716
2823
  color: var(--dl-text-tertiary, #999);
2717
2824
  padding: 4px 0;
2718
2825
  }
@@ -2745,7 +2852,7 @@ svg.react-flow__connectionline {
2745
2852
  }
2746
2853
 
2747
2854
  .panel-input-expression-summary {
2748
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2855
+ font-family: var(--font-mono);
2749
2856
  color: var(--dl-text-primary, #1a1a1a);
2750
2857
  overflow: hidden;
2751
2858
  text-overflow: ellipsis;
@@ -2773,7 +2880,7 @@ svg.react-flow__connectionline {
2773
2880
  }
2774
2881
 
2775
2882
  .panel-input-json {
2776
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2883
+ font-family: var(--font-mono);
2777
2884
  font-size: 12px;
2778
2885
  line-height: 1.5;
2779
2886
  resize: vertical;
@@ -2881,7 +2988,7 @@ svg.react-flow__connectionline {
2881
2988
  }
2882
2989
 
2883
2990
  .panel-hint-description code {
2884
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
2991
+ font-family: var(--font-mono);
2885
2992
  font-size: 11px;
2886
2993
  background: var(--dl-bg-code, #e8e8e8);
2887
2994
  padding: 1px 4px;
@@ -2916,7 +3023,7 @@ svg.react-flow__connectionline {
2916
3023
  }
2917
3024
 
2918
3025
  .panel-context-example {
2919
- font-family: var(--dl-font-mono, 'SF Mono', 'Monaco', 'Inconsolata', monospace);
3026
+ font-family: var(--font-mono);
2920
3027
  font-size: 11px;
2921
3028
  background: var(--dl-bg-code, rgba(0, 0, 0, 0.06));
2922
3029
  padding: 2px 6px;
@@ -2937,64 +3044,608 @@ svg.react-flow__connectionline {
2937
3044
  color: var(--dl-text-tertiary, #999);
2938
3045
  }
2939
3046
  /* ============================================
2940
- CSS Variables - Debug Colors
3047
+ Signal Board operand pills, LEDs, op glyphs, shape silhouettes
2941
3048
  ============================================ */
2942
3049
 
2943
- .logic-editor {
2944
- --debug-current-color: #F59E0B;
2945
- --debug-current-glow: rgba(245, 158, 11, 0.4);
2946
- --debug-executed-color: #10B981;
2947
- --debug-executed-border: rgba(16, 185, 129, 0.6);
2948
- --debug-pending-opacity: 0.5;
2949
- --debug-error-color: #EF4444;
2950
- --debug-error-glow: rgba(239, 68, 68, 0.4);
2951
- --debug-error-border: rgba(239, 68, 68, 0.6);
3050
+ /* type-coloured operand pills (colour = the operand's value type) */
3051
+ .dl-pill {
3052
+ display: inline-flex;
3053
+ align-items: center;
3054
+ gap: 5px;
3055
+ padding: 2px 8px;
3056
+ border-radius: 6px;
3057
+ font-family: var(--font-mono);
3058
+ font-size: 12px;
3059
+ font-weight: 500;
3060
+ border: 1px solid transparent;
3061
+ white-space: nowrap;
3062
+ max-width: 100%;
3063
+ overflow: hidden;
3064
+ text-overflow: ellipsis;
3065
+ min-width: 0;
2952
3066
  }
2953
-
2954
- .logic-editor[data-theme="dark"] {
2955
- --debug-current-glow: rgba(245, 158, 11, 0.5);
2956
- --debug-executed-border: rgba(16, 185, 129, 0.8);
2957
- --debug-error-glow: rgba(239, 68, 68, 0.5);
2958
- --debug-error-border: rgba(239, 68, 68, 0.8);
3067
+ .dl-pill-tap { color: var(--sig-data); background: var(--sig-data-bg); border-color: color-mix(in srgb, var(--sig-data) 24%, transparent); }
3068
+ .dl-pill-tap::before { content: "\2041"; font-size: 11px; opacity: 0.8; }
3069
+ .dl-pill-num { color: var(--sig-number); background: var(--sig-number-bg); border-color: color-mix(in srgb, var(--sig-number) 22%, transparent); }
3070
+ .dl-pill-str { color: var(--sig-string); background: var(--sig-string-bg); border-color: color-mix(in srgb, var(--sig-string) 26%, transparent); }
3071
+ .dl-pill-bool { color: var(--sig-bool-true); background: var(--sig-bool-true-bg); border-color: color-mix(in srgb, var(--sig-bool-true) 24%, transparent); }
3072
+ .dl-pill-coll { color: var(--sig-collection); background: var(--sig-collection-bg); border-color: color-mix(in srgb, var(--sig-collection) 24%, transparent); }
3073
+ .dl-pill-temp { color: var(--sig-temporal); background: var(--sig-temporal-bg); border-color: color-mix(in srgb, var(--sig-temporal) 24%, transparent); }
3074
+ .dl-pill-nul { color: var(--sig-null); background: var(--sig-null-bg); border-color: color-mix(in srgb, var(--sig-null) 22%, transparent); font-style: italic; }
3075
+
3076
+ /* boolean gate/quantifier LED */
3077
+ .dl-led {
3078
+ width: 10px;
3079
+ height: 10px;
3080
+ border-radius: 50%;
3081
+ flex-shrink: 0;
3082
+ border: 1.5px solid var(--sig-bool-rest);
3083
+ background: transparent;
2959
3084
  }
2960
-
2961
- /* ============================================
2962
- .dl-node — Shared Visual Base
2963
- ============================================ */
2964
-
2965
- .dl-node {
2966
- border-radius: 8px;
2967
- border: 2px solid;
2968
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
2969
- font-size: 13px;
2970
- width: 100%;
2971
- box-sizing: border-box;
2972
- box-shadow: 0 2px 6px var(--node-shadow);
2973
- transition: box-shadow 0.2s, transform 0.1s;
2974
- background: var(--node-bg) !important;
2975
- position: relative;
3085
+ .dl-node.debug-executed .dl-led {
3086
+ border-color: var(--sig-bool-true);
3087
+ background: var(--sig-bool-true);
3088
+ box-shadow: 0 0 0 3px var(--sig-bool-true-bg);
2976
3089
  }
2977
-
2978
- .dl-node:hover {
2979
- box-shadow: 0 4px 12px var(--node-shadow-hover);
3090
+ .dl-node.debug-error .dl-led {
3091
+ border-color: var(--sig-bool-false);
3092
+ background: var(--sig-bool-false);
2980
3093
  }
2981
3094
 
2982
- .dl-node.selected {
2983
- box-shadow: 0 0 0 2px var(--accent-blue), 0 4px 12px var(--node-shadow-hover);
3095
+ /* operator math glyph (gate / arithmetic) */
3096
+ .dl-op-glyph {
3097
+ font-family: var(--font-mono);
3098
+ font-size: 17px;
3099
+ font-weight: 700;
3100
+ line-height: 1;
3101
+ color: var(--dl-sig);
3102
+ flex-shrink: 0;
3103
+ min-width: 14px;
3104
+ text-align: center;
2984
3105
  }
2985
3106
 
2986
- /* ============================================
2987
- .dl-node Debug States
2988
- States ONLY change: border-color, box-shadow, opacity, animation
2989
- ============================================ */
2990
-
2991
- /* Disable transitions on debug-active nodes to prevent animation-to-static handoff glitches */
2992
- .dl-node[class*="debug-"] {
2993
- transition: none !important;
3107
+ /* gate & arithmetic: the op-glyph carries the meaning, so drop the category
3108
+ badge and demote the verbose label to a small-caps eyebrow */
3109
+ .dl-shape-gate .vertical-cell-icon,
3110
+ .dl-shape-arith .vertical-cell-icon {
3111
+ display: none;
3112
+ }
3113
+ .dl-shape-gate .vertical-cell-label,
3114
+ .dl-shape-arith .vertical-cell-label {
3115
+ font-size: 10.5px;
3116
+ font-weight: 600;
3117
+ letter-spacing: 0.04em;
3118
+ text-transform: uppercase;
3119
+ color: var(--muted);
2994
3120
  }
2995
3121
 
2996
- /* Contain overflow on all debug-state nodes except current (which needs the bubble visible) */
2997
- .dl-node[class*="debug-"]:not(.debug-current) {
3122
+ /* data tap (var / val / exists): a teal PLUG that reads from the data and points
3123
+ into the flow. The node box itself is transparent; the inner .dl-tap carries the
3124
+ silhouette (clip-path), so the ReactFlow output handle — a sibling of .dl-tap —
3125
+ stays at the plug's tip and is never clipped. */
3126
+ .dl-shape-tap { --dl-sig: var(--sig-data); }
3127
+ .dl-node.dl-shape-tap {
3128
+ background: transparent !important;
3129
+ border: none;
3130
+ box-shadow: none;
3131
+ width: fit-content;
3132
+ display: inline-flex;
3133
+ align-items: center;
3134
+ gap: 5px;
3135
+ overflow: visible;
3136
+ }
3137
+ .dl-node.dl-shape-tap::before { display: none; } /* no left rail — the plug is fully tinted */
3138
+ .dl-node.dl-shape-tap:hover { box-shadow: none; }
3139
+ /* keep the plug's 1px drop-shadow outline from being clipped in debug states */
3140
+ .dl-node.dl-shape-tap[class*="debug-"]:not(.debug-current) { overflow: visible; }
3141
+
3142
+ .dl-tap {
3143
+ --tap-line: color-mix(in srgb, var(--sig-data) 55%, var(--node-bg));
3144
+ position: relative;
3145
+ display: inline-flex;
3146
+ align-items: center;
3147
+ gap: 6px;
3148
+ white-space: nowrap;
3149
+ padding: 6px 19px 6px 12px; /* extra right padding leaves room for the plug point */
3150
+ font-family: var(--font-mono);
3151
+ font-size: 12px; /* matches the operand pills so operands read at one size */
3152
+ font-weight: 500;
3153
+ color: var(--sig-data);
3154
+ background: color-mix(in srgb, var(--sig-data) 15%, var(--node-bg));
3155
+ clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 0 100%);
3156
+ filter:
3157
+ drop-shadow(1px 0 0 var(--tap-line)) drop-shadow(-1px 0 0 var(--tap-line))
3158
+ drop-shadow(0 1px 0 var(--tap-line)) drop-shadow(0 -1px 0 var(--tap-line))
3159
+ drop-shadow(0.8px 0.8px 0 var(--tap-line)) drop-shadow(-0.8px 0.8px 0 var(--tap-line))
3160
+ drop-shadow(0.8px -0.8px 0 var(--tap-line)) drop-shadow(-0.8px -0.8px 0 var(--tap-line));
3161
+ transition: filter var(--motion-base) var(--ease-out);
3162
+ }
3163
+ .dl-tap-glyph { opacity: 0.85; font-size: 11px; }
3164
+ .dl-tap-path { color: var(--sig-data); font-weight: 600; }
3165
+ .dl-tap-val { color: var(--muted); font-size: 11px; }
3166
+
3167
+ /* hover: deepen the plug outline (parallels the border-tint hover on card nodes) */
3168
+ .dl-node.dl-shape-tap:hover .dl-tap {
3169
+ --tap-line: color-mix(in srgb, var(--sig-data) 82%, var(--node-bg));
3170
+ }
3171
+
3172
+ /* selection ring FOLLOWS the plug silhouette: an accent copy of the plug shape
3173
+ rendered 2px larger BEHIND the plug, on the un-clipped node wrapper. (A
3174
+ box-shadow / drop-shadow on the plug itself is swallowed by its own clip-path.) */
3175
+ .dl-node.dl-shape-tap.selected { box-shadow: none; }
3176
+ .dl-node.dl-shape-tap .dl-tap { z-index: 1; }
3177
+ .dl-node.dl-shape-tap.selected::after {
3178
+ content: "";
3179
+ position: absolute;
3180
+ inset: -2px;
3181
+ z-index: 0;
3182
+ background: var(--accent);
3183
+ clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%);
3184
+ pointer-events: none;
3185
+ }
3186
+
3187
+ /* debug rings: an accent-free copy of the plug silhouette, tinted per state, so the
3188
+ highlight follows the plug SHAPE. The node box is transparent, so the generic
3189
+ rectangular box-shadow debug rings would halo empty space — suppress them here
3190
+ and let the clip-path ::after ring carry every debug state instead. */
3191
+ .dl-node.dl-shape-tap[class*="debug-"] {
3192
+ box-shadow: none !important;
3193
+ animation: none !important;
3194
+ }
3195
+ .dl-node.dl-shape-tap[class*="debug-"]::after {
3196
+ content: "";
3197
+ position: absolute;
3198
+ inset: -2px;
3199
+ z-index: 0;
3200
+ clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%);
3201
+ pointer-events: none;
3202
+ }
3203
+ .dl-node.dl-shape-tap.debug-executed::after { background: var(--debug-executed-color); }
3204
+ .dl-node.dl-shape-tap.debug-on-path::after { background: var(--debug-current-color); opacity: 0.55; }
3205
+ .dl-node.dl-shape-tap.debug-error::after { background: var(--debug-error-color); }
3206
+ .dl-node.dl-shape-tap.debug-current::after {
3207
+ background: var(--debug-current-color);
3208
+ animation: debug-pulse-plug 1.5s ease-in-out infinite;
3209
+ }
3210
+ .dl-node.dl-shape-tap.debug-error.debug-current::after { background: var(--debug-error-color); }
3211
+
3212
+ /* box-shadow can't follow the clip-path, so pulse the silhouette ring's own
3213
+ size/opacity to echo the card nodes' debug-current pulse. */
3214
+ @keyframes debug-pulse-plug {
3215
+ 0%, 100% { inset: -2px; opacity: 1; }
3216
+ 50% { inset: -4px; opacity: 0.7; }
3217
+ }
3218
+
3219
+ /* branch (if / switch / match): structural accent */
3220
+ .dl-shape-branch { --dl-sig: var(--accent); }
3221
+ .dl-shape-branch .vertical-cell-icon {
3222
+ color: var(--accent);
3223
+ background: var(--accent-soft);
3224
+ }
3225
+
3226
+ /* iterator / quantifier: stacked "collection" frame — an offset card outline
3227
+ behind the node (drawn with layered box-shadows so it renders above canvas) */
3228
+ .dl-shape-iterator,
3229
+ .dl-shape-quantifier { --dl-sig: var(--sig-collection); }
3230
+ .dl-shape-iterator,
3231
+ .dl-shape-quantifier {
3232
+ box-shadow:
3233
+ 5px -5px 0 -1px var(--node-bg),
3234
+ 5px -5px 0 0 color-mix(in srgb, var(--sig-collection) 38%, var(--hairline)),
3235
+ var(--node-shadow);
3236
+ }
3237
+ .dl-shape-iterator:hover,
3238
+ .dl-shape-quantifier:hover {
3239
+ box-shadow:
3240
+ 5px -5px 0 -1px var(--node-bg),
3241
+ 5px -5px 0 0 color-mix(in srgb, var(--sig-collection) 50%, var(--hairline)),
3242
+ var(--node-shadow-hover);
3243
+ }
3244
+ .dl-shape-quantifier { --dl-sig: var(--sig-bool-rest); }
3245
+ .dl-shape-quantifier .vertical-cell-icon {
3246
+ color: var(--sig-collection);
3247
+ background: color-mix(in srgb, var(--sig-collection) 14%, transparent);
3248
+ }
3249
+
3250
+ /* literal: a folded-corner CONSTANT TAG, tinted by its value type. The fold +
3251
+ outline live on the inner .dl-lit (clip-path); the .dl-node wrapper stays
3252
+ UNCLIPPED and transparent so it can host a selection / debug ring (::after)
3253
+ that follows the fold shape — a box-shadow ring is swallowed by the clip.
3254
+ Mirrors the data-tap plug. */
3255
+ .dl-node.dl-shape-literal {
3256
+ background: transparent !important;
3257
+ border: none;
3258
+ border-radius: 0;
3259
+ box-shadow: none;
3260
+ padding: 0;
3261
+ width: fit-content;
3262
+ display: inline-flex;
3263
+ align-items: center;
3264
+ overflow: visible;
3265
+ }
3266
+ .dl-node.dl-shape-literal::before { display: none; } /* no left rail — the tag is fully tinted */
3267
+ .dl-node.dl-shape-literal:hover { box-shadow: none; }
3268
+ .dl-node.dl-shape-literal[class*="debug-"]:not(.debug-current) { overflow: visible; }
3269
+
3270
+ .dl-lit {
3271
+ --lit-line: color-mix(in srgb, var(--dl-sig) 55%, var(--node-bg));
3272
+ position: relative;
3273
+ z-index: 1;
3274
+ display: inline-flex;
3275
+ align-items: center;
3276
+ gap: 7px;
3277
+ padding: 6px 12px;
3278
+ font-family: var(--font-mono);
3279
+ font-size: 12px; /* matches the operand pills / data taps */
3280
+ font-weight: 600;
3281
+ color: var(--dl-sig);
3282
+ background: color-mix(in srgb, var(--dl-sig) 12%, var(--node-bg));
3283
+ clip-path: polygon(9px 0, 100% 0, 100% 100%, 0 100%, 0 9px);
3284
+ filter:
3285
+ drop-shadow(1px 0 0 var(--lit-line)) drop-shadow(-1px 0 0 var(--lit-line))
3286
+ drop-shadow(0 1px 0 var(--lit-line)) drop-shadow(0 -1px 0 var(--lit-line))
3287
+ drop-shadow(0.8px 0.8px 0 var(--lit-line)) drop-shadow(-0.8px 0.8px 0 var(--lit-line))
3288
+ drop-shadow(0.8px -0.8px 0 var(--lit-line)) drop-shadow(-0.8px -0.8px 0 var(--lit-line));
3289
+ transition: filter var(--motion-base) var(--ease-out);
3290
+ }
3291
+ /* hover: deepen the fold outline (parallels the card border-tint hover) */
3292
+ .dl-node.dl-shape-literal:hover .dl-lit {
3293
+ --lit-line: color-mix(in srgb, var(--dl-sig) 82%, var(--node-bg));
3294
+ }
3295
+
3296
+ /* selection ring FOLLOWS the fold silhouette: an accent copy of the tag shape,
3297
+ 2px larger, BEHIND the tag (a box-shadow ring is swallowed by the clip-path). */
3298
+ .dl-node.dl-shape-literal.selected { box-shadow: none; }
3299
+ .dl-node.dl-shape-literal.selected::after {
3300
+ content: "";
3301
+ position: absolute;
3302
+ inset: -2px;
3303
+ z-index: 0;
3304
+ background: var(--accent);
3305
+ clip-path: polygon(11px 0, 100% 0, 100% 100%, 0 100%, 0 11px);
3306
+ pointer-events: none;
3307
+ }
3308
+
3309
+ /* debug rings: the same folded silhouette tinted per state — the transparent box
3310
+ would otherwise halo empty space with the generic rectangular ring. */
3311
+ .dl-node.dl-shape-literal[class*="debug-"] {
3312
+ box-shadow: none !important;
3313
+ animation: none !important;
3314
+ }
3315
+ .dl-node.dl-shape-literal[class*="debug-"]::after {
3316
+ content: "";
3317
+ position: absolute;
3318
+ inset: -2px;
3319
+ z-index: 0;
3320
+ clip-path: polygon(11px 0, 100% 0, 100% 100%, 0 100%, 0 11px);
3321
+ pointer-events: none;
3322
+ }
3323
+ .dl-node.dl-shape-literal.debug-executed::after { background: var(--debug-executed-color); }
3324
+ .dl-node.dl-shape-literal.debug-on-path::after { background: var(--debug-current-color); opacity: 0.55; }
3325
+ .dl-node.dl-shape-literal.debug-error::after { background: var(--debug-error-color); }
3326
+ .dl-node.dl-shape-literal.debug-current::after {
3327
+ background: var(--debug-current-color);
3328
+ animation: debug-pulse-plug 1.5s ease-in-out infinite;
3329
+ }
3330
+ .dl-node.dl-shape-literal.debug-error.debug-current::after { background: var(--debug-error-color); }
3331
+ .dl-lit-ptag {
3332
+ font-family: var(--font-mono);
3333
+ font-size: 8px;
3334
+ letter-spacing: 0.1em;
3335
+ text-transform: uppercase;
3336
+ color: var(--muted);
3337
+ font-weight: 600;
3338
+ margin-left: 3px; /* clear the folded corner */
3339
+ }
3340
+ .dl-shape-literal .literal-value {
3341
+ color: var(--dl-sig);
3342
+ font-weight: 600;
3343
+ font-size: 12px; /* override the legacy .literal-value 13px so operands read at one size */
3344
+ word-break: break-word;
3345
+ }
3346
+
3347
+ /* ============================================
3348
+ Infix operator chips — the readable "shape = role" forms for the two most
3349
+ common families:
3350
+ • compare (== != < > in …): a chip with a boolean LED + infix glyph
3351
+ • arithmetic (+ − × ÷ …): the op glyph in a round number-tinted badge
3352
+ Both keep the .dl-node chip (border, signal rail, shadow); only the BODY is
3353
+ a horizontal infix run of operand pills instead of stacked cell rows.
3354
+ ============================================ */
3355
+ .dl-node.dl-infix-node {
3356
+ display: inline-flex;
3357
+ align-items: center;
3358
+ width: max-content; /* size to the unwrapped infix run, not the RF wrapper width */
3359
+ max-width: 520px;
3360
+ }
3361
+ .dl-infix {
3362
+ display: inline-flex;
3363
+ align-items: center;
3364
+ gap: 7px;
3365
+ flex-wrap: nowrap;
3366
+ white-space: nowrap;
3367
+ padding: 7px 13px 7px 15px;
3368
+ min-width: 0;
3369
+ }
3370
+
3371
+ /* operator glyph */
3372
+ .dl-inop {
3373
+ font-family: var(--font-mono);
3374
+ line-height: 1;
3375
+ flex-shrink: 0;
3376
+ }
3377
+ .dl-infix-gate .dl-inop {
3378
+ font-size: 17px;
3379
+ font-weight: 700;
3380
+ color: var(--ink);
3381
+ padding: 0 1px;
3382
+ }
3383
+ /* arithmetic op glyph rides in a round badge — the "operation node" convention */
3384
+ .dl-infix-arith .dl-inop {
3385
+ display: inline-grid;
3386
+ place-items: center;
3387
+ width: 23px;
3388
+ height: 23px;
3389
+ border-radius: 50%;
3390
+ font-size: 13.5px;
3391
+ font-weight: 600;
3392
+ color: var(--sig-number);
3393
+ background: color-mix(in srgb, var(--sig-number) 13%, var(--node-bg));
3394
+ border: 1px solid color-mix(in srgb, var(--sig-number) 42%, var(--hairline));
3395
+ }
3396
+
3397
+ /* the boolean LED leads the compare chip */
3398
+ .dl-infix-gate .dl-led { margin-right: 2px; }
3399
+
3400
+ /* the (single) wired operand connects at the chip's LEFT edge, centred, so the
3401
+ arrow points at the edge instead of into the middle of the chip */
3402
+ .dl-node.dl-infix-node .dl-infix-in.react-flow__handle {
3403
+ left: -6px;
3404
+ top: 50%;
3405
+ transform: translateY(-50%);
3406
+ }
3407
+ .dl-pill-expr {
3408
+ color: var(--ink-2);
3409
+ background: var(--surface-2);
3410
+ border-color: var(--hairline);
3411
+ font-family: var(--font-mono);
3412
+ max-width: 210px;
3413
+ }
3414
+
3415
+ /* ============================================
3416
+ Boolean logic-gate silhouettes — AND / OR / NOT
3417
+ Rendered when a logical op's operands are ALL wired children. The node box is
3418
+ transparent; the SVG silhouette carries the shape, input ports spread down the
3419
+ left edge, output on the right. The child nodes carry the logic.
3420
+ ============================================ */
3421
+ .dl-node.dl-gate-node {
3422
+ background: transparent !important;
3423
+ border: none;
3424
+ box-shadow: none;
3425
+ width: fit-content;
3426
+ min-width: 84px;
3427
+ /* floor only; the true height is pinned inline (gateNodeHeight) so the drawn
3428
+ silhouette matches the footprint the layout reserved for it. */
3429
+ min-height: 44px;
3430
+ display: grid;
3431
+ place-items: center;
3432
+ position: relative;
3433
+ padding: 2px 8px;
3434
+ }
3435
+ .dl-node.dl-gate-node::before { display: none; }
3436
+ .dl-node.dl-gate-node:hover { box-shadow: none; }
3437
+ .dl-gate-svg {
3438
+ position: absolute;
3439
+ inset: 0;
3440
+ width: 100%;
3441
+ height: 100%;
3442
+ overflow: visible;
3443
+ }
3444
+ .dl-gate-sil {
3445
+ fill: color-mix(in srgb, var(--dl-sig) 12%, var(--node-bg));
3446
+ stroke: var(--dl-sig);
3447
+ stroke-width: 1.5;
3448
+ vector-effect: non-scaling-stroke;
3449
+ }
3450
+ .dl-gate-label {
3451
+ position: relative;
3452
+ z-index: 2;
3453
+ font-family: var(--font-mono);
3454
+ font-weight: 700;
3455
+ font-size: 11px;
3456
+ letter-spacing: 0.04em;
3457
+ color: var(--dl-sig);
3458
+ pointer-events: none;
3459
+ transform: translateX(-8px);
3460
+ }
3461
+ .dl-node.dl-gate-node .dl-gate-in.react-flow__handle {
3462
+ width: 8px;
3463
+ height: 8px;
3464
+ }
3465
+ /* selection follows the gate silhouette — suppress the generic rectangular ring */
3466
+ .dl-node.dl-gate-node.selected { box-shadow: none; }
3467
+ .dl-node.dl-gate-node.selected .dl-gate-sil { stroke: var(--accent); stroke-width: 2.5; }
3468
+ .dl-node.dl-gate-node.selected .dl-gate-svg {
3469
+ filter: drop-shadow(0 0 3px color-mix(in srgb, var(--accent) 45%, transparent));
3470
+ }
3471
+ .dl-node.dl-gate-node[class*="debug-"] { box-shadow: none !important; }
3472
+ .dl-node.dl-gate-node.debug-executed .dl-gate-sil { stroke: var(--debug-executed-color); }
3473
+ .dl-node.dl-gate-node.debug-error .dl-gate-sil { stroke: var(--debug-error-color); }
3474
+ .dl-node.dl-gate-node.debug-current .dl-gate-sil { stroke: var(--debug-current-color); }
3475
+
3476
+ /* ============================================
3477
+ Decision diamond — if / else-if
3478
+ Each condition is its own standalone flowchart diamond. Three inputs on the
3479
+ left (when / then / else, colour-coded); an else-if chains into the else input.
3480
+ ============================================ */
3481
+ .dl-node.dl-decision-node {
3482
+ background: transparent !important;
3483
+ border: none;
3484
+ box-shadow: none;
3485
+ width: fit-content;
3486
+ /* 72px square (was 90) — reserved to match in getNodeDimensions/DECISION_NODE,
3487
+ so the diamond sits as tight to its neighbours as any other node. */
3488
+ min-width: 72px;
3489
+ min-height: 72px;
3490
+ display: grid;
3491
+ place-items: center;
3492
+ position: relative;
3493
+ padding: 2px;
3494
+ }
3495
+ .dl-node.dl-decision-node::before { display: none; }
3496
+ .dl-node.dl-decision-node:hover { box-shadow: none; }
3497
+ .dl-dec-svg {
3498
+ position: absolute;
3499
+ inset: 0;
3500
+ width: 100%;
3501
+ height: 100%;
3502
+ overflow: visible;
3503
+ }
3504
+ .dl-dec-sil {
3505
+ fill: var(--accent-soft);
3506
+ stroke: var(--accent);
3507
+ stroke-width: 1.5;
3508
+ vector-effect: non-scaling-stroke;
3509
+ }
3510
+ .dl-dec-label {
3511
+ position: relative;
3512
+ z-index: 2;
3513
+ font-family: var(--font-mono);
3514
+ font-weight: 700;
3515
+ font-size: 15px;
3516
+ color: var(--accent);
3517
+ pointer-events: none;
3518
+ }
3519
+ .dl-node.dl-decision-node .dl-dec-port.react-flow__handle {
3520
+ width: 9px;
3521
+ height: 9px;
3522
+ border: 1.5px solid var(--node-bg);
3523
+ }
3524
+ .dl-node.dl-decision-node .dl-dec-when.react-flow__handle { background: var(--sig-bool-rest); }
3525
+ .dl-node.dl-decision-node .dl-dec-then.react-flow__handle { background: var(--sig-bool-true); }
3526
+ .dl-node.dl-decision-node .dl-dec-else.react-flow__handle { background: var(--sig-bool-false); }
3527
+ /* selection follows the diamond silhouette — suppress the generic rectangular ring */
3528
+ .dl-node.dl-decision-node.selected { box-shadow: none; }
3529
+ .dl-node.dl-decision-node.selected .dl-dec-sil {
3530
+ stroke: var(--accent);
3531
+ stroke-width: 2.5;
3532
+ fill: color-mix(in srgb, var(--accent) 20%, var(--node-bg));
3533
+ }
3534
+ .dl-node.dl-decision-node.selected .dl-dec-svg {
3535
+ filter: drop-shadow(0 0 3px color-mix(in srgb, var(--accent) 45%, transparent));
3536
+ }
3537
+ .dl-node.dl-decision-node[class*="debug-"] { box-shadow: none !important; }
3538
+ .dl-node.dl-decision-node.debug-executed .dl-dec-sil { stroke: var(--debug-executed-color); }
3539
+ .dl-node.dl-decision-node.debug-error .dl-dec-sil { stroke: var(--debug-error-color); }
3540
+ .dl-node.dl-decision-node.debug-current .dl-dec-sil { stroke: var(--debug-current-color); }
3541
+
3542
+ /* ============================================
3543
+ Direction: hierarchy (root on the left)
3544
+ Mirrors the compact directional cues so plugs/chips point toward their
3545
+ consumer, which now sits on the LEFT. Layout, handles and edges are flipped
3546
+ in JS (see utils/layout, edge-builder, and the handle components); only the
3547
+ pure-visual silhouettes are mirrored here.
3548
+ ============================================ */
3549
+ .logic-editor[data-direction="hierarchy"] .dl-tap {
3550
+ padding: 6px 12px 6px 19px; /* room for the plug point on the LEFT */
3551
+ clip-path: polygon(10px 0, 100% 0, 100% 100%, 10px 100%, 0 50%);
3552
+ }
3553
+ .logic-editor[data-direction="hierarchy"] .dl-node.dl-shape-tap.selected::after,
3554
+ .logic-editor[data-direction="hierarchy"] .dl-node.dl-shape-tap[class*="debug-"]::after {
3555
+ clip-path: polygon(12px 0, 100% 0, 100% 100%, 12px 100%, 0 50%);
3556
+ }
3557
+ .logic-editor[data-direction="hierarchy"] .dl-node.dl-infix-node .dl-infix-in.react-flow__handle {
3558
+ left: auto;
3559
+ right: -6px;
3560
+ }
3561
+ /* gate points toward its output, which is on the LEFT in hierarchy → mirror it */
3562
+ .logic-editor[data-direction="hierarchy"] .dl-gate-svg {
3563
+ transform: scaleX(-1);
3564
+ }
3565
+ .logic-editor[data-direction="hierarchy"] .dl-gate-label {
3566
+ transform: translateX(8px);
3567
+ }
3568
+
3569
+ /* ============================================
3570
+ CSS Variables - Debug Colors
3571
+ ============================================ */
3572
+
3573
+ .logic-editor {
3574
+ --debug-current-color: #F59E0B;
3575
+ --debug-current-glow: rgba(245, 158, 11, 0.4);
3576
+ --debug-executed-color: #10B981;
3577
+ --debug-executed-border: rgba(16, 185, 129, 0.6);
3578
+ --debug-pending-opacity: 0.5;
3579
+ --debug-error-color: #EF4444;
3580
+ --debug-error-glow: rgba(239, 68, 68, 0.4);
3581
+ --debug-error-border: rgba(239, 68, 68, 0.6);
3582
+ }
3583
+
3584
+ .logic-editor[data-theme="dark"] {
3585
+ --debug-current-glow: rgba(245, 158, 11, 0.5);
3586
+ --debug-executed-border: rgba(16, 185, 129, 0.8);
3587
+ --debug-error-glow: rgba(239, 68, 68, 0.5);
3588
+ --debug-error-border: rgba(239, 68, 68, 0.8);
3589
+ }
3590
+
3591
+ /* ============================================
3592
+ .dl-node — Shared Visual Base
3593
+ ============================================ */
3594
+
3595
+ .dl-node {
3596
+ --dl-sig: var(--sig-bool-rest); /* set per-node from its signal (return type) */
3597
+ border-radius: var(--radius-md);
3598
+ border: 1px solid var(--hairline);
3599
+ font-family: inherit;
3600
+ font-size: 13px;
3601
+ width: 100%;
3602
+ box-sizing: border-box;
3603
+ box-shadow: var(--node-shadow);
3604
+ transition: box-shadow var(--motion-base) var(--ease-out),
3605
+ border-color var(--motion-base) var(--ease-out),
3606
+ transform var(--motion-fast) var(--ease-out);
3607
+ background: var(--node-bg) !important;
3608
+ position: relative;
3609
+ }
3610
+
3611
+ /* thin left "signal rail" — tinted by the value type this node outputs.
3612
+ Quiet by default; the chip stays near-neutral so colour reads as meaning. */
3613
+ .dl-node::before {
3614
+ content: "";
3615
+ position: absolute;
3616
+ left: 0;
3617
+ top: 8px;
3618
+ bottom: 8px;
3619
+ width: 3px;
3620
+ border-radius: 0 3px 3px 0;
3621
+ background: var(--dl-sig);
3622
+ opacity: 0.9;
3623
+ z-index: 1;
3624
+ pointer-events: none;
3625
+ }
3626
+
3627
+ .dl-node:hover {
3628
+ border-color: color-mix(in srgb, var(--dl-sig) 45%, var(--hairline));
3629
+ box-shadow: var(--node-shadow-hover);
3630
+ }
3631
+
3632
+ .dl-node.selected {
3633
+ border-color: var(--accent);
3634
+ box-shadow: 0 0 0 2px var(--accent), var(--node-shadow-hover);
3635
+ }
3636
+
3637
+ /* ============================================
3638
+ .dl-node Debug States
3639
+ States ONLY change: border-color, box-shadow, opacity, animation
3640
+ ============================================ */
3641
+
3642
+ /* Disable transitions on debug-active nodes to prevent animation-to-static handoff glitches */
3643
+ .dl-node[class*="debug-"] {
3644
+ transition: none !important;
3645
+ }
3646
+
3647
+ /* Contain overflow on all debug-state nodes except current (which needs the bubble visible) */
3648
+ .dl-node[class*="debug-"]:not(.debug-current) {
2998
3649
  overflow: hidden;
2999
3650
  }
3000
3651
 
@@ -3062,12 +3713,12 @@ svg.react-flow__connectionline {
3062
3713
  ============================================ */
3063
3714
 
3064
3715
  .vertical-cell-header {
3065
- padding: 4px 10px;
3066
- border-radius: 6px 6px 0 0;
3067
- color: white;
3716
+ padding: 7px 12px 7px 15px;
3717
+ color: var(--ink);
3068
3718
  display: flex;
3069
3719
  align-items: center;
3070
3720
  gap: 8px;
3721
+ border-bottom: 1px solid var(--hairline-2);
3071
3722
  }
3072
3723
 
3073
3724
  .vertical-cell-header .vertical-cell-label {
@@ -3078,15 +3729,24 @@ svg.react-flow__connectionline {
3078
3729
  margin-left: auto;
3079
3730
  }
3080
3731
 
3732
+ /* category glyph reads as a monochrome badge tinted by the node's signal */
3081
3733
  .vertical-cell-icon {
3082
- font-size: 16px;
3734
+ width: 20px;
3735
+ height: 20px;
3736
+ border-radius: 6px;
3737
+ display: grid;
3738
+ place-items: center;
3739
+ flex-shrink: 0;
3740
+ color: var(--dl-sig);
3741
+ background: color-mix(in srgb, var(--dl-sig) 14%, transparent);
3083
3742
  }
3084
3743
 
3085
3744
  .vertical-cell-label {
3086
3745
  font-weight: 600;
3087
- font-size: 16px;
3088
- letter-spacing: 0.5px;
3746
+ font-size: 13px;
3747
+ letter-spacing: -0.01em;
3089
3748
  white-space: nowrap;
3749
+ color: var(--ink);
3090
3750
  }
3091
3751
 
3092
3752
  .vertical-cell-body {
@@ -3094,7 +3754,7 @@ svg.react-flow__connectionline {
3094
3754
  }
3095
3755
 
3096
3756
  .vertical-cell-row {
3097
- padding: 6px 12px;
3757
+ padding: 6px 12px 6px 15px;
3098
3758
  border-bottom: 1px solid var(--border-light);
3099
3759
  display: flex;
3100
3760
  align-items: center;
@@ -3102,10 +3762,11 @@ svg.react-flow__connectionline {
3102
3762
  position: relative;
3103
3763
  }
3104
3764
 
3105
- /* Handle positioned inside cell row */
3765
+ /* Handle positioned inside cell row — LEFT edge (children/operands flow in from
3766
+ the left in the Signal Board left->right data flow) */
3106
3767
  .vertical-cell-row .cell-handle {
3107
3768
  position: absolute;
3108
- right: -5px;
3769
+ left: -5px;
3109
3770
  top: 50%;
3110
3771
  transform: translateY(-50%);
3111
3772
  }
@@ -3141,7 +3802,7 @@ svg.react-flow__connectionline {
3141
3802
  }
3142
3803
 
3143
3804
  .vertical-cell-inline {
3144
- font-family: 'SF Mono', 'Consolas', monospace;
3805
+ font-family: var(--font-mono);
3145
3806
  font-size: 12px;
3146
3807
  color: var(--text-primary);
3147
3808
  word-break: break-word;
@@ -3167,6 +3828,91 @@ svg.react-flow__connectionline {
3167
3828
  border-left-color: #64748b;
3168
3829
  }
3169
3830
 
3831
+ /* Branch rails — a wired child operand. The child's logic lives in its own node,
3832
+ so the row shows a compact type-tinted "extends to child" chip (dl-child-link
3833
+ reuses the dl-pill tint) instead of repeating the expression. */
3834
+ .dl-child-link {
3835
+ flex-shrink: 0;
3836
+ padding: 1px 9px;
3837
+ cursor: default;
3838
+ }
3839
+ .dl-child-glyph {
3840
+ font-size: 13px;
3841
+ line-height: 1;
3842
+ opacity: 0.9;
3843
+ }
3844
+
3845
+ /* If / Then / Else rows read as coloured rails (design-system When/Then/Else). */
3846
+ .branch-rail .vertical-cell-row-label {
3847
+ letter-spacing: 0.03em;
3848
+ }
3849
+ .branch-rail-when .vertical-cell-row-label { color: var(--sig-bool-rest); }
3850
+ .branch-rail-then .vertical-cell-row-label { color: var(--sig-bool-true); }
3851
+ .branch-rail-else .vertical-cell-row-label { color: var(--sig-bool-false); }
3852
+
3853
+ /* If as a chained decision — flowchart diamonds ("if" / "elif") down a spine,
3854
+ with the Then / Else rails indented beneath each (design-system diamond). */
3855
+ .dl-shape-branch .vertical-cell-body {
3856
+ position: relative;
3857
+ }
3858
+ .dl-shape-branch .vertical-cell-body::before {
3859
+ content: "";
3860
+ position: absolute;
3861
+ left: 34px; /* through the diamond centres */
3862
+ top: 12px;
3863
+ bottom: 12px;
3864
+ width: 1.5px;
3865
+ background: color-mix(in srgb, var(--accent) 30%, var(--hairline));
3866
+ z-index: 0;
3867
+ }
3868
+ .dl-shape-branch .vertical-cell-row {
3869
+ z-index: 1;
3870
+ }
3871
+ /* condition diamond — the decision shape, "if" / "elif" chained down the spine */
3872
+ .dl-cond-diamond {
3873
+ position: relative;
3874
+ display: inline-grid;
3875
+ place-items: center;
3876
+ width: 40px;
3877
+ height: 40px;
3878
+ flex-shrink: 0;
3879
+ margin: -3px 4px -3px 0;
3880
+ }
3881
+ .dl-cond-diamond svg {
3882
+ position: absolute;
3883
+ inset: 0;
3884
+ width: 100%;
3885
+ height: 100%;
3886
+ overflow: visible;
3887
+ }
3888
+ .dl-cond-diamond svg path {
3889
+ fill: var(--accent-soft);
3890
+ stroke: var(--accent);
3891
+ stroke-width: 1.5;
3892
+ }
3893
+ .dl-cond-label {
3894
+ position: relative;
3895
+ z-index: 1;
3896
+ font-family: var(--font-mono);
3897
+ font-weight: 700;
3898
+ font-size: 10px;
3899
+ letter-spacing: 0.02em;
3900
+ color: var(--accent);
3901
+ }
3902
+ /* Then / Else rails sit indented under the diamond, colour-coded */
3903
+ .vertical-cell-row.branch-rail-then,
3904
+ .vertical-cell-row.branch-rail-else {
3905
+ padding-left: 48px;
3906
+ }
3907
+ .branch-rail-then .vertical-cell-row-icon { color: var(--sig-bool-true); }
3908
+ .branch-rail-else .vertical-cell-row-icon { color: var(--sig-bool-false); }
3909
+ .branch-rail-then .vertical-cell-row-label,
3910
+ .branch-rail-else .vertical-cell-row-label {
3911
+ text-transform: uppercase;
3912
+ letter-spacing: 0.08em;
3913
+ font-size: 9.5px;
3914
+ }
3915
+
3170
3916
  /* Header right section for result badge and collapse toggle */
3171
3917
  .header-right {
3172
3918
  display: flex;
@@ -3179,7 +3925,7 @@ svg.react-flow__connectionline {
3179
3925
  .collapse-toggle {
3180
3926
  background: transparent;
3181
3927
  border: none;
3182
- color: white;
3928
+ color: var(--muted);
3183
3929
  font-size: 10px;
3184
3930
  cursor: pointer;
3185
3931
  padding: 2px 6px;
@@ -3194,7 +3940,7 @@ svg.react-flow__connectionline {
3194
3940
 
3195
3941
  /* Expression text for collapsed nodes */
3196
3942
  .expression-text {
3197
- font-family: 'SF Mono', 'Consolas', monospace;
3943
+ font-family: var(--font-mono);
3198
3944
  font-size: 12px;
3199
3945
  color: var(--text-primary);
3200
3946
  padding: 4px 8px;
@@ -3238,7 +3984,7 @@ svg.react-flow__connectionline {
3238
3984
  }
3239
3985
 
3240
3986
  .arg-label {
3241
- font-family: 'SF Mono', 'Consolas', monospace;
3987
+ font-family: var(--font-mono);
3242
3988
  color: var(--text-primary);
3243
3989
  white-space: nowrap;
3244
3990
  overflow: hidden;
@@ -3250,7 +3996,7 @@ svg.react-flow__connectionline {
3250
3996
  ============================================ */
3251
3997
 
3252
3998
  .literal-node {
3253
- padding: 8px 12px;
3999
+ padding: 8px 12px 8px 15px;
3254
4000
  }
3255
4001
 
3256
4002
  .literal-node-content {
@@ -3267,7 +4013,7 @@ svg.react-flow__connectionline {
3267
4013
  }
3268
4014
 
3269
4015
  .literal-value {
3270
- font-family: 'SF Mono', 'Consolas', monospace;
4016
+ font-family: var(--font-mono);
3271
4017
  font-size: 13px;
3272
4018
  color: var(--text-primary);
3273
4019
  word-break: break-all;
@@ -3284,33 +4030,38 @@ svg.react-flow__connectionline {
3284
4030
  }
3285
4031
 
3286
4032
  .structure-node-header {
3287
- padding: 6px 12px;
3288
- border-radius: 6px 6px 0 0;
3289
- color: white;
4033
+ padding: 6px 12px 6px 15px;
4034
+ color: var(--ink);
3290
4035
  display: flex;
3291
4036
  align-items: center;
3292
4037
  gap: 8px;
3293
4038
  height: 32px;
3294
4039
  box-sizing: border-box;
4040
+ border-bottom: 1px solid var(--hairline-2);
3295
4041
  }
3296
4042
 
3297
4043
  .structure-node-icon {
3298
- font-size: 14px;
3299
- display: flex;
3300
- align-items: center;
4044
+ width: 20px;
4045
+ height: 20px;
4046
+ border-radius: 6px;
4047
+ display: grid;
4048
+ place-items: center;
4049
+ color: var(--dl-sig);
4050
+ background: color-mix(in srgb, var(--dl-sig) 14%, transparent);
3301
4051
  }
3302
4052
 
3303
4053
  .structure-node-label {
3304
4054
  font-weight: 600;
3305
- font-size: 14px;
3306
- letter-spacing: 0.5px;
4055
+ font-size: 13px;
4056
+ letter-spacing: -0.01em;
3307
4057
  flex: 1;
4058
+ color: var(--ink);
3308
4059
  }
3309
4060
 
3310
4061
  .structure-node-body {
3311
4062
  padding: 8px 12px;
3312
4063
  padding-right: 24px;
3313
- font-family: 'SF Mono', 'Consolas', monospace;
4064
+ font-family: var(--font-mono);
3314
4065
  font-size: 12px;
3315
4066
  white-space: pre;
3316
4067
  line-height: 18px;
@@ -3393,20 +4144,17 @@ svg.react-flow__connectionline {
3393
4144
  bottom: -6px;
3394
4145
  }
3395
4146
 
4147
+ /* input handles (connection to parent) now sit on the RIGHT, centred */
3396
4148
  .react-flow__handle-right {
3397
4149
  right: -6px;
3398
- }
3399
-
3400
- .react-flow__handle-left {
3401
- left: -6px;
3402
4150
  top: 50% !important;
3403
4151
  transform: translateY(-50%) !important;
3404
4152
  }
3405
4153
 
3406
- /* Ensure left handles are centered on simple nodes */
3407
- .literal-node .react-flow__handle-left {
3408
- top: 50% !important;
3409
- transform: translateY(-50%) !important;
4154
+ /* left handles are the per-cell branch handles — their vertical position is set
4155
+ inline / by .cell-handle, so do NOT force-centre them here */
4156
+ .react-flow__handle-left {
4157
+ left: -6px;
3410
4158
  }
3411
4159
 
3412
4160
  /* Edge styles */
@@ -3434,7 +4182,7 @@ svg.react-flow__connectionline {
3434
4182
  padding: 2px 8px;
3435
4183
  border-radius: 4px;
3436
4184
  font-size: 11px;
3437
- font-family: 'SF Mono', 'Consolas', monospace;
4185
+ font-family: var(--font-mono);
3438
4186
  font-weight: 500;
3439
4187
  max-width: 120px;
3440
4188
  overflow: hidden;
@@ -3462,11 +4210,11 @@ svg.react-flow__connectionline {
3462
4210
  margin-top: 4px;
3463
4211
  background: var(--debug-popover-bg);
3464
4212
  color: var(--debug-popover-text);
3465
- border-radius: 6px;
4213
+ border-radius: var(--radius-sm);
3466
4214
  padding: 8px 12px;
3467
4215
  font-size: 11px;
3468
4216
  z-index: 1000;
3469
- box-shadow: 0 4px 12px var(--debug-popover-shadow);
4217
+ box-shadow: var(--shadow-md);
3470
4218
  min-width: 150px;
3471
4219
  max-width: 300px;
3472
4220
  max-height: 200px;
@@ -3477,7 +4225,7 @@ svg.react-flow__connectionline {
3477
4225
  margin: 0;
3478
4226
  white-space: pre-wrap;
3479
4227
  word-break: break-word;
3480
- font-family: 'SF Mono', 'Consolas', monospace;
4228
+ font-family: var(--font-mono);
3481
4229
  }
3482
4230
 
3483
4231
  .result-popover.error {
@@ -3696,17 +4444,34 @@ svg.react-flow__connectionline {
3696
4444
 
3697
4445
  .debug-info-bubble {
3698
4446
  position: absolute;
3699
- background: var(--debug-popover-bg);
3700
- color: var(--debug-popover-text);
3701
- border-radius: 8px;
3702
- padding: 10px 12px;
4447
+ width: 264px;
4448
+ max-width: 300px;
4449
+ background: var(--chip);
4450
+ color: var(--ink-2);
4451
+ border: 1px solid var(--hairline);
4452
+ border-radius: 11px;
4453
+ padding: 0;
4454
+ font-family: var(--font-mono);
3703
4455
  font-size: 11px;
3704
4456
  z-index: 9999;
3705
- box-shadow: 0 4px 16px var(--debug-popover-shadow);
3706
- min-width: 180px;
3707
- max-width: 280px;
4457
+ box-shadow: var(--shadow-lg);
3708
4458
  pointer-events: auto;
3709
4459
  }
4460
+ /* signal rail — accent by default, red on error (design-system .pop::before) */
4461
+ .debug-info-bubble::before {
4462
+ content: "";
4463
+ position: absolute;
4464
+ left: 0;
4465
+ top: 8px;
4466
+ bottom: 8px;
4467
+ width: 3px;
4468
+ border-radius: 3px;
4469
+ background: var(--accent);
4470
+ z-index: 1;
4471
+ }
4472
+ .debug-info-bubble.error::before {
4473
+ background: var(--sig-bool-false);
4474
+ }
3710
4475
 
3711
4476
  .debug-info-bubble.debug-info-top {
3712
4477
  bottom: 100%;
@@ -3790,45 +4555,61 @@ svg.react-flow__connectionline {
3790
4555
  }
3791
4556
 
3792
4557
  .debug-info-iteration {
3793
- font-size: 10px;
3794
- font-weight: 600;
3795
- color: var(--debug-iteration-color);
3796
- margin-bottom: 8px;
3797
- padding-bottom: 6px;
3798
- border-bottom: 1px solid var(--debug-border-color);
4558
+ display: flex;
4559
+ align-items: center;
4560
+ gap: 5px;
4561
+ font-family: var(--font-ui);
4562
+ font-size: 9.5px;
4563
+ font-weight: 700;
4564
+ letter-spacing: 0.04em;
4565
+ color: var(--sig-collection);
4566
+ padding: 8px 12px 8px 15px;
4567
+ border-bottom: 1px solid var(--hairline-2);
3799
4568
  }
3800
4569
 
3801
4570
  .debug-info-section {
3802
- margin-bottom: 8px;
4571
+ padding: 9px 12px 9px 15px;
4572
+ border-bottom: 1px solid var(--hairline-2);
3803
4573
  }
3804
4574
 
3805
4575
  .debug-info-section:last-child {
3806
- margin-bottom: 0;
4576
+ border-bottom: none;
3807
4577
  }
3808
4578
 
3809
4579
  .debug-info-label {
3810
- display: block;
3811
- font-size: 10px;
3812
- font-weight: 600;
3813
- color: var(--debug-label-color);
4580
+ display: flex;
4581
+ align-items: center;
4582
+ font-family: var(--font-ui);
4583
+ font-size: 9.5px;
4584
+ font-weight: 700;
4585
+ color: var(--muted);
3814
4586
  text-transform: uppercase;
3815
- letter-spacing: 0.5px;
3816
- margin-bottom: 4px;
4587
+ letter-spacing: 0.1em;
4588
+ margin-bottom: 6px;
3817
4589
  }
3818
4590
 
3819
4591
  .debug-info-value {
3820
4592
  margin: 0;
3821
- padding: 4px 6px;
3822
- background: var(--debug-popover-value-bg);
3823
- border-radius: 4px;
3824
- font-family: 'SF Mono', 'Consolas', monospace;
3825
- font-size: 10px;
4593
+ padding: 7px 9px;
4594
+ background: var(--surface-2);
4595
+ border: 1px solid var(--hairline-2);
4596
+ border-radius: 7px;
4597
+ font-family: var(--font-mono);
4598
+ font-size: 10.5px;
4599
+ line-height: 1.6;
4600
+ color: var(--ink-2);
3826
4601
  white-space: pre-wrap;
3827
4602
  word-break: break-word;
3828
- max-height: 100px;
4603
+ max-height: 116px;
3829
4604
  overflow: auto;
3830
4605
  }
3831
4606
 
4607
+ .debug-info-simple-value {
4608
+ font-family: var(--font-mono);
4609
+ font-size: 18px;
4610
+ font-weight: 700;
4611
+ }
4612
+
3832
4613
  /* Custom scrollbar styling */
3833
4614
  .debug-info-value::-webkit-scrollbar {
3834
4615
  width: 6px;
@@ -3888,7 +4669,7 @@ svg.react-flow__connectionline {
3888
4669
  }
3889
4670
 
3890
4671
  .debug-info-simple-value {
3891
- font-family: 'SF Mono', 'Consolas', monospace;
4672
+ font-family: var(--font-mono);
3892
4673
  font-size: 12px;
3893
4674
  font-weight: 500;
3894
4675
  }
@@ -3926,7 +4707,7 @@ svg.react-flow__connectionline {
3926
4707
  height: 100%;
3927
4708
  position: relative;
3928
4709
  background: var(--bg-tertiary);
3929
- border-radius: 8px;
4710
+ border-radius: var(--radius-md);
3930
4711
  overflow: hidden;
3931
4712
  display: flex;
3932
4713
  flex-direction: column;
@@ -3957,13 +4738,11 @@ svg.react-flow__connectionline {
3957
4738
  background: var(--bg-secondary, #ffffff);
3958
4739
  flex-shrink: 0;
3959
4740
  gap: 10px;
3960
- overflow-x: auto;
3961
- -webkit-overflow-scrolling: touch;
3962
- scrollbar-width: none;
3963
- }
3964
-
3965
- .logic-editor-toolbar::-webkit-scrollbar {
3966
- display: none;
4741
+ /* Desktop: visible overflow so tooltips on toolbar buttons aren't clipped.
4742
+ Horizontal-scroll behavior is scoped to the mobile breakpoint below. */
4743
+ overflow: visible;
4744
+ position: relative;
4745
+ z-index: 2;
3967
4746
  }
3968
4747
 
3969
4748
  .logic-editor[data-theme="dark"] .logic-editor-toolbar {
@@ -3975,7 +4754,7 @@ svg.react-flow__connectionline {
3975
4754
  flex: 1;
3976
4755
  }
3977
4756
 
3978
- .logic-editor-toolbar .dl-preserve-structure-toggle {
4757
+ .logic-editor-toolbar .dl-templating-toggle {
3979
4758
  display: flex;
3980
4759
  align-items: center;
3981
4760
  gap: 6px;
@@ -3987,11 +4766,50 @@ svg.react-flow__connectionline {
3987
4766
  flex-shrink: 0;
3988
4767
  }
3989
4768
 
3990
- .logic-editor-toolbar .dl-preserve-structure-toggle input[type="checkbox"] {
4769
+ .logic-editor-toolbar .dl-templating-toggle input[type="checkbox"] {
3991
4770
  margin: 0;
3992
4771
  cursor: pointer;
3993
4772
  }
3994
4773
 
4774
+ /* Direction toggle — a compact segmented control: Data flow ⇄ Hierarchy */
4775
+ .logic-editor-toolbar .dl-direction-toggle {
4776
+ display: inline-flex;
4777
+ align-items: center;
4778
+ flex-shrink: 0;
4779
+ border: 1px solid var(--hairline, #ddd);
4780
+ border-radius: var(--radius-sm, 6px);
4781
+ overflow: hidden;
4782
+ }
4783
+
4784
+ .logic-editor-toolbar .dl-direction-toggle button {
4785
+ appearance: none;
4786
+ border: none;
4787
+ background: transparent;
4788
+ color: var(--text-secondary, #666);
4789
+ font: inherit;
4790
+ font-size: 12px;
4791
+ line-height: 1;
4792
+ padding: 4px 10px;
4793
+ cursor: pointer;
4794
+ white-space: nowrap;
4795
+ transition: background var(--motion-fast) var(--ease-out),
4796
+ color var(--motion-fast) var(--ease-out);
4797
+ }
4798
+
4799
+ .logic-editor-toolbar .dl-direction-toggle button + button {
4800
+ border-left: 1px solid var(--hairline, #ddd);
4801
+ }
4802
+
4803
+ .logic-editor-toolbar .dl-direction-toggle button:hover:not(.active) {
4804
+ background: var(--bg-hover, #f0f0f0);
4805
+ color: var(--text-primary, #1a1a1a);
4806
+ }
4807
+
4808
+ .logic-editor-toolbar .dl-direction-toggle button.active {
4809
+ background: var(--accent, #6366f1);
4810
+ color: #fff;
4811
+ }
4812
+
3995
4813
  /* Shared toolbar button style (undo/redo, etc.) */
3996
4814
  .dl-toolbar-btn {
3997
4815
  display: flex;
@@ -4002,10 +4820,12 @@ svg.react-flow__connectionline {
4002
4820
  padding: 0;
4003
4821
  background: transparent;
4004
4822
  border: none;
4005
- border-radius: 5px;
4823
+ border-radius: var(--radius-sm);
4006
4824
  color: var(--text-secondary, #666);
4007
4825
  cursor: pointer;
4008
- transition: background 0.15s, color 0.15s;
4826
+ transition: background var(--motion-fast) var(--ease-out),
4827
+ color var(--motion-fast) var(--ease-out),
4828
+ box-shadow var(--motion-fast) var(--ease-out);
4009
4829
  flex-shrink: 0;
4010
4830
  }
4011
4831
 
@@ -4014,6 +4834,11 @@ svg.react-flow__connectionline {
4014
4834
  color: var(--text-primary, #1a1a1a);
4015
4835
  }
4016
4836
 
4837
+ .dl-toolbar-btn:focus-visible {
4838
+ outline: none;
4839
+ box-shadow: var(--focus-ring);
4840
+ }
4841
+
4017
4842
  .dl-toolbar-btn:disabled {
4018
4843
  opacity: 0.35;
4019
4844
  cursor: not-allowed;
@@ -4042,23 +4867,95 @@ svg.react-flow__connectionline {
4042
4867
  text-align: center;
4043
4868
  color: var(--text-tertiary);
4044
4869
  pointer-events: none;
4870
+ max-width: 420px;
4871
+ width: calc(100% - 32px);
4872
+ display: flex;
4873
+ flex-direction: column;
4874
+ align-items: center;
4875
+ gap: 14px;
4876
+ }
4877
+
4878
+ .logic-editor-empty-icon {
4879
+ display: flex;
4880
+ align-items: center;
4881
+ justify-content: center;
4882
+ width: 64px;
4883
+ height: 64px;
4884
+ border-radius: var(--radius-lg);
4885
+ background: var(--bg-secondary);
4886
+ border: 1px solid var(--border-light);
4887
+ color: var(--accent-blue);
4888
+ box-shadow: var(--shadow-sm);
4889
+ margin-bottom: 2px;
4045
4890
  }
4046
4891
 
4047
4892
  .logic-editor-empty p {
4048
4893
  margin: 0;
4049
- font-size: 16px;
4894
+ font-size: 15px;
4895
+ font-weight: 500;
4896
+ color: var(--text-secondary);
4050
4897
  }
4051
4898
 
4052
4899
  .logic-editor-empty-hint {
4053
- margin-top: 8px !important;
4900
+ margin-top: 0 !important;
4054
4901
  font-size: 13px !important;
4902
+ font-weight: 400 !important;
4903
+ color: var(--text-muted) !important;
4904
+ max-width: 320px;
4905
+ }
4906
+
4907
+ .logic-editor-empty-chips {
4908
+ display: flex;
4909
+ flex-wrap: wrap;
4910
+ align-items: center;
4911
+ justify-content: center;
4912
+ gap: 6px;
4913
+ margin-top: 4px;
4914
+ pointer-events: auto;
4915
+ }
4916
+
4917
+ .logic-editor-empty-chips-label {
4918
+ font-size: 11px;
4919
+ font-weight: 600;
4055
4920
  color: var(--text-muted);
4921
+ text-transform: uppercase;
4922
+ letter-spacing: 0.5px;
4923
+ margin-right: 4px;
4924
+ }
4925
+
4926
+ .logic-editor-empty-chip {
4927
+ display: inline-flex;
4928
+ align-items: center;
4929
+ padding: 4px 10px;
4930
+ font-size: 12px;
4931
+ font-family: inherit;
4932
+ font-weight: 500;
4933
+ background: var(--bg-secondary);
4934
+ color: var(--text-secondary);
4935
+ border: 1px solid var(--border-secondary);
4936
+ border-radius: 999px;
4937
+ cursor: pointer;
4938
+ transition: background var(--motion-fast) var(--ease-out),
4939
+ border-color var(--motion-fast) var(--ease-out),
4940
+ color var(--motion-fast) var(--ease-out),
4941
+ box-shadow var(--motion-fast) var(--ease-out);
4942
+ }
4943
+
4944
+ .logic-editor-empty-chip:hover {
4945
+ background: var(--accent-blue-light);
4946
+ border-color: var(--accent-blue);
4947
+ color: var(--accent-blue);
4948
+ }
4949
+
4950
+ .logic-editor-empty-chip:focus-visible {
4951
+ outline: none;
4952
+ box-shadow: var(--focus-ring);
4056
4953
  }
4057
4954
 
4058
4955
  /* ReactFlow overrides */
4059
4956
  .logic-editor .react-flow__controls {
4060
- box-shadow: 0 2px 8px var(--node-shadow);
4061
- border-radius: 8px;
4957
+ box-shadow: var(--shadow-md);
4958
+ border-radius: var(--radius-md);
4062
4959
  overflow: hidden;
4063
4960
  }
4064
4961
 
@@ -4112,6 +5009,15 @@ svg.react-flow__connectionline {
4112
5009
  .logic-editor-toolbar {
4113
5010
  padding: 0 8px;
4114
5011
  gap: 6px;
5012
+ /* Restore horizontal scrolling on narrow viewports where buttons can overflow */
5013
+ overflow-x: auto;
5014
+ overflow-y: hidden;
5015
+ -webkit-overflow-scrolling: touch;
5016
+ scrollbar-width: none;
5017
+ }
5018
+
5019
+ .logic-editor-toolbar::-webkit-scrollbar {
5020
+ display: none;
4115
5021
  }
4116
5022
 
4117
5023
  .logic-editor-toolbar-spacer {
@@ -4123,7 +5029,7 @@ svg.react-flow__connectionline {
4123
5029
  height: 40px;
4124
5030
  }
4125
5031
 
4126
- .dl-preserve-structure-toggle span {
5032
+ .dl-templating-toggle span {
4127
5033
  font-size: 11px;
4128
5034
  }
4129
5035
 
@@ -4146,8 +5052,8 @@ svg.react-flow__connectionline {
4146
5052
  gap: 4px;
4147
5053
  padding: 4px 8px;
4148
5054
  margin: 4px 8px 8px;
4149
- border: 1.5px dashed var(--color-primary, #2563eb);
4150
- border-radius: 4px;
5055
+ border: 1.5px dashed color-mix(in srgb, var(--accent) 55%, var(--hairline));
5056
+ border-radius: var(--radius-sm);
4151
5057
  background: transparent;
4152
5058
  color: var(--color-primary, #2563eb);
4153
5059
  font-size: 11px;
@@ -4194,10 +5100,10 @@ svg.react-flow__connectionline {
4194
5100
  z-index: 1000;
4195
5101
  min-width: 180px;
4196
5102
  max-width: 280px;
4197
- background: var(--bg-primary, #ffffff);
4198
- border: 1px solid var(--border-color, #e0e0e0);
4199
- border-radius: 8px;
4200
- box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08);
5103
+ background: var(--bg-secondary);
5104
+ border: 1px solid var(--border-primary);
5105
+ border-radius: var(--radius-md);
5106
+ box-shadow: var(--shadow-lg);
4201
5107
  padding: 4px 0;
4202
5108
  font-size: 13px;
4203
5109
  outline: none;