@d34dman/flowdrop 0.0.44 → 0.0.45

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.
@@ -178,19 +178,18 @@
178
178
  });
179
179
  </script>
180
180
 
181
- <!-- Input Handles -->
181
+ <!-- Input Handles: center at 20/40/60px (multiple of 10), 20px connection area -->
182
182
  {#each inputPorts as port, index}
183
- <!-- Data Input - positioned at top-left if both types exist, otherwise center -->
184
183
  <Handle
185
184
  type="target"
186
185
  position={Position.Left}
187
- style="background-color: {getDataTypeColor(
186
+ style="--fd-handle-fill: {getDataTypeColor(
188
187
  port.dataType
189
- )}; border-color: var(--fd-handle-border); top: {inputPorts.length > 1
188
+ )}; --fd-handle-border-color: var(--fd-handle-border); top: {inputPorts.length > 1
190
189
  ? index === 0
191
- ? '25%'
192
- : '75%'
193
- : '50%'}; z-index: 30;"
190
+ ? 20
191
+ : 60
192
+ : 40}px; transform: translateY(-50%); margin-left: -10px; z-index: 30;"
194
193
  id={`${props.data.nodeId}-input-${port.id}`}
195
194
  />
196
195
  {/each}
@@ -250,19 +249,18 @@
250
249
  </button>
251
250
  </div>
252
251
 
253
- <!-- Output Handles -->
252
+ <!-- Output Handles: center at 20/40/60px (multiple of 10), 20px connection area -->
254
253
  {#each outputPorts as port, index}
255
- <!-- Data Output - positioned at top-right if both types exist, otherwise center -->
256
254
  <Handle
257
255
  type="source"
258
256
  position={Position.Right}
259
- style="background-color: {getDataTypeColor(
257
+ style="--fd-handle-fill: {getDataTypeColor(
260
258
  port.dataType
261
- )}; border-color: var(--fd-handle-border); top: {outputPorts.length > 1
259
+ )}; --fd-handle-border-color: var(--fd-handle-border); top: {outputPorts.length > 1
262
260
  ? index === 0
263
- ? '25%'
264
- : '75%'
265
- : '50%'}; z-index: 30;"
261
+ ? 20
262
+ : 60
263
+ : 40}px; transform: translateY(-50%); margin-right: -10px; z-index: 30;"
266
264
  id={`${props.data.nodeId}-output-${port.id}`}
267
265
  />
268
266
  {/each}
@@ -287,7 +285,9 @@
287
285
 
288
286
  /* Normal layout (default) */
289
287
  .flowdrop-simple-node--normal {
290
- width: 18rem;
288
+ width: var(--fd-node-default-width);
289
+ height: var(--fd-node-simple-height);
290
+ overflow: hidden;
291
291
  }
292
292
 
293
293
  .flowdrop-simple-node:hover {
@@ -296,12 +296,16 @@
296
296
  }
297
297
 
298
298
  .flowdrop-simple-node--selected {
299
- box-shadow: 0 0 0 2px var(--fd-primary-muted), var(--fd-shadow-lg);
299
+ box-shadow:
300
+ 0 0 0 2px var(--fd-primary-muted),
301
+ var(--fd-shadow-lg);
300
302
  border-color: var(--fd-primary);
301
303
  }
302
304
 
303
305
  .flowdrop-simple-node--selected:hover {
304
- box-shadow: 0 0 0 2px var(--fd-primary-muted), var(--fd-shadow-lg);
306
+ box-shadow:
307
+ 0 0 0 2px var(--fd-primary-muted),
308
+ var(--fd-shadow-lg);
305
309
  border-color: var(--fd-primary);
306
310
  }
307
311
 
@@ -339,13 +343,17 @@
339
343
  width: 2.25rem;
340
344
  height: 2.25rem;
341
345
  border-radius: 0.5rem;
342
- background: color-mix(in srgb, var(--_icon-color) 15%, transparent);
346
+ background: color-mix(in srgb, var(--_icon-color) var(--fd-node-icon-bg-opacity), transparent);
343
347
  flex-shrink: 0;
344
348
  transition: all var(--fd-transition-normal);
345
349
  }
346
350
 
347
351
  .flowdrop-simple-node:hover .flowdrop-simple-node__icon-wrapper {
348
- background: color-mix(in srgb, var(--_icon-color) 22%, transparent);
352
+ background: color-mix(
353
+ in srgb,
354
+ var(--_icon-color) var(--fd-node-icon-bg-opacity-hover),
355
+ transparent
356
+ );
349
357
  transform: scale(1.05);
350
358
  }
