{"project":{"id":"zORVPeh","userId":"davidyarham@gmail.com","username":null,"userPicture":null,"name":"Sketch Pad","visible":true,"contributors":"","githubRepo":null,"forkedFrom":null,"isTemplate":false,"tags":"","files":{"folder":"","files":[{"name":"index.html","content":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Untitled</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap\" rel=\"stylesheet\">\n<script src=\"https://unpkg.com/lucide@latest/dist/umd/lucide.js\"></script>\n</head>\n<body>\n<main class=\"app\">\n\t<header class=\"app-header\" aria-label=\"App header\">\n\t\t<div class=\"app-header__identity\">\n\t\t\t<div class=\"app-icon\" aria-hidden=\"true\">\n\t\t\t\t<i data-lucide=\"square-pen\"></i>\n\t\t\t</div>\n\t\t\t<div>\n\t\t\t\t<p class=\"app-header__eyebrow\">Sketchbook</p>\n\t\t\t\t<h1 class=\"app-header__title\">Notes Draw</h1>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div class=\"app-header__actions\" role=\"group\" aria-label=\"Canvas actions\">\n\t\t\t<button id=\"clearBtn\" class=\"header-button\" type=\"button\" aria-label=\"Clear canvas\">\n\t\t\t\t<i data-lucide=\"trash-2\"></i>\n\t\t\t</button>\n\t\t\t<button id=\"saveBtn\" class=\"header-button header-button--primary\" type=\"button\" aria-label=\"Save PNG\">\n\t\t\t\t<i data-lucide=\"download\"></i>\n\t\t\t</button>\n\t\t</div>\n\t</header>\n\n\t<section class=\"board\" aria-label=\"Drawing area\">\n\t\t<div class=\"board__badge\" aria-live=\"polite\">\n\t\t\t<span class=\"status-dot\"></span>\n\t\t\t<span id=\"statusText\">Pen selected</span>\n\t\t</div>\n\t\t<div class=\"canvas-shell\">\n\t\t\t<canvas id=\"drawingCanvas\" aria-label=\"Drawing canvas\"></canvas>\n\t\t</div>\n\t</section>\n\n\t<section class=\"dock\" aria-label=\"Drawing controls\">\n\t\t<div class=\"dock__tools\" role=\"group\" aria-label=\"Drawing tools\">\n\t\t\t<button class=\"tool-chip is-active\" type=\"button\" data-tool=\"pen\" aria-pressed=\"true\" title=\"Pen\">\n\t\t\t\t<i data-lucide=\"pen-tool\"></i>\n\t\t\t\t<span>Pen</span>\n\t\t\t</button>\n\t\t\t<button class=\"tool-chip\" type=\"button\" data-tool=\"pencil\" aria-pressed=\"false\" title=\"Pencil\">\n\t\t\t\t<i data-lucide=\"pencil\"></i>\n\t\t\t\t<span>Pencil</span>\n\t\t\t</button>\n\t\t\t<button class=\"tool-chip\" type=\"button\" data-tool=\"marker\" aria-pressed=\"false\" title=\"Marker\">\n\t\t\t\t<i data-lucide=\"highlighter\"></i>\n\t\t\t\t<span>Marker</span>\n\t\t\t</button>\n\t\t\t<button class=\"tool-chip\" type=\"button\" data-tool=\"eraser\" aria-pressed=\"false\" title=\"Eraser\">\n\t\t\t\t<i data-lucide=\"eraser\"></i>\n\t\t\t\t<span>Eraser</span>\n\t\t\t</button>\n\t\t\t<button class=\"tool-chip\" type=\"button\" data-tool=\"line\" aria-pressed=\"false\" title=\"Line\">\n\t\t\t\t<i data-lucide=\"slash\"></i>\n\t\t\t\t<span>Line</span>\n\t\t\t</button>\n\t\t\t<button class=\"tool-chip\" type=\"button\" data-tool=\"rectangle\" aria-pressed=\"false\" title=\"Rectangle\">\n\t\t\t\t<i data-lucide=\"square\"></i>\n\t\t\t\t<span>Rect</span>\n\t\t\t</button>\n\t\t\t<button class=\"tool-chip\" type=\"button\" data-tool=\"circle\" aria-pressed=\"false\" title=\"Circle\">\n\t\t\t\t<i data-lucide=\"circle\"></i>\n\t\t\t\t<span>Circle</span>\n\t\t\t</button>\n\t\t\t<button class=\"tool-chip\" type=\"button\" data-tool=\"fill\" aria-pressed=\"false\" title=\"Fill\">\n\t\t\t\t<i data-lucide=\"paint-bucket\"></i>\n\t\t\t\t<span>Fill</span>\n\t\t\t</button>\n\t\t</div>\n\n\t\t<div class=\"dock__bottom\">\n\t\t\t<div class=\"swatches\" role=\"group\" aria-label=\"Color swatches\">\n\t\t\t\t<button class=\"swatch is-active\" type=\"button\" data-color=\"#1c1c1e\" style=\"--swatch:#1c1c1e\" aria-label=\"Black\"></button>\n\t\t\t\t<button class=\"swatch\" type=\"button\" data-color=\"#8e8e93\" style=\"--swatch:#8e8e93\" aria-label=\"Gray\"></button>\n\t\t\t\t<button class=\"swatch\" type=\"button\" data-color=\"#0a84ff\" style=\"--swatch:#0a84ff\" aria-label=\"Blue\"></button>\n\t\t\t\t<button class=\"swatch\" type=\"button\" data-color=\"#30b0c7\" style=\"--swatch:#30b0c7\" aria-label=\"Teal\"></button>\n\t\t\t\t<button class=\"swatch\" type=\"button\" data-color=\"#34c759\" style=\"--swatch:#34c759\" aria-label=\"Green\"></button>\n\t\t\t\t<button class=\"swatch\" type=\"button\" data-color=\"#ff9f0a\" style=\"--swatch:#ff9f0a\" aria-label=\"Orange\"></button>\n\t\t\t\t<button class=\"swatch\" type=\"button\" data-color=\"#ff3b30\" style=\"--swatch:#ff3b30\" aria-label=\"Red\"></button>\n\t\t\t\t<label class=\"swatch swatch--picker\" aria-label=\"Custom color\">\n\t\t\t\t\t<input id=\"colorPicker\" class=\"swatch__input\" type=\"color\" value=\"#1c1c1e\" aria-label=\"Custom color picker\" />\n\t\t\t\t</label>\n\t\t\t</div>\n\n\t\t\t<label class=\"size-control\" for=\"sizeRange\">\n\t\t\t\t<span class=\"size-control__label\">Thickness</span>\n\t\t\t\t<input id=\"sizeRange\" class=\"size-control__range\" type=\"range\" min=\"1\" max=\"48\" value=\"6\" />\n\t\t\t\t<output id=\"sizeValue\" class=\"size-control__value\" for=\"sizeRange\">6</output>\n\t\t\t</label>\n\t\t</div>\n\t</section>\n</main>\n  <script type=\"module\" src=\"main.js\"></script>\n</body>\n</html>"},{"name":"main.js","content":"const canvas = document.getElementById('drawingCanvas');\nconst ctx = canvas.getContext('2d');\nconst colorPicker = document.getElementById('colorPicker');\nconst sizeRange = document.getElementById('sizeRange');\nconst sizeValue = document.getElementById('sizeValue');\nconst clearBtn = document.getElementById('clearBtn');\nconst saveBtn = document.getElementById('saveBtn');\nconst statusText = document.getElementById('statusText');\nconst toolButtons = document.querySelectorAll('[data-tool]');\nconst swatches = document.querySelectorAll('.swatch[data-color]');\n\nlet currentTool = 'pen';\nlet drawing = false;\nlet brushColor = colorPicker.value;\nlet brushSize = Number(sizeRange.value);\nlet lastX = 0;\nlet lastY = 0;\nlet startX = 0;\nlet startY = 0;\nlet canvasSnapshot = null;\n\nfunction showControls() {\n\tdocument.body.classList.remove('is-drawing');\n}\n\nfunction resizeCanvas() {\n\tconst ratio = window.devicePixelRatio || 1;\n\tconst rect = {\n\t\twidth: window.innerWidth,\n\t\theight: window.innerHeight\n\t};\n\tconst snapshot = canvas.toDataURL();\n\tconst image = new Image();\n\n\timage.onload = () => {\n\t\tcanvas.width = Math.floor(rect.width * ratio);\n\t\tcanvas.height = Math.floor(rect.height * ratio);\n\t\tctx.setTransform(ratio, 0, 0, ratio, 0, 0);\n\t\tctx.lineCap = 'round';\n\t\tctx.lineJoin = 'round';\n\t\tctx.imageSmoothingEnabled = true;\n\t\tctx.clearRect(0, 0, canvas.width, canvas.height);\n\t\tctx.drawImage(image, 0, 0, rect.width, rect.height);\n\t};\n\n\timage.src = snapshot;\n\n\tif (!snapshot || snapshot === 'data:,') {\n\t\tcanvas.width = Math.floor(rect.width * ratio);\n\t\tcanvas.height = Math.floor(rect.height * ratio);\n\t\tctx.setTransform(ratio, 0, 0, ratio, 0, 0);\n\t\tctx.lineCap = 'round';\n\t\tctx.lineJoin = 'round';\n\t\tctx.imageSmoothingEnabled = true;\n\t}\n}\n\nfunction getPoint(event) {\n\tconst rect = canvas.getBoundingClientRect();\n\treturn {\n\t\tx: event.clientX - rect.left,\n\t\ty: event.clientY - rect.top\n\t};\n}\n\nfunction getToolLabel(tool) {\n\tconst labels = {\n\t\tpen: 'Pen',\n\t\tpencil: 'Pencil',\n\t\tmarker: 'Marker',\n\t\teraser: 'Eraser',\n\t\tline: 'Line',\n\t\trectangle: 'Rectangle',\n\t\tcircle: 'Circle',\n\t\tfill: 'Fill'\n\t};\n\treturn labels[tool] || 'Tool';\n}\n\nfunction getToolSettings(tool) {\n\tif (tool === 'pencil') {\n\t\treturn {\n\t\t\talpha: 0.55,\n\t\t\twidth: Math.max(1, brushSize * 0.7),\n\t\t\tcomposite: 'source-over'\n\t\t};\n\t}\n\n\tif (tool === 'marker') {\n\t\treturn {\n\t\t\talpha: 0.22,\n\t\t\twidth: Math.max(6, brushSize * 1.6),\n\t\t\tcomposite: 'multiply'\n\t\t};\n\t}\n\n\tif (tool === 'eraser') {\n\t\treturn {\n\t\t\talpha: 1,\n\t\t\twidth: Math.max(4, brushSize * 1.2),\n\t\t\tcomposite: 'destination-out'\n\t\t};\n\t}\n\n\treturn {\n\t\talpha: 1,\n\t\twidth: brushSize,\n\t\tcomposite: 'source-over'\n\t};\n}\n\nfunction updateSwatches(color) {\n\tswatches.forEach((swatch) => {\n\t\tswatch.classList.toggle('is-active', swatch.dataset.color.toLowerCase() === color.toLowerCase());\n\t});\n}\n\nfunction floodFill(x, y, fillColor) {\n\tconst width = canvas.width;\n\tconst height = canvas.height;\n\tconst ratio = window.devicePixelRatio || 1;\n\tconst imageData = ctx.getImageData(0, 0, width, height);\n\tconst data = imageData.data;\n\tconst px = Math.floor(x * ratio);\n\tconst py = Math.floor(y * ratio);\n\tconst startIndex = (py * width + px) * 4;\n\n\tif (startIndex < 0 || startIndex >= data.length) return;\n\n\tconst target = [\n\t\tdata[startIndex],\n\t\tdata[startIndex + 1],\n\t\tdata[startIndex + 2],\n\t\tdata[startIndex + 3]\n\t];\n\n\tconst hex = fillColor.replace('#', '');\n\tconst fill = [\n\t\tparseInt(hex.slice(0, 2), 16),\n\t\tparseInt(hex.slice(2, 4), 16),\n\t\tparseInt(hex.slice(4, 6), 16),\n\t\t255\n\t];\n\n\tif (target.every((value, index) => value === fill[index])) return;\n\n\tconst stack = [\n\t\t[px, py]\n\t];\n\n\twhile (stack.length) {\n\t\tconst [cx, cy] = stack.pop();\n\t\tif (cx < 0 || cy < 0 || cx >= width || cy >= height) continue;\n\n\t\tconst index = (cy * width + cx) * 4;\n\t\tif (\n\t\t\tdata[index] !== target[0] ||\n\t\t\tdata[index + 1] !== target[1] ||\n\t\t\tdata[index + 2] !== target[2] ||\n\t\t\tdata[index + 3] !== target[3]\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdata[index] = fill[0];\n\t\tdata[index + 1] = fill[1];\n\t\tdata[index + 2] = fill[2];\n\t\tdata[index + 3] = fill[3];\n\n\t\tstack.push([cx + 1, cy]);\n\t\tstack.push([cx - 1, cy]);\n\t\tstack.push([cx, cy + 1]);\n\t\tstack.push([cx, cy - 1]);\n\t}\n\n\tctx.putImageData(imageData, 0, 0);\n}\n\nfunction setTool(tool) {\n\tcurrentTool = tool;\n\ttoolButtons.forEach((button) => {\n\t\tconst active = button.dataset.tool === tool;\n\t\tbutton.classList.toggle('is-active', active);\n\t\tbutton.setAttribute('aria-pressed', String(active));\n\t});\n\n\tcanvas.style.cursor = tool === 'eraser' ? 'cell' : tool === 'fill' ? 'pointer' : 'crosshair';\n\tstatusText.textContent = `${getToolLabel(tool)} selected`;\n}\n\nfunction startDrawing(event) {\n\tevent.preventDefault();\n\tcanvas.setPointerCapture(event.pointerId);\n\n\tconst point = getPoint(event);\n\tstartX = point.x;\n\tstartY = point.y;\n\tlastX = point.x;\n\tlastY = point.y;\n\n\tif (currentTool === 'fill') {\n\t\tfloodFill(point.x, point.y, brushColor);\n\t\tstatusText.textContent = 'Area filled';\n\t\tshowControls();\n\t\tcanvas.releasePointerCapture(event.pointerId);\n\t\treturn;\n\t}\n\n\tdrawing = true;\n\tdocument.body.classList.add('is-drawing');\n\tcanvasSnapshot = ctx.getImageData(0, 0, canvas.width, canvas.height);\n\n\tif (currentTool === 'pen' || currentTool === 'pencil' || currentTool === 'marker' || currentTool === 'eraser') {\n\t\tconst settings = getToolSettings(currentTool);\n\t\tctx.save();\n\t\tctx.globalCompositeOperation = settings.composite;\n\t\tctx.globalAlpha = settings.alpha;\n\t\tctx.lineWidth = settings.width;\n\t\tctx.strokeStyle = brushColor;\n\t\tctx.beginPath();\n\t\tctx.moveTo(point.x, point.y);\n\t\tctx.lineTo(point.x + 0.01, point.y + 0.01);\n\t\tctx.stroke();\n\t\tctx.restore();\n\t}\n}\n\nfunction draw(event) {\n\tif (!drawing) return;\n\tevent.preventDefault();\n\n\tconst point = getPoint(event);\n\n\tif (currentTool === 'pen' || currentTool === 'pencil' || currentTool === 'marker' || currentTool === 'eraser') {\n\t\tconst settings = getToolSettings(currentTool);\n\t\tctx.save();\n\t\tctx.lineCap = currentTool === 'marker' ? 'square' : 'round';\n\t\tctx.lineJoin = 'round';\n\t\tctx.globalCompositeOperation = settings.composite;\n\t\tctx.globalAlpha = settings.alpha;\n\t\tctx.lineWidth = settings.width;\n\t\tctx.strokeStyle = brushColor;\n\t\tctx.beginPath();\n\t\tctx.moveTo(lastX, lastY);\n\t\tctx.lineTo(point.x, point.y);\n\t\tctx.stroke();\n\t\tctx.restore();\n\t} else {\n\t\tctx.putImageData(canvasSnapshot, 0, 0);\n\t\tctx.save();\n\t\tctx.globalAlpha = 1;\n\t\tctx.lineWidth = brushSize;\n\t\tctx.strokeStyle = brushColor;\n\t\tctx.beginPath();\n\n\t\tif (currentTool === 'line') {\n\t\t\tctx.moveTo(startX, startY);\n\t\t\tctx.lineTo(point.x, point.y);\n\t\t\tctx.stroke();\n\t\t}\n\n\t\tif (currentTool === 'rectangle') {\n\t\t\tctx.strokeRect(startX, startY, point.x - startX, point.y - startY);\n\t\t}\n\n\t\tif (currentTool === 'circle') {\n\t\t\tconst radius = Math.hypot(point.x - startX, point.y - startY);\n\t\t\tctx.arc(startX, startY, radius, 0, Math.PI * 2);\n\t\t\tctx.stroke();\n\t\t}\n\n\t\tctx.restore();\n\t}\n\n\tlastX = point.x;\n\tlastY = point.y;\n}\n\nfunction stopDrawing(event) {\n\tif (event && canvas.hasPointerCapture(event.pointerId)) {\n\t\tcanvas.releasePointerCapture(event.pointerId);\n\t}\n\n\tif (!drawing) {\n\t\tshowControls();\n\t\treturn;\n\t}\n\n\tdrawing = false;\n\tcanvasSnapshot = null;\n\tshowControls();\n}\n\nfunction clearCanvas() {\n\tctx.clearRect(0, 0, canvas.width, canvas.height);\n\tstatusText.textContent = 'Canvas cleared';\n}\n\nfunction saveCanvas() {\n\tconst link = document.createElement('a');\n\tlink.href = canvas.toDataURL('image/png');\n\tlink.download = 'notes-draw.png';\n\tlink.click();\n\tstatusText.textContent = 'PNG downloaded';\n}\n\nsizeRange.addEventListener('input', () => {\n\tbrushSize = Number(sizeRange.value);\n\tsizeValue.value = String(brushSize);\n\tstatusText.textContent = `Thickness set to ${brushSize}`;\n});\n\ncolorPicker.addEventListener('input', () => {\n\tbrushColor = colorPicker.value;\n\tupdateSwatches(brushColor);\n\tstatusText.textContent = 'Custom color selected';\n});\n\nswatches.forEach((swatch) => {\n\tswatch.addEventListener('click', () => {\n\t\tbrushColor = swatch.dataset.color;\n\t\tcolorPicker.value = brushColor;\n\t\tupdateSwatches(brushColor);\n\t\tstatusText.textContent = 'Color selected';\n\t});\n});\n\nclearBtn.addEventListener('click', clearCanvas);\nsaveBtn.addEventListener('click', saveCanvas);\n\ntoolButtons.forEach((button) => {\n\tbutton.addEventListener('click', () => setTool(button.dataset.tool));\n});\n\ncanvas.addEventListener('pointerdown', startDrawing);\ncanvas.addEventListener('pointermove', draw);\ncanvas.addEventListener('pointerup', stopDrawing);\ncanvas.addEventListener('pointercancel', stopDrawing);\nwindow.addEventListener('resize', resizeCanvas);\n\nresizeCanvas();\nsetTool('pen');\nupdateSwatches(brushColor);\nsizeValue.value = String(brushSize);\n\nif (window.lucide) {\n\tlucide.createIcons();\n}"},{"name":"style.css","content":":root {\n\tcolor-scheme: light dark;\n\tfont-family: Inter, system-ui, sans-serif;\n\t--bg: #ececf1;\n\t--panel: rgba(248, 248, 250, 0.78);\n\t--panel-strong: rgba(255, 255, 255, 0.92);\n\t--line: rgba(60, 60, 67, 0.12);\n\t--text: #111214;\n\t--muted: #6e6e73;\n\t--accent: #111214;\n\t--canvas: #ffffff;\n\t--shadow: 0 10px 30px rgba(17, 18, 20, 0.1);\n}\n\n* {\n\tbox-sizing: border-box;\n}\n\nhtml,\nbody {\n\tmargin: 0;\n\twidth: 100%;\n\theight: 100%;\n}\n\nbody {\n\tmin-height: 100vh;\n\toverflow: hidden;\n\tbackground: var(--bg);\n\tcolor: var(--text);\n}\n\nbutton,\ninput {\n\tfont: inherit;\n}\n\nbutton {\n\tcursor: pointer;\n}\n\n.app-header,\n.dock,\n.board__badge {\n\ttransition: opacity 150ms ease, transform 150ms ease;\n}\n\nbody.is-drawing .app-header,\nbody.is-drawing .dock,\nbody.is-drawing .board__badge {\n\topacity: 0;\n\ttransform: translateY(8px);\n\tpointer-events: none;\n}\n\n.app {\n\twidth: 100vw;\n\theight: 100vh;\n\tposition: relative;\n}\n\n.app-header {\n\tposition: fixed;\n\ttop: 1rem;\n\tleft: 1rem;\n\tright: 1rem;\n\tz-index: 20;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 1rem;\n}\n\n.app-header__identity {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 0.85rem;\n\tpadding: 0.75rem 0.95rem;\n\tbackground: var(--panel);\n\tbackdrop-filter: blur(20px);\n\tborder: 1px solid var(--line);\n\tborder-radius: 20px;\n\tbox-shadow: var(--shadow);\n}\n\n.app-icon {\n\twidth: 2.5rem;\n\theight: 2.5rem;\n\tborder-radius: 14px;\n\tbackground: #ffffff;\n\tborder: 1px solid rgba(60, 60, 67, 0.08);\n\tdisplay: grid;\n\tplace-items: center;\n\tcolor: #ff9f0a;\n\tflex: 0 0 auto;\n}\n\n.app-header__eyebrow {\n\tmargin: 0 0 0.16rem;\n\tfont-size: 0.72rem;\n\tfont-weight: 600;\n\tletter-spacing: 0.08em;\n\ttext-transform: uppercase;\n\tcolor: var(--muted);\n}\n\n.app-header__title {\n\tmargin: 0;\n\tfont-size: 1.05rem;\n\tfont-weight: 700;\n\tletter-spacing: -0.03em;\n}\n\n.app-header__actions {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 0.55rem;\n\tpadding: 0.45rem;\n\tbackground: var(--panel);\n\tbackdrop-filter: blur(20px);\n\tborder: 1px solid var(--line);\n\tborder-radius: 18px;\n\tbox-shadow: var(--shadow);\n}\n\n.header-button,\n.tool-chip {\n\tborder: 1px solid var(--line);\n\tbackground: var(--panel-strong);\n\tcolor: var(--text);\n\ttransition: background 150ms ease, border-color 150ms ease, transform 150ms ease;\n}\n\n.header-button {\n\twidth: 2.5rem;\n\theight: 2.5rem;\n\tpadding: 0;\n\tborder-radius: 14px;\n\tdisplay: inline-grid;\n\tplace-items: center;\n}\n\n.header-button--primary {\n\tbackground: #111214;\n\tborder-color: #111214;\n\tcolor: #ffffff;\n}\n\n.board {\n\tposition: relative;\n\twidth: 100%;\n\theight: 100%;\n}\n\n.board__badge {\n\tposition: fixed;\n\tleft: 50%;\n\ttop: 1.1rem;\n\ttransform: translateX(-50%);\n\tz-index: 15;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 0.55rem;\n\tpadding: 0.65rem 0.9rem;\n\tbackground: rgba(255, 255, 255, 0.8);\n\tbackdrop-filter: blur(18px);\n\tborder: 1px solid var(--line);\n\tborder-radius: 999px;\n\tfont-size: 0.82rem;\n\tbox-shadow: var(--shadow);\n}\n\n.status-dot {\n\twidth: 0.55rem;\n\theight: 0.55rem;\n\tborder-radius: 50%;\n\tbackground: #ff9f0a;\n}\n\n.canvas-shell {\n\tposition: fixed;\n\tinset: 0;\n\tbackground: var(--canvas);\n\toverflow: hidden;\n}\n\n#drawingCanvas {\n\tdisplay: block;\n\twidth: 100%;\n\theight: 100vh;\n\ttouch-action: none;\n\tcursor: crosshair;\n}\n\n.dock {\n\tposition: fixed;\n\tleft: 1rem;\n\tright: 1rem;\n\tbottom: 1rem;\n\tz-index: 20;\n\tpadding: 0.7rem;\n\tbackground: var(--panel);\n\tbackdrop-filter: blur(24px);\n\tborder: 1px solid var(--line);\n\tborder-radius: 26px;\n\tbox-shadow: var(--shadow);\n\tdisplay: grid;\n\tgap: 0.7rem;\n}\n\n.dock__tools {\n\tdisplay: flex;\n\tgap: 0.45rem;\n\toverflow-x: auto;\n\tscrollbar-width: none;\n}\n\n.dock__tools::-webkit-scrollbar {\n\tdisplay: none;\n}\n\n.tool-chip {\n\tpadding: 0.62rem 0.8rem;\n\tmin-width: 4.6rem;\n\tborder-radius: 16px;\n\tdisplay: inline-flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 0.35rem;\n\tfont-size: 0.74rem;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n\tflex: 0 0 auto;\n}\n\n.tool-chip.is-active {\n\tbackground: #111214;\n\tborder-color: #111214;\n\tcolor: #ffffff;\n}\n\n.dock__bottom {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 1rem;\n\tflex-wrap: wrap;\n}\n\n.swatches {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 0.55rem;\n\tflex-wrap: wrap;\n}\n\n.swatch {\n\twidth: 1.9rem;\n\theight: 1.9rem;\n\tpadding: 0;\n\tborder-radius: 50%;\n\tborder: 2px solid rgba(255, 255, 255, 0.95);\n\tbackground: var(--swatch);\n\tbox-shadow: 0 0 0 1px rgba(17, 18, 20, 0.12);\n\tposition: relative;\n\tflex: 0 0 auto;\n}\n\n.swatch.is-active::after {\n\tcontent: '';\n\tposition: absolute;\n\tinset: -0.22rem;\n\tborder-radius: 50%;\n\tborder: 1.5px solid #111214;\n}\n\n.swatch--picker {\n\toverflow: hidden;\n\tbackground: conic-gradient(from 180deg, #ff3b30, #ff9f0a, #ffd60a, #34c759, #30b0c7, #0a84ff, #bf5af2, #ff375f, #ff3b30);\n}\n\n.swatch__input {\n\topacity: 0;\n\twidth: 100%;\n\theight: 100%;\n\tcursor: pointer;\n}\n\n.size-control {\n\tdisplay: grid;\n\tgrid-template-columns: auto minmax(160px, 240px) auto;\n\talign-items: center;\n\tgap: 0.7rem;\n\tmin-width: min(100%, 360px);\n}\n\n.size-control__label {\n\tfont-size: 0.72rem;\n\tfont-weight: 600;\n\ttext-transform: uppercase;\n\tletter-spacing: 0.08em;\n\tcolor: var(--muted);\n}\n\n.size-control__range {\n\taccent-color: #111214;\n}\n\n.size-control__value {\n\tmin-width: 2rem;\n\ttext-align: right;\n\tfont-size: 0.82rem;\n\tfont-weight: 700;\n}\n\n.header-button:hover,\n.tool-chip:hover,\n.swatch:hover {\n\ttransform: translateY(-1px);\n}\n\n.lucide {\n\twidth: 0.95rem;\n\theight: 0.95rem;\n\tstroke-width: 2.1;\n}\n\n@media (max-width: 860px) {\n\t.app-header {\n\t\tgap: 0.75rem;\n\t}\n\n\t.app-header__identity {\n\t\tpadding: 0.7rem 0.85rem;\n\t}\n\n\t.app-header__title {\n\t\tfont-size: 0.98rem;\n\t}\n\n\t.dock {\n\t\tleft: 0.75rem;\n\t\tright: 0.75rem;\n\t\tbottom: 0.75rem;\n\t}\n\n\t.size-control {\n\t\tgrid-template-columns: 1fr;\n\t\tmin-width: 100%;\n\t}\n}\n\n@media (max-width: 640px) {\n\t.app-header {\n\t\ttop: 0.7rem;\n\t\tleft: 0.7rem;\n\t\tright: 0.7rem;\n\t}\n\n\t.board__badge {\n\t\ttop: 4.9rem;\n\t\tmax-width: calc(100vw - 1.4rem);\n\t}\n\n\t.app-header__eyebrow {\n\t\tdisplay: none;\n\t}\n\n\t.tool-chip {\n\t\tmin-width: 4.2rem;\n\t\tpadding: 0.58rem 0.72rem;\n\t}\n\n\t.dock {\n\t\tpadding: 0.62rem;\n\t\tborder-radius: 22px;\n\t}\n}\n\n@media (prefers-color-scheme: dark) {\n\t:root {\n\t\t--bg: #1c1d20;\n\t\t--panel: rgba(34, 34, 38, 0.76);\n\t\t--panel-strong: rgba(44, 45, 50, 0.92);\n\t\t--line: rgba(255, 255, 255, 0.08);\n\t\t--text: #f5f5f7;\n\t\t--muted: #a1a1aa;\n\t\t--canvas: #ffffff;\n\t\t--shadow: 0 12px 34px rgba(0, 0, 0, 0.28);\n\t}\n\n\tbody {\n\t\tbackground: #1b1c1f;\n\t}\n\n\t.app-icon {\n\t\tbackground: rgba(255, 255, 255, 0.08);\n\t\tborder-color: rgba(255, 255, 255, 0.06);\n\t}\n\n\t.header-button--primary,\n\t.tool-chip.is-active {\n\t\tbackground: #f5f5f7;\n\t\tborder-color: #f5f5f7;\n\t\tcolor: #111214;\n\t}\n\n\t.board__badge {\n\t\tbackground: rgba(44, 45, 50, 0.86);\n\t}\n\n\t.size-control__range {\n\t\taccent-color: #f5f5f7;\n\t}\n\n\t.swatch.is-active::after {\n\t\tborder-color: #f5f5f7;\n\t}\n}"}],"folders":[]},"variants":null,"createdAt":"2026-03-08T22:33:17.412Z","updatedAt":"2026-03-08T22:33:24.510Z","hasThumbnail":true}}