@lupinum/vue-board 0.1.0 → 1.0.0-beta.2

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.
@@ -1,6 +1,17 @@
1
- import { type Component, type PropType } from 'vue';
1
+ import { type Component } from 'vue';
2
2
  import { type BoardState, type Camera, type BoardEngine, type GridSettings, type BoardNode as BoardNodeState, type InteractionState, type NodeId } from '@lupinum/board-core';
3
3
  import { type BoardGridOptions, type BoardRendererRegistry } from '../grid.js';
4
+ import { type BoardContextMenuInfo } from '../composables/useBoardContextMenu.js';
5
+ interface Props {
6
+ engine?: BoardEngine;
7
+ cullMargin?: number;
8
+ grid?: boolean | BoardGridOptions;
9
+ selectionToolbar?: boolean;
10
+ snapGuides?: boolean;
11
+ boxSelect?: boolean;
12
+ renderers?: BoardRendererRegistry;
13
+ fallbackRenderer?: Component | null;
14
+ }
4
15
  declare var __VLS_12: {
5
16
  engine: BoardEngine<import("@lupinum/board-core").BoardPluginApis, {}>;
6
17
  state: BoardState;
@@ -49,78 +60,24 @@ type __VLS_Slots = {} & {
49
60
  } & {
50
61
  default?: (props: typeof __VLS_54) => any;
51
62
  };
52
- declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
53
- engine: {
54
- type: PropType<BoardEngine | undefined>;
55
- default: undefined;
56
- };
57
- cullMargin: {
58
- type: NumberConstructor;
59
- default: number;
60
- };
61
- grid: {
62
- type: PropType<boolean | BoardGridOptions>;
63
- default: boolean;
64
- };
65
- selectionToolbar: {
66
- type: BooleanConstructor;
67
- default: boolean;
68
- };
69
- snapGuides: {
70
- type: BooleanConstructor;
71
- default: boolean;
72
- };
73
- boxSelect: {
74
- type: BooleanConstructor;
75
- default: boolean;
76
- };
77
- renderers: {
78
- type: PropType<BoardRendererRegistry>;
79
- default: () => {};
80
- };
81
- fallbackRenderer: {
82
- type: PropType<Component | null>;
83
- default: null;
84
- };
85
- }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
63
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
86
64
  ready: (engine: BoardEngine<import("@lupinum/board-core").BoardPluginApis, {}>) => any;