351
359
 
@@ -438,27 +446,21 @@
438
446
  }
439
447
  }
440
448
 
441
- /* Handle styles - matching WorkflowNode exactly */
449
+ /* Handle: 20px/12px from base.css; position offsets for 20px handle */
442
450
  :global(.svelte-flow__node-simple .svelte-flow__handle) {
443
- width: 18px !important;
444
- height: 18px !important;
445
- border-radius: 50% !important;
446
- transition: all var(--fd-transition-normal) !important;
447
- cursor: pointer !important;
448
451
  z-index: 20 !important;
449
452
  pointer-events: auto !important;
450
453
  }
451
454
 
452
455
  :global(.svelte-flow__node-simple .svelte-flow__handle-left) {
453
- left: -6px !important;
456
+ left: -10px !important;
454
457
  }
455
458
 
456
459
  :global(.svelte-flow__node-simple .svelte-flow__handle-right) {
457
- right: -6px !important;
460
+ right: -10px !important;
458
461
  }
459
462
 
460
- :global(.svelte-flow__node-simple .svelte-flow__handle:focus) {
461
- outline: 2px solid var(--fd-ring) !important;
462
- outline-offset: 2px !important;
463
+ :global(.svelte-flow__node-simple .svelte-flow__handle:hover) {
464
+ transform: translateY(-50%) scale(1.2) !important;
463
465
  }
464
466
  </style>
@@ -49,17 +49,13 @@
49
49
  * Get icon using the same resolution as WorkflowNode
50
50
  * Uses getNodeIcon utility with category fallback
51
51
  */
52
- let squareIcon = $derived(
53
- getNodeIcon(props.data.metadata?.icon, props.data.metadata?.category)
54
- );
52
+ let squareIcon = $derived(getNodeIcon(props.data.metadata?.icon, props.data.metadata?.category));
55
53
 
56
54
  /**
57
55
  * Get icon color using category-based color tokens for consistency
58
56
  * Falls back to primary color if category not available
59
57
  */
60
- let squareColor = $derived(
61
- getCategoryColorToken(props.data.metadata?.category)
62
- );
58
+ let squareColor = $derived(getCategoryColorToken(props.data.metadata?.category));
63
59
 
64
60
  // Handle configuration sidebar - now using global ConfigSidebar
65
61
  function openConfigSidebar(): void {
@@ -168,19 +164,18 @@
168
164
  });
169
165
  </script>
170
166
 
171
- <!-- Input Handles -->
167
+ <!-- Input Handles: center at 20/40/60px (multiple of 10), 20px connection area -->
172
168
  {#each inputPorts as port, index}
173
- <!-- Data Input - positioned at top-left if both types exist, otherwise center -->
174
169
  <Handle
175
170
  type="target"
176
171
  position={Position.Left}
177
- style="background-color: {getDataTypeColor(
172
+ style="--fd-handle-fill: {getDataTypeColor(
178
173
  port.dataType
179
- )}; border-color: var(--fd-handle-border); top: {inputPorts.length > 1
174
+ )}; --fd-handle-border-color: var(--fd-handle-border); top: {inputPorts.length > 1
180
175
  ? index === 0
181
- ? '25%'
182
- : '75%'
183
- : '50%'}; z-index: 30;"
176
+ ? 20
177
+ : 60
178
+ : 40}px; transform: translateY(-50%); margin-left: -10px; z-index: 30;"
184
179
  id={`${props.data.nodeId}-input-${port.id}`}
185
180
  />
186
181
  {/each}
@@ -199,14 +194,8 @@
199
194
  >
200
195
  <!-- Square Layout: Always compact with centered icon in squircle wrapper -->
201
196
  <div class="flowdrop-square-node__compact-content">
202
- <div
203
- class="flowdrop-square-node__icon-wrapper"
204
- style="--_icon-color: {squareColor}"
205
- >
206
- <Icon
207
- icon={squareIcon}
208
- class="flowdrop-square-node__icon"
209
- />
197
+ <div class="flowdrop-square-node__icon-wrapper" style="--_icon-color: {squareColor}">
198
+ <Icon icon={squareIcon} class="flowdrop-square-node__icon" />
210
199
  </div>
211
200
  </div>
212
201
 
@@ -234,19 +223,18 @@
234
223
  </button>
235
224
  </div>
