@elixpo/lixsketch 5.5.11 → 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 (45) 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 +55 -47
  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/canvas/FindBar.jsx +1 -1
  24. package/src/react/components/modals/CanvasPropertiesModal.jsx +1 -1
  25. package/src/react/components/modals/CommandPalette.jsx +3 -3
  26. package/src/react/components/sidebars/ArrowSidebar.jsx +6 -6
  27. package/src/react/components/sidebars/CircleSidebar.jsx +3 -3
  28. package/src/react/components/sidebars/FrameSidebar.jsx +2 -2
  29. package/src/react/components/sidebars/IconSidebar.jsx +2 -2
  30. package/src/react/components/sidebars/LineSidebar.jsx +4 -4
  31. package/src/react/components/sidebars/PaintbrushSidebar.jsx +5 -5
  32. package/src/react/components/sidebars/RectangleSidebar.jsx +4 -4
  33. package/src/react/components/sidebars/ShapeSidebar.jsx +1 -1
  34. package/src/react/components/sidebars/TextSidebar.jsx +5 -5
  35. package/src/react/store/useSketchStore.js +7 -2
  36. package/src/react/store/useUIStore.js +3 -4
  37. package/src/react/styles.css +12 -3
  38. package/src/shapes/FreehandStroke.js +28 -3
  39. package/dist/react/FreehandStroke-CK24NUT3.js +0 -8
  40. package/dist/react/MermaidStructuredRenderer-GGOOGON5.js.map +0 -7
  41. package/dist/react/chunk-YKJUBFHE.js.map +0 -7
  42. /package/dist/react/{CopyPaste-SA72NDFN.js.map → CopyPaste-VUM5WRDX.js.map} +0 -0
  43. /package/dist/react/{FreehandStroke-CK24NUT3.js.map → FreehandStroke-JKTCTOKU.js.map} +0 -0
  44. /package/dist/react/{SceneSerializer-ZPHV6IUP.js.map → SceneSerializer-3RWFYSLY.js.map} +0 -0
  45. /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" }) })