87
- }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
88
- engine: {
89
- type: PropType<BoardEngine | undefined>;
90
- default: undefined;
91
- };
92
- cullMargin: {
93
- type: NumberConstructor;
94
- default: number;
95
- };
96
- grid: {
97
- type: PropType<boolean | BoardGridOptions>;
98
- default: boolean;
99
- };
100
- selectionToolbar: {
101
- type: BooleanConstructor;
102
- default: boolean;
103
- };
104
- snapGuides: {
105
- type: BooleanConstructor;
106
- default: boolean;
107
- };
108
- boxSelect: {
109
- type: BooleanConstructor;
110
- default: boolean;
111
- };
112
- renderers: {
113
- type: PropType<BoardRendererRegistry>;
114
- default: () => {};
115
- };
116
- fallbackRenderer: {
117
- type: PropType<Component | null>;
118
- default: null;
119
- };
120
- }>> & Readonly<{
65
+ nodeContextmenu: (info: BoardContextMenuInfo & {
66
+ node: BoardNodeState;
67
+ }) => any;
68
+ canvasContextmenu: (info: BoardContextMenuInfo & {
69
+ node: null;
70
+ }) => any;
71
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
121
72
  onReady?: ((engine: BoardEngine<import("@lupinum/board-core").BoardPluginApis, {}>) => any) | undefined;
73
+ onNodeContextmenu?: ((info: BoardContextMenuInfo & {
74
+ node: BoardNodeState;
75
+ }) => any) | undefined;
76
+ onCanvasContextmenu?: ((info: BoardContextMenuInfo & {
77
+ node: null;
78
+ }) => any) | undefined;
122
79
  }>, {
123
- engine: BoardEngine<import("@lupinum/board-core").BoardPluginApis, {}> | undefined;
80
+ engine: BoardEngine;
124
81
  grid: boolean | BoardGridOptions;
125
82
  cullMargin: number;
126
83
  selectionToolbar: boolean;
@@ -128,7 +85,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
128
85
  boxSelect: boolean;
129
86
  renderers: Partial<Readonly<Record<import("@lupinum/board-core").JsonCanvasNodeType, Component>>>;
130
87
  fallbackRenderer: Component | null;
131
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
88
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
132
89
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
133
90
  declare const _default: typeof __VLS_export;
134
91
  export default _default;
@@ -0,0 +1,52 @@
1
+ import type { Point, ResizeHandle } from '@lupinum/board-core';
2
+ export type TouchIntent = {
3
+ kind: 'pan';
4
+ } | {
5
+ kind: 'drag';
6
+ nodeId: string;
7
+ } | {
8
+ kind: 'resize';
9
+ nodeId: string;
10
+ handle: ResizeHandle;
11
+ };
12
+ type TouchPoint = {
13
+ pointerId: number;
14
+ point: Point;
15
+ };
16
+ export type TouchSessionState = {
17
+ kind: 'idle';
18
+ } | {
19
+ kind: 'pending';
20
+ pointer: TouchPoint;
21
+ startPoint: Point;
22
+ intent: TouchIntent;
23
+ } | {
24
+ kind: 'active-single';
25
+ pointer: TouchPoint;
26
+ intent: TouchIntent;
27
+ } | {
28
+ kind: 'pinch';
29
+ pointers: readonly [TouchPoint, TouchPoint];
30
+ previousDistance: number;
31
+ previousMidpoint: Point;
32
+ };
33
+ interface TouchSessionActions {
34
+ dragThreshold: number;
35
+ start(intent: TouchIntent, pointerId: number, startPoint: Point): boolean;
36
+ update(pointerId: number, point: Point): void;
37
+ flush(): void;
38
+ cancelQueued(): void;
39
+ end(pointerId?: number): void;
40
+ cancel(pointerId?: number): void;
41
+ clearSelection(): void;
42
+ updatePinch(midpoint: Point, pan: Point, zoomDelta: number): void;
43
+ }
44
+ /** Own the complete one- and two-finger session as one discriminated state. */
45
+ export declare function createTouchSession(actions: TouchSessionActions): {
46
+ pointerDown: (pointerId: number, point: Point, intent: TouchIntent) => void;
47
+ pointerMove: (pointerId: number, point: Point) => void;
48
+ pointerUp: (pointerId: number) => void;
49
+ pointerCancel: (pointerId?: number) => void;
50
+ getState: () => TouchSessionState;
51
+ };
52
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { Ref } from 'vue';
2
+ import type { BoardEngine } from '@lupinum/board-core';
3
+ interface UseBoardClipboardOptions {
4
+ engine: BoardEngine;
5
+ rootElement: Ref<HTMLElement | null>;
6
+ }
7
+ /** Let the browser paste event own external parsing and internal fallback. */
8
+ export declare function useBoardClipboard(options: UseBoardClipboardOptions): {
9
+ onPaste: (event: ClipboardEvent) => void;
10
+ };
11
+ export {};
@@ -0,0 +1,20 @@
1
+ import type { Ref } from 'vue';
2
+ import { type BoardEngine, type BoardNode, type Point } from '@lupinum/board-core';
3
+ /** Information emitted when the user opens a board context menu. */
4
+ export interface BoardContextMenuInfo {
5
+ event: MouseEvent;
6
+ node: BoardNode | null;
7
+ world: Point;
8
+ screen: Point;
9
+ }
10
+ interface UseBoardContextMenuOptions {
11
+ engine: BoardEngine;
12
+ rootElement: Ref<HTMLElement | null>;
13
+ toLocalPoint: (clientX: number, clientY: number) => Point;
14
+ onContextMenu: (info: BoardContextMenuInfo) => void;
15
+ }
16
+ /** Emit board context without taking ownership of the native browser menu. */
17
+ export declare function useBoardContextMenu(options: UseBoardContextMenuOptions): {
18
+ onContextMenu: (event: MouseEvent) => void;
19
+ };
20
+ export {};
@@ -10,7 +10,7 @@ interface UseKeyboardShortcutsOptions {
10
10
  /**
11
11
  * Provide the keyboard handlers used by `BoardRoot`.
12
12
  *
13
- * Shortcuts cover selection, clipboard commands, history, zoom presets, and
13
+ * Shortcuts cover selection, clipboard commands, zoom presets, and
14
14
  * keyboard nudging while intentionally ignoring editable targets.
15
15
  */
16
16
  export declare function useKeyboardShortcuts(options: UseKeyboardShortcutsOptions): {
@@ -1,4 +1,8 @@
1
+ import { isEventOwnedByBoardRoot } from '@lupinum/board-core/internal';
2
+ import type { ResizeHandle } from '@lupinum/board-core';
1
3
  /** Whether a bubbled DOM event belongs to this board rather than a nested root. */
2
- export declare function isEventOwnedByBoardRoot(target: EventTarget | null, root: HTMLElement | null): boolean;
4
+ export { isEventOwnedByBoardRoot };
3
5
  /** Whether an embedded editor or screen-space control owns the event. */
4
6
  export declare function isBoardInteractiveEventTarget(target: EventTarget | null): boolean;
7
+ export declare function findBoardNodeId(target: EventTarget | null): string | undefined;
8
+ export declare function findBoardResizeHandle(target: EventTarget | null): ResizeHandle | undefined;
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- :root{--board-bg: #fbfbfd;--board-bg-elevated: #ffffff;--board-bg-subtle: #f3f4f9;--board-canvas-bg: #f5f6fa;--board-fg: #14161f;--board-muted-fg: #5b6075;--board-dim-fg: #8b90a7;--board-border: #e4e5ee;--board-border-strong: #c9cbdb;--board-divider: rgba(20, 22, 31, .08);--board-grid-minor-rgb: 131 134 160;--board-grid-major-rgb: 91 96 117;--board-grid-dot: rgba(131, 134, 160, .32);--board-grid-dot-major: rgba(131, 134, 160, .55);--board-accent: #6366e8;--board-accent-fg: #ffffff;--board-accent-ring: rgba(99, 102, 232, .35);--board-accent-soft: rgba(99, 102, 232, .12);--board-node-bg: #ffffff;--board-node-border: #e4e5ee;--board-node-border-hover: #c9cbdb;--board-node-radius: 10px;--board-node-shadow: 0 .5px 1px .5px rgba(9, 14, 28, .08);--board-node-shadow-hover: 0 .5px 1px .5px rgba(9, 14, 28, .08), 0 2px 8px -2px rgba(9, 14, 28, .12);--board-node-shadow-selected: 0 .5px 1px .5px rgba(9, 14, 28, .08);--board-node-shadow-drag: 0 10px 30px -8px rgba(9, 14, 28, .22);--board-group-bg: rgba(99, 102, 232, .05);--board-group-border: rgba(99, 102, 232, .26);--board-group-label-fg: #ffffff;--board-group-radius: 16px;--board-node-ring: rgba(99, 102, 232, .42);--board-node-selection: #6366e8;--board-edge-color: rgba(91, 96, 117, .72);--board-edge-active-color: #6366e8;--board-snap-guide-color: rgba(99, 102, 232, .95);--board-box-select-fill: rgba(99, 102, 232, .1);--board-box-select-stroke: rgba(99, 102, 232, .6);--board-node-handle-bg: #ffffff;--board-node-handle-dot: rgba(131, 134, 160, .72);--board-handle-shadow: rgba(9, 14, 28, .1);--board-radius-xs: 4px;--board-radius-sm: 8px;--board-radius-md: 10px;--board-radius-lg: 16px;--board-preset-1: #e5476a;--board-preset-2: #d97a1c;--board-preset-3: #b89a14;--board-preset-4: #2fa560;--board-preset-5: #3b7de0;--board-preset-6: #7e5ae4}:root[data-theme=dark]{--board-bg: #151922;--board-bg-elevated: #202633;--board-bg-subtle: #1a1f2a;--board-canvas-bg: #171b24;--board-fg: #ecedf3;--board-muted-fg: #adb3c7;--board-dim-fg: #7f879f;--board-border: #303646;--board-border-strong: #454d61;--board-divider: rgba(236, 237, 243, .08);--board-grid-minor-rgb: 108 116 138;--board-grid-major-rgb: 142 151 176;--board-grid-dot: rgba(142, 151, 176, .16);--board-grid-dot-major: rgba(166, 174, 198, .24);--board-accent: #8487f2;--board-accent-fg: #0a0c12;--board-accent-ring: rgba(132, 135, 242, .35);--board-accent-soft: rgba(132, 135, 242, .16);--board-node-bg: #202633;--board-node-border: #343b4c;--board-node-border-hover: #4b5469;--board-node-shadow: 0 .5px 1px .5px rgba(0, 0, 0, .28);--board-node-shadow-hover: 0 .5px 1px .5px rgba(0, 0, 0, .28), 0 4px 14px -2px rgba(0, 0, 0, .38);--board-node-shadow-selected: 0 .5px 1px .5px rgba(0, 0, 0, .28);--board-node-shadow-drag: 0 12px 34px -8px rgba(0, 0, 0, .56);--board-group-bg: rgba(132, 135, 242, .07);--board-group-border: rgba(132, 135, 242, .34);--board-node-ring: rgba(132, 135, 242, .45);--board-node-selection: #8487f2;--board-edge-color: rgba(173, 179, 199, .66);--board-edge-active-color: #8487f2;--board-snap-guide-color: rgba(132, 135, 242, .95);--board-box-select-fill: rgba(132, 135, 242, .12);--board-box-select-stroke: rgba(132, 135, 242, .7);--board-node-handle-bg: #202633;--board-node-handle-dot: rgba(173, 179, 199, .72);--board-handle-shadow: rgba(0, 0, 0, .38);--board-preset-1: #f06783;--board-preset-2: #e8933b;--board-preset-3: #d8bc2e;--board-preset-4: #4dc27e;--board-preset-5: #6b9dec;--board-preset-6: #9d7df0}:root{--board-ease-out: cubic-bezier(.22, 1, .36, 1);--board-ease-spring: cubic-bezier(.34, 1.3, .64, 1);--board-ease-in-out: cubic-bezier(.65, 0, .35, 1);--board-dur-instant: 80ms;--board-dur-fast: .12s;--board-dur-base: .18s;--board-dur-slow: .26s}.board-box-select[data-v-fb31d12b]{position:absolute;border-radius:6px;box-shadow:inset 0 0 0 1px #ffffff2e;pointer-events:none}.board-box-select--window[data-v-fb31d12b]{border:1.5px solid var(--board-box-select-window-stroke, rgba(37, 99, 235, .72));background:var(--board-box-select-window-fill, rgba(37, 99, 235, .1))}.board-box-select--crossing[data-v-fb31d12b]{border:1.5px dashed var(--board-box-select-crossing-stroke, rgba(15, 118, 110, .8));background:var(--board-box-select-crossing-fill, rgba(15, 118, 110, .12))}.board-grid[data-v-f3663c53]{position:absolute;inset:0;pointer-events:none;-webkit-mask-image:var(--grid-mask-image);mask-image:var(--grid-mask-image)}.board-node-handle[data-v-004da51c]{--_hit: calc(18px / var(--board-zoom, 1));--_dot: calc(7px / var(--board-zoom, 1));--_half: calc(var(--_hit) / 2);position:absolute;width:var(--_hit);height:var(--_hit);box-sizing:border-box;border:0;background:transparent;cursor:nwse-resize;transition:transform var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.board-node-handle[data-v-004da51c]:before{content:"";position:absolute;top:50%;left:50%;width:var(--_dot);height:var(--_dot);box-sizing:border-box;border:calc(1px / var(--board-zoom, 1)) solid var(--board-node-selection, var(--board-accent, #6366e8));border-radius:calc(1.5px / var(--board-zoom, 1));background:var(--board-node-handle-bg, var(--board-node-bg, #fff));transform:translate(-50%,-50%);transition:background-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),transform var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.is-n[data-v-004da51c],.is-s[data-v-004da51c]{left:calc(50% - var(--_half))}.is-e[data-v-004da51c],.is-w[data-v-004da51c]{top:calc(50% - var(--_half))}.is-n[data-v-004da51c],.is-ne[data-v-004da51c],.is-nw[data-v-004da51c]{top:calc(-1 * var(--_half))}.is-s[data-v-004da51c],.is-se[data-v-004da51c],.is-sw[data-v-004da51c]{bottom:calc(-1 * var(--_half))}.is-e[data-v-004da51c],.is-ne[data-v-004da51c],.is-se[data-v-004da51c]{right:calc(-1 * var(--_half))}.is-w[data-v-004da51c],.is-nw[data-v-004da51c],.is-sw[data-v-004da51c]{left:calc(-1 * var(--_half))}.is-n[data-v-004da51c],.is-s[data-v-004da51c]{cursor:ns-resize}.is-e[data-v-004da51c],.is-w[data-v-004da51c]{cursor:ew-resize}.is-ne[data-v-004da51c],.is-sw[data-v-004da51c]{cursor:nesw-resize}.is-nw[data-v-004da51c],.is-se[data-v-004da51c]{cursor:nwse-resize}.board-node-handle[data-v-004da51c]:hover:before{background:var(--board-node-selection, var(--board-accent, #6366e8));transform:translate(-50%,-50%) scale(1.15)}@media(pointer:coarse){.board-node-handle[data-v-004da51c]{--_hit: calc(36px / var(--board-zoom, 1));--_dot: calc(9px / var(--board-zoom, 1))}}@media(prefers-reduced-motion:reduce){.board-node-handle[data-v-004da51c]{transition:none}}.board-node[data-v-9aa9b6cd]{position:absolute;box-sizing:border-box;overflow:visible;border:calc(1px / var(--board-zoom, 1)) solid var(--board-node-border, rgba(148, 163, 184, .28));border-radius:calc(var(--board-node-radius, 10px) / var(--board-zoom, 1));box-shadow:var(--board-node-shadow, 0 .5px 1px .5px rgba(9, 14, 28, .08));background:var(--board-node-bg, #fff);color:inherit;contain:layout style;transform:translateZ(0);transition:border-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),box-shadow var(--board-dur-fast, .12s) var(--board-ease-out, ease),background-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),outline-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),transform var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.board-node[data-v-9aa9b6cd]:hover:not(.is-group):not(.is-editing){border-color:var(--board-node-border-hover, rgba(100, 116, 139, .42));box-shadow:var( --board-node-shadow-hover, 0 2px 8px -2px rgba(9, 14, 28, .12) )}.board-node[data-v-9aa9b6cd]:focus-visible{outline:calc(2px / var(--board-zoom, 1)) solid var(--board-node-ring, rgba(99, 102, 232, .42));outline-offset:calc(2px / var(--board-zoom, 1))}.board-node.is-selected[data-v-9aa9b6cd],.board-node.is-editing[data-v-9aa9b6cd]{border-color:var( --board-node-color-ring, var(--board-node-selection, var(--board-accent, #6366e8)) );box-shadow:0 0 0 calc(1px / var(--board-zoom, 1)) var( --board-node-color-ring, var(--board-node-selection, var(--board-accent, #6366e8)) ),var(--board-node-shadow-selected, var(--board-node-shadow, none))}.board-node.is-locked[data-v-9aa9b6cd]{opacity:.8;filter:saturate(.82)}.board-node.is-group[data-v-9aa9b6cd]{background:var(--board-group-bg, rgba(99, 102, 232, .05));border-style:dashed;border-color:var(--board-group-border, rgba(99, 102, 232, .26));border-radius:calc(var(--board-group-radius, 16px) / var(--board-zoom, 1));outline:none;box-shadow:none}.board-node.is-colored[data-v-9aa9b6cd]:not(.is-group){background:var(--board-node-tint);border-color:var(--board-node-color)}.board-node.is-colored[data-v-9aa9b6cd]:not(.is-group):hover:not(.is-editing){background:var(--board-node-tint-strong);border-color:var(--board-node-color)}.board-node.is-group.is-colored[data-v-9aa9b6cd]{background:var(--board-node-tint);border-color:var(--board-node-color)}.board-node__content[data-v-9aa9b6cd],.board-node__editor[data-v-9aa9b6cd]{width:100%;height:100%;padding:16px 18px;border:0;background:transparent;color:inherit;font:inherit;resize:none;outline:none;overflow:auto;white-space:pre-wrap}.board-node__content[data-v-9aa9b6cd]{display:flex;align-items:flex-start;line-height:1.45;letter-spacing:-.01em}.board-node__editor[data-v-9aa9b6cd]{display:block;-webkit-user-select:text;user-select:text;cursor:text;line-height:1.45;letter-spacing:-.01em;caret-color:var(--board-node-selection, var(--board-accent, #0f766e))}.board-node__editor[data-v-9aa9b6cd]::selection{background:color-mix(in srgb,var(--board-node-selection, var(--board-accent, #0f766e)) 22%,transparent)}.board-node__editor-help[data-v-9aa9b6cd]{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}@media(prefers-reduced-motion:reduce){.board-node[data-v-9aa9b6cd]{transition:none}}.board-snap-guides[data-v-2c604885]{position:absolute;inset:0;pointer-events:none;z-index:999999;color:var(--board-snap-guide-color, var(--board-accent, #6366e8))}.board-snap-guide[data-v-2c604885]{position:absolute;background:currentColor;opacity:.95;animation:board-snap-guide-in-2c604885 .12s var(--board-ease-out, ease)}.board-snap-guide--vertical[data-v-2c604885]{width:1px;transform:translate(-.5px)}.board-snap-guide--horizontal[data-v-2c604885]{height:1px;transform:translateY(-.5px)}.board-snap-guide[data-v-2c604885]:before,.board-snap-guide[data-v-2c604885]:after{content:"";position:absolute;background:currentColor}.board-snap-guide--vertical[data-v-2c604885]:before,.board-snap-guide--vertical[data-v-2c604885]:after{left:-3px;width:7px;height:1px}.board-snap-guide--vertical[data-v-2c604885]:before{top:-.5px}.board-snap-guide--vertical[data-v-2c604885]:after{bottom:-.5px}.board-snap-guide--horizontal[data-v-2c604885]:before,.board-snap-guide--horizontal[data-v-2c604885]:after{top:-3px;width:1px;height:7px}.board-snap-guide--horizontal[data-v-2c604885]:before{left:-.5px}.board-snap-guide--horizontal[data-v-2c604885]:after{right:-.5px}@keyframes board-snap-guide-in-2c604885{0%{opacity:0}to{opacity:.95}}@media(prefers-reduced-motion:reduce){.board-snap-guide[data-v-2c604885]{animation:none}}.board-viewport[data-v-9eeb9aab]{position:absolute;inset:0;transform-origin:0 0;will-change:transform}.board-selection-toolbar[data-v-c1436955]{position:absolute;z-index:12;display:inline-flex;align-items:center;gap:2px;padding:4px;border:1px solid var(--board-border, rgba(15, 23, 42, .1));border-radius:10px;background:var(--board-bg-elevated, #ffffff);box-shadow:0 8px 24px -6px #090e1c2e,0 1px 2px #090e1c14;transform:translate(-50%,calc(-100% - 14px));pointer-events:auto;-webkit-user-select:none;user-select:none;-webkit-backdrop-filter:saturate(1.2);backdrop-filter:saturate(1.2)}.board-selection-toolbar__button[data-v-c1436955]{display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;padding:0;border:none;border-radius:8px;background:transparent;color:var(--board-muted-fg, #5b6075);cursor:pointer;transition:background-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),color var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.board-selection-toolbar__button[data-v-c1436955]:hover:not(:disabled){background:color-mix(in srgb,var(--board-fg, #14161f) 6%,transparent);color:var(--board-fg, #14161f)}.board-selection-toolbar__button[data-v-c1436955]:disabled{cursor:default;opacity:.38}.board-selection-toolbar__button.is-danger[data-v-c1436955]{color:var(--board-preset-1, #e5476a)}.board-selection-toolbar__button.is-danger[data-v-c1436955]:hover:not(:disabled){background:color-mix(in srgb,var(--board-preset-1, #e5476a) 10%,transparent);color:var(--board-preset-1, #e5476a)}.board-selection-toolbar__button svg[data-v-c1436955]{width:17px;height:17px;fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.board-selection-toolbar__popover-anchor[data-v-c1436955]{position:relative;display:inline-flex}.board-selection-toolbar__palette[data-v-c1436955]{position:absolute;top:calc(100% + 8px);left:50%;z-index:1;display:inline-flex;gap:8px;padding:10px;border:1px solid var(--board-border, rgba(15, 23, 42, .1));border-radius:10px;background:var(--board-bg-elevated, #ffffff);box-shadow:0 12px 32px -8px #090e1c38,0 1px 2px #090e1c14;transform:translate(-50%);animation:board-palette-in-c1436955 var(--board-dur-fast, .14s) var(--board-ease-out, ease)}@keyframes board-palette-in-c1436955{0%{opacity:0;transform:translate(-50%) scale(.96)}to{opacity:1;transform:translate(-50%) scale(1)}}.board-selection-toolbar__swatch[data-v-c1436955]{width:20px;height:20px;padding:0;border:1px solid rgba(15,23,42,.14);border-radius:999px;background:var(--swatch-color);cursor:pointer;transition:transform var(--board-dur-fast, .12s) var(--board-ease-spring, ease)}.board-selection-toolbar__swatch[data-v-c1436955]:hover{transform:scale(1.12)}.board-selection-toolbar__swatch.is-default[data-v-c1436955]{--swatch-color: var(--board-border-strong, #c9cbdb)}.board-selection-toolbar__swatch.is-active[data-v-c1436955]{box-shadow:0 0 0 2px var(--board-bg-elevated, #ffffff),0 0 0 4px var(--swatch-color)}@media(prefers-reduced-motion:reduce){.board-selection-toolbar[data-v-c1436955],.board-selection-toolbar__button[data-v-c1436955],.board-selection-toolbar__swatch[data-v-c1436955],.board-selection-toolbar__palette[data-v-c1436955]{animation:none;transition:none}}.board-root[data-v-931e1ec3]{position:relative;width:100%;height:100%;overflow:hidden;touch-action:none;-webkit-user-select:none;user-select:none;background:var(--board-canvas-bg, var(--board-bg, #f5f6fa));color:var(--board-fg, #14161f);isolation:isolate;transition:background-color var(--board-dur-slow, .26s) var(--board-ease-out, ease),color var(--board-dur-slow, .26s) var(--board-ease-out, ease)}.board-node-simple[data-v-931e1ec3]{position:absolute;box-sizing:border-box;border:calc(1px / var(--board-zoom, 1)) solid var(--board-node-border, rgba(148, 163, 184, .28));background:var(--board-node-bg, #fff);border-radius:calc(var(--board-node-radius, 10px) / var(--board-zoom, 1));box-shadow:var(--board-node-shadow, 0 .5px 1px .5px rgba(9, 14, 28, .08));overflow:hidden;contain:layout style paint}.board-node-simple.is-colored[data-v-931e1ec3]{border-color:var(--board-node-color);background:var(--board-node-tint)}.board-node-simple.is-group[data-v-931e1ec3]{border-style:dashed;border-radius:calc(var(--board-group-radius, 16px) / var(--board-zoom, 1))}.board-node-simple[data-v-931e1ec3]:after{content:"";position:absolute;top:25%;left:20%;right:20%;height:50%;background:repeating-linear-gradient(to bottom,var(--board-divider, rgba(15, 23, 42, .06)) 0px,var(--board-divider, rgba(15, 23, 42, .06)) 2px,transparent 2px,transparent 6px)}@media(prefers-reduced-motion:reduce){.board-root[data-v-931e1ec3]{transition:none}}
1
+ :root{--board-bg: #fbfbfd;--board-bg-elevated: #ffffff;--board-bg-subtle: #f3f4f9;--board-canvas-bg: #f5f6fa;--board-fg: #14161f;--board-muted-fg: #5b6075;--board-dim-fg: #8b90a7;--board-border: #e4e5ee;--board-border-strong: #c9cbdb;--board-divider: rgba(20, 22, 31, .08);--board-grid-minor-rgb: 131 134 160;--board-grid-major-rgb: 91 96 117;--board-grid-dot: rgba(131, 134, 160, .32);--board-grid-dot-major: rgba(131, 134, 160, .55);--board-accent: #6366e8;--board-accent-fg: #ffffff;--board-accent-ring: rgba(99, 102, 232, .35);--board-accent-soft: rgba(99, 102, 232, .12);--board-node-bg: #ffffff;--board-node-border: #e4e5ee;--board-node-border-hover: #c9cbdb;--board-node-radius: 10px;--board-node-shadow: 0 .5px 1px .5px rgba(9, 14, 28, .08);--board-node-shadow-hover: 0 .5px 1px .5px rgba(9, 14, 28, .08), 0 2px 8px -2px rgba(9, 14, 28, .12);--board-node-shadow-selected: 0 .5px 1px .5px rgba(9, 14, 28, .08);--board-node-shadow-drag: 0 10px 30px -8px rgba(9, 14, 28, .22);--board-group-bg: rgba(99, 102, 232, .05);--board-group-border: rgba(99, 102, 232, .26);--board-group-label-fg: #ffffff;--board-group-radius: 16px;--board-node-ring: rgba(99, 102, 232, .42);--board-node-selection: #6366e8;--board-edge-color: rgba(91, 96, 117, .72);--board-edge-active-color: #6366e8;--board-snap-guide-color: rgba(99, 102, 232, .95);--board-box-select-fill: rgba(99, 102, 232, .1);--board-box-select-stroke: rgba(99, 102, 232, .6);--board-node-handle-bg: #ffffff;--board-node-handle-dot: rgba(131, 134, 160, .72);--board-handle-shadow: rgba(9, 14, 28, .1);--board-radius-xs: 4px;--board-radius-sm: 8px;--board-radius-md: 10px;--board-radius-lg: 16px;--board-preset-1: #e5476a;--board-preset-2: #d97a1c;--board-preset-3: #b89a14;--board-preset-4: #2fa560;--board-preset-5: #3b7de0;--board-preset-6: #7e5ae4}:root[data-theme=dark]{--board-bg: #151922;--board-bg-elevated: #202633;--board-bg-subtle: #1a1f2a;--board-canvas-bg: #171b24;--board-fg: #ecedf3;--board-muted-fg: #adb3c7;--board-dim-fg: #7f879f;--board-border: #303646;--board-border-strong: #454d61;--board-divider: rgba(236, 237, 243, .08);--board-grid-minor-rgb: 108 116 138;--board-grid-major-rgb: 142 151 176;--board-grid-dot: rgba(142, 151, 176, .16);--board-grid-dot-major: rgba(166, 174, 198, .24);--board-accent: #8487f2;--board-accent-fg: #0a0c12;--board-accent-ring: rgba(132, 135, 242, .35);--board-accent-soft: rgba(132, 135, 242, .16);--board-node-bg: #202633;--board-node-border: #343b4c;--board-node-border-hover: #4b5469;--board-node-shadow: 0 .5px 1px .5px rgba(0, 0, 0, .28);--board-node-shadow-hover: 0 .5px 1px .5px rgba(0, 0, 0, .28), 0 4px 14px -2px rgba(0, 0, 0, .38);--board-node-shadow-selected: 0 .5px 1px .5px rgba(0, 0, 0, .28);--board-node-shadow-drag: 0 12px 34px -8px rgba(0, 0, 0, .56);--board-group-bg: rgba(132, 135, 242, .07);--board-group-border: rgba(132, 135, 242, .34);--board-node-ring: rgba(132, 135, 242, .45);--board-node-selection: #8487f2;--board-edge-color: rgba(173, 179, 199, .66);--board-edge-active-color: #8487f2;--board-snap-guide-color: rgba(132, 135, 242, .95);--board-box-select-fill: rgba(132, 135, 242, .12);--board-box-select-stroke: rgba(132, 135, 242, .7);--board-node-handle-bg: #202633;--board-node-handle-dot: rgba(173, 179, 199, .72);--board-handle-shadow: rgba(0, 0, 0, .38);--board-preset-1: #f06783;--board-preset-2: #e8933b;--board-preset-3: #d8bc2e;--board-preset-4: #4dc27e;--board-preset-5: #6b9dec;--board-preset-6: #9d7df0}:root{--board-ease-out: cubic-bezier(.22, 1, .36, 1);--board-ease-spring: cubic-bezier(.34, 1.3, .64, 1);--board-ease-in-out: cubic-bezier(.65, 0, .35, 1);--board-dur-instant: 80ms;--board-dur-fast: .12s;--board-dur-base: .18s;--board-dur-slow: .26s}.board-box-select[data-v-fb31d12b]{position:absolute;border-radius:6px;box-shadow:inset 0 0 0 1px #ffffff2e;pointer-events:none}.board-box-select--window[data-v-fb31d12b]{border:1.5px solid var(--board-box-select-window-stroke, rgba(37, 99, 235, .72));background:var(--board-box-select-window-fill, rgba(37, 99, 235, .1))}.board-box-select--crossing[data-v-fb31d12b]{border:1.5px dashed var(--board-box-select-crossing-stroke, rgba(15, 118, 110, .8));background:var(--board-box-select-crossing-fill, rgba(15, 118, 110, .12))}.board-grid[data-v-f3663c53]{position:absolute;inset:0;pointer-events:none;-webkit-mask-image:var(--grid-mask-image);mask-image:var(--grid-mask-image)}.board-node-handle[data-v-004da51c]{--_hit: calc(18px / var(--board-zoom, 1));--_dot: calc(7px / var(--board-zoom, 1));--_half: calc(var(--_hit) / 2);position:absolute;width:var(--_hit);height:var(--_hit);box-sizing:border-box;border:0;background:transparent;cursor:nwse-resize;transition:transform var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.board-node-handle[data-v-004da51c]:before{content:"";position:absolute;top:50%;left:50%;width:var(--_dot);height:var(--_dot);box-sizing:border-box;border:calc(1px / var(--board-zoom, 1)) solid var(--board-node-selection, var(--board-accent, #6366e8));border-radius:calc(1.5px / var(--board-zoom, 1));background:var(--board-node-handle-bg, var(--board-node-bg, #fff));transform:translate(-50%,-50%);transition:background-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),transform var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.is-n[data-v-004da51c],.is-s[data-v-004da51c]{left:calc(50% - var(--_half))}.is-e[data-v-004da51c],.is-w[data-v-004da51c]{top:calc(50% - var(--_half))}.is-n[data-v-004da51c],.is-ne[data-v-004da51c],.is-nw[data-v-004da51c]{top:calc(-1 * var(--_half))}.is-s[data-v-004da51c],.is-se[data-v-004da51c],.is-sw[data-v-004da51c]{bottom:calc(-1 * var(--_half))}.is-e[data-v-004da51c],.is-ne[data-v-004da51c],.is-se[data-v-004da51c]{right:calc(-1 * var(--_half))}.is-w[data-v-004da51c],.is-nw[data-v-004da51c],.is-sw[data-v-004da51c]{left:calc(-1 * var(--_half))}.is-n[data-v-004da51c],.is-s[data-v-004da51c]{cursor:ns-resize}.is-e[data-v-004da51c],.is-w[data-v-004da51c]{cursor:ew-resize}.is-ne[data-v-004da51c],.is-sw[data-v-004da51c]{cursor:nesw-resize}.is-nw[data-v-004da51c],.is-se[data-v-004da51c]{cursor:nwse-resize}.board-node-handle[data-v-004da51c]:hover:before{background:var(--board-node-selection, var(--board-accent, #6366e8));transform:translate(-50%,-50%) scale(1.15)}@media(pointer:coarse){.board-node-handle[data-v-004da51c]{--_hit: calc(36px / var(--board-zoom, 1));--_dot: calc(9px / var(--board-zoom, 1))}}@media(prefers-reduced-motion:reduce){.board-node-handle[data-v-004da51c]{transition:none}}.board-node[data-v-27ec147c]{position:absolute;box-sizing:border-box;overflow:visible;border:calc(1px / var(--board-zoom, 1)) solid var(--board-node-border, rgba(148, 163, 184, .28));border-radius:calc(var(--board-node-radius, 10px) / var(--board-zoom, 1));box-shadow:var(--board-node-shadow, 0 .5px 1px .5px rgba(9, 14, 28, .08));background:var(--board-node-bg, #fff);color:inherit;contain:layout style;transform:translateZ(0);transition:border-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),box-shadow var(--board-dur-fast, .12s) var(--board-ease-out, ease),background-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),outline-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),transform var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.board-node[data-v-27ec147c]:hover:not(.is-group):not(.is-editing){border-color:var(--board-node-border-hover, rgba(100, 116, 139, .42));box-shadow:var( --board-node-shadow-hover, 0 2px 8px -2px rgba(9, 14, 28, .12) )}.board-node[data-v-27ec147c]:focus-visible{outline:calc(2px / var(--board-zoom, 1)) solid var(--board-node-ring, rgba(99, 102, 232, .42));outline-offset:calc(2px / var(--board-zoom, 1))}.board-node.is-selected[data-v-27ec147c],.board-node.is-editing[data-v-27ec147c]{border-color:var( --board-node-color-ring, var(--board-node-selection, var(--board-accent, #6366e8)) );box-shadow:0 0 0 calc(1px / var(--board-zoom, 1)) var( --board-node-color-ring, var(--board-node-selection, var(--board-accent, #6366e8)) ),var(--board-node-shadow-selected, var(--board-node-shadow, none))}.board-node.is-locked[data-v-27ec147c]{opacity:.8;filter:saturate(.82)}.board-node.is-group[data-v-27ec147c]{background:var(--board-group-bg, rgba(99, 102, 232, .05));border-style:dashed;border-color:var(--board-group-border, rgba(99, 102, 232, .26));border-radius:calc(var(--board-group-radius, 16px) / var(--board-zoom, 1));outline:none;box-shadow:none}.board-node.is-colored[data-v-27ec147c]:not(.is-group){background:var(--board-node-tint);border-color:var(--board-node-color)}.board-node.is-colored[data-v-27ec147c]:not(.is-group):hover:not(.is-editing){background:var(--board-node-tint-strong);border-color:var(--board-node-color)}.board-node.is-group.is-colored[data-v-27ec147c]{background:var(--board-node-tint);border-color:var(--board-node-color)}.board-node__content[data-v-27ec147c],.board-node__editor[data-v-27ec147c]{width:100%;height:100%;padding:16px 18px;border:0;background:transparent;color:inherit;font:inherit;resize:none;outline:none;overflow:auto;white-space:pre-wrap}.board-node__content[data-v-27ec147c]{display:flex;align-items:flex-start;line-height:1.45;letter-spacing:-.01em}.board-node__editor[data-v-27ec147c]{display:block;-webkit-user-select:text;user-select:text;cursor:text;line-height:1.45;letter-spacing:-.01em;caret-color:var(--board-node-selection, var(--board-accent, #0f766e))}.board-node__editor[data-v-27ec147c]::selection{background:color-mix(in srgb,var(--board-node-selection, var(--board-accent, #0f766e)) 22%,transparent)}.board-node__editor-help[data-v-27ec147c]{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}@media(prefers-reduced-motion:reduce){.board-node[data-v-27ec147c]{transition:none}}.board-snap-guides[data-v-2c604885]{position:absolute;inset:0;pointer-events:none;z-index:999999;color:var(--board-snap-guide-color, var(--board-accent, #6366e8))}.board-snap-guide[data-v-2c604885]{position:absolute;background:currentColor;opacity:.95;animation:board-snap-guide-in-2c604885 .12s var(--board-ease-out, ease)}.board-snap-guide--vertical[data-v-2c604885]{width:1px;transform:translate(-.5px)}.board-snap-guide--horizontal[data-v-2c604885]{height:1px;transform:translateY(-.5px)}.board-snap-guide[data-v-2c604885]:before,.board-snap-guide[data-v-2c604885]:after{content:"";position:absolute;background:currentColor}.board-snap-guide--vertical[data-v-2c604885]:before,.board-snap-guide--vertical[data-v-2c604885]:after{left:-3px;width:7px;height:1px}.board-snap-guide--vertical[data-v-2c604885]:before{top:-.5px}.board-snap-guide--vertical[data-v-2c604885]:after{bottom:-.5px}.board-snap-guide--horizontal[data-v-2c604885]:before,.board-snap-guide--horizontal[data-v-2c604885]:after{top:-3px;width:1px;height:7px}.board-snap-guide--horizontal[data-v-2c604885]:before{left:-.5px}.board-snap-guide--horizontal[data-v-2c604885]:after{right:-.5px}@keyframes board-snap-guide-in-2c604885{0%{opacity:0}to{opacity:.95}}@media(prefers-reduced-motion:reduce){.board-snap-guide[data-v-2c604885]{animation:none}}.board-viewport[data-v-9eeb9aab]{position:absolute;inset:0;transform-origin:0 0;will-change:transform}.board-selection-toolbar[data-v-c1436955]{position:absolute;z-index:12;display:inline-flex;align-items:center;gap:2px;padding:4px;border:1px solid var(--board-border, rgba(15, 23, 42, .1));border-radius:10px;background:var(--board-bg-elevated, #ffffff);box-shadow:0 8px 24px -6px #090e1c2e,0 1px 2px #090e1c14;transform:translate(-50%,calc(-100% - 14px));pointer-events:auto;-webkit-user-select:none;user-select:none;-webkit-backdrop-filter:saturate(1.2);backdrop-filter:saturate(1.2)}.board-selection-toolbar__button[data-v-c1436955]{display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;padding:0;border:none;border-radius:8px;background:transparent;color:var(--board-muted-fg, #5b6075);cursor:pointer;transition:background-color var(--board-dur-fast, .12s) var(--board-ease-out, ease),color var(--board-dur-fast, .12s) var(--board-ease-out, ease)}.board-selection-toolbar__button[data-v-c1436955]:hover:not(:disabled){background:color-mix(in srgb,var(--board-fg, #14161f) 6%,transparent);color:var(--board-fg, #14161f)}.board-selection-toolbar__button[data-v-c1436955]:disabled{cursor:default;opacity:.38}.board-selection-toolbar__button.is-danger[data-v-c1436955]{color:var(--board-preset-1, #e5476a)}.board-selection-toolbar__button.is-danger[data-v-c1436955]:hover:not(:disabled){background:color-mix(in srgb,var(--board-preset-1, #e5476a) 10%,transparent);color:var(--board-preset-1, #e5476a)}.board-selection-toolbar__button svg[data-v-c1436955]{width:17px;height:17px;fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:2}.board-selection-toolbar__popover-anchor[data-v-c1436955]{position:relative;display:inline-flex}.board-selection-toolbar__palette[data-v-c1436955]{position:absolute;top:calc(100% + 8px);left:50%;z-index:1;display:inline-flex;gap:8px;padding:10px;border:1px solid var(--board-border, rgba(15, 23, 42, .1));border-radius:10px;background:var(--board-bg-elevated, #ffffff);box-shadow:0 12px 32px -8px #090e1c38,0 1px 2px #090e1c14;transform:translate(-50%);animation:board-palette-in-c1436955 var(--board-dur-fast, .14s) var(--board-ease-out, ease)}@keyframes board-palette-in-c1436955{0%{opacity:0;transform:translate(-50%) scale(.96)}to{opacity:1;transform:translate(-50%) scale(1)}}.board-selection-toolbar__swatch[data-v-c1436955]{width:20px;height:20px;padding:0;border:1px solid rgba(15,23,42,.14);border-radius:999px;background:var(--swatch-color);cursor:pointer;transition:transform var(--board-dur-fast, .12s) var(--board-ease-spring, ease)}.board-selection-toolbar__swatch[data-v-c1436955]:hover{transform:scale(1.12)}.board-selection-toolbar__swatch.is-default[data-v-c1436955]{--swatch-color: var(--board-border-strong, #c9cbdb)}.board-selection-toolbar__swatch.is-active[data-v-c1436955]{box-shadow:0 0 0 2px var(--board-bg-elevated, #ffffff),0 0 0 4px var(--swatch-color)}@media(prefers-reduced-motion:reduce){.board-selection-toolbar[data-v-c1436955],.board-selection-toolbar__button[data-v-c1436955],.board-selection-toolbar__swatch[data-v-c1436955],.board-selection-toolbar__palette[data-v-c1436955]{animation:none;transition:none}}.board-root[data-v-a4902983]{position:relative;width:100%;height:100%;overflow:hidden;touch-action:none;-webkit-user-select:none;user-select:none;background:var(--board-canvas-bg, var(--board-bg, #f5f6fa));color:var(--board-fg, #14161f);isolation:isolate;transition:background-color var(--board-dur-slow, .26s) var(--board-ease-out, ease),color var(--board-dur-slow, .26s) var(--board-ease-out, ease)}.board-node-simple[data-v-a4902983]{position:absolute;box-sizing:border-box;border:calc(1px / var(--board-zoom, 1)) solid var(--board-node-border, rgba(148, 163, 184, .28));background:var(--board-node-bg, #fff);border-radius:calc(var(--board-node-radius, 10px) / var(--board-zoom, 1));box-shadow:var(--board-node-shadow, 0 .5px 1px .5px rgba(9, 14, 28, .08));overflow:hidden;contain:layout style paint}.board-node-simple.is-colored[data-v-a4902983]{border-color:var(--board-node-color);background:var(--board-node-tint)}.board-node-simple.is-group[data-v-a4902983]{border-style:dashed;border-radius:calc(var(--board-group-radius, 16px) / var(--board-zoom, 1))}.board-node-simple[data-v-a4902983]:after{content:"";position:absolute;top:25%;left:20%;right:20%;height:50%;background:repeating-linear-gradient(to bottom,var(--board-divider, rgba(15, 23, 42, .06)) 0px,var(--board-divider, rgba(15, 23, 42, .06)) 2px,transparent 2px,transparent 6px)}@media(prefers-reduced-motion:reduce){.board-root[data-v-a4902983]{transition:none}}