236
225
 
237
- <!-- Output Handles -->
226
+ <!-- Output Handles: center at 20/40/60px (multiple of 10), 20px connection area -->
238
227
  {#each outputPorts as port, index}
239
- <!-- Data Output - positioned at top-right if both types exist, otherwise center -->
240
228
  <Handle
241
229
  type="source"
242
230
  position={Position.Right}
243
- style="background-color: {getDataTypeColor(
231
+ style="--fd-handle-fill: {getDataTypeColor(
244
232
  port.dataType
245
- )}; border-color: var(--fd-handle-border); top: {outputPorts.length > 1
233
+ )}; --fd-handle-border-color: var(--fd-handle-border); top: {outputPorts.length > 1
246
234
  ? index === 0
247
- ? '25%'
248
- : '75%'
249
- : '50%'}; z-index: 30;"
235
+ ? 20
236
+ : 60
237
+ : 40}px; transform: translateY(-50%); margin-right: -10px; z-index: 30;"
250
238
  id={`${props.data.nodeId}-output-${port.id}`}
251
239
  />
252
240
  {/each}
@@ -269,8 +257,8 @@
269
257
 
270
258
  /* Square layout (always compact) */
271
259
  .flowdrop-square-node--compact {
272
- width: 80px;
273
- height: 80px;
260
+ width: var(--fd-node-square-size);
261
+ height: var(--fd-node-square-size);
274
262
  justify-content: center;
275
263
  align-items: center;
276
264
  }
@@ -281,12 +269,16 @@
281
269
  }
282
270
 
283
271
  .flowdrop-square-node--selected {
284
- box-shadow: 0 0 0 2px var(--fd-primary-muted), var(--fd-shadow-lg);
272
+ box-shadow:
273
+ 0 0 0 2px var(--fd-primary-muted),
274
+ var(--fd-shadow-lg);
285
275
  border-color: var(--fd-primary);
286
276
  }
287
277
 
288
278
  .flowdrop-square-node--selected:hover {
289
- box-shadow: 0 0 0 2px var(--fd-primary-muted), var(--fd-shadow-lg);
279
+ box-shadow:
280
+ 0 0 0 2px var(--fd-primary-muted),
281
+ var(--fd-shadow-lg);
290
282
  border-color: var(--fd-primary);
291
283
  }
292
284
 
@@ -321,13 +313,17 @@
321
313
  width: 3rem;
322
314
  height: 3rem;
323
315
  border-radius: 0.625rem;
324
- background: color-mix(in srgb, var(--_icon-color) 15%, transparent);
316
+ background: color-mix(in srgb, var(--_icon-color) var(--fd-node-icon-bg-opacity), transparent);
325
317
  flex-shrink: 0;
326
318
  transition: all var(--fd-transition-normal);
327
319
  }
328
320
 
329
321
  .flowdrop-square-node:hover .flowdrop-square-node__icon-wrapper {
330
- background: color-mix(in srgb, var(--_icon-color) 22%, transparent);
322
+ background: color-mix(
323
+ in srgb,
324
+ var(--_icon-color) var(--fd-node-icon-bg-opacity-hover),
325
+ transparent
326
+ );
331
327
  transform: scale(1.05);
332
328
  }
333
329
 
@@ -403,27 +399,21 @@
403
399
  }
404
400
  }
405
401
 
406
- /* Handle styles - matching WorkflowNode exactly */
402
+ /* Handle: 20px/12px from base.css; position offsets for 20px handle */
407
403
  :global(.svelte-flow__node-square .svelte-flow__handle) {
408
- width: 18px !important;
409
- height: 18px !important;
410
- border-radius: 50% !important;
411
- transition: all var(--fd-transition-normal) !important;
412
- cursor: pointer !important;
413
404
  z-index: 20 !important;
414
405
  pointer-events: auto !important;
415
406
  }
416
407
 
417
408
  :global(.svelte-flow__node-square .svelte-flow__handle-left) {
418
- left: -6px !important;
409
+ left: -10px !important;
419
410
  }
420
411
 
421
412
  :global(.svelte-flow__node-square .svelte-flow__handle-right) {
422
- right: -6px !important;
413
+ right: -10px !important;
423
414
  }
424
415
 
