@elixpo/lixsketch 5.5.12 → 5.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/react/{AIRenderer-PWWLWI6U.js → AIRenderer-ATIKGFB4.js} +90 -8
  2. package/dist/react/{AIRenderer-PWWLWI6U.js.map → AIRenderer-ATIKGFB4.js.map} +2 -2
  3. package/dist/react/{CopyPaste-SA72NDFN.js → CopyPaste-VUM5WRDX.js} +2 -2
  4. package/dist/react/FreehandStroke-JKTCTOKU.js +8 -0
  5. package/dist/react/{GraphEngine-IHRVGUGG.js → GraphEngine-KQXHNTZQ.js} +39 -1
  6. package/dist/react/{GraphEngine-IHRVGUGG.js.map → GraphEngine-KQXHNTZQ.js.map} +2 -2
  7. package/dist/react/{MermaidStructuredRenderer-GGOOGON5.js → MermaidStructuredRenderer-26WGA6YD.js} +152 -25
  8. package/dist/react/MermaidStructuredRenderer-26WGA6YD.js.map +7 -0
  9. package/dist/react/{SceneSerializer-ZPHV6IUP.js → SceneSerializer-3RWFYSLY.js} +2 -2
  10. package/dist/react/{SketchEngine-NPF2XN6Z.js → SketchEngine-WW5LIHNT.js} +6 -6
  11. package/dist/react/{chunk-YKJUBFHE.js → chunk-ABZEV54U.js} +23 -2
  12. package/dist/react/chunk-ABZEV54U.js.map +7 -0
  13. package/dist/react/index.js +26 -18
  14. package/dist/react/index.js.map +2 -2
  15. package/dist/react/styles.css +10 -3
  16. package/package.json +1 -1
  17. package/src/core/AIRenderer.js +104 -6
  18. package/src/core/GraphEngine.js +45 -0
  19. package/src/core/MermaidStructuredRenderer.js +162 -22
  20. package/src/react/LixSketchCanvas.jsx +4 -0
  21. package/src/react/components/AppMenu.jsx +2 -2
  22. package/src/react/components/Toolbar.jsx +1 -1
  23. package/src/react/components/modals/CommandPalette.jsx +3 -3
  24. package/src/react/components/sidebars/FrameSidebar.jsx +1 -1
  25. package/src/react/components/sidebars/IconSidebar.jsx +2 -2
  26. package/src/react/components/sidebars/ShapeSidebar.jsx +1 -1
  27. package/src/react/store/useSketchStore.js +7 -2
  28. package/src/react/store/useUIStore.js +3 -4
  29. package/src/react/styles.css +12 -3
  30. package/src/shapes/FreehandStroke.js +28 -3
  31. package/dist/react/FreehandStroke-CK24NUT3.js +0 -8
  32. package/dist/react/MermaidStructuredRenderer-GGOOGON5.js.map +0 -7
  33. package/dist/react/chunk-YKJUBFHE.js.map +0 -7
  34. /package/dist/react/{CopyPaste-SA72NDFN.js.map → CopyPaste-VUM5WRDX.js.map} +0 -0
  35. /package/dist/react/{FreehandStroke-CK24NUT3.js.map → FreehandStroke-JKTCTOKU.js.map} +0 -0
  36. /package/dist/react/{SceneSerializer-ZPHV6IUP.js.map → SceneSerializer-3RWFYSLY.js.map} +0 -0
  37. /package/dist/react/{SketchEngine-NPF2XN6Z.js.map → SketchEngine-WW5LIHNT.js.map} +0 -0
@@ -170,7 +170,7 @@ var SketchEngine = class {
170
170
  import("./ImageShape-CHHGBXUQ.js"),
171
171
  import("./IconShape-KMIA6T2H.js"),
172
172
  import("./Frame-6UR5XPAX.js"),
173
- import("./FreehandStroke-CK24NUT3.js")
173
+ import("./FreehandStroke-JKTCTOKU.js")
174
174
  ]);
175
175
  window.Rectangle = Rectangle;
176
176
  window.Circle = Circle;