@@ -1469,7 +1473,7 @@ function ColorGrid({ colors, selected, onSelect }) {
1469
1473
  "button",
1470
1474
  {
1471
1475
  onClick: () => onSelect(c),
1472
- className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#5B57D1] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
1476
+ className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#7667a8] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
1473
1477
  style: !isTrans ? { backgroundColor: c } : void 0,
1474
1478
  children: isTrans && /* @__PURE__ */ jsx6("svg", { className: "w-full h-full text-text-dim", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6("line", { x1: "4", y1: "16", x2: "16", y2: "4", stroke: "currentColor", strokeWidth: "2" }) })
1475
1479
  },
@@ -1541,7 +1545,7 @@ function RectangleSidebar() {
1541
1545
  "button",
1542
1546
  {
1543
1547
  onClick: () => updateThickness(w),
1544
- className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-muted hover:bg-white/[0.06]"}`,
1548
+ className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-muted hover:bg-white/[0.06]"}`,
1545
1549
  children: /* @__PURE__ */ jsx6("div", { className: "w-5 rounded-full bg-current", style: { height: Math.max(1, w) } })
1546
1550
  },
1547
1551
  w
@@ -1558,7 +1562,7 @@ function RectangleSidebar() {
1558
1562
  "button",
1559
1563
  {
1560
1564
  onClick: () => updateStyle(s.v),
1561
- className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${lineStyle === s.v ? "bg-[#5B57D1]/20" : "hover:bg-white/[0.06]"}`,
1565
+ className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${lineStyle === s.v ? "bg-[#7667a8]/20" : "hover:bg-white/[0.06]"}`,
1562
1566
  children: /* @__PURE__ */ jsx6("svg", { width: "28", height: "4", viewBox: "0 0 28 4", children: /* @__PURE__ */ jsx6("line", { x1: "0", y1: "2", x2: "28", y2: "2", stroke: "#fff", strokeWidth: "2", strokeDasharray: s.d, strokeLinecap: "round" }) })
1563
1567
  },
1564
1568
  s.v
@@ -1571,7 +1575,7 @@ function RectangleSidebar() {
1571
1575
  "button",
1572
1576
  {
1573
1577
  onClick: () => updateFill(f.value),
1574
- className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${fillStyle === f.value ? "bg-[#5B57D1] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
1578
+ className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${fillStyle === f.value ? "bg-[#7667a8] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
1575
1579
  children: [
1576
1580
  /* @__PURE__ */ jsx6("span", { className: "w-1.5 h-1.5 rounded-full bg-current" }),
1577
1581
  t(f.label)
@@ -1672,7 +1676,7 @@ function CircleSidebar() {
1672
1676
  "button",
1673
1677
  {
1674
1678
  onClick: () => updateThickness(w),
1675
- className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-muted hover:bg-white/[0.06]"}`,
1679
+ className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-muted hover:bg-white/[0.06]"}`,
1676
1680
  children: /* @__PURE__ */ jsx7("div", { className: "w-5 rounded-full bg-current", style: { height: Math.max(1, w) } })
1677
1681
  },
1678
1682
  w
@@ -1685,7 +1689,7 @@ function CircleSidebar() {
1685
1689
  "button",
1686
1690
  {
1687
1691
  onClick: () => updateStyle(s.v),
1688
- className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${lineStyle === s.v ? "bg-[#5B57D1]/20" : "hover:bg-white/[0.06]"}`,
1692
+ className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${lineStyle === s.v ? "bg-[#7667a8]/20" : "hover:bg-white/[0.06]"}`,
1689
1693
  children: /* @__PURE__ */ jsx7("svg", { width: "28", height: "4", viewBox: "0 0 28 4", children: /* @__PURE__ */ jsx7("line", { x1: "0", y1: "2", x2: "28", y2: "2", stroke: "#fff", strokeWidth: "2", strokeDasharray: s.d, strokeLinecap: "round" }) })
1690
1694
  },
1691
1695
  s.v
@@ -1698,7 +1702,7 @@ function CircleSidebar() {
1698
1702
  "button",
1699
1703
  {
1700
1704
  onClick: () => updateFill(f.value),
1701
- className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${fillStyle === f.value ? "bg-[#5B57D1] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
1705
+ className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${fillStyle === f.value ? "bg-[#7667a8] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
1702
1706
  children: [
1703
1707
  /* @__PURE__ */ jsx7("span", { className: "w-1.5 h-1.5 rounded-full bg-current" }),
1704
1708
  t(f.label)
@@ -1721,7 +1725,7 @@ function ColorGrid3({ colors, selected, onSelect }) {
1721
1725
  "button",
1722
1726
  {
1723
1727
  onClick: () => onSelect(c),
1724
- className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#5B57D1] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
1728
+ className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#7667a8] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
1725
1729
  style: { backgroundColor: c }
1726
1730
  },
1727
1731
  c
@@ -1775,7 +1779,7 @@ function LineSidebar() {
1775
1779
  "button",
1776
1780
  {
1777
1781
  onClick: () => updateThickness(w),
1778
- className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-muted hover:bg-white/[0.06]"}`,
1782
+ className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-muted hover:bg-white/[0.06]"}`,
1779
1783
  children: /* @__PURE__ */ jsx8("div", { className: "w-5 rounded-full bg-current", style: { height: Math.max(1, w) } })
1780
1784
  },
1781
1785
  w
@@ -1788,7 +1792,7 @@ function LineSidebar() {
1788
1792
  "button",
1789
1793
  {
1790
1794
  onClick: () => updateStyle(s.v),
1791
- className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${lineStyle === s.v ? "bg-[#5B57D1]/20" : "hover:bg-white/[0.06]"}`,
1795
+ className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${lineStyle === s.v ? "bg-[#7667a8]/20" : "hover:bg-white/[0.06]"}`,
1792
1796
  children: /* @__PURE__ */ jsx8("svg", { width: "28", height: "4", viewBox: "0 0 28 4", children: /* @__PURE__ */ jsx8("line", { x1: "0", y1: "2", x2: "28", y2: "2", stroke: "#fff", strokeWidth: "2", strokeDasharray: s.d, strokeLinecap: "round" }) })
1793
1797
  },
1794
1798
  s.v
@@ -1801,7 +1805,7 @@ function LineSidebar() {
1801
1805
  "button",
1802
1806
  {
1803
1807
  onClick: () => updateSloppiness(s.v),
1804
- className: `w-8 h-8 flex items-center justify-center rounded-lg text-xs transition-all duration-100 ${sloppiness === s.v ? "bg-[#5B57D1]/20 text-accent-blue" : "text-text-muted hover:bg-white/6"}`,
1808
+ className: `w-8 h-8 flex items-center justify-center rounded-lg text-xs transition-all duration-100 ${sloppiness === s.v ? "bg-[#7667a8]/20 text-accent-blue" : "text-text-muted hover:bg-white/6"}`,
1805
1809
  children: s.l
1806
1810
  },
1807
1811
  s.v
@@ -1847,7 +1851,7 @@ function ColorGrid4({ colors, selected, onSelect }) {
1847
1851
  "button",
1848
1852
  {
1849
1853
  onClick: () => onSelect(c),
1850
- className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#5B57D1] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
1854
+ className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#7667a8] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
1851
1855
  style: { backgroundColor: c }
1852
1856
  },
1853
1857
  c
@@ -1900,7 +1904,7 @@ function ArrowSidebar() {
1900
1904
  "button",
1901
1905
  {
1902
1906
  onClick: () => updateHead(h.value),
1903
- className: `w-10 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${headStyle === h.value ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-secondary hover:bg-white/[0.06]"}`,
1907
+ className: `w-10 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${headStyle === h.value ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-secondary hover:bg-white/[0.06]"}`,
1904
1908
  children: /* @__PURE__ */ jsx9(SvgIcon, { svg: h.svg })
1905
1909
  },
1906
1910
  h.value
@@ -1925,7 +1929,7 @@ function ArrowSidebar() {
1925
1929
  "button",
1926
1930
  {
1927
1931
  onClick: () => updateThickness(w),
1928
- className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-secondary hover:bg-white/[0.06]"}`,
1932
+ className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-secondary hover:bg-white/[0.06]"}`,
1929
1933
  children: /* @__PURE__ */ jsx9("div", { className: "w-5 rounded-full bg-current", style: { height: Math.max(1, w) } })
1930
1934
  },
1931
1935
  w
@@ -1938,7 +1942,7 @@ function ArrowSidebar() {
1938
1942
  "button",
1939
1943
  {
1940
1944
  onClick: () => updateOutline(s.v),
1941
- className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${outlineStyle === s.v ? "bg-[#5B57D1]/20" : "hover:bg-white/[0.06]"}`,
1945
+ className: `w-11 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${outlineStyle === s.v ? "bg-[#7667a8]/20" : "hover:bg-white/[0.06]"}`,
1942
1946
  children: /* @__PURE__ */ jsx9("svg", { width: "28", height: "4", viewBox: "0 0 28 4", children: /* @__PURE__ */ jsx9("line", { x1: "0", y1: "2", x2: "28", y2: "2", stroke: "#fff", strokeWidth: "2", strokeDasharray: s.d, strokeLinecap: "round" }) })
1943
1947
  },
1944
1948
  s.v
@@ -1956,7 +1960,7 @@ function ArrowSidebar() {
1956
1960
  "button",
1957
1961
  {
1958
1962
  onClick: () => updateType(a.v),
1959
- className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${arrowType === a.v ? "bg-[#5B57D1] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
1963
+ className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${arrowType === a.v ? "bg-[#7667a8] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
1960
1964
  children: [
1961
1965
  /* @__PURE__ */ jsx9("i", { className: `bx ${a.i} text-sm` }),
1962
1966
  " ",
@@ -1972,7 +1976,7 @@ function ArrowSidebar() {
1972
1976
  "button",
1973
1977
  {
1974
1978
  onClick: () => updateCurvature(c.v),
1975
- className: `flex-1 py-1 rounded-md text-xs text-center transition-all duration-100 ${curvature === c.v ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-secondary hover:bg-white/[0.06]"}`,
1979
+ className: `flex-1 py-1 rounded-md text-xs text-center transition-all duration-100 ${curvature === c.v ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-secondary hover:bg-white/[0.06]"}`,
1976
1980
  children: c.l
1977
1981
  },
1978
1982
  c.v
@@ -1995,7 +1999,7 @@ function ColorGrid5({ colors, selected, onSelect }) {
1995
1999
  "button",
1996
2000
  {
1997
2001
  onClick: () => onSelect(c),
1998
- className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#5B57D1] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
2002
+ className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${selected === c ? "border-[#7667a8] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
1999
2003
  style: { backgroundColor: c }
2000
2004
  },
2001
2005
  c
@@ -2050,7 +2054,7 @@ function PaintbrushSidebar() {
2050
2054
  "button",
2051
2055
  {
2052
2056
  onClick: () => updateThickness(w),
2053
- className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-muted hover:bg-white/[0.06]"}`,
2057
+ className: `w-9 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ${thickness === w ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-muted hover:bg-white/[0.06]"}`,
2054
2058
  children: /* @__PURE__ */ jsx10("div", { className: "w-5 rounded-full bg-current", style: { height: Math.max(1, w) } })
2055
2059
  },
2056
2060
  w
@@ -2067,7 +2071,7 @@ function PaintbrushSidebar() {
2067
2071
  "button",
2068
2072
  {
2069
2073
  onClick: () => updateTaper(t2.v),
2070
- className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${taper === t2.v ? "bg-[#5B57D1] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2074
+ className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${taper === t2.v ? "bg-[#7667a8] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2071
2075
  children: [
2072
2076
  /* @__PURE__ */ jsx10("i", { className: `bx ${t2.i} text-sm` }),
2073
2077
  " ",
@@ -2088,7 +2092,7 @@ function PaintbrushSidebar() {
2088
2092
  "button",
2089
2093
  {
2090
2094
  onClick: () => updateRoughness(r.v),
2091
- className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${roughness === r.v ? "bg-[#5B57D1] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2095
+ className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${roughness === r.v ? "bg-[#7667a8] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2092
2096
  children: [
2093
2097
  /* @__PURE__ */ jsx10("i", { className: `bx ${r.i} text-sm` }),
2094
2098
  " ",
@@ -2114,7 +2118,7 @@ function PaintbrushSidebar() {
2114
2118
  step: "0.05",
2115
2119
  value: opacity,
2116
2120
  onChange: (e) => updateOpacity(parseFloat(e.target.value)),
2117
- className: "w-28 h-1 bg-white/10 rounded-full appearance-none cursor-pointer accent-[#5B57D1]"
2121
+ className: "w-28 h-1 bg-white/10 rounded-full appearance-none cursor-pointer accent-[#7667a8]"
2118
2122
  }
2119
2123
  )
2120
2124
  ] }),
@@ -2214,7 +2218,7 @@ function TextSidebar() {
2214
2218
  "button",
2215
2219
  {
2216
2220
  onClick: () => updateColor(c),
2217
- className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${textColor === c ? "border-[#5B57D1] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
2221
+ className: `w-7 h-7 rounded-md border-[1.5px] transition-all duration-100 ${textColor === c ? "border-[#7667a8] scale-110" : "border-white/[0.08] hover:border-white/20"}`,
2218
2222
  style: { backgroundColor: c }
2219
2223
  },
2220
2224
  c
@@ -2230,7 +2234,7 @@ function TextSidebar() {
2230
2234
  "button",
2231
2235
  {
2232
2236
  onClick: () => updateFont(f.value),
2233
- className: `flex items-center px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${font === f.value ? "bg-[#5B57D1] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2237
+ className: `flex items-center px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${font === f.value ? "bg-[#7667a8] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2234
2238
  style: { fontFamily: f.value },
2235
2239
  children: f.label
2236
2240
  },
@@ -2245,7 +2249,7 @@ function TextSidebar() {
2245
2249
  "button",
2246
2250
  {
2247
2251
  onClick: () => updateSize(s),
2248
- className: `w-8 h-8 flex items-center justify-center rounded-lg text-xs transition-all duration-100 ${fontSize === s ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-muted hover:bg-white/[0.06]"}`,
2252
+ className: `w-8 h-8 flex items-center justify-center rounded-lg text-xs transition-all duration-100 ${fontSize === s ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-muted hover:bg-white/[0.06]"}`,
2249
2253
  children: s
2250
2254
  },
2251
2255
  s
@@ -2259,7 +2263,7 @@ function TextSidebar() {
2259
2263
  "button",
2260
2264
  {
2261
2265
  onClick: toggleCodeMode,
2262
- className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${codeMode ? "bg-[#5B57D1] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2266
+ className: `flex items-center gap-2 px-2.5 py-1.5 rounded-lg text-xs transition-all duration-100 ${codeMode ? "bg-[#7667a8] text-white" : "text-text-secondary hover:bg-white/[0.06]"}`,
2263
2267
  children: [
2264
2268
  /* @__PURE__ */ jsx11("div", { className: `w-6 h-3 rounded-full transition-all duration-150 relative ${codeMode ? "bg-white/30" : "bg-white/10"}`, children: /* @__PURE__ */ jsx11("div", { className: `absolute top-0.5 w-2 h-2 rounded-full bg-white transition-all duration-150 ${codeMode ? "left-3.5" : "left-0.5"}` }) }),
2265
2269
  codeMode ? t("sidebar.on") : t("sidebar.off")
@@ -2270,7 +2274,7 @@ function TextSidebar() {
2270
2274
  "button",
2271
2275
  {
2272
2276
  onClick: () => updateLanguage(lang),
2273
- className: `px-1.5 py-0.5 rounded text-[9px] transition-all duration-100 ${language === lang ? "bg-[#5B57D1]/20 text-[#5B57D1]" : "text-text-dim hover:bg-white/[0.06] hover:text-text-secondary"}`,
2277
+ className: `px-1.5 py-0.5 rounded text-[9px] transition-all duration-100 ${language === lang ? "bg-[#7667a8]/20 text-[#7667a8]" : "text-text-dim hover:bg-white/[0.06] hover:text-text-secondary"}`,
2274
2278
  children: lang
2275
2279
  },
2276
2280
  lang
@@ -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",
@@ -2387,7 +2391,7 @@ function FrameSidebar() {
2387
2391
  type: "text",
2388
2392
  value: frameName,
2389
2393
  onChange: updateName,
2390
- className: "w-32 px-2.5 py-1.5 bg-white/[0.05] border border-white/[0.1] rounded-lg text-white text-xs outline-none focus:border-[#5B57D1]/50 transition-all duration-150 font-[lixFont]",
2394
+ className: "w-32 px-2.5 py-1.5 bg-white/[0.05] border border-white/[0.1] rounded-lg text-white text-xs outline-none focus:border-[#7667a8]/50 transition-all duration-150 font-[lixFont]",
2391
2395
  spellCheck: false
2392
2396
  }
2393
2397
  )
@@ -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
  )
@@ -3386,7 +3390,7 @@ function FindBar() {
3386
3390
  rect.setAttribute("width", w + 8);
3387
3391
  rect.setAttribute("height", h + 8);
3388
3392
  rect.setAttribute("fill", "rgba(91, 87, 209, 0.15)");
3389
- rect.setAttribute("stroke", "#5B57D1");
3393
+ rect.setAttribute("stroke", "#7667a8");
3390
3394
  rect.setAttribute("stroke-width", "2");
3391
3395
  rect.setAttribute("stroke-dasharray", "4,2");
3392
3396
  rect.setAttribute("rx", "4");
@@ -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;