425
- :global(.svelte-flow__node-square .svelte-flow__handle:focus) {
426
- outline: 2px solid var(--fd-ring) !important;
427
- outline-offset: 2px !important;
416
+ :global(.svelte-flow__node-square .svelte-flow__handle:hover) {
417
+ transform: translateY(-50%) scale(1.2) !important;
428
418
  }
429
419
  </style>
@@ -320,9 +320,9 @@
320
320
  <Handle
321
321
  type="target"
322
322
  position={Position.Left}
323
- style="background-color: {getDataTypeColor(
323
+ style="--fd-handle-fill: {getDataTypeColor(
324
324
  port.dataType
325
- )}; border-color: var(--fd-handle-border); top: 50%; transform: translateY(-50%); z-index: 30;"
325
+ )}; --fd-handle-border-color: var(--fd-handle-border); top: 40px; transform: translateY(-50%); margin-left: -10px; z-index: 30;"
326
326
  id={`${props.data.nodeId}-input-${port.id}`}
327
327
  />
328
328
  {/each}
@@ -330,14 +330,8 @@
330
330
 
331
331
  <!-- Circular content with icon in squircle wrapper -->
332
332
  <div class="flowdrop-terminal-node__content">
333
- <div
334
- class="flowdrop-terminal-node__icon-wrapper"
335
- style="--_icon-color: {terminalColor}"
336
- >
337
- <Icon
338
- icon={terminalIcon}
339
- class="flowdrop-terminal-node__icon"
340
- />
333
+ <div class="flowdrop-terminal-node__icon-wrapper" style="--_icon-color: {terminalColor}">
334
+ <Icon icon={terminalIcon} class="flowdrop-terminal-node__icon" />
341
335
  </div>
342
336
  </div>
343
337
 
@@ -348,9 +342,9 @@
348
342
  type="source"
349
343
  position={Position.Right}
350
344
  id={`${props.data.nodeId}-output-${port.id}`}
351
- style="background-color: {getDataTypeColor(
345
+ style="--fd-handle-fill: {getDataTypeColor(
352
346
  port.dataType
353
- )}; border-color: var(--fd-handle-border); top: 50%; transform: translateY(-50%); z-index: 30;"
347
+ )}; --fd-handle-border-color: var(--fd-handle-border); top: 40px; transform: translateY(-50%); margin-right: -10px; z-index: 30;"
354
348
  />
355
349
  {/each}
356
350
  {/if}
@@ -405,8 +399,8 @@
405
399
  }
406
400
 
407
401
  .flowdrop-terminal-node__content {
408
- width: 72px;
409
- height: 72px;
402
+ width: var(--fd-node-terminal-size);
403
+ height: var(--fd-node-terminal-size);
410
404
  background-color: var(--fd-background);
411
405
  border: 3px solid var(--terminal-color, var(--fd-muted-foreground));
412
406
  border-radius: 50%;
@@ -464,7 +458,8 @@
464
458
  0 4px 6px -2px color-mix(in srgb, var(--fd-success) 15%, transparent);
465
459
  }
466
460
 
467
- .flowdrop-terminal-node--start.flowdrop-terminal-node--selected:hover .flowdrop-terminal-node__content {
461
+ .flowdrop-terminal-node--start.flowdrop-terminal-node--selected:hover
462
+ .flowdrop-terminal-node__content {
468
463
  box-shadow:
469
464
  0 10px 15px -3px color-mix(in srgb, var(--fd-success) 30%, transparent),
470
465
  0 4px 6px -2px color-mix(in srgb, var(--fd-success) 15%, transparent),
@@ -483,7 +478,8 @@
483
478
  0 4px 6px -2px color-mix(in srgb, var(--fd-error) 15%, transparent);
484
479
  }
485
480
 
486
- .flowdrop-terminal-node--exit.flowdrop-terminal-node--selected:hover .flowdrop-terminal-node__content {
481
+ .flowdrop-terminal-node--exit.flowdrop-terminal-node--selected:hover
482
+ .flowdrop-terminal-node__content {
487
483
  box-shadow:
488
484
  0 10px 15px -3px color-mix(in srgb, var(--fd-error) 30%, transparent),
489
485
  0 4px 6px -2px color-mix(in srgb, var(--fd-error) 15%, transparent),
@@ -498,13 +494,17 @@
498
494
  width: 2.75rem;
499
495
  height: 2.75rem;
500
496
  border-radius: 0.625rem;
501
- background: color-mix(in srgb, var(--_icon-color) 15%, transparent);
497
+ background: color-mix(in srgb, var(--_icon-color) var(--fd-node-icon-bg-opacity), transparent);
502
498
  flex-shrink: 0;
503
499
  transition: all var(--fd-transition-normal);
504
500
  }
505
501
 
506
502
  .flowdrop-terminal-node:hover .flowdrop-terminal-node__icon-wrapper {
507
- background: color-mix(in srgb, var(--_icon-color) 22%, transparent);
503
+ background: color-mix(
504
+ in srgb,
505
+ var(--_icon-color) var(--fd-node-icon-bg-opacity-hover),
506
+ transparent
507
+ );
508
508
  }
509
509
 
510
510
  .flowdrop-terminal-node__icon-wrapper :global(.flowdrop-terminal-node__icon) {
@@ -614,61 +614,25 @@
614
614
  }
615
615
  }
616
616
 
617
- /* Handle styles - positioned relative to circle wrapper */
618
- :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle) {
619
- width: 16px !important;
620
- height: 16px !important;
621
- border-radius: 50% !important;
622
- border: 2px solid var(--fd-handle-border) !important;
623
- transition: all var(--fd-transition-normal) !important;
624
- cursor: pointer !important;
625
- z-index: 20 !important;
626
- pointer-events: auto !important;
627
- }
628
-
629
- :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle-left) {
630
- left: -8px !important;
631
- }
632
-
633
- :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle-right) {
634
- right: -8px !important;
635
- }
636
-
637
- :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle:hover) {
638
- transform: translateY(-50%) scale(1.2) !important;
639
- }
640
-
641
- :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle:focus) {
642
- outline: 2px solid var(--fd-ring) !important;
643
- outline-offset: 2px !important;
644
- }
645
-
646
- /* Also keep node-level handle styles for fallback */
617
+ /* Handle: 20px/12px from base.css; position offsets for 20px handle */
618
+ :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle),
647
619
  :global(.svelte-flow__node-terminal .svelte-flow__handle) {
648
- width: 16px !important;
649
- height: 16px !important;
650
- border-radius: 50% !important;
651
- border: 2px solid var(--fd-handle-border) !important;
652
- transition: all var(--fd-transition-normal) !important;
653
- cursor: pointer !important;
654
620
  z-index: 20 !important;
655
621
  pointer-events: auto !important;
656
622
  }
657
623
 
624
+ :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle-left),
658
625
  :global(.svelte-flow__node-terminal .svelte-flow__handle-left) {
659
- left: -8px !important;
626
+ left: -10px !important;
660
627
  }
661
628
 
629
+ :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle-right),
662
630
  :global(.svelte-flow__node-terminal .svelte-flow__handle-right) {
663
- right: -8px !important;
631
+ right: -10px !important;
664
632
  }
665
633
 
634
+ :global(.flowdrop-terminal-node__circle-wrapper .svelte-flow__handle:hover),
666
635
  :global(.svelte-flow__node-terminal .svelte-flow__handle:hover) {
667
636
  transform: translateY(-50%) scale(1.2) !important;
668
637
  }
669
-
670
- :global(.svelte-flow__node-terminal .svelte-flow__handle:focus) {
671
- outline: 2px solid var(--fd-ring) !important;
672
- outline-offset: 2px !important;
673
- }
674
638
  </style>
@@ -141,13 +141,15 @@
141
141
  }
142
142
  </script>
143
143
 
144
- <!-- Tool Input Handle (optional) -->
144
+ <!-- Tool Input Handle (optional): center at 40px (multiple of 10), 20px connection area -->
145
145
  {#if hasToolInputPort && toolInputPort}
146
146
  <Handle
147
147
  type="target"
148
148
  position={Position.Left}
149
149
  id={`${props.data.nodeId}-input-${toolInputPort.id}`}
150
- style="background-color: {getDataTypeColor('tool')}; border-color: var(--fd-handle-border);"
150
+ style="top: 40px; transform: translateY(-50%); margin-left: -10px; --fd-handle-fill: {getDataTypeColor(
151
+ 'tool'
152
+ )}; --fd-handle-border-color: var(--fd-handle-border);"
151
153
  />
152
154
  {/if}
153
155
 
@@ -212,13 +214,15 @@
212
214
  </button>
213
215
  </div>
214
216
 
