@mhamz.01/easyflow-whiteboard 2.14.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/node/custom-node-overlay-layer.d.ts.map +1 -1
- package/dist/components/node/custom-node-overlay-layer.js +197 -258
- package/dist/components/toolbar/task-dropdown.d.ts.map +1 -1
- package/dist/components/toolbar/tooloptions-panel.d.ts +1 -1
- package/dist/components/toolbar/tooloptions-panel.d.ts.map +1 -1
- package/dist/components/toolbar/whiteboard-toolbar.d.ts.map +1 -1
- package/dist/hooks/useCanvasInit.d.ts.map +1 -1
- package/dist/hooks/useCanvasInit.js +1 -0
- package/dist/hooks/useEraser.d.ts +1 -2
- package/dist/hooks/useEraser.d.ts.map +1 -1
- package/dist/hooks/useEraser.js +1 -2
- package/dist/hooks/useToolManager.d.ts +1 -2
- package/dist/hooks/useToolManager.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -28
- package/dist/lib/fabric-utils.d.ts.map +1 -1
- package/dist/lib/fabric-utils.js +1 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qBAAqB,CAAC,EAAE,YAAY,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAoBD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,KAAK,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,UAAc,EACd,cAA+B,EAC/B,YAAmB,EACnB,qBAA0B,EAC1B,YAAY,GACb,EAAE,uBAAuB,2CAqZzB"}
|
|
@@ -1,108 +1,93 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState, useEffect, useRef } from "react";
|
|
3
|
+
import { useState, useEffect, useRef, useCallback, memo } from "react";
|
|
4
4
|
import TaskNode from "./custom-node";
|
|
5
5
|
import DocumentNode from "./document-node";
|
|
6
|
+
// ── PERF: Memoized node wrappers ──────────────────────────────────────────────
|
|
7
|
+
// Prevents sibling nodes from re-rendering when only one node's position changes.
|
|
8
|
+
// Without memo, every setLocalTasks call during drag re-renders ALL nodes.
|
|
9
|
+
const MemoTaskNode = memo(TaskNode);
|
|
10
|
+
const MemoDocumentNode = memo(DocumentNode);
|
|
6
11
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
7
12
|
export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, onDocumentsUpdate, canvasZoom = 1, canvasViewport = { x: 0, y: 0 }, selectionBox = null, selectedCanvasObjects = [], fabricCanvas, }) {
|
|
8
13
|
const [localTasks, setLocalTasks] = useState(tasks);
|
|
9
14
|
const [localDocuments, setLocalDocuments] = useState(documents);
|
|
10
15
|
const [selectedIds, setSelectedIds] = useState(new Set());
|
|
11
|
-
|
|
16
|
+
// ─── Core refs ────────────────────────────────────────────────────────────
|
|
12
17
|
const dragStateRef = useRef({
|
|
13
|
-
isDragging: false,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
canvasObjectsStartPos: new Map(),
|
|
17
|
-
offsetX: 0,
|
|
18
|
-
offsetY: 0,
|
|
18
|
+
isDragging: false, itemIds: [],
|
|
19
|
+
startPositions: new Map(), canvasObjectsStartPos: new Map(),
|
|
20
|
+
offsetX: 0, offsetY: 0,
|
|
19
21
|
});
|
|
20
22
|
const rafIdRef = useRef(null);
|
|
21
23
|
const overlayRef = useRef(null);
|
|
22
|
-
// ──
|
|
24
|
+
// ── PERF: Mutex prevents object:moving and handleMove writing simultaneously ─
|
|
25
|
+
const isHtmlDraggingRef = useRef(false);
|
|
26
|
+
// ── PERF: Always-fresh refs — rebuilt synchronously every render ──────────
|
|
27
|
+
// Eliminates ALL stale closure problems without any useCallback deps.
|
|
28
|
+
// nodePositionsRef: ground truth for positions at drag start
|
|
29
|
+
const nodePositionsRef = useRef(new Map());
|
|
30
|
+
nodePositionsRef.current = new Map([
|
|
31
|
+
...localTasks.map((t) => [t.id, { x: t.x, y: t.y }]),
|
|
32
|
+
...localDocuments.map((d) => [d.id, { x: d.x, y: d.y }]),
|
|
33
|
+
]);
|
|
34
|
+
// selectedIdsRef: used in stable effect closures
|
|
35
|
+
const selectedIdsRef = useRef(selectedIds);
|
|
36
|
+
selectedIdsRef.current = selectedIds;
|
|
37
|
+
// selectedCanvasObjectsRef: avoids stale prop in handleDragStart
|
|
38
|
+
const selectedCanvasObjectsRef = useRef(selectedCanvasObjects);
|
|
39
|
+
selectedCanvasObjectsRef.current = selectedCanvasObjects;
|
|
40
|
+
// Parent callbacks in refs — handleEnd never captures stale callbacks
|
|
41
|
+
const onTasksUpdateRef = useRef(onTasksUpdate);
|
|
42
|
+
const onDocumentsUpdateRef = useRef(onDocumentsUpdate);
|
|
43
|
+
onTasksUpdateRef.current = onTasksUpdate;
|
|
44
|
+
onDocumentsUpdateRef.current = onDocumentsUpdate;
|
|
45
|
+
// ─── Sync props → local state ─────────────────────────────────────────────
|
|
23
46
|
useEffect(() => { setLocalTasks(tasks); }, [tasks]);
|
|
24
47
|
useEffect(() => { setLocalDocuments(documents); }, [documents]);
|
|
25
|
-
//
|
|
26
|
-
const handleOverlayWheel = (e) => {
|
|
27
|
-
if (e.ctrlKey || e.metaKey || e.shiftKey) {
|
|
28
|
-
const canvas = fabricCanvas?.current;
|
|
29
|
-
if (!canvas)
|
|
30
|
-
return;
|
|
31
|
-
const nativeEvent = e.nativeEvent;
|
|
32
|
-
// getScenePoint handles the transformation from screen to canvas space
|
|
33
|
-
const scenePoint = canvas.getScenePoint(nativeEvent);
|
|
34
|
-
// Viewport point is simply the mouse position relative to the canvas element
|
|
35
|
-
const rect = canvas.getElement().getBoundingClientRect();
|
|
36
|
-
const viewportPoint = {
|
|
37
|
-
x: nativeEvent.clientX - rect.left,
|
|
38
|
-
y: nativeEvent.clientY - rect.top,
|
|
39
|
-
};
|
|
40
|
-
// We cast to 'any' here because we are manually triggering an internal
|
|
41
|
-
// event bus, and Fabric's internal types for .fire() can be overly strict.
|
|
42
|
-
canvas.fire("mouse:wheel", {
|
|
43
|
-
e: nativeEvent,
|
|
44
|
-
scenePoint,
|
|
45
|
-
viewportPoint,
|
|
46
|
-
});
|
|
47
|
-
e.preventDefault();
|
|
48
|
-
e.stopPropagation();
|
|
49
|
-
}
|
|
50
|
-
};
|
|
48
|
+
// ─── Wheel forwarding ─────────────────────────────────────────────────────
|
|
51
49
|
useEffect(() => {
|
|
52
50
|
const overlayEl = overlayRef.current;
|
|
53
51
|
const canvas = fabricCanvas?.current;
|
|
54
52
|
if (!overlayEl || !canvas)
|
|
55
53
|
return;
|
|
56
54
|
const handleGlobalWheel = (e) => {
|
|
57
|
-
|
|
58
|
-
// (meaning they are hovering over a Task or Document)
|
|
59
|
-
const target = e.target;
|
|
60
|
-
const isOverNode = target !== overlayEl;
|
|
55
|
+
const isOverNode = e.target !== overlayEl;
|
|
61
56
|
if ((e.ctrlKey || e.metaKey) && isOverNode) {
|
|
62
|
-
// 1. Prevent Browser Zoom immediately
|
|
63
57
|
e.preventDefault();
|
|
64
58
|
e.stopPropagation();
|
|
65
|
-
// 2. Calculate coordinates for Fabric
|
|
66
59
|
const scenePoint = canvas.getScenePoint(e);
|
|
67
60
|
const rect = canvas.getElement().getBoundingClientRect();
|
|
68
|
-
const viewportPoint = {
|
|
69
|
-
x: e.clientX - rect.left,
|
|
70
|
-
y: e.clientY - rect.top,
|
|
71
|
-
};
|
|
72
|
-
// 3. Manually fire the event into Fabric
|
|
73
61
|
canvas.fire("mouse:wheel", {
|
|
74
|
-
e
|
|
75
|
-
|
|
76
|
-
viewportPoint,
|
|
62
|
+
e, scenePoint,
|
|
63
|
+
viewportPoint: { x: e.clientX - rect.left, y: e.clientY - rect.top },
|
|
77
64
|
});
|
|
78
65
|
}
|
|
79
66
|
};
|
|
80
|
-
// CRITICAL: { passive: false } allows us to cancel the browser's zoom
|
|
81
67
|
overlayEl.addEventListener("wheel", handleGlobalWheel, { passive: false });
|
|
82
|
-
return () =>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}, [fabricCanvas, canvasZoom]); // Re-bind when zoom changes to keep closure fresh
|
|
86
|
-
// ── Fabric → Overlay Sync (Fixes Dragging from Fabric area) ──────────────────
|
|
68
|
+
return () => overlayEl.removeEventListener("wheel", handleGlobalWheel);
|
|
69
|
+
}, [fabricCanvas]);
|
|
70
|
+
// ─── Fabric → Overlay sync ────────────────────────────────────────────────
|
|
87
71
|
useEffect(() => {
|
|
88
72
|
const canvas = fabricCanvas?.current;
|
|
89
73
|
if (!canvas)
|
|
90
74
|
return;
|
|
91
75
|
const handleObjectMoving = (e) => {
|
|
76
|
+
// MUTEX: HTML drag and Fabric drag must never write positions simultaneously
|
|
77
|
+
if (isHtmlDraggingRef.current)
|
|
78
|
+
return;
|
|
92
79
|
const target = e.transform?.target || e.target;
|
|
93
80
|
if (!target)
|
|
94
81
|
return;
|
|
95
|
-
// 1. Calculate delta in raw Scene Coordinates
|
|
96
|
-
// We do NOT divide by zoom here because target.left/top are world units.
|
|
97
82
|
const deltaX = target.left - (target._prevLeft ?? target.left);
|
|
98
83
|
const deltaY = target.top - (target._prevTop ?? target.top);
|
|
99
84
|
target._prevLeft = target.left;
|
|
100
85
|
target._prevTop = target.top;
|
|
101
86
|
if (deltaX === 0 && deltaY === 0)
|
|
102
87
|
return;
|
|
103
|
-
|
|
104
|
-
setLocalTasks((prev) => prev.map((t) =>
|
|
105
|
-
setLocalDocuments((prev) => prev.map((d) =>
|
|
88
|
+
const sel = selectedIdsRef.current;
|
|
89
|
+
setLocalTasks((prev) => prev.map((t) => sel.has(t.id) ? { ...t, x: t.x + deltaX, y: t.y + deltaY } : t));
|
|
90
|
+
setLocalDocuments((prev) => prev.map((d) => sel.has(d.id) ? { ...d, x: d.x + deltaX, y: d.y + deltaY } : d));
|
|
106
91
|
};
|
|
107
92
|
const handleMouseDown = (e) => {
|
|
108
93
|
const target = e.target;
|
|
@@ -117,138 +102,68 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
117
102
|
canvas.off("object:moving", handleObjectMoving);
|
|
118
103
|
canvas.off("mouse:down", handleMouseDown);
|
|
119
104
|
};
|
|
120
|
-
}, [
|
|
121
|
-
//
|
|
122
|
-
const getItemPosition = (id) => {
|
|
123
|
-
const task = localTasks.find((t) => t.id === id);
|
|
124
|
-
if (task)
|
|
125
|
-
return { x: task.x, y: task.y };
|
|
126
|
-
const doc = localDocuments.find((d) => d.id === id);
|
|
127
|
-
if (doc)
|
|
128
|
-
return { x: doc.x, y: doc.y };
|
|
129
|
-
return undefined;
|
|
130
|
-
};
|
|
131
|
-
const isItemInSelectionBox = (x, y, width, height, box) => {
|
|
132
|
-
const itemX1 = x * canvasZoom + canvasViewport.x;
|
|
133
|
-
const itemY1 = y * canvasZoom + canvasViewport.y;
|
|
134
|
-
const itemX2 = itemX1 + width * canvasZoom;
|
|
135
|
-
const itemY2 = itemY1 + height * canvasZoom;
|
|
136
|
-
const boxX1 = Math.min(box.x1, box.x2);
|
|
137
|
-
const boxY1 = Math.min(box.y1, box.y2);
|
|
138
|
-
const boxX2 = Math.max(box.x1, box.x2);
|
|
139
|
-
const boxY2 = Math.max(box.y1, box.y2);
|
|
140
|
-
return !(boxX2 < itemX1 || boxX1 > itemX2 || boxY2 < itemY1 || boxY1 > itemY2);
|
|
141
|
-
};
|
|
142
|
-
// ── Selection box detection ──────────────────────────────────────────────────
|
|
105
|
+
}, [fabricCanvas]);
|
|
106
|
+
// ─── Selection box ────────────────────────────────────────────────────────
|
|
143
107
|
useEffect(() => {
|
|
144
108
|
if (!selectionBox)
|
|
145
109
|
return;
|
|
146
|
-
// ── O(n) single pass — no sort, no join, no extra allocations ──
|
|
147
110
|
const newSelected = new Set();
|
|
148
111
|
for (const task of localTasks) {
|
|
149
|
-
|
|
112
|
+
const x1 = task.x * canvasZoom + canvasViewport.x;
|
|
113
|
+
const y1 = task.y * canvasZoom + canvasViewport.y;
|
|
114
|
+
const x2 = x1 + 300 * canvasZoom;
|
|
115
|
+
const y2 = y1 + 140 * canvasZoom;
|
|
116
|
+
const bX1 = Math.min(selectionBox.x1, selectionBox.x2);
|
|
117
|
+
const bY1 = Math.min(selectionBox.y1, selectionBox.y2);
|
|
118
|
+
const bX2 = Math.max(selectionBox.x1, selectionBox.x2);
|
|
119
|
+
const bY2 = Math.max(selectionBox.y1, selectionBox.y2);
|
|
120
|
+
if (!(bX2 < x1 || bX1 > x2 || bY2 < y1 || bY1 > y2))
|
|
150
121
|
newSelected.add(task.id);
|
|
151
122
|
}
|
|
152
123
|
for (const doc of localDocuments) {
|
|
153
|
-
|
|
124
|
+
const x1 = doc.x * canvasZoom + canvasViewport.x;
|
|
125
|
+
const y1 = doc.y * canvasZoom + canvasViewport.y;
|
|
126
|
+
const x2 = x1 + 320 * canvasZoom;
|
|
127
|
+
const y2 = y1 + 160 * canvasZoom;
|
|
128
|
+
const bX1 = Math.min(selectionBox.x1, selectionBox.x2);
|
|
129
|
+
const bY1 = Math.min(selectionBox.y1, selectionBox.y2);
|
|
130
|
+
const bX2 = Math.max(selectionBox.x1, selectionBox.x2);
|
|
131
|
+
const bY2 = Math.max(selectionBox.y1, selectionBox.y2);
|
|
132
|
+
if (!(bX2 < x1 || bX1 > x2 || bY2 < y1 || bY1 > y2))
|
|
154
133
|
newSelected.add(doc.id);
|
|
155
134
|
}
|
|
156
|
-
//
|
|
135
|
+
// O(n) equality — same Set ref if unchanged, blocks unnecessary re-render
|
|
157
136
|
setSelectedIds((prev) => {
|
|
158
137
|
if (prev.size !== newSelected.size)
|
|
159
138
|
return newSelected;
|
|
160
|
-
for (const id of newSelected)
|
|
139
|
+
for (const id of newSelected)
|
|
161
140
|
if (!prev.has(id))
|
|
162
|
-
return newSelected;
|
|
163
|
-
|
|
164
|
-
return prev; // identical — return same reference, no re-render
|
|
165
|
-
});
|
|
166
|
-
}, [selectionBox, localTasks, localDocuments]);
|
|
167
|
-
// ── Drag start (HTML Node side) ──────────────────────────────────────────────
|
|
168
|
-
// Helper to extract coordinates regardless of event type
|
|
169
|
-
const getPointerEvent = (e) => {
|
|
170
|
-
if ('touches' in e && e.touches.length > 0)
|
|
171
|
-
return e.touches[0];
|
|
172
|
-
return e;
|
|
173
|
-
};
|
|
174
|
-
const handleDragStart = (itemId, e) => {
|
|
175
|
-
// 1. Safety check for the Fabric instance
|
|
176
|
-
const canvas = fabricCanvas?.current;
|
|
177
|
-
if (!canvas)
|
|
178
|
-
return;
|
|
179
|
-
// 2. Normalize the event (Touch vs Mouse)
|
|
180
|
-
if (e.cancelable)
|
|
181
|
-
e.preventDefault();
|
|
182
|
-
const pointer = getPointerEvent(e);
|
|
183
|
-
// 3. Determine which items are being dragged
|
|
184
|
-
// selection update DOES NOT trigger before drag snapshot
|
|
185
|
-
let itemsToDrag;
|
|
186
|
-
if (selectedIds.has(itemId)) {
|
|
187
|
-
itemsToDrag = Array.from(selectedIds);
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
itemsToDrag = [itemId];
|
|
191
|
-
}
|
|
192
|
-
// 4. Capture current World Transform (Zoom & Pan)
|
|
193
|
-
// We read directly from the canvas to ensure zero-frame lag
|
|
194
|
-
const vpt = canvas.viewportTransform || [1, 0, 0, 1, 0, 0];
|
|
195
|
-
const liveZoom = vpt[0];
|
|
196
|
-
const liveVpX = vpt[4];
|
|
197
|
-
const liveVpY = vpt[5];
|
|
198
|
-
// 5. Convert the Click Position from Screen Pixels to World Units
|
|
199
|
-
const clickWorldX = (pointer.clientX - liveVpX) / liveZoom;
|
|
200
|
-
const clickWorldY = (pointer.clientY - liveVpY) / liveZoom;
|
|
201
|
-
// 6. Get the clicked item's current World Position
|
|
202
|
-
const clickedPos = getItemPosition(itemId);
|
|
203
|
-
if (!clickedPos)
|
|
204
|
-
return;
|
|
205
|
-
// 7. Calculate the Offset in WORLD UNITS
|
|
206
|
-
// This is the distance from the mouse to the node's top-left in the infinite grid.
|
|
207
|
-
// This value remains constant even if you zoom during the drag.
|
|
208
|
-
const worldOffsetX = clickWorldX - clickedPos.x;
|
|
209
|
-
const worldOffsetY = clickWorldY - clickedPos.y;
|
|
210
|
-
// 8. Snapshot starting positions for all selected HTML nodes
|
|
211
|
-
const startPositions = new Map();
|
|
212
|
-
itemsToDrag.forEach((id) => {
|
|
213
|
-
const pos = getItemPosition(id);
|
|
214
|
-
if (pos)
|
|
215
|
-
startPositions.set(id, pos);
|
|
216
|
-
});
|
|
217
|
-
// 9. Snapshot starting positions for all selected Fabric objects
|
|
218
|
-
const canvasObjectsStartPos = new Map();
|
|
219
|
-
selectedCanvasObjects.forEach((obj) => {
|
|
220
|
-
canvasObjectsStartPos.set(obj, { left: obj.left || 0, top: obj.top || 0 });
|
|
141
|
+
return newSelected;
|
|
142
|
+
return prev;
|
|
221
143
|
});
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
document.body.style.userSelect = "none";
|
|
238
|
-
document.body.style.touchAction = "none";
|
|
239
|
-
};
|
|
240
|
-
// ── Drag move (HTML Node side) ───────────────────────────────────────────────
|
|
144
|
+
}, [selectionBox, localTasks, localDocuments, canvasZoom, canvasViewport]);
|
|
145
|
+
// ─── Global drag listeners — attached ONCE on mount ───────────────────────
|
|
146
|
+
//
|
|
147
|
+
// ROOT CAUSE OF THE POSITION JUMP — fixed here:
|
|
148
|
+
//
|
|
149
|
+
// Old pattern: useEffect(() => { mousemove }, [dragging, localTasks, localDocuments])
|
|
150
|
+
// Problem:
|
|
151
|
+
// 1. handleDragStart → setDragging() → React re-render
|
|
152
|
+
// 2. Re-render tears down mousemove listener, attaches new one
|
|
153
|
+
// 3. First real mousemove fires into old (dead) listener → ignored or wrong
|
|
154
|
+
// 4. New listener fires with potentially different startPositions → JUMP
|
|
155
|
+
//
|
|
156
|
+
// Fix: attach listeners ONCE. They read all mutable state via refs.
|
|
157
|
+
// Zero re-registration, zero double-fires, zero stale closure issues.
|
|
158
|
+
//
|
|
241
159
|
useEffect(() => {
|
|
242
|
-
if (!dragging)
|
|
243
|
-
return;
|
|
244
|
-
// Inside the useEffect that watches [dragging, localTasks, localDocuments, fabricCanvas]
|
|
245
160
|
const handleMove = (e) => {
|
|
246
161
|
if (!dragStateRef.current.isDragging)
|
|
247
162
|
return;
|
|
248
163
|
if (e.cancelable)
|
|
249
164
|
e.preventDefault();
|
|
250
|
-
const pointer =
|
|
251
|
-
|
|
165
|
+
const pointer = "touches" in e && e.touches.length > 0
|
|
166
|
+
? e.touches[0] : e;
|
|
252
167
|
if (rafIdRef.current !== null)
|
|
253
168
|
cancelAnimationFrame(rafIdRef.current);
|
|
254
169
|
rafIdRef.current = requestAnimationFrame(() => {
|
|
@@ -256,59 +171,50 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
256
171
|
const canvas = fabricCanvas?.current;
|
|
257
172
|
if (!canvas)
|
|
258
173
|
return;
|
|
259
|
-
//
|
|
174
|
+
// Live VPT — never from React state
|
|
260
175
|
const vpt = canvas.viewportTransform;
|
|
261
|
-
const liveZoom = vpt[0];
|
|
262
|
-
const liveVpX = vpt[4];
|
|
263
|
-
const liveVpY = vpt[5];
|
|
264
|
-
//
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
// (Current Mouse World - Initial World Offset from Start)
|
|
269
|
-
const newWorldX = currentWorldX - offsetX;
|
|
270
|
-
const newWorldY = currentWorldY - offsetY;
|
|
271
|
-
// 5. Calculate the Movement Delta in World Units
|
|
272
|
-
// We compare where the first item started vs where it is now.
|
|
273
|
-
const firstId = itemIds[0];
|
|
274
|
-
const firstStart = startPositions.get(firstId);
|
|
176
|
+
const liveZoom = vpt[0];
|
|
177
|
+
const liveVpX = vpt[4];
|
|
178
|
+
const liveVpY = vpt[5];
|
|
179
|
+
// Screen → World, subtract world-space offset
|
|
180
|
+
const newWorldX = (pointer.clientX - liveVpX) / liveZoom - offsetX;
|
|
181
|
+
const newWorldY = (pointer.clientY - liveVpY) / liveZoom - offsetY;
|
|
182
|
+
const firstStart = startPositions.get(itemIds[0]);
|
|
275
183
|
if (!firstStart)
|
|
276
184
|
return;
|
|
277
185
|
const deltaX = newWorldX - firstStart.x;
|
|
278
186
|
const deltaY = newWorldY - firstStart.y;
|
|
279
|
-
//
|
|
280
|
-
setLocalTasks((prev) => prev.map((t) => itemIds.includes(t.id)
|
|
281
|
-
...t,
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
} : d));
|
|
290
|
-
// 7. Sync Fabric Objects (Imperative update for performance)
|
|
187
|
+
// ── PERF: Only map over items being dragged ────────────────────────
|
|
188
|
+
setLocalTasks((prev) => prev.map((t) => itemIds.includes(t.id)
|
|
189
|
+
? { ...t, x: (startPositions.get(t.id)?.x ?? t.x) + deltaX,
|
|
190
|
+
y: (startPositions.get(t.id)?.y ?? t.y) + deltaY }
|
|
191
|
+
: t));
|
|
192
|
+
setLocalDocuments((prev) => prev.map((d) => itemIds.includes(d.id)
|
|
193
|
+
? { ...d, x: (startPositions.get(d.id)?.x ?? d.x) + deltaX,
|
|
194
|
+
y: (startPositions.get(d.id)?.y ?? d.y) + deltaY }
|
|
195
|
+
: d));
|
|
196
|
+
// Sync Fabric objects imperatively
|
|
291
197
|
canvasObjectsStartPos.forEach((startPos, obj) => {
|
|
292
|
-
obj.set({
|
|
293
|
-
|
|
294
|
-
top: startPos.top + deltaY,
|
|
295
|
-
});
|
|
296
|
-
obj.setCoords(); // Required for selection/intersection accuracy
|
|
198
|
+
obj.set({ left: startPos.left + deltaX, top: startPos.top + deltaY });
|
|
199
|
+
obj.setCoords();
|
|
297
200
|
});
|
|
298
|
-
// 8. Single render call for all Fabric changes
|
|
299
201
|
canvas.requestRenderAll();
|
|
300
202
|
});
|
|
301
203
|
};
|
|
302
204
|
const handleEnd = () => {
|
|
303
|
-
if (
|
|
205
|
+
if (!dragStateRef.current.isDragging)
|
|
206
|
+
return;
|
|
207
|
+
if (rafIdRef.current !== null) {
|
|
304
208
|
cancelAnimationFrame(rafIdRef.current);
|
|
209
|
+
rafIdRef.current = null;
|
|
210
|
+
}
|
|
305
211
|
dragStateRef.current.isDragging = false;
|
|
306
|
-
|
|
212
|
+
isHtmlDraggingRef.current = false;
|
|
307
213
|
document.body.style.cursor = "";
|
|
308
214
|
document.body.style.userSelect = "";
|
|
309
215
|
document.body.style.touchAction = "";
|
|
310
|
-
|
|
311
|
-
|
|
216
|
+
setLocalTasks((prev) => { onTasksUpdateRef.current?.(prev); return prev; });
|
|
217
|
+
setLocalDocuments((prev) => { onDocumentsUpdateRef.current?.(prev); return prev; });
|
|
312
218
|
};
|
|
313
219
|
window.addEventListener("mousemove", handleMove, { passive: false });
|
|
314
220
|
window.addEventListener("mouseup", handleEnd);
|
|
@@ -322,9 +228,62 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
322
228
|
window.removeEventListener("touchend", handleEnd);
|
|
323
229
|
window.removeEventListener("touchcancel", handleEnd);
|
|
324
230
|
};
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
231
|
+
// Empty deps — registered once, reads everything via refs
|
|
232
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
233
|
+
// ─── Drag start ───────────────────────────────────────────────────────────
|
|
234
|
+
const handleDragStart = useCallback((itemId, e) => {
|
|
235
|
+
const canvas = fabricCanvas?.current;
|
|
236
|
+
if (!canvas)
|
|
237
|
+
return;
|
|
238
|
+
if (e.cancelable)
|
|
239
|
+
e.preventDefault();
|
|
240
|
+
const pointer = "touches" in e && e.touches.length > 0
|
|
241
|
+
? e.touches[0] : e;
|
|
242
|
+
// Read from ref — not state (avoids async lag from setSelectedIds)
|
|
243
|
+
const currentSelected = selectedIdsRef.current;
|
|
244
|
+
const itemsToDrag = currentSelected.has(itemId)
|
|
245
|
+
? Array.from(currentSelected) : [itemId];
|
|
246
|
+
if (!currentSelected.has(itemId))
|
|
247
|
+
setSelectedIds(new Set([itemId]));
|
|
248
|
+
// Live VPT
|
|
249
|
+
const vpt = canvas.viewportTransform || [1, 0, 0, 1, 0, 0];
|
|
250
|
+
const liveZoom = vpt[0];
|
|
251
|
+
const liveVpX = vpt[4];
|
|
252
|
+
const liveVpY = vpt[5];
|
|
253
|
+
// Pointer → world
|
|
254
|
+
const pointerWorldX = (pointer.clientX - liveVpX) / liveZoom;
|
|
255
|
+
const pointerWorldY = (pointer.clientY - liveVpY) / liveZoom;
|
|
256
|
+
// nodePositionsRef is rebuilt synchronously every render — never stale
|
|
257
|
+
const clickedPos = nodePositionsRef.current.get(itemId);
|
|
258
|
+
if (!clickedPos)
|
|
259
|
+
return;
|
|
260
|
+
// Snapshot ALL start positions from ref synchronously
|
|
261
|
+
const startPositions = new Map();
|
|
262
|
+
for (const id of itemsToDrag) {
|
|
263
|
+
const pos = nodePositionsRef.current.get(id);
|
|
264
|
+
if (pos)
|
|
265
|
+
startPositions.set(id, { x: pos.x, y: pos.y });
|
|
266
|
+
}
|
|
267
|
+
const canvasObjectsStartPos = new Map();
|
|
268
|
+
for (const obj of selectedCanvasObjectsRef.current) {
|
|
269
|
+
canvasObjectsStartPos.set(obj, { left: obj.left || 0, top: obj.top || 0 });
|
|
270
|
+
}
|
|
271
|
+
dragStateRef.current = {
|
|
272
|
+
isDragging: true,
|
|
273
|
+
itemIds: itemsToDrag,
|
|
274
|
+
startPositions,
|
|
275
|
+
canvasObjectsStartPos,
|
|
276
|
+
// World-space offset: pointer distance from node top-left in world units
|
|
277
|
+
offsetX: pointerWorldX - clickedPos.x,
|
|
278
|
+
offsetY: pointerWorldY - clickedPos.y,
|
|
279
|
+
};
|
|
280
|
+
isHtmlDraggingRef.current = true;
|
|
281
|
+
document.body.style.cursor = "grabbing";
|
|
282
|
+
document.body.style.userSelect = "none";
|
|
283
|
+
document.body.style.touchAction = "none";
|
|
284
|
+
}, [fabricCanvas]);
|
|
285
|
+
// ─── Node interaction ─────────────────────────────────────────────────────
|
|
286
|
+
const handleSelect = useCallback((id, e) => {
|
|
328
287
|
if (e?.shiftKey || e?.ctrlKey || e?.metaKey) {
|
|
329
288
|
setSelectedIds((prev) => {
|
|
330
289
|
const next = new Set(prev);
|
|
@@ -335,68 +294,48 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
335
294
|
else {
|
|
336
295
|
setSelectedIds(new Set([id]));
|
|
337
296
|
}
|
|
338
|
-
};
|
|
339
|
-
const handleStatusChange = (taskId, newStatus) => {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
297
|
+
}, []);
|
|
298
|
+
const handleStatusChange = useCallback((taskId, newStatus) => {
|
|
299
|
+
setLocalTasks((prev) => {
|
|
300
|
+
const updated = prev.map((t) => t.id === taskId ? { ...t, status: newStatus } : t);
|
|
301
|
+
onTasksUpdateRef.current?.(updated);
|
|
302
|
+
return updated;
|
|
303
|
+
});
|
|
304
|
+
}, []);
|
|
305
|
+
// ─── Keyboard shortcuts ───────────────────────────────────────────────────
|
|
344
306
|
useEffect(() => {
|
|
345
307
|
const handleKeyDown = (e) => {
|
|
346
|
-
// Don't trigger if typing in input
|
|
347
308
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement)
|
|
348
309
|
return;
|
|
349
|
-
// Select All
|
|
350
310
|
if ((e.ctrlKey || e.metaKey) && e.key === "a") {
|
|
351
311
|
e.preventDefault();
|
|
352
312
|
setSelectedIds(new Set([...localTasks.map((t) => t.id), ...localDocuments.map((d) => d.id)]));
|
|
353
313
|
}
|
|
354
|
-
|
|
355
|
-
if (e.key === "Escape") {
|
|
314
|
+
if (e.key === "Escape")
|
|
356
315
|
setSelectedIds(new Set());
|
|
357
|
-
|
|
358
|
-
// ← ADD THIS: Delete selected nodes
|
|
359
|
-
if ((e.key === "Delete" || e.key === "Backspace") && selectedIds.size > 0) {
|
|
316
|
+
if ((e.key === "Delete" || e.key === "Backspace") && selectedIdsRef.current.size > 0) {
|
|
360
317
|
e.preventDefault();
|
|
361
|
-
const
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
setLocalDocuments(updatedDocs);
|
|
318
|
+
const ids = selectedIdsRef.current;
|
|
319
|
+
setLocalTasks((prev) => { const u = prev.filter((t) => !ids.has(t.id)); onTasksUpdateRef.current?.(u); return u; });
|
|
320
|
+
setLocalDocuments((prev) => { const u = prev.filter((d) => !ids.has(d.id)); onDocumentsUpdateRef.current?.(u); return u; });
|
|
365
321
|
setSelectedIds(new Set());
|
|
366
|
-
onTasksUpdate?.(updatedTasks);
|
|
367
|
-
onDocumentsUpdate?.(updatedDocs);
|
|
368
322
|
}
|
|
369
323
|
};
|
|
370
324
|
window.addEventListener("keydown", handleKeyDown);
|
|
371
325
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
372
|
-
}, [localTasks, localDocuments
|
|
373
|
-
//
|
|
374
|
-
const renderItem = (id, x, y, children) => {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
// 2. Use translate3d for GPU performance
|
|
385
|
-
transform: `translate3d(${screenX}px, ${screenY}px, 0) scale(${canvasZoom})`,
|
|
386
|
-
transformOrigin: "top left",
|
|
387
|
-
// 3. THE FIX: Remove transition entirely during any viewport change
|
|
388
|
-
// Any 'ease' during zoom causes the "shaking" behavior.
|
|
389
|
-
transition: "none",
|
|
390
|
-
// 4. Optimization
|
|
391
|
-
willChange: "transform",
|
|
392
|
-
zIndex: isDragging ? 1000 : 1,
|
|
393
|
-
}, children: children }, id));
|
|
394
|
-
};
|
|
395
|
-
return (_jsx("div", { ref: overlayRef, className: "absolute inset-0 pointer-events-none", style: { zIndex: 50 }, onWheel: handleOverlayWheel, onClick: (e) => {
|
|
396
|
-
if (e.target === e.currentTarget)
|
|
397
|
-
setSelectedIds(new Set());
|
|
398
|
-
}, children: _jsxs("div", { className: "absolute top-0 left-0 pointer-events-none", style: {
|
|
326
|
+
}, [localTasks, localDocuments]);
|
|
327
|
+
// ─── Render ───────────────────────────────────────────────────────────────
|
|
328
|
+
const renderItem = (id, x, y, children) => (_jsx("div", { className: "pointer-events-auto absolute", style: {
|
|
329
|
+
left: 0, top: 0,
|
|
330
|
+
transform: `translate3d(${x * canvasZoom}px, ${y * canvasZoom}px, 0) scale(${canvasZoom})`,
|
|
331
|
+
transformOrigin: "top left",
|
|
332
|
+
transition: "none", // No CSS transitions — causes shaking during zoom
|
|
333
|
+
willChange: "transform", // GPU layer hint
|
|
334
|
+
zIndex: dragStateRef.current.itemIds.includes(id) ? 1000 : 1,
|
|
335
|
+
}, children: children }, id));
|
|
336
|
+
return (_jsx("div", { ref: overlayRef, className: "absolute inset-0 pointer-events-none", style: { zIndex: 50 }, onClick: (e) => { if (e.target === e.currentTarget)
|
|
337
|
+
setSelectedIds(new Set()); }, children: _jsxs("div", { className: "absolute top-0 left-0 pointer-events-none", style: {
|
|
399
338
|
transform: `translate(${canvasViewport.x}px, ${canvasViewport.y}px)`,
|
|
400
339
|
transformOrigin: "top left",
|
|
401
|
-
}, children: [localTasks.map((task) => renderItem(task.id, task.x, task.y, _jsx(
|
|
340
|
+
}, children: [localTasks.map((task) => renderItem(task.id, task.x, task.y, _jsx(MemoTaskNode, { ...task, isSelected: selectedIds.has(task.id), onSelect: handleSelect, onDragStart: handleDragStart, onStatusChange: handleStatusChange, zoom: 1 }))), localDocuments.map((doc) => renderItem(doc.id, doc.x, doc.y, _jsx(MemoDocumentNode, { ...doc, isSelected: selectedIds.has(doc.id), onSelect: handleSelect, onDragStart: handleDragStart })))] }) }));
|
|
402
341
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-dropdown.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/task-dropdown.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"task-dropdown.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/task-dropdown.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CACzC;AA2DD,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,SAAS,EAAE,EAAE,iBAAiB,2CAkGpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooloptions-panel.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/tooloptions-panel.tsx"],"names":[],"mappings":"AAGA,OAAc,EAAE,SAAS,EAAgC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tooloptions-panel.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/tooloptions-panel.tsx"],"names":[],"mappings":"AAGA,OAAc,EAAE,SAAS,EAAgC,MAAM,OAAO,CAAC;AAUvE,OAAO,MAA2C,MAAM,QAAQ,CAAC;AAGjE,UAAU,qBAAqB;IAC7B,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,YAAY,GACb,EAAE,qBAAqB,2CAuMvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whiteboard-toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/whiteboard-toolbar.tsx"],"names":[],"mappings":"AAEA,OAAa,EAAqB,gBAAgB,EAAY,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"whiteboard-toolbar.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/whiteboard-toolbar.tsx"],"names":[],"mappings":"AAEA,OAAa,EAAqB,gBAAgB,EAAY,MAAM,OAAO,CAAC;AAK5E,OAAO,EAAE,MAAM,EAAQ,MAAM,QAAQ,CAAC;AAOtC,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7F;AACD,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5D;AAkBD,UAAU,sBAAsB;IAC9B,YAAY,EAAE,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,cAAc,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACjD;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,sBAAsB,2CAiM3H"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCanvasInit.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasInit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,UAAU,kBAAkB;IAC1B,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/C,eAAe,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,cAAc,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAErC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACjC,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CACrC;AAKD,eAAO,MAAM,aAAa,GAAI,sHAS3B,kBAAkB,
|
|
1
|
+
{"version":3,"file":"useCanvasInit.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasInit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,UAAU,kBAAkB;IAC1B,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/C,eAAe,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,cAAc,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAErC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACjC,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;CACrC;AAKD,eAAO,MAAM,aAAa,GAAI,sHAS3B,kBAAkB,SA0FpB,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { RefObject } from "react";
|
|
2
|
-
import { Canvas, Circle, FabricObject } from "fabric";
|
|
3
|
-
import * as fabric from "fabric";
|
|
2
|
+
import fabric, { Canvas, Circle, FabricObject } from "fabric";
|
|
4
3
|
interface UseEraserProps {
|
|
5
4
|
fabricCanvas: RefObject<Canvas | null>;
|
|
6
5
|
activeTool: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEraser.d.ts","sourceRoot":"","sources":["../../src/hooks/useEraser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"useEraser.d.ts","sourceRoot":"","sources":["../../src/hooks/useEraser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,MAAM,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE7D,UAAU,cAAc;IACtB,YAAY,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,GAAG,CAAC;IACjB,cAAc,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,gBAAgB,EAAE,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/C,eAAe,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACpC,aAAa,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC7C,mBAAmB,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,kBAAkB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,SAAS,GAAI,oKAWvB,cAAc;;;;gCAsBoB;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;;CA0I5D,CAAC"}
|
package/dist/hooks/useEraser.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Circle } from "fabric";
|
|
2
|
-
import * as fabric from "fabric";
|
|
1
|
+
import fabric, { Circle } from "fabric";
|
|
3
2
|
export const useEraser = ({ fabricCanvas, activeTool, toolOptions, eraserTraceRef, eraserTargetsRef, eraserActiveRef, eraserPathRef, eraserPathPointsRef, suppressHistoryRef, pushHistory, }) => {
|
|
4
3
|
const handleMouseOver = () => {
|
|
5
4
|
if (activeTool === "eraser" && eraserTraceRef.current) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useToolManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useToolManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"useToolManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useToolManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,MAAM,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI/C,UAAU,mBAAmB;IAC3B,YAAY,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,GAAG,CAAC;IACjB,cAAc,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,aAAa,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC7C,mBAAmB,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,gBAAgB,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,cAAc,GAAI,kHAQ5B,mBAAmB,SA8HrB,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,2 @@
|
|
|
1
|
-
// export {default as EasyflowWhiteboard} from "./components/whiteboard/whiteboard-test";
|
|
2
|
-
// export * from "./hooks/useCanvasInit";
|
|
3
|
-
// export * from "./hooks/useDrawing";
|
|
4
|
-
// export * from "./hooks/useEraser";
|
|
5
|
-
// export * from "./hooks/usePan";
|
|
6
|
-
// export * from "./hooks/useZoom";
|
|
7
|
-
// export * from "./hooks/useSelection";
|
|
8
|
-
// export * from "./hooks/useLiveUpdate";
|
|
9
|
-
// export * from "./hooks/useMouseHandlers";
|
|
10
|
-
// export * from "./hooks/usePersistance";
|
|
11
|
-
// export * from "./hooks/useToolManager";
|
|
12
|
-
// export * from "./hooks/useTextStyle";
|
|
13
|
-
// export * from "./lib/fabric-frame";
|
|
14
|
-
// export * from "./lib/fabric-arrow";
|
|
15
|
-
// export * from "./lib/fabric-bidirectional-arrow";
|
|
16
|
-
// export * from "./lib/fabric-utils";
|
|
17
|
-
// export * from "./lib/utils";
|
|
18
|
-
// export * from "./store/whiteboard-store";
|
|
19
|
-
// export * from "./components/toolbar/whiteboard-toolbar";
|
|
20
|
-
// export * from "./components/toolbar/tooloptions-panel";
|
|
21
|
-
// export * from "./components/node/custom-node-overlay-layer";
|
|
22
|
-
// export * from "./components/zoomcontrol/zoom-control";
|
|
23
|
-
// export * from "./components/whiteboard/whiteboard-test";
|
|
24
|
-
// export * from "./components/node/document-node";
|
|
25
|
-
// export * from "./components/node/custom-node";
|
|
26
|
-
// export * from "./components/toolbar/document-dropdown";
|
|
27
|
-
// export * from "./components/toolbar/task-dropdown";
|
|
28
|
-
// export * from "./components/toolbar/document-dropdown";
|
|
29
1
|
export { default as EasyflowWhiteboard } from "./components/whiteboard/whiteboard-test";
|
|
30
2
|
export { useWhiteboardStore } from './store/whiteboard-store';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fabric-utils.d.ts","sourceRoot":"","sources":["../../src/lib/fabric-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"fabric-utils.d.ts","sourceRoot":"","sources":["../../src/lib/fabric-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAwE,WAAW,EAAc,MAAM,QAAQ,CAAC;AAK7I,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,WAkBpD,CAAC;AAQF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,YAAY,EACnB,UAAU,MAAM,EAChB,YAAY;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACpC,cAAc;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,SAwEvC,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,SASnD,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,SAEhD,CAAC;AAGF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,WAAW,MAAM,IAAI,SAMtB,CAAC;AAGF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,SAAQ,KAAK,GAAG,MAAc,WAO/B,CAAC;AAUF,eAAO,MAAM,kBAAkB,GAC7B,iBAAiB,MAAM,EAAE,GAAG,IAAI,EAChC,aAAa,MAAM,KAClB,MAAM,EAAE,GAAG,SAKb,CAAC;AAKF,eAAO,MAAM,OAAO,GAClB,QAAQ,MAAM,EACd,SAAS;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,SAmBF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,EAAE,KAAK,MAAM,iJAuCjE,CAAC;AAGF,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,SAIzC,CAAC;AAGF,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,EAAE,WAAW,MAAM,SAG3D,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,SAoBhD,CAAC;AAIF,eAAO,MAAM,iBAAiB,GAAU,QAAQ,MAAM,EAAE,SAAS,MAAM,kBAoFtE,CAAC"}
|
package/dist/lib/fabric-utils.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { FabricObject, Line, Group, IText, PencilBrush, FabricImage, util } from "fabric";
|
|
2
|
-
import { Text } from "fabric";
|
|
1
|
+
import { FabricObject, Text, Line, Group, IText, PencilBrush, FabricImage, util } from "fabric";
|
|
3
2
|
// Initialize canvas with default settings
|
|
4
3
|
export const initializeFabricCanvas = (canvas) => {
|
|
5
4
|
// Set default object properties
|
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-scroll-snap-strictness:proximity;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-serif:ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-500:oklch(63.7% .237 25.331);--color-orange-500:oklch(70.5% .213 47.604);--color-emerald-500:oklch(69.6% .17 162.48);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tighter:-.05em;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-md:12px;--blur-xl:24px;--blur-2xl:40px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.-inset-px{inset:-1px}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-11{top:calc(var(--spacing) * -11)}.top-0{top:calc(var(--spacing) * 0)}.top-1\/2{top:50%}.top-3{top:calc(var(--spacing) * 3)}.top-4{top:calc(var(--spacing) * 4)}.top-6{top:calc(var(--spacing) * 6)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-4{bottom:calc(var(--spacing) * 4)}.bottom-6{bottom:calc(var(--spacing) * 6)}.-left-\[1px\]{left:-1px}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-3{left:calc(var(--spacing) * 3)}.left-4{left:calc(var(--spacing) * 4)}.-z-10{z-index:calc(10 * -1)}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[60\]{z-index:60}.z-\[100\]{z-index:100}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-1{margin-inline:calc(var(--spacing) * 1)}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-0{height:calc(var(--spacing) * 0)}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-\[1px\]{height:1px}.h-\[2px\]{height:2px}.h-\[48px\]{height:48px}.h-\[100px\]{height:100px}.h-\[300px\]{height:300px}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-\[60vh\]{max-height:60vh}.max-h-\[70vh\]{max-height:70vh}.max-h-\[85vh\]{max-height:85vh}.w-1{width:calc(var(--spacing) * 1)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-64{width:calc(var(--spacing) * 64)}.w-\[3px\]{width:3px}.w-\[310px\]{width:310px}.w-\[320px\]{width:320px}.w-\[340px\]{width:340px}.w-\[380px\]{width:380px}.w-\[400px\]{width:400px}.w-\[calc\(100\%-80px\)\]{width:calc(100% - 80px)}.w-full{width:100%}.w-px{width:1px}.w-screen{width:100vw}.max-w-\[120px\]{max-width:120px}.max-w-\[180px\]{max-width:180px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[48px\]{min-width:48px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.origin-\(--radix-dropdown-menu-content-transform-origin\){transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-12{--tw-translate-x:calc(var(--spacing) * -12);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-95{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-\[1\.03\]{scale:1.03}.scale-\[1\.04\]{scale:1.04}.rotate-0{rotate:none}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.snap-x{scroll-snap-type:x var(--tw-scroll-snap-strictness)}.snap-mandatory{--tw-scroll-snap-strictness:mandatory}.snap-center{scroll-snap-align:center}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.-space-x-1\.5>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -1.5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -1.5) * calc(1 - var(--tw-space-x-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.scroll-smooth{scroll-behavior:smooth}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[24px\]{border-radius:24px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-l-2xl{border-top-left-radius:var(--radius-2xl);border-bottom-left-radius:var(--radius-2xl)}.rounded-r-2xl{border-top-right-radius:var(--radius-2xl);border-bottom-right-radius:var(--radius-2xl)}.rounded-r-full{border-top-right-radius:3.40282e38px;border-bottom-right-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-\[\#2C2C2E\]{border-color:#2c2c2e}.border-\[\#10B981\]{border-color:#10b981}.border-\[\#10B981\]\/20{border-color:oklab(69.5873% -.142158 .0448781/.2)}.border-\[\#029AFF\]{border-color:#029aff}.border-\[\#029AFF\]\/20{border-color:oklab(67.1382% -.0668607 -.16985/.2)}.border-\[\#333\]{border-color:#333}.border-\[\#28282b\]{border-color:#28282b}.border-\[\#121214\]{border-color:#121214}.border-\[\#232326\]{border-color:#232326}.border-\[\#252526\]{border-color:#252526}.border-\[\#A1A1A1\]{border-color:#a1a1a1}.border-gray-700{border-color:var(--color-gray-700)}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-500{border-color:var(--color-neutral-500)}.border-neutral-700{border-color:var(--color-neutral-700)}.border-neutral-800{border-color:var(--color-neutral-800)}.border-transparent{border-color:#0000}.border-white\/5{border-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.border-white\/5{border-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.border-white\/10{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-\[\#0b0b0b\]{background-color:#0b0b0b}.bg-\[\#1A1A1E\]\/90{background-color:oklab(21.9517% .00210053 -.00745043/.9)}.bg-\[\#1A1A1E\]\/95{background-color:oklab(21.9517% .00210053 -.00745043/.95)}.bg-\[\#1C1C1E\]{background-color:#1c1c1e}.bg-\[\#2C2C2E\]{background-color:#2c2c2e}.bg-\[\#3A3A3C\]{background-color:#3a3a3c}.bg-\[\#10B981\]{background-color:#10b981}.bg-\[\#10B981\]\/10{background-color:oklab(69.5873% -.142158 .0448781/.1)}.bg-\[\#029AFF\]{background-color:#029aff}.bg-\[\#029AFF\]\/10{background-color:oklab(67.1382% -.0668607 -.16985/.1)}.bg-\[\#09090A\]{background-color:#09090a}.bg-\[\#121214\]{background-color:#121214}.bg-\[\#121214\]\/95{background-color:oklab(18.3088% .00111321 -.00388381/.95)}.bg-\[\#161617\]{background-color:#161617}.bg-\[\#A1A1A1\]{background-color:#a1a1a1}.bg-black\/95{background-color:#000000f2}@supports (color:color-mix(in lab, red, red)){.bg-black\/95{background-color:color-mix(in oklab, var(--color-black) 95%, transparent)}}.bg-current{background-color:currentColor}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-neutral-500{background-color:var(--color-neutral-500)}.bg-neutral-700{background-color:var(--color-neutral-700)}.bg-neutral-800{background-color:var(--color-neutral-800)}.bg-neutral-800\/50{background-color:#26262680}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/50{background-color:color-mix(in oklab, var(--color-neutral-800) 50%, transparent)}}.bg-neutral-900{background-color:var(--color-neutral-900)}.bg-orange-500{background-color:var(--color-orange-500)}.bg-red-500{background-color:var(--color-red-500)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.bg-white\/5{background-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\/10{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-white\/30{background-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.bg-white\/30{background-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.bg-white\/\[0\.02\]{background-color:#ffffff05}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.02\]{background-color:color-mix(in oklab, var(--color-white) 2%, transparent)}}.bg-gradient-to-l{--tw-gradient-position:to left in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-\[\#0b0b0b\]{--tw-gradient-from:#0b0b0b;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-\[\#029AFF\]\/20{--tw-gradient-from:oklab(67.1382% -.0668607 -.16985/.2);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-\[\#09090A\]{--tw-gradient-from:#09090a;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-\[\#7000FF\]\/20{--tw-gradient-to:oklab(51.3555% .0937862 -.277611/.2);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.fill-current{fill:currentColor}.p-0{padding:calc(var(--spacing) * 0)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-0{padding-bottom:calc(var(--spacing) * 0)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[0\.2em\]{--tw-tracking:.2em;letter-spacing:.2em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-tighter{--tw-tracking:var(--tracking-tighter);letter-spacing:var(--tracking-tighter)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.whitespace-nowrap{white-space:nowrap}.text-\[\#10B981\]{color:#10b981}.text-\[\#029AFF\]{color:#029aff}.text-black{color:var(--color-black)}.text-current{color:currentColor}.text-gray-100{color:var(--color-gray-100)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-neutral-100{color:var(--color-neutral-100)}.text-neutral-200{color:var(--color-neutral-200)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-red-500{color:var(--color-red-500)}.text-transparent{color:#0000}.text-white{color:var(--color-white)}.text-white\/40{color:#fff6}@supports (color:color-mix(in lab, red, red)){.text-white\/40{color:color-mix(in oklab, var(--color-white) 40%, transparent)}}.text-white\/50{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.text-white\/50{color:color-mix(in oklab, var(--color-white) 50%, transparent)}}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.accent-neutral-200{accent-color:var(--color-neutral-200)}.opacity-0{opacity:0}.opacity-30{opacity:.3}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_15px_\#029AFF\]{--tw-shadow:0 0 15px var(--tw-shadow-color,#029aff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_20px_50px_rgba\(0\,0\,0\,0\.5\)\]{--tw-shadow:0 20px 50px var(--tw-shadow-color,#00000080);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_32px_64px_rgba\(0\,0\,0\,0\.6\)\]{--tw-shadow:0 32px 64px var(--tw-shadow-color,#0009);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[\#10B981\]\/20{--tw-shadow-color:#10b98133}@supports (color:color-mix(in lab, red, red)){.shadow-\[\#10B981\]\/20{--tw-shadow-color:color-mix(in oklab, oklab(69.5873% -.142158 .0448781/.2) var(--tw-shadow-alpha), transparent)}}.shadow-black\/20{--tw-shadow-color:#0003}@supports (color:color-mix(in lab, red, red)){.shadow-black\/20{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 20%, transparent) var(--tw-shadow-alpha), transparent)}}.ring-\[\#029AFF\]{--tw-ring-color:#029aff}.ring-\[\#161617\]{--tw-ring-color:#161617}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.outline-2{outline-style:var(--tw-outline-style);outline-width:2px}.outline-neutral-400{outline-color:var(--color-neutral-400)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.blur-md{--tw-blur:blur(var(--blur-md));filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-2xl{--tw-backdrop-blur:blur(var(--blur-2xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-\[cubic-bezier\(0\.23\,1\,0\.32\,1\)\]{--tw-ease:cubic-bezier(.23,1,.32,1);transition-timing-function:cubic-bezier(.23,1,.32,1)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:scale-110:is(:where(.group):hover *){--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.group-hover\:bg-\[\#029AFF\]:is(:where(.group):hover *){background-color:#029aff}.group-hover\:text-\[\#10B981\]:is(:where(.group):hover *){color:#10b981}.group-hover\:text-gray-400:is(:where(.group):hover *){color:var(--color-gray-400)}.group-hover\:text-white:is(:where(.group):hover *){color:var(--color-white)}.group-hover\/title\:text-\[\#029AFF\]:is(:where(.group\/title):hover *){color:#029aff}.group-hover\/tooltip\:opacity-100:is(:where(.group\/tooltip):hover *){opacity:1}}.group-data-\[disabled\=true\]\:pointer-events-none:is(:where(.group)[data-disabled=true] *){pointer-events:none}.group-data-\[disabled\=true\]\:opacity-50:is(:where(.group)[data-disabled=true] *){opacity:.5}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-50:is(:where(.peer):disabled~*){opacity:.5}.selection\:bg-\[\#029AFF\]\/40 ::selection{background-color:oklab(67.1382% -.0668607 -.16985/.4)}.selection\:bg-\[\#029AFF\]\/40::selection{background-color:oklab(67.1382% -.0668607 -.16985/.4)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-0:after{content:var(--tw-content);top:calc(var(--spacing) * 0)}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:-translate-x-1\/2:after{content:var(--tw-content);--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.after\:-translate-y-full:after{content:var(--tw-content);--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.after\:border-4:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:4px}.after\:border-transparent:after{content:var(--tw-content);border-color:#0000}.after\:border-b-gray-900:after{content:var(--tw-content);border-bottom-color:var(--color-gray-900)}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}@media (hover:hover){.hover\:border-\[\#3e3e42\]:hover{border-color:#3e3e42}.hover\:border-\[\#10B981\]:hover{border-color:#10b981}.hover\:border-neutral-500:hover{border-color:var(--color-neutral-500)}.hover\:border-white\/5:hover{border-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.hover\:border-white\/5:hover{border-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.hover\:bg-\[\#10B981\]:hover{background-color:#10b981}.hover\:bg-\[\#029AFF\]:hover{background-color:#029aff}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-neutral-800:hover{background-color:var(--color-neutral-800)}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.hover\:text-\[\#10B981\]\/50:hover{color:oklab(69.5873% -.142158 .0448781/.5)}.hover\:text-black:hover{color:var(--color-black)}.hover\:text-blue-400:hover{color:var(--color-blue-400)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:ring-4:hover{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-4:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-blue-500:focus-visible{--tw-ring-color:var(--color-blue-500)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:outline-hidden:focus-visible{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus-visible\:outline-hidden:focus-visible{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:bg-white\/20:active{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.active\:bg-white\/20:active{background-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[inset\]\:pl-8[data-inset]{padding-left:calc(var(--spacing) * 8)}.data-\[orientation\=horizontal\]\:h-1\.5[data-orientation=horizontal]{height:calc(var(--spacing) * 1.5)}.data-\[orientation\=horizontal\]\:h-full[data-orientation=horizontal]{height:100%}.data-\[orientation\=horizontal\]\:w-full[data-orientation=horizontal]{width:100%}.data-\[orientation\=vertical\]\:h-full[data-orientation=vertical]{height:100%}.data-\[orientation\=vertical\]\:min-h-44[data-orientation=vertical]{min-height:calc(var(--spacing) * 44)}.data-\[orientation\=vertical\]\:w-1\.5[data-orientation=vertical]{width:calc(var(--spacing) * 1.5)}.data-\[orientation\=vertical\]\:w-auto[data-orientation=vertical]{width:auto}.data-\[orientation\=vertical\]\:w-full[data-orientation=vertical]{width:100%}.data-\[orientation\=vertical\]\:flex-col[data-orientation=vertical]{flex-direction:column}@media (min-width:48rem){.md\:bottom-6{bottom:calc(var(--spacing) * 6)}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-auto{width:auto}.md\:snap-none{scroll-snap-type:none}.md\:overflow-x-visible{overflow-x:visible}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.easyflow-whiteboard{isolation:isolate;--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(97% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(97% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(97% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.2% 0 0);--input:oklch(92.2% 0 0);--ring:oklch(70.8% 0 0);--chart-1:oklch(64.6% .222 41.116);--chart-2:oklch(60% .118 184.704);--chart-3:oklch(39.8% .07 227.392);--chart-4:oklch(82.8% .189 84.429);--chart-5:oklch(76.9% .188 70.08);--sidebar:oklch(98.5% 0 0);--sidebar-foreground:oklch(14.5% 0 0);--sidebar-primary:oklch(20.5% 0 0);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(97% 0 0);--sidebar-accent-foreground:oklch(20.5% 0 0);--sidebar-border:oklch(92.2% 0 0);--sidebar-ring:oklch(70.8% 0 0);--color-background:var(--background);--color-foreground:var(--foreground);--color-card:var(--card);--color-card-foreground:var(--card-foreground);--color-popover:var(--popover);--color-popover-foreground:var(--popover-foreground);--color-primary:var(--primary);--color-primary-foreground:var(--primary-foreground);--color-secondary:var(--secondary);--color-secondary-foreground:var(--secondary-foreground);--color-muted:var(--muted);--color-muted-foreground:var(--muted-foreground);--color-accent:var(--accent);--color-accent-foreground:var(--accent-foreground);--color-destructive:var(--destructive);--color-border:var(--border);--color-input:var(--input);--color-ring:var(--ring);--color-chart-1:var(--chart-1);--color-chart-2:var(--chart-2);--color-chart-3:var(--chart-3);--color-chart-4:var(--chart-4);--color-chart-5:var(--chart-5);--color-sidebar:var(--sidebar);--color-sidebar-foreground:var(--sidebar-foreground);--color-sidebar-primary:var(--sidebar-primary);--color-sidebar-primary-foreground:var(--sidebar-primary-foreground);--color-sidebar-accent:var(--sidebar-accent);--color-sidebar-accent-foreground:var(--sidebar-accent-foreground);--color-sidebar-border:var(--sidebar-border);--color-sidebar-ring:var(--sidebar-ring);--radius-sm:calc(var(--radius) - 4px);--radius-md:calc(var(--radius) - 2px);--radius-lg:var(--radius);--radius-xl:calc(var(--radius) + 4px);--radius-2xl:calc(var(--radius) + 8px);--radius-3xl:calc(var(--radius) + 12px);--radius-4xl:calc(var(--radius) + 16px);width:100%;height:100%;position:relative}.easyflow-whiteboard *{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.easyflow-whiteboard *{outline-color:color-mix(in oklch, var(--ring) 50%, transparent)}}.easyflow-whiteboard.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(20.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(20.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(92.2% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.6% 0 0);--chart-1:oklch(48.8% .243 264.376);--chart-2:oklch(69.6% .17 162.48);--chart-3:oklch(76.9% .188 70.08);--chart-4:oklch(62.7% .265 303.9);--chart-5:oklch(64.5% .246 16.439);--sidebar:oklch(20.5% 0 0);--sidebar-foreground:oklch(98.5% 0 0);--sidebar-primary:oklch(48.8% .243 264.376);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(26.9% 0 0);--sidebar-accent-foreground:oklch(98.5% 0 0);--sidebar-border:oklch(100% 0 0/.1);--sidebar-ring:oklch(55.6% 0 0)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-scroll-snap-strictness{syntax:"*";inherits:false;initial-value:proximity}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes pulse{50%{opacity:.5}}
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-scroll-snap-strictness:proximity;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-serif:ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-500:oklch(63.7% .237 25.331);--color-orange-500:oklch(70.5% .213 47.604);--color-emerald-500:oklch(69.6% .17 162.48);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tighter:-.05em;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-md:12px;--blur-xl:24px;--blur-2xl:40px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.-inset-px{inset:-1px}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-11{top:calc(var(--spacing) * -11)}.top-0{top:calc(var(--spacing) * 0)}.top-1\/2{top:50%}.top-3{top:calc(var(--spacing) * 3)}.top-4{top:calc(var(--spacing) * 4)}.top-6{top:calc(var(--spacing) * 6)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-4{bottom:calc(var(--spacing) * 4)}.bottom-6{bottom:calc(var(--spacing) * 6)}.-left-\[1px\]{left:-1px}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-3{left:calc(var(--spacing) * 3)}.left-4{left:calc(var(--spacing) * 4)}.-z-10{z-index:calc(10 * -1)}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.z-\[60\]{z-index:60}.z-\[100\]{z-index:100}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-1{margin-inline:calc(var(--spacing) * 1)}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.h-0{height:calc(var(--spacing) * 0)}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-\[1px\]{height:1px}.h-\[2px\]{height:2px}.h-\[48px\]{height:48px}.h-\[100px\]{height:100px}.h-\[300px\]{height:300px}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-\[60vh\]{max-height:60vh}.max-h-\[70vh\]{max-height:70vh}.max-h-\[85vh\]{max-height:85vh}.w-1{width:calc(var(--spacing) * 1)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-64{width:calc(var(--spacing) * 64)}.w-\[3px\]{width:3px}.w-\[310px\]{width:310px}.w-\[320px\]{width:320px}.w-\[340px\]{width:340px}.w-\[380px\]{width:380px}.w-\[400px\]{width:400px}.w-\[calc\(100\%-80px\)\]{width:calc(100% - 80px)}.w-full{width:100%}.w-px{width:1px}.w-screen{width:100vw}.max-w-\[120px\]{max-width:120px}.max-w-\[180px\]{max-width:180px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[48px\]{min-width:48px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.origin-\(--radix-dropdown-menu-content-transform-origin\){transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-12{--tw-translate-x:calc(var(--spacing) * -12);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.scale-95{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}.scale-\[1\.03\]{scale:1.03}.scale-\[1\.04\]{scale:1.04}.rotate-0{rotate:none}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.snap-x{scroll-snap-type:x var(--tw-scroll-snap-strictness)}.snap-mandatory{--tw-scroll-snap-strictness:mandatory}.snap-center{scroll-snap-align:center}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.-space-x-1\.5>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -1.5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -1.5) * calc(1 - var(--tw-space-x-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.scroll-smooth{scroll-behavior:smooth}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[24px\]{border-radius:24px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-l-2xl{border-top-left-radius:var(--radius-2xl);border-bottom-left-radius:var(--radius-2xl)}.rounded-r-2xl{border-top-right-radius:var(--radius-2xl);border-bottom-right-radius:var(--radius-2xl)}.rounded-r-full{border-top-right-radius:3.40282e38px;border-bottom-right-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-\[\#2C2C2E\]{border-color:#2c2c2e}.border-\[\#10B981\]{border-color:#10b981}.border-\[\#10B981\]\/20{border-color:oklab(69.5873% -.142158 .0448781/.2)}.border-\[\#029AFF\]{border-color:#029aff}.border-\[\#029AFF\]\/20{border-color:oklab(67.1382% -.0668607 -.16985/.2)}.border-\[\#333\]{border-color:#333}.border-\[\#28282b\]{border-color:#28282b}.border-\[\#121214\]{border-color:#121214}.border-\[\#232326\]{border-color:#232326}.border-\[\#252526\]{border-color:#252526}.border-\[\#A1A1A1\]{border-color:#a1a1a1}.border-gray-700{border-color:var(--color-gray-700)}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-500{border-color:var(--color-neutral-500)}.border-neutral-700{border-color:var(--color-neutral-700)}.border-neutral-800{border-color:var(--color-neutral-800)}.border-transparent{border-color:#0000}.border-white\/5{border-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.border-white\/5{border-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.border-white\/10{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-\[\#0b0b0b\]{background-color:#0b0b0b}.bg-\[\#1A1A1E\]\/90{background-color:oklab(21.9517% .00210053 -.00745043/.9)}.bg-\[\#1A1A1E\]\/95{background-color:oklab(21.9517% .00210053 -.00745043/.95)}.bg-\[\#1C1C1E\]{background-color:#1c1c1e}.bg-\[\#2C2C2E\]{background-color:#2c2c2e}.bg-\[\#3A3A3C\]{background-color:#3a3a3c}.bg-\[\#10B981\]{background-color:#10b981}.bg-\[\#10B981\]\/10{background-color:oklab(69.5873% -.142158 .0448781/.1)}.bg-\[\#029AFF\]{background-color:#029aff}.bg-\[\#029AFF\]\/10{background-color:oklab(67.1382% -.0668607 -.16985/.1)}.bg-\[\#09090A\]{background-color:#09090a}.bg-\[\#121214\]{background-color:#121214}.bg-\[\#121214\]\/95{background-color:oklab(18.3088% .00111321 -.00388381/.95)}.bg-\[\#161617\]{background-color:#161617}.bg-\[\#A1A1A1\]{background-color:#a1a1a1}.bg-black\/95{background-color:#000000f2}@supports (color:color-mix(in lab, red, red)){.bg-black\/95{background-color:color-mix(in oklab, var(--color-black) 95%, transparent)}}.bg-current{background-color:currentColor}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-neutral-500{background-color:var(--color-neutral-500)}.bg-neutral-700{background-color:var(--color-neutral-700)}.bg-neutral-800{background-color:var(--color-neutral-800)}.bg-neutral-800\/50{background-color:#26262680}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/50{background-color:color-mix(in oklab, var(--color-neutral-800) 50%, transparent)}}.bg-neutral-900{background-color:var(--color-neutral-900)}.bg-orange-500{background-color:var(--color-orange-500)}.bg-red-500{background-color:var(--color-red-500)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.bg-white\/5{background-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\/10{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-white\/30{background-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.bg-white\/30{background-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.bg-white\/\[0\.02\]{background-color:#ffffff05}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.02\]{background-color:color-mix(in oklab, var(--color-white) 2%, transparent)}}.bg-gradient-to-l{--tw-gradient-position:to left in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-\[\#0b0b0b\]{--tw-gradient-from:#0b0b0b;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-\[\#029AFF\]\/20{--tw-gradient-from:oklab(67.1382% -.0668607 -.16985/.2);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-\[\#09090A\]{--tw-gradient-from:#09090a;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-\[\#7000FF\]\/20{--tw-gradient-to:oklab(51.3555% .0937862 -.277611/.2);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.fill-current{fill:currentColor}.p-0{padding:calc(var(--spacing) * 0)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-0{padding-bottom:calc(var(--spacing) * 0)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.font-serif{font-family:var(--font-serif)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[0\.2em\]{--tw-tracking:.2em;letter-spacing:.2em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-tighter{--tw-tracking:var(--tracking-tighter);letter-spacing:var(--tracking-tighter)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.whitespace-nowrap{white-space:nowrap}.text-\[\#10B981\]{color:#10b981}.text-\[\#029AFF\]{color:#029aff}.text-black{color:var(--color-black)}.text-current{color:currentColor}.text-gray-100{color:var(--color-gray-100)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-neutral-100{color:var(--color-neutral-100)}.text-neutral-200{color:var(--color-neutral-200)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-red-500{color:var(--color-red-500)}.text-transparent{color:#0000}.text-white{color:var(--color-white)}.text-white\/40{color:#fff6}@supports (color:color-mix(in lab, red, red)){.text-white\/40{color:color-mix(in oklab, var(--color-white) 40%, transparent)}}.text-white\/50{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.text-white\/50{color:color-mix(in oklab, var(--color-white) 50%, transparent)}}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.accent-neutral-200{accent-color:var(--color-neutral-200)}.opacity-0{opacity:0}.opacity-30{opacity:.3}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_15px_\#029AFF\]{--tw-shadow:0 0 15px var(--tw-shadow-color,#029aff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_20px_50px_rgba\(0\,0\,0\,0\.5\)\]{--tw-shadow:0 20px 50px var(--tw-shadow-color,#00000080);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_32px_64px_rgba\(0\,0\,0\,0\.6\)\]{--tw-shadow:0 32px 64px var(--tw-shadow-color,#0009);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[\#10B981\]\/20{--tw-shadow-color:#10b98133}@supports (color:color-mix(in lab, red, red)){.shadow-\[\#10B981\]\/20{--tw-shadow-color:color-mix(in oklab, oklab(69.5873% -.142158 .0448781/.2) var(--tw-shadow-alpha), transparent)}}.shadow-black\/20{--tw-shadow-color:#0003}@supports (color:color-mix(in lab, red, red)){.shadow-black\/20{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 20%, transparent) var(--tw-shadow-alpha), transparent)}}.ring-\[\#029AFF\]{--tw-ring-color:#029aff}.ring-\[\#161617\]{--tw-ring-color:#161617}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.outline-2{outline-style:var(--tw-outline-style);outline-width:2px}.outline-neutral-400{outline-color:var(--color-neutral-400)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.blur-md{--tw-blur:blur(var(--blur-md));filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-2xl{--tw-backdrop-blur:blur(var(--blur-2xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-\[cubic-bezier\(0\.23\,1\,0\.32\,1\)\]{--tw-ease:cubic-bezier(.23,1,.32,1);transition-timing-function:cubic-bezier(.23,1,.32,1)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:scale-110:is(:where(.group):hover *){--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}.group-hover\:bg-\[\#029AFF\]:is(:where(.group):hover *){background-color:#029aff}.group-hover\:text-\[\#10B981\]:is(:where(.group):hover *){color:#10b981}.group-hover\:text-gray-400:is(:where(.group):hover *){color:var(--color-gray-400)}.group-hover\:text-white:is(:where(.group):hover *){color:var(--color-white)}.group-hover\/title\:text-\[\#029AFF\]:is(:where(.group\/title):hover *){color:#029aff}.group-hover\/tooltip\:opacity-100:is(:where(.group\/tooltip):hover *){opacity:1}}.group-data-\[disabled\=true\]\:pointer-events-none:is(:where(.group)[data-disabled=true] *){pointer-events:none}.group-data-\[disabled\=true\]\:opacity-50:is(:where(.group)[data-disabled=true] *){opacity:.5}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-50:is(:where(.peer):disabled~*){opacity:.5}.selection\:bg-\[\#029AFF\]\/40 ::selection{background-color:oklab(67.1382% -.0668607 -.16985/.4)}.selection\:bg-\[\#029AFF\]\/40::selection{background-color:oklab(67.1382% -.0668607 -.16985/.4)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:top-0:after{content:var(--tw-content);top:calc(var(--spacing) * 0)}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:-translate-x-1\/2:after{content:var(--tw-content);--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.after\:-translate-y-full:after{content:var(--tw-content);--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.after\:border-4:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:4px}.after\:border-transparent:after{content:var(--tw-content);border-color:#0000}.after\:border-b-gray-900:after{content:var(--tw-content);border-bottom-color:var(--color-gray-900)}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}@media (hover:hover){.hover\:border-\[\#3e3e42\]:hover{border-color:#3e3e42}.hover\:border-\[\#10B981\]:hover{border-color:#10b981}.hover\:border-neutral-500:hover{border-color:var(--color-neutral-500)}.hover\:border-white\/5:hover{border-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.hover\:border-white\/5:hover{border-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.hover\:bg-\[\#10B981\]:hover{background-color:#10b981}.hover\:bg-\[\#029AFF\]:hover{background-color:#029aff}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-neutral-800:hover{background-color:var(--color-neutral-800)}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.hover\:bg-white\/10:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/10:hover{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.hover\:text-\[\#10B981\]\/50:hover{color:oklab(69.5873% -.142158 .0448781/.5)}.hover\:text-black:hover{color:var(--color-black)}.hover\:text-blue-400:hover{color:var(--color-blue-400)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-white:hover{color:var(--color-white)}.hover\:underline:hover{text-decoration-line:underline}.hover\:ring-4:hover{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-4:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-blue-500:focus-visible{--tw-ring-color:var(--color-blue-500)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:outline-hidden:focus-visible{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus-visible\:outline-hidden:focus-visible{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.active\:bg-white\/20:active{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.active\:bg-white\/20:active{background-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[inset\]\:pl-8[data-inset]{padding-left:calc(var(--spacing) * 8)}.data-\[orientation\=horizontal\]\:h-1\.5[data-orientation=horizontal]{height:calc(var(--spacing) * 1.5)}.data-\[orientation\=horizontal\]\:h-full[data-orientation=horizontal]{height:100%}.data-\[orientation\=horizontal\]\:w-full[data-orientation=horizontal]{width:100%}.data-\[orientation\=vertical\]\:h-full[data-orientation=vertical]{height:100%}.data-\[orientation\=vertical\]\:min-h-44[data-orientation=vertical]{min-height:calc(var(--spacing) * 44)}.data-\[orientation\=vertical\]\:w-1\.5[data-orientation=vertical]{width:calc(var(--spacing) * 1.5)}.data-\[orientation\=vertical\]\:w-auto[data-orientation=vertical]{width:auto}.data-\[orientation\=vertical\]\:w-full[data-orientation=vertical]{width:100%}.data-\[orientation\=vertical\]\:flex-col[data-orientation=vertical]{flex-direction:column}@media (min-width:48rem){.md\:bottom-6{bottom:calc(var(--spacing) * 6)}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-auto{width:auto}.md\:snap-none{scroll-snap-type:none}.md\:overflow-x-visible{overflow-x:visible}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.easyflow-whiteboard{isolation:isolate;--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(97% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(97% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(97% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.2% 0 0);--input:oklch(92.2% 0 0);--ring:oklch(70.8% 0 0);--chart-1:oklch(64.6% .222 41.116);--chart-2:oklch(60% .118 184.704);--chart-3:oklch(39.8% .07 227.392);--chart-4:oklch(82.8% .189 84.429);--chart-5:oklch(76.9% .188 70.08);--sidebar:oklch(98.5% 0 0);--sidebar-foreground:oklch(14.5% 0 0);--sidebar-primary:oklch(20.5% 0 0);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(97% 0 0);--sidebar-accent-foreground:oklch(20.5% 0 0);--sidebar-border:oklch(92.2% 0 0);--sidebar-ring:oklch(70.8% 0 0);--color-background:var(--background);--color-foreground:var(--foreground);--color-card:var(--card);--color-card-foreground:var(--card-foreground);--color-popover:var(--popover);--color-popover-foreground:var(--popover-foreground);--color-primary:var(--primary);--color-primary-foreground:var(--primary-foreground);--color-secondary:var(--secondary);--color-secondary-foreground:var(--secondary-foreground);--color-muted:var(--muted);--color-muted-foreground:var(--muted-foreground);--color-accent:var(--accent);--color-accent-foreground:var(--accent-foreground);--color-destructive:var(--destructive);--color-border:var(--border);--color-input:var(--input);--color-ring:var(--ring);--color-chart-1:var(--chart-1);--color-chart-2:var(--chart-2);--color-chart-3:var(--chart-3);--color-chart-4:var(--chart-4);--color-chart-5:var(--chart-5);--color-sidebar:var(--sidebar);--color-sidebar-foreground:var(--sidebar-foreground);--color-sidebar-primary:var(--sidebar-primary);--color-sidebar-primary-foreground:var(--sidebar-primary-foreground);--color-sidebar-accent:var(--sidebar-accent);--color-sidebar-accent-foreground:var(--sidebar-accent-foreground);--color-sidebar-border:var(--sidebar-border);--color-sidebar-ring:var(--sidebar-ring);--radius-sm:calc(var(--radius) - 4px);--radius-md:calc(var(--radius) - 2px);--radius-lg:var(--radius);--radius-xl:calc(var(--radius) + 4px);--radius-2xl:calc(var(--radius) + 8px);--radius-3xl:calc(var(--radius) + 12px);--radius-4xl:calc(var(--radius) + 16px);width:100%;height:100%;position:relative}.easyflow-whiteboard.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(20.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(20.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(92.2% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.6% 0 0);--chart-1:oklch(48.8% .243 264.376);--chart-2:oklch(69.6% .17 162.48);--chart-3:oklch(76.9% .188 70.08);--chart-4:oklch(62.7% .265 303.9);--chart-5:oklch(64.5% .246 16.439);--sidebar:oklch(20.5% 0 0);--sidebar-foreground:oklch(98.5% 0 0);--sidebar-primary:oklch(48.8% .243 264.376);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(26.9% 0 0);--sidebar-accent-foreground:oklch(98.5% 0 0);--sidebar-border:oklch(100% 0 0/.1);--sidebar-ring:oklch(55.6% 0 0)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-scroll-snap-strictness{syntax:"*";inherits:false;initial-value:proximity}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes pulse{50%{opacity:.5}}
|