@@ -243,7 +243,7 @@ var SketchEngine = class {
243
243
  import("./UndoRedo-M2JZUBKN.js"),
244
244
  import("./Selection-VVUHY5YJ.js"),
245
245
  import("./ZoomPan-NYPDJBD5.js"),
246
- import("./CopyPaste-SA72NDFN.js"),
246
+ import("./CopyPaste-VUM5WRDX.js"),
247
247
  import("./EraserTrail-PA6IQLQN.js"),
248
248
  import("./ResizeShapes-LKEQTITP.js"),
249
249
  import("./ResizeCode-WAMDTKSW.js")
@@ -262,7 +262,7 @@ var SketchEngine = class {
262
262
  eventDispatcher.initEventDispatcher(this.svg);
263
263
  }
264
264
  window.__sketchInteractionReady = true;
265
- const sceneSerializer = await import("./SceneSerializer-ZPHV6IUP.js");
265
+ const sceneSerializer = await import("./SceneSerializer-3RWFYSLY.js");
266
266
  if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
267
267
  await Promise.all([
268
268
  import("./eraserTool-2GS2LQCS.js"),
@@ -275,9 +275,9 @@ var SketchEngine = class {
275
275
  if (selection.multiSelection) window.multiSelection = selection.multiSelection;
276
276
  if (selection.clearAllSelections) window.clearAllSelections = selection.clearAllSelections;
277
277
  if (copyPaste.initCopyPaste) copyPaste.initCopyPaste();
278
- const aiRenderer = await import("./AIRenderer-PWWLWI6U.js");
278
+ const aiRenderer = await import("./AIRenderer-ATIKGFB4.js");
279
279
  if (aiRenderer.initAIRenderer) aiRenderer.initAIRenderer();
280
- const graphEngine = await import("./GraphEngine-IHRVGUGG.js");
280
+ const graphEngine = await import("./GraphEngine-KQXHNTZQ.js");
281
281
  if (graphEngine.initGraphEngine) graphEngine.initGraphEngine();
282
282
  const layerOrder = await import("./LayerOrder-XCHF4MSS.js");
283
283
  if (layerOrder.initLayerOrder) layerOrder.initLayerOrder();
@@ -414,4 +414,4 @@ export {
414
414
  SketchEngine,
415
415
  SketchEngine_default as default
416
416
  };
417
- //# sourceMappingURL=SketchEngine-NPF2XN6Z.js.map
417
+ //# sourceMappingURL=SketchEngine-WW5LIHNT.js.map
@@ -138,6 +138,10 @@ var FreehandStroke = class {
138
138
  // Enhanced path generation with better curve fitting
139
139
  getPathData() {
140
140
  if (this.points.length < 2) return "";
141
+ if (this.options.closedFill) {
142
+ const [first, ...rest] = this.points;
143
+ return [`M ${first[0]} ${first[1]}`, ...rest.map((point) => `L ${point[0]} ${point[1]}`), "Z"].join(" ");
144
+ }
141
145
  const isRough = this.options.roughness === "rough";
142
146
  const isMedium = this.options.roughness === "medium";
143
147
  let pts = this.points;
@@ -232,7 +236,12 @@ var FreehandStroke = class {
232
236
  path.setAttribute("d", pathData);
233
237
  path.setAttribute("fill", this.options.stroke);
234
238
  path.setAttribute("fill-opacity", this.options.strokeOpacity);
235
- path.setAttribute("stroke", "none");
239
+ path.setAttribute("stroke", this.options.closedFill ? this.options.outlineStroke || "none" : "none");
240
+ if (this.options.closedFill) {
241
+ path.setAttribute("stroke-width", this.options.outlineWidth || this.options.strokeWidth || 1);
242
+ path.setAttribute("stroke-linejoin", "round");
243
+ path.setAttribute("vector-effect", "non-scaling-stroke");
244
+ }
236
245
  if (this.options.strokeStyle === "dashed" || this.options.strokeStyle === "dotted") {
237
246
  const dashArray = this.options.strokeStyle === "dashed" ? `${this.options.strokeWidth * 3} ${this.options.strokeWidth * 2}` : `${this.options.strokeWidth * 0.5} ${this.options.strokeWidth * 2}`;
238
247
  const overlay = document.createElementNS("http://www.w3.org/2000/svg", "path");
@@ -332,6 +341,18 @@ var FreehandStroke = class {
332
341
  const angleRad = -this.rotation * Math.PI / 180;
333
342
  const rotatedX = dx * Math.cos(angleRad) - dy * Math.sin(angleRad) + centerX;
334
343
  const rotatedY = dx * Math.sin(angleRad) + dy * Math.cos(angleRad) + centerY;
344
+ if (this.options.closedFill && this.points.length >= 3) {
345
+ const localX = rotatedX - ox;
346
+ const localY = rotatedY - oy;
347
+ let inside = false;
348
+ for (let i = 0, j = this.points.length - 1; i < this.points.length; j = i++) {
349
+ const xi = this.points[i][0], yi = this.points[i][1];
350
+ const xj = this.points[j][0], yj = this.points[j][1];
351
+ const crosses = yi > localY !== yj > localY && localX < (xj - xi) * (localY - yi) / (yj - yi || Number.EPSILON) + xi;
352
+ if (crosses) inside = !inside;
353
+ }
354
+ return inside;
355
+ }
335
356
  return rotatedX >= bbX && rotatedX <= bbX + this.boundingBox.width && rotatedY >= bbY && rotatedY <= bbY + this.boundingBox.height;
336
357
  }
337
358
  isNearAnchor(x, y) {
@@ -572,4 +593,4 @@ var FreehandStroke = class {
572
593
  export {
573
594
  FreehandStroke
574
595
  };
575
- //# sourceMappingURL=chunk-YKJUBFHE.js.map
596
+ //# sourceMappingURL=chunk-ABZEV54U.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shapes/FreehandStroke.js"],
4
+ "sourcesContent": ["/* eslint-disable */\nimport { getStroke } from \"perfect-freehand\";\n// FreehandStroke shape class - extracted from canvasStroke.js\n// Depends on globals: svg, shapes, currentShape, currentZoom, currentViewBox\n\nfunction getSvgCoordinates(event) {\n const rect = svg.getBoundingClientRect();\n const scaleX = currentViewBox.width / rect.width;\n const scaleY = currentViewBox.height / rect.height;\n\n const svgX = currentViewBox.x + (event.clientX - rect.left) * scaleX;\n const svgY = currentViewBox.y + (event.clientY - rect.top) * scaleY;\n\n return { x: svgX, y: svgY };\n}\n\nfunction getSvgPathFromStroke(stroke) {\n if (!stroke.length) return '';\n \n // Use more sophisticated curve fitting\n const pathData = [];\n pathData.push('M', stroke[0][0], stroke[0][1]);\n \n for (let i = 1; i < stroke.length - 1; i++) {\n const curr = stroke[i];\n const next = stroke[i + 1];\n \n // Calculate control points for smoother curves\n const cpX = curr[0] + (next[0] - curr[0]) * 0.5;\n const cpY = curr[1] + (next[1] - curr[1]) * 0.5;\n \n pathData.push('Q', curr[0], curr[1], cpX, cpY);\n }\n \n // Add final point\n if (stroke.length > 1) {\n const lastPoint = stroke[stroke.length - 1];\n pathData.push('L', lastPoint[0], lastPoint[1]);\n }\n \n return pathData.join(' ');\n}\n\nclass FreehandStroke {\n constructor(points = [], options = {}) {\n this.points = points;\n this.rawPoints = []; \n this.options = {\n stroke: \"#fff\",\n strokeWidth: 3,\n fill: \"none\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n strokeOpacity: 1,\n thinning: 0.5,\n roughness: 0,\n strokeStyle: \"solid\",\n ...options\n };\n this.element = null;\n this.isSelected = false;\n this.rotation = 0;\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.anchors = [];\n this.rotationAnchor = null;\n this.rotationLine = null;\n this.selectionPadding = 8;\n this.selectionOutline = null;\n this.boundingBox = { x: 0, y: 0, width: 0, height: 0 };\n this.shapeName = \"freehandStroke\";\n this._moveOffsetX = 0;\n this._moveOffsetY = 0;\n\n // Frame attachment properties\n this.parentFrame = null;\n \n svg.appendChild(this.group);\n this.draw();\n }\n\n // Add position and dimension properties for frame compatibility\n // Getters include pending move offset so callers see the visual position\n get x() {\n return this.boundingBox.x + (this._moveOffsetX || 0);\n }\n\n set x(value) {\n const dx = value - this.boundingBox.x - (this._moveOffsetX || 0);\n this.points = this.points.map(point => [point[0] + dx, point[1], point[2] || 0.5]);\n this.boundingBox.x = value - (this._moveOffsetX || 0);\n }\n\n get y() {\n return this.boundingBox.y + (this._moveOffsetY || 0);\n }\n\n set y(value) {\n const dy = value - this.boundingBox.y - (this._moveOffsetY || 0);\n this.points = this.points.map(point => [point[0], point[1] + dy, point[2] || 0.5]);\n this.boundingBox.y = value - (this._moveOffsetY || 0);\n }\n \n get width() {\n return this.boundingBox.width;\n }\n \n set width(value) {\n if (this.boundingBox.width === 0) return;\n const scaleX = value / this.boundingBox.width;\n const centerX = this.boundingBox.x + this.boundingBox.width / 2;\n this.points = this.points.map(point => [\n centerX + (point[0] - centerX) * scaleX,\n point[1],\n point[2] || 0.5\n ]);\n this.boundingBox.width = value;\n }\n \n get height() {\n return this.boundingBox.height;\n }\n \n set height(value) {\n if (this.boundingBox.height === 0) return;\n const scaleY = value / this.boundingBox.height;\n const centerY = this.boundingBox.y + this.boundingBox.height / 2;\n this.points = this.points.map(point => [\n point[0],\n centerY + (point[1] - centerY) * scaleY,\n point[2] || 0.5\n ]);\n this.boundingBox.height = value;\n }\n\n // Enhanced smoothing algorithm\n smoothPoints(points, factor = 0.8) {\n if (points.length < 3) return points;\n \n const smoothed = [points[0]]; // Keep first point\n \n for (let i = 1; i < points.length - 1; i++) {\n const prev = points[i - 1];\n const curr = points[i];\n const next = points[i + 1];\n \n // Apply weighted average smoothing\n const smoothedX = curr[0] * (1 - factor) + (prev[0] + next[0]) * factor * 0.5;\n const smoothedY = curr[1] * (1 - factor) + (prev[1] + next[1]) * factor * 0.5;\n const pressure = curr[2] || 0.5;\n \n smoothed.push([smoothedX, smoothedY, pressure]);\n }\n \n smoothed.push(points[points.length - 1]); // Keep last point\n return smoothed;\n }\n\n // Interpolate points for smoother curves\n interpolatePoints(points, steps = 2) {\n if (points.length < 2) return points;\n \n const interpolated = [points[0]];\n \n for (let i = 0; i < points.length - 1; i++) {\n const curr = points[i];\n const next = points[i + 1];\n \n for (let j = 1; j <= steps; j++) {\n const t = j / (steps + 1);\n const x = curr[0] + (next[0] - curr[0]) * t;\n const y = curr[1] + (next[1] - curr[1]) * t;\n const pressure = curr[2] + (next[2] - curr[2]) * t;\n interpolated.push([x, y, pressure]);\n }\n \n if (i < points.length - 2) {\n interpolated.push(next);\n }\n }\n \n interpolated.push(points[points.length - 1]);\n return interpolated;\n }\n\n // Enhanced path generation with better curve fitting\n getPathData() {\n if (this.points.length < 2) return '';\n\n if (this.options.closedFill) {\n const [first, ...rest] = this.points;\n return [`M ${first[0]} ${first[1]}`, ...rest.map(point => `L ${point[0]} ${point[1]}`), 'Z'].join(' ');\n }\n\n const isRough = this.options.roughness === \"rough\";\n const isMedium = this.options.roughness === \"medium\";\n\n // Roughness: jitter points before smoothing\n let pts = this.points;\n if (isRough || isMedium) {\n const jitter = isRough ? 3.5 : 1.5;\n pts = pts.map((p, i) => {\n if (i === 0 || i === pts.length - 1) return p;\n return [\n p[0] + (Math.random() - 0.5) * jitter,\n p[1] + (Math.random() - 0.5) * jitter,\n p[2] || 0.5\n ];\n });\n }\n\n let smoothedPoints = this.interpolatePoints(pts, 1);\n if (!isRough) {\n smoothedPoints = this.smoothPoints(smoothedPoints, 0.6);\n smoothedPoints = this.smoothPoints(smoothedPoints, 0.4);\n }\n\n const thinning = this.options.thinning !== undefined ? this.options.thinning : 0;\n const smoothing = isRough ? 0.3 : isMedium ? 0.6 : 0.9;\n const streamline = isRough ? 0.1 : isMedium ? 0.25 : 0.4;\n\n const stroke = getStroke(smoothedPoints, {\n size: this.options.strokeWidth,\n thinning: thinning,\n smoothing: smoothing,\n streamline: streamline,\n easing: (t) => Math.sin(t * Math.PI * 0.5),\n start: {\n taper: thinning > 0 ? this.options.strokeWidth * 2 : 0,\n easing: (t) => t * t,\n cap: thinning === 0\n },\n end: {\n taper: thinning > 0 ? this.options.strokeWidth * 2 : 0,\n easing: (t) => --t * t * t + 1,\n cap: thinning === 0\n },\n simulatePressure: thinning > 0\n });\n\n return getSvgPathFromStroke(stroke);\n }\n\n // Simple centerline path used for dashed/dotted overlays\n getCenterlinePathData() {\n if (this.points.length < 2) return '';\n const d = [`M ${this.points[0][0]} ${this.points[0][1]}`];\n for (let i = 1; i < this.points.length - 1; i++) {\n const curr = this.points[i];\n const next = this.points[i + 1];\n const cpX = curr[0] + (next[0] - curr[0]) * 0.5;\n const cpY = curr[1] + (next[1] - curr[1]) * 0.5;\n d.push(`Q ${curr[0]} ${curr[1]} ${cpX} ${cpY}`);\n }\n const last = this.points[this.points.length - 1];\n d.push(`L ${last[0]} ${last[1]}`);\n return d.join(' ');\n }\n\n // Calculate the bounding box of the stroke\n calculateBoundingBox() {\n if (this.points.length === 0) {\n return { x: 0, y: 0, width: 0, height: 0 };\n }\n \n let minX = Infinity, minY = Infinity;\n let maxX = -Infinity, maxY = -Infinity;\n \n this.points.forEach(point => {\n minX = Math.min(minX, point[0]);\n minY = Math.min(minY, point[1]);\n maxX = Math.max(maxX, point[0]);\n maxY = Math.max(maxY, point[1]);\n });\n \n // Ensure we have valid dimensions\n if (minX === Infinity || minY === Infinity) {\n return { x: 0, y: 0, width: 0, height: 0 };\n }\n \n // Add padding for stroke width\n const padding = this.options.strokeWidth / 2;\n return {\n x: minX - padding,\n y: minY - padding,\n width: Math.max(0, (maxX - minX) + padding * 2),\n height: Math.max(0, (maxY - minY) + padding * 2)\n };\n }\n\n draw() {\n while (this.group.firstChild) {\n this.group.removeChild(this.group.firstChild);\n }\n\n if (this.selectionOutline && this.selectionOutline.parentNode === this.group) {\n this.group.removeChild(this.selectionOutline);\n this.selectionOutline = null;\n }\n\n // Normal freehand paths use the filled outline from perfect-freehand.\n // Closed-fill paths (pie sectors, polygons) use their actual polygon\n // geometry with a separate outline, preserving sharp radial edges.\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n const pathData = this.getPathData();\n path.setAttribute('d', pathData);\n path.setAttribute('fill', this.options.stroke);\n path.setAttribute('fill-opacity', this.options.strokeOpacity);\n path.setAttribute('stroke', this.options.closedFill ? (this.options.outlineStroke || 'none') : 'none');\n if (this.options.closedFill) {\n path.setAttribute('stroke-width', this.options.outlineWidth || this.options.strokeWidth || 1);\n path.setAttribute('stroke-linejoin', 'round');\n path.setAttribute('vector-effect', 'non-scaling-stroke');\n }\n\n // Overlay a dashed/dotted centerline if needed\n if (this.options.strokeStyle === \"dashed\" || this.options.strokeStyle === \"dotted\") {\n const dashArray = this.options.strokeStyle === \"dashed\"\n ? `${this.options.strokeWidth * 3} ${this.options.strokeWidth * 2}`\n : `${this.options.strokeWidth * 0.5} ${this.options.strokeWidth * 2}`;\n const overlay = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n overlay.setAttribute('d', this.getCenterlinePathData());\n overlay.setAttribute('fill', 'none');\n overlay.setAttribute('stroke', this.options.stroke);\n overlay.setAttribute('stroke-width', this.options.strokeWidth);\n overlay.setAttribute('stroke-linecap', 'round');\n overlay.setAttribute('stroke-linejoin', 'round');\n overlay.setAttribute('stroke-dasharray', dashArray);\n overlay.setAttribute('stroke-opacity', this.options.strokeOpacity);\n this.group.appendChild(overlay);\n }\n\n this.element = path;\n this.group.appendChild(path);\n\n // Calculate and store bounding box\n this.boundingBox = this.calculateBoundingBox();\n\n // Apply rotation\n const centerX = this.boundingBox.x + this.boundingBox.width / 2;\n const centerY = this.boundingBox.y + this.boundingBox.height / 2;\n\n // Ensure centerX and centerY are valid numbers\n if (!isNaN(centerX) && !isNaN(centerY)) {\n this.group.setAttribute('transform', `rotate(${this.rotation} ${centerX} ${centerY})`);\n }\n\n if (this.isSelected) {\n this.addAnchors();\n }\n }\n\n move(dx, dy) {\n // Accumulate offset for transform-based movement (avoids full path rebuild)\n this._moveOffsetX = (this._moveOffsetX || 0) + dx;\n this._moveOffsetY = (this._moveOffsetY || 0) + dy;\n const centerX = this.boundingBox.x + this.boundingBox.width / 2;\n const centerY = this.boundingBox.y + this.boundingBox.height / 2;\n const rot = this.rotation ? `rotate(${this.rotation} ${centerX} ${centerY})` : '';\n this.group.setAttribute('transform', `translate(${this._moveOffsetX}, ${this._moveOffsetY}) ${rot}`);\n }\n\n // Call after drag ends to bake the offset into actual point coordinates\n finalizeMove() {\n if (this._moveOffsetX || this._moveOffsetY) {\n const ox = this._moveOffsetX || 0;\n const oy = this._moveOffsetY || 0;\n this.points = this.points.map(point => [point[0] + ox, point[1] + oy, point[2] || 0.5]);\n this._moveOffsetX = 0;\n this._moveOffsetY = 0;\n this.draw();\n }\n }\n\n updateAttachedArrows() {\n if (typeof window.__updateArrowsForShape === 'function') {\n window.__updateArrowsForShape(this);\n }\n }\n\n selectStroke() {\n this.isSelected = true;\n this.draw();\n // Show sidebar and update it with current stroke properties\n disableAllSideBars();\n paintBrushSideBar.classList.remove(\"hidden\");\n if (window.__showSidebarForShape) window.__showSidebarForShape('freehandStroke');\n this.updateSidebar();\n }\n\n deselectStroke() {\n this.isSelected = false;\n this.anchors = [];\n this.rotationAnchor = null;\n this.draw();\n }\n\n removeSelection() {\n this.anchors.forEach(anchor => {\n if (anchor.parentNode === this.group) {\n this.group.removeChild(anchor);\n }\n });\n if (this.rotationAnchor && this.rotationAnchor.parentNode === this.group) {\n this.group.removeChild(this.rotationAnchor);\n }\n if (this.rotationLine && this.rotationLine.parentNode === this.group) {\n this.group.removeChild(this.rotationLine);\n }\n if (this.selectionOutline && this.selectionOutline.parentNode === this.group) {\n this.group.removeChild(this.selectionOutline);\n }\n this.anchors = [];\n this.rotationAnchor = null;\n this.rotationLine = null;\n this.selectionOutline = null;\n this.isSelected = false;\n }\n\n // No-op: React sidebar handles UI updates via Zustand store\n updateSidebar() {}\n\n contains(x, y) {\n // Account for pending move offset (during drag, points aren't updated yet)\n const ox = this._moveOffsetX || 0;\n const oy = this._moveOffsetY || 0;\n const bbX = this.boundingBox.x + ox;\n const bbY = this.boundingBox.y + oy;\n const centerX = bbX + this.boundingBox.width / 2;\n const centerY = bbY + this.boundingBox.height / 2;\n\n // Adjust for rotation\n const dx = x - centerX;\n const dy = y - centerY;\n\n const angleRad = -this.rotation * Math.PI / 180;\n const rotatedX = dx * Math.cos(angleRad) - dy * Math.sin(angleRad) + centerX;\n const rotatedY = dx * Math.sin(angleRad) + dy * Math.cos(angleRad) + centerY;\n\n if (this.options.closedFill && this.points.length >= 3) {\n const localX = rotatedX - ox;\n const localY = rotatedY - oy;\n let inside = false;\n for (let i = 0, j = this.points.length - 1; i < this.points.length; j = i++) {\n const xi = this.points[i][0], yi = this.points[i][1];\n const xj = this.points[j][0], yj = this.points[j][1];\n const crosses = ((yi > localY) !== (yj > localY))\n && (localX < (xj - xi) * (localY - yi) / ((yj - yi) || Number.EPSILON) + xi);\n if (crosses) inside = !inside;\n }\n return inside;\n }\n\n return rotatedX >= bbX &&\n rotatedX <= bbX + this.boundingBox.width &&\n rotatedY >= bbY &&\n rotatedY <= bbY + this.boundingBox.height;\n }\n\n isNearAnchor(x, y) {\n if (!this.isSelected) return null;\n const buffer = 10;\n const anchorSize = 10 / currentZoom;\n\n // Account for pending move offset\n const ox = this._moveOffsetX || 0;\n const oy = this._moveOffsetY || 0;\n\n // Transform the input coordinates to account for rotation\n const centerX = this.boundingBox.x + ox + this.boundingBox.width / 2;\n const centerY = this.boundingBox.y + oy + this.boundingBox.height / 2;\n\n // Rotate the mouse coordinates to the shape's local coordinate system\n const angleRad = -this.rotation * Math.PI / 180;\n const dx = x - centerX;\n const dy = y - centerY;\n const localX = dx * Math.cos(angleRad) - dy * Math.sin(angleRad) + centerX;\n const localY = dx * Math.sin(angleRad) + dy * Math.cos(angleRad) + centerY;\n\n // Check resize anchors in local space\n const expandedX = this.boundingBox.x + ox - this.selectionPadding;\n const expandedY = this.boundingBox.y + oy - this.selectionPadding;\n const expandedWidth = this.boundingBox.width + 2 * this.selectionPadding;\n const expandedHeight = this.boundingBox.height + 2 * this.selectionPadding;\n \n const anchorPositions = [\n { x: expandedX, y: expandedY }, // top-left\n { x: expandedX + expandedWidth, y: expandedY }, // top-right\n { x: expandedX, y: expandedY + expandedHeight }, // bottom-left\n { x: expandedX + expandedWidth, y: expandedY + expandedHeight }, // bottom-right\n { x: expandedX + expandedWidth / 2, y: expandedY }, // top-center\n { x: expandedX + expandedWidth / 2, y: expandedY + expandedHeight }, // bottom-center\n { x: expandedX, y: expandedY + expandedHeight / 2 }, // left-center\n { x: expandedX + expandedWidth, y: expandedY + expandedHeight / 2 } // right-center\n ];\n\n for (let i = 0; i < anchorPositions.length; i++) {\n const anchor = anchorPositions[i];\n const distance = Math.sqrt(Math.pow(localX - anchor.x, 2) + Math.pow(localY - anchor.y, 2));\n if (distance <= anchorSize / 2 + buffer) {\n return { type: 'resize', index: i };\n }\n }\n \n // Check rotation anchor (this one stays in world coordinates)\n if (this.rotationAnchor) {\n const rotationX = parseFloat(this.rotationAnchor.getAttribute('cx'));\n const rotationY = parseFloat(this.rotationAnchor.getAttribute('cy'));\n const distance = Math.sqrt(Math.pow(x - rotationX, 2) + Math.pow(y - rotationY, 2));\n if (distance <= anchorSize / 2 + buffer) {\n return { type: 'rotate' };\n }\n }\n \n return null;\n}\n\n rotate(angle) {\n this.rotation = angle;\n // If anchors exist, update their cursors for the new rotation\n if (this.isSelected && this.anchors.length > 0) {\n const cursors = ['nw-resize', 'ne-resize', 'sw-resize', 'se-resize', 'n-resize', 's-resize', 'w-resize', 'e-resize'];\n this.anchors.forEach((anchor, i) => {\n if (anchor) {\n const originalCursor = cursors[i];\n const rotatedCursor = this.getRotatedCursor(originalCursor, this.rotation);\n anchor.style.cursor = rotatedCursor;\n }\n });\n }\n}\n\n addAnchors() {\n const anchorSize = 10 / currentZoom;\n const anchorStrokeWidth = 2 / currentZoom;\n \n const expandedX = this.boundingBox.x - this.selectionPadding;\n const expandedY = this.boundingBox.y - this.selectionPadding;\n const expandedWidth = this.boundingBox.width + 2 * this.selectionPadding;\n const expandedHeight = this.boundingBox.height + 2 * this.selectionPadding;\n \n const positions = [\n { x: expandedX, y: expandedY, cursor: 'nw-resize' }, // top-left\n { x: expandedX + expandedWidth, y: expandedY, cursor: 'ne-resize' }, // top-right\n { x: expandedX, y: expandedY + expandedHeight, cursor: 'sw-resize' }, // bottom-left\n { x: expandedX + expandedWidth, y: expandedY + expandedHeight, cursor: 'se-resize' }, // bottom-right\n { x: expandedX + expandedWidth / 2, y: expandedY, cursor: 'n-resize' }, // top-center\n { x: expandedX + expandedWidth / 2, y: expandedY + expandedHeight, cursor: 's-resize' }, // bottom-center\n { x: expandedX, y: expandedY + expandedHeight / 2, cursor: 'w-resize' }, // left-center\n { x: expandedX + expandedWidth, y: expandedY + expandedHeight / 2, cursor: 'e-resize' } // right-center\n ];\n \n // Create resize anchors\n positions.forEach((pos, i) => {\n const anchor = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n anchor.setAttribute('x', pos.x - anchorSize / 2);\n anchor.setAttribute('y', pos.y - anchorSize / 2);\n anchor.setAttribute('width', anchorSize);\n anchor.setAttribute('height', anchorSize);\n anchor.setAttribute('class', 'anchor');\n anchor.setAttribute('data-index', i);\n anchor.setAttribute('fill', '#121212');\n anchor.setAttribute('stroke', '#5B57D1');\n anchor.setAttribute('stroke-width', anchorStrokeWidth);\n anchor.setAttribute('vector-effect', 'non-scaling-stroke');\n\n // Set proper cursor for each anchor direction, accounting for rotation\n const rotatedCursor = this.getRotatedCursor(pos.cursor, this.rotation);\n anchor.style.cursor = rotatedCursor;\n anchor.style.pointerEvents = 'all';\n \n this.group.appendChild(anchor);\n this.anchors[i] = anchor;\n });\n\n // Create rotation anchor\n const rotationAnchorDistance = 30 / currentZoom;\n const rotationX = expandedX + expandedWidth / 2;\n const rotationY = expandedY - rotationAnchorDistance;\n \n const rotationAnchor = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n rotationAnchor.setAttribute('cx', rotationX);\n rotationAnchor.setAttribute('cy', rotationY);\n rotationAnchor.setAttribute('r', anchorSize / 2);\n rotationAnchor.setAttribute('fill', '#121212');\n rotationAnchor.setAttribute('stroke', '#5B57D1');\n rotationAnchor.setAttribute('stroke-width', anchorStrokeWidth);\n rotationAnchor.setAttribute('vector-effect', 'non-scaling-stroke');\n rotationAnchor.setAttribute('class', 'rotation-anchor');\n rotationAnchor.style.cursor = 'grab';\n rotationAnchor.style.pointerEvents = 'all';\n \n this.group.appendChild(rotationAnchor);\n this.rotationAnchor = rotationAnchor;\n\n // Create selection outline\n const outlinePoints = [\n [expandedX, expandedY],\n [expandedX + expandedWidth, expandedY],\n [expandedX + expandedWidth, expandedY + expandedHeight],\n [expandedX, expandedY + expandedHeight],\n [expandedX, expandedY]\n ];\n \n const outline = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');\n outline.setAttribute('points', outlinePoints.map(p => p.join(',')).join(' '));\n outline.setAttribute('fill', 'none');\n outline.setAttribute('stroke', '#5B57D1');\n outline.setAttribute('stroke-width', 1.5);\n outline.setAttribute('vector-effect', 'non-scaling-stroke');\n outline.setAttribute('stroke-dasharray', '4 2');\n outline.setAttribute('style', 'pointer-events: none;');\n this.group.appendChild(outline);\n this.selectionOutline = outline;\n\n // Add line from rotation anchor to shape\n const rotationLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n rotationLine.setAttribute('x1', rotationX);\n rotationLine.setAttribute('y1', rotationY);\n rotationLine.setAttribute('x2', expandedX + expandedWidth / 2);\n rotationLine.setAttribute('y2', expandedY);\n rotationLine.setAttribute('stroke', '#5B57D1');\n rotationLine.setAttribute('stroke-width', 1);\n rotationLine.setAttribute('vector-effect', 'non-scaling-stroke');\n rotationLine.setAttribute('stroke-dasharray', '2 2');\n rotationLine.setAttribute('style', 'pointer-events: none;');\n this.group.appendChild(rotationLine);\n this.rotationLine = rotationLine;\n\n // Show sidebar when anchors are added (when shape is selected)\n disableAllSideBars();\n paintBrushSideBar.classList.remove(\"hidden\");\n if (window.__showSidebarForShape) window.__showSidebarForShape('freehandStroke');\n this.updateSidebar();\n}\n\ngetRotatedCursor(direction, angle) {\n // Normalize angle to 0-360\n const normalizedAngle = ((angle % 360) + 360) % 360;\n \n // Map of cursor directions\n const cursors = ['n-resize', 'ne-resize', 'e-resize', 'se-resize', 's-resize', 'sw-resize', 'w-resize', 'nw-resize'];\n const directionMap = {\n 'n-resize': 0,\n 'ne-resize': 1,\n 'e-resize': 2,\n 'se-resize': 3,\n 's-resize': 4,\n 'sw-resize': 5,\n 'w-resize': 6,\n 'nw-resize': 7\n };\n \n if (!(direction in directionMap)) return direction;\n \n // Calculate how many 45-degree increments to rotate\n const rotationSteps = Math.round(normalizedAngle / 45);\n const currentIndex = directionMap[direction];\n const newIndex = (currentIndex + rotationSteps) % 8;\n \n return cursors[newIndex];\n}\n\n updatePosition(anchorIndex, newX, newY) {\n const centerX = this.boundingBox.x + this.boundingBox.width / 2;\n const centerY = this.boundingBox.y + this.boundingBox.height / 2;\n \n // Transform new coordinates to local space (accounting for rotation)\n const angleRad = -this.rotation * Math.PI / 180;\n const dx = newX - centerX;\n const dy = newY - centerY;\n const localX = dx * Math.cos(angleRad) - dy * Math.sin(angleRad) + centerX;\n const localY = dx * Math.sin(angleRad) + dy * Math.cos(angleRad) + centerY;\n \n // Calculate scale factors based on anchor movement in local space\n const expandedX = this.boundingBox.x - this.selectionPadding;\n const expandedY = this.boundingBox.y - this.selectionPadding;\n const expandedWidth = this.boundingBox.width + 2 * this.selectionPadding;\n const expandedHeight = this.boundingBox.height + 2 * this.selectionPadding;\n \n let scaleX = 1, scaleY = 1;\n switch(anchorIndex) {\n case 0: // top-left\n scaleX = (centerX - localX) / (centerX - expandedX);\n scaleY = (centerY - localY) / (centerY - expandedY);\n break;\n case 1: // top-right\n scaleX = (localX - centerX) / (expandedX + expandedWidth - centerX);\n scaleY = (centerY - localY) / (centerY - expandedY);\n break;\n case 2: // bottom-left\n scaleX = (centerX - localX) / (centerX - expandedX);\n scaleY = (localY - centerY) / (expandedY + expandedHeight - centerY);\n break;\n case 3: // bottom-right\n scaleX = (localX - centerX) / (expandedX + expandedWidth - centerX);\n scaleY = (localY - centerY) / (expandedY + expandedHeight - centerY);\n break;\n case 4: // top-center\n scaleY = (centerY - localY) / (centerY - expandedY);\n break;\n case 5: // bottom-center\n scaleY = (localY - centerY) / (expandedY + expandedHeight - centerY);\n break;\n case 6: // left-center\n scaleX = (centerX - localX) / (centerX - expandedX);\n break;\n case 7: // right-center\n scaleX = (localX - centerX) / (expandedX + expandedWidth - centerX);\n break;\n }\n \n // Prevent negative scaling\n scaleX = Math.max(0.1, Math.abs(scaleX));\n scaleY = Math.max(0.1, Math.abs(scaleY));\n \n // Apply scaling to all points relative to center\n this.points = this.points.map(point => {\n const relX = point[0] - centerX;\n const relY = point[1] - centerY;\n return [\n centerX + relX * scaleX,\n centerY + relY * scaleY,\n point[2] || 0.5\n ];\n });\n \n this.draw();\n}\n}\n\nexport { FreehandStroke };\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -156,8 +156,13 @@ var useSketchStore = create((set, get) => ({
156
156
  setIsPanning: (v) => set({ isPanning: v }),
157
157
  setPanStart: (p) => set({ panStart: p }),
158
158
  // --- Canvas background ---
159
- canvasBackground: "var(--lixsketch-bg, #ffffff)",
160
- setCanvasBackground: (color) => set({ canvasBackground: color }),
159
+ canvasBackground: "var(--lixsketch-bg, #15111f)",
160
+ setCanvasBackground: (color) => {
161
+ set({ canvasBackground: color });
162
+ if (typeof window !== "undefined") {
163
+ requestAnimationFrame(() => window.__adaptCanvasContrast?.(color));
164
+ }
165
+ },
161
166
  // --- Grid ---
162
167
  gridEnabled: false,
163
168
  toggleGrid: () => set((s) => ({ gridEnabled: !s.gridEnabled })),
@@ -254,9 +259,9 @@ function applyTheme(theme) {
254
259
  if (!body) return;
255
260
  const resolved = theme === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : theme;
256
261
  body.classList.remove("theme-dark", "theme-light");
257
- if (resolved === "dark") body.classList.add("theme-dark");
262
+ body.classList.add(`theme-${resolved}`);
258
263
  const svgEl = window.svg;
259
- if (svgEl) svgEl.style.background = resolved === "light" ? "#f4f3ee" : "";
264
+ if (svgEl) svgEl.style.background = resolved === "light" ? "#fbf9fd" : "#15111f";
260
265
  }
261
266
  var useUIStore = create2((set, get) => ({
262
267
  // --- Modals ---
@@ -330,8 +335,7 @@ var useUIStore = create2((set, get) => ({
330
335
  canvasLoadingMessage: "Loading canvas...",
331
336
  setCanvasLoading: (loading, message) => set({ canvasLoading: loading, canvasLoadingMessage: message || "Loading canvas..." }),
332
337
  // --- Theme ---
333
- // Issue #38 bug #1: light by default. Dark stays available via toggle.
334
- theme: "light",
338
+ theme: "dark",
335
339
  setTheme: (newTheme) => {
336
340
  const prev = get().theme;
337
341
  const resolve = (t) => t === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : t;
@@ -427,7 +431,7 @@ function useSketchEngine(svgRef, ready = true) {
427
431
  setZoom: (zoom) => useSketchStore_default.setState({ zoom }),
428
432
  getState: () => useSketchStore_default.getState()
429
433
  };
430
- const { SketchEngine } = await import("./SketchEngine-NPF2XN6Z.js");
434
+ const { SketchEngine } = await import("./SketchEngine-WW5LIHNT.js");
431
435
  if (cancelled) return;
432
436
  const engine = new SketchEngine(svgRef.current);
433
437
  await engine.init();
@@ -692,7 +696,7 @@ function Toolbar() {
692
696
  {
693
697
  title: item.title,
694
698
  onClick: () => setActiveTool(item.tool),
695
- className: `relative w-[33px] h-[31px] flex items-center justify-center rounded-lg transition-all duration-200 ${isActive ? "bg-surface-active text-text-primary" : "text-text-muted hover:text-text-primary hover:bg-surface-hover"}`,
699
+ className: `relative w-[33px] h-[31px] flex items-center justify-center rounded-lg transition-all duration-200 ${isActive ? "bg-accent-blue/20 text-accent-blue" : "text-text-muted hover:text-text-primary hover:bg-surface-hover"}`,
696
700
  children: [
697
701
  /* @__PURE__ */ jsx2(
698
702
  "i",
@@ -897,7 +901,7 @@ function useTranslation() {
897
901
  import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
898
902
  var CANVAS_BACKGROUNDS_LIGHT = [
899
903
  { color: "#ffffff", label: "menu.canvasBg.white" },
900
- { color: "#faf9f5", label: "menu.canvasBg.cream" },
904
+ { color: "#fbf9fd", label: "menu.canvasBg.cream" },
901
905
  { color: "#f5f3ed", label: "menu.canvasBg.paper" },
902
906
  { color: "#f0f5fb", label: "menu.canvasBg.skyTint" },
903
907
  { color: "#f0f5ef", label: "menu.canvasBg.sageTint" }
@@ -905,7 +909,7 @@ var CANVAS_BACKGROUNDS_LIGHT = [
905
909
  var CANVAS_BACKGROUNDS_DARK = [
906
910
  { color: "#000000", label: "menu.canvasBg.black" },
907
911
  { color: "#161718", label: "menu.canvasBg.darkGray" },
908
- { color: "#13171C", label: "menu.canvasBg.blueBlack" },
912
+ { color: "#15111f", label: "menu.canvasBg.blueBlack" },
909
913
  { color: "#181605", label: "menu.canvasBg.darkYellow" },
910
914
  { color: "#1B1615", label: "menu.canvasBg.darkBrown" }
911
915
  ];
@@ -1376,7 +1380,7 @@ function ToolbarButton({ icon, preview, children, tooltip }) {
1376
1380
  {
1377
1381
  onClick: () => setOpen(!open),
1378
1382
  title: tooltip,
1379
- className: `h-9 flex items-center gap-1.5 px-3 rounded-lg transition-all duration-100 ${open ? "bg-surface-active text-text-primary" : "text-text-muted hover:text-text-primary hover:bg-surface-hover"}`,
1383
+ className: `h-9 flex items-center gap-1.5 px-3 rounded-lg transition-all duration-100 ${open ? "bg-accent-blue/20 text-accent-blue" : "text-text-muted hover:text-text-primary hover:bg-surface-hover"}`,
1380
1384
  children: [
1381
1385
  preview || icon && /* @__PURE__ */ jsx5("i", { className: `bx ${icon} text-base` }),
1382
1386
  /* @__PURE__ */ jsx5("svg", { className: `w-2 h-2 opacity-40 transition-transform duration-100 ${open ? "rotate-180" : ""}`, viewBox: "0 0 8 5", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ jsx5("path", { d: "M1 1l3 3 3-3" }) })
@@ -2310,7 +2314,7 @@ var FILL_STYLES = [
2310
2314
  ];
2311
2315
  var FILL_COLORS = [
2312
2316
  "#1e1e28",
2313
- "#13171C",
2317
+ "#15111f",
2314
2318
  "#1a1a2e",
2315
2319
  "#0d1117",
2316
2320
  "#2d2d3a",
@@ -2579,7 +2583,7 @@ function IconCell({ icon, onClick }) {
2579
2583
  children: normalizedSvg ? /* @__PURE__ */ jsx13(
2580
2584
  "div",
2581
2585
  {
2582
- style: { width: "24px", height: "24px", overflow: "visible", flexShrink: 0, pointerEvents: "none", filter: "brightness(0) invert(1)" },
2586
+ style: { width: "24px", height: "24px", overflow: "visible", flexShrink: 0, pointerEvents: "none", filter: "var(--lix-icon-filter, brightness(0) invert(1))" },
2583
2587
  dangerouslySetInnerHTML: { __html: normalizedSvg }
2584
2588
  }
2585
2589
  ) : /* @__PURE__ */ jsx13(
@@ -2587,7 +2591,7 @@ function IconCell({ icon, onClick }) {
2587
2591
  {
2588
2592
  src: `/icons/${encodeURIComponent(icon.filename)}`,
2589
2593
  alt: "",
2590
- style: { width: "24px", height: "24px", pointerEvents: "none", filter: "invert(1)" },
2594
+ style: { width: "24px", height: "24px", pointerEvents: "none", filter: "var(--lix-icon-filter, brightness(0) invert(1))" },
2591
2595
  loading: "lazy"
2592
2596
  }
2593
2597
  )
@@ -3988,14 +3992,14 @@ function CommandPalette() {
3988
3992
  return /* @__PURE__ */ jsxs21(
3989
3993
  "div",
3990
3994
  {
3991
- className: "fixed inset-0 z-[9999] flex items-start justify-center pt-[12vh] font-[lixFont]",
3995
+ className: "fixed inset-0 z-[9999] flex items-center justify-center font-[lixFont]",
3992
3996
  onClick: toggleCommandPalette,
3993
3997
  children: [
3994
3998
  /* @__PURE__ */ jsx21("div", { className: "absolute inset-0 bg-black/60 backdrop-blur-sm" }),
3995
3999
  /* @__PURE__ */ jsxs21(
3996
4000
  "div",
3997
4001
  {
3998
- className: "relative bg-surface-card border border-border-light rounded-2xl w-full max-w-[540px] mx-4 overflow-hidden",
4002
+ className: "relative bg-surface-card border border-border-light rounded-2xl w-[92vw] max-w-[1200px] h-[88vh] max-h-[88vh] mx-4 overflow-hidden flex flex-col",
3999
4003
  onClick: (e) => e.stopPropagation(),
4000
4004
  children: [
4001
4005
  /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-border-light", children: [
@@ -4013,7 +4017,7 @@ function CommandPalette() {
4013
4017
  }
4014
4018
  )
4015
4019
  ] }),
4016
- /* @__PURE__ */ jsxs21("div", { ref: listRef, className: "max-h-[55vh] overflow-y-auto no-scrollbar py-2", children: [
4020
+ /* @__PURE__ */ jsxs21("div", { ref: listRef, className: "flex-1 min-h-0 overflow-y-auto no-scrollbar py-2", children: [
4017
4021
  filtered.length === 0 && /* @__PURE__ */ jsx21("div", { className: "px-4 py-6 text-center text-text-dim text-xs", children: "No commands found" }),
4018
4022
  sectionOrder.map((section) => /* @__PURE__ */ jsxs21("div", { children: [
4019
4023
  /* @__PURE__ */ jsx21("div", { className: "px-4 pt-3 pb-1", children: /* @__PURE__ */ jsx21("span", { className: "text-text-dim text-xs uppercase tracking-wider", children: section }) }),
@@ -4737,7 +4741,7 @@ var _saveScene = null;
4737
4741
  var _loadScene = null;
4738
4742
  async function ensureSceneSerializer() {
4739
4743
  if (_saveScene && _loadScene) return;
4740
- const m = await import("./SceneSerializer-ZPHV6IUP.js");
4744
+ const m = await import("./SceneSerializer-3RWFYSLY.js");
4741
4745
  _saveScene = m.saveScene;
4742
4746
  _loadScene = m.loadScene;
4743
4747
  }
@@ -4795,6 +4799,10 @@ function LixSketchCanvas({
4795
4799
  }, [initialScene, bootstrapped]);
4796
4800
  useEffect15(() => {
4797
4801
  function handleKey(e) {
4802
+ if (e.key === "Escape") {
4803
+ useUIStore_default.getState().closeAllModals?.();
4804
+ return;
4805
+ }
4798
4806
  if (!(e.ctrlKey || e.metaKey)) return;
4799
4807
  const key = (e.key || "").toLowerCase();
4800
4808
  if (key !== "s" || e.shiftKey) return;