215
- <!-- Tool Output Handle (optional) -->
217
+ <!-- Tool Output Handle (optional): center at 40px (multiple of 10), 20px connection area -->
216
218
  {#if hasToolOutputPort && toolOutputPort}
217
219
  <Handle
218
220
  type="source"
219
221
  position={Position.Right}
220
222
  id={`${props.data.nodeId}-output-${toolOutputPort.id}`}
221
- style="background-color: {getDataTypeColor('tool')}; border-color: var(--fd-handle-border);"
223
+ style="top: 40px; transform: translateY(-50%); margin-right: -10px; --fd-handle-fill: {getDataTypeColor(
224
+ 'tool'
225
+ )}; --fd-handle-border-color: var(--fd-handle-border);"
222
226
  />
223
227
  {/if}
224
228
 
@@ -228,7 +232,8 @@
228
232
  background-color: var(--fd-card);
229
233
  border: 1.5px solid var(--fd-node-border);
230
234
  border-radius: var(--fd-radius-xl);
231
- width: 18rem;
235
+ width: var(--fd-node-default-width);
236
+ min-height: var(--fd-node-tool-min-height);
232
237
  display: flex;
233
238
  flex-direction: column;
234
239
  cursor: pointer;
@@ -245,12 +250,16 @@
245
250
  }
246
251
 
247
252
  .flowdrop-tool-node--selected {
248
- box-shadow: 0 0 0 2px color-mix(in srgb, var(--fd-tool-node-color) 30%, transparent), var(--fd-shadow-lg);
253
+ box-shadow:
254
+ 0 0 0 2px color-mix(in srgb, var(--fd-tool-node-color) 30%, transparent),
255
+ var(--fd-shadow-lg);
249
256
  border-color: var(--fd-tool-node-color);
250
257
  }
251
258
 
252
259
  .flowdrop-tool-node--selected:hover {
253
- box-shadow: 0 0 0 2px color-mix(in srgb, var(--fd-tool-node-color) 30%, transparent), var(--fd-shadow-lg);
260
+ box-shadow:
261
+ 0 0 0 2px color-mix(in srgb, var(--fd-tool-node-color) 30%, transparent),
262
+ var(--fd-shadow-lg);
254
263
  border-color: var(--fd-tool-node-color);
255
264
  }
256
265
 
@@ -300,13 +309,21 @@
300
309
  width: 2.5rem;
301
310
  height: 2.5rem;
302
311
  border-radius: 0.625rem;
303
- background: color-mix(in srgb, var(--fd-tool-node-color) 18%, transparent);
312
+ background: color-mix(
313
+ in srgb,
314
+ var(--fd-tool-node-color) var(--fd-node-icon-bg-opacity),
315
+ transparent
316
+ );
304
317
  flex-shrink: 0;
305
318
  transition: all var(--fd-transition-normal);
306
319
  }
307
320
 
308
321
  .flowdrop-tool-node:hover .flowdrop-tool-node__icon-wrapper {
309
- background: color-mix(in srgb, var(--fd-tool-node-color) 25%, transparent);
322
+ background: color-mix(
323
+ in srgb,
324
+ var(--fd-tool-node-color) var(--fd-node-icon-bg-opacity-hover),
325
+ transparent
326
+ );
310
327
  transform: scale(1.05);
311
328
  }
312
329
 
@@ -418,24 +435,25 @@
418
435
  }
419
436
  }
420
437
 
421
- /* Handle styles - special metadata port styling */
438
+ /* Handle: 20px/12px from base.css; position offsets, tool-specific hover/focus */
422
439
  :global(.svelte-flow__node-tool .svelte-flow__handle) {
423
- width: 16px !important;
424
- height: 16px !important;
425
- border: 2px solid var(--fd-handle-border) !important;
426
- border-radius: 50% !important;
427
- transition: all 0.2s ease-in-out !important;
428
- cursor: pointer !important;
429
440
  z-index: 20 !important;
430
441
  pointer-events: auto !important;
431
442
  }
432
443
 
444
+ :global(.svelte-flow__node-tool .svelte-flow__handle-left) {
445
+ left: -10px !important;
446
+ }
447
+
433
448
  :global(.svelte-flow__node-tool .svelte-flow__handle-right) {
434
- right: -6px !important;
449
+ right: -10px !important;
435
450
  }
436
451
 
437
- /* Metadata port hover effects */
438
452
  :global(.svelte-flow__node-tool .svelte-flow__handle:hover) {
453
+ transform: translateY(-50%) scale(1.2) !important;
454
+ }
455
+
456
+ :global(.svelte-flow__node-tool .svelte-flow__handle:hover::before) {
439
457
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--fd-tool-node-color) 30%, transparent) !important;
440
458
  }
441
459