@ben-million/tweaker 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +66 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -146,6 +146,7 @@ const MOUSE_PADDING_SENSITIVITY = .2;
|
|
|
146
146
|
const MINIMAP_WIDTH_PX = 160;
|
|
147
147
|
const MINIMAP_HEIGHT_PX = 100;
|
|
148
148
|
const THUMB_SIZE_PX = 10;
|
|
149
|
+
const DOM_TREE_MAX_NODES = 40;
|
|
149
150
|
|
|
150
151
|
//#endregion
|
|
151
152
|
//#region src/utils/color.ts
|
|
@@ -287,12 +288,19 @@ const describeModification = (modification) => {
|
|
|
287
288
|
if (modification.textPreview) nameParts.push(`("${modification.textPreview}")`);
|
|
288
289
|
return nameParts.join(" ");
|
|
289
290
|
};
|
|
290
|
-
const
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
291
|
+
const formatTreeNode = (node, indent, newPositionY) => {
|
|
292
|
+
const prefix = " " + " ".repeat(indent);
|
|
293
|
+
const nameParts = [];
|
|
294
|
+
if (node.componentName) nameParts.push(`<${node.componentName}>`);
|
|
295
|
+
nameParts.push(node.selector);
|
|
296
|
+
if (node.textPreview && node.children.length === 0) nameParts.push(`("${node.textPreview}")`);
|
|
297
|
+
const description = nameParts.join(" ");
|
|
298
|
+
const marker = node.isSelf ? "★ " : "";
|
|
299
|
+
const dragSuffix = node.isSelf ? ` → DRAGGED TO Y=${newPositionY}` : "";
|
|
300
|
+
const lines = [];
|
|
301
|
+
lines.push(`${prefix}${marker}${description} — Y=${node.positionY}${dragSuffix}`);
|
|
302
|
+
for (const child of node.children) lines.push(...formatTreeNode(child, indent + 1, newPositionY));
|
|
303
|
+
return lines;
|
|
296
304
|
};
|
|
297
305
|
const generatePrompt = (modifications, scales, scaleKey, repositionContexts) => {
|
|
298
306
|
if (modifications.length === 0) return "";
|
|
@@ -314,24 +322,14 @@ const generatePrompt = (modifications, scales, scaleKey, repositionContexts) =>
|
|
|
314
322
|
if (modification.sourceFile) paddingLines.push(` Source: ${modification.sourceFile}`);
|
|
315
323
|
const context = repositionContexts?.get(index);
|
|
316
324
|
if (context && (modification.translateX !== 0 || modification.translateY !== 0)) {
|
|
317
|
-
const axisLabel = context.axis === "x" ? "X" : "Y";
|
|
318
325
|
positionLines.push(`- ${description}`);
|
|
319
326
|
if (modification.sourceFile) positionLines.push(` Source: ${modification.sourceFile}`);
|
|
320
|
-
positionLines.push(` Dragged from
|
|
327
|
+
positionLines.push(` Dragged from Y=${context.originalPositionY} to Y=${context.newPositionY} (offset: ${context.translateX}px horizontal, ${context.translateY}px vertical)`);
|
|
321
328
|
positionLines.push("");
|
|
322
|
-
positionLines.push(`
|
|
323
|
-
positionLines.push(
|
|
324
|
-
if (context.parentSourceFile) positionLines.push(` Source: ${context.parentSourceFile}`);
|
|
329
|
+
positionLines.push(` Page structure (Y = absolute position from document top):`);
|
|
330
|
+
positionLines.push(...formatTreeNode(context.tree, 0, context.newPositionY));
|
|
325
331
|
positionLines.push("");
|
|
326
|
-
positionLines.push(`
|
|
327
|
-
context.siblings.forEach((sibling, siblingIndex) => {
|
|
328
|
-
const marker = sibling.isSelf ? "★" : " ";
|
|
329
|
-
const dragNote = sibling.isSelf ? ` → DRAGGED TO ${axisLabel}=${context.newPosition}` : "";
|
|
330
|
-
positionLines.push(` ${marker} ${siblingIndex + 1}. ${describeSibling(sibling)} — ${axisLabel}=${sibling.position}${dragNote}`);
|
|
331
|
-
if (sibling.sourceFile) positionLines.push(` Source: ${sibling.sourceFile}`);
|
|
332
|
-
});
|
|
333
|
-
positionLines.push("");
|
|
334
|
-
positionLines.push(` → Move this element to position ${context.suggestedIndex + 1} in the JSX (re-order the JSX elements in the source file to match).`);
|
|
332
|
+
positionLines.push(` → Based on the Y positions above, move this element to its closest logical position in the JSX source.`);
|
|
335
333
|
}
|
|
336
334
|
});
|
|
337
335
|
const sections = [];
|
|
@@ -362,85 +360,64 @@ const getSourceFromStack = async (element, reactGrab) => {
|
|
|
362
360
|
try {
|
|
363
361
|
const stack = await reactGrab.getStack(element);
|
|
364
362
|
if (stack) {
|
|
365
|
-
for (const frame of stack) if (frame.fileName && !frame.fileName.includes("node_modules"))
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
};
|
|
363
|
+
for (const frame of stack) if (frame.fileName && !frame.fileName.includes("node_modules")) {
|
|
364
|
+
if (frame.functionName && /^[A-Z]/.test(frame.functionName)) return frame.functionName;
|
|
365
|
+
}
|
|
369
366
|
}
|
|
370
367
|
} catch {}
|
|
368
|
+
return null;
|
|
369
|
+
};
|
|
370
|
+
const getAncestorPath = (element) => {
|
|
371
|
+
const path = [];
|
|
372
|
+
let current = element;
|
|
373
|
+
while (current && current !== document.body && current !== document.documentElement) {
|
|
374
|
+
path.unshift(current);
|
|
375
|
+
current = current.parentElement;
|
|
376
|
+
}
|
|
377
|
+
return path;
|
|
378
|
+
};
|
|
379
|
+
const buildTreeNode = async (node, ancestorSet, targetElement, targetTranslateY, reactGrab, nodeCount) => {
|
|
380
|
+
if (nodeCount.value >= DOM_TREE_MAX_NODES) return null;
|
|
381
|
+
nodeCount.value++;
|
|
382
|
+
const isSelf = node === targetElement;
|
|
383
|
+
const isOnAncestorPath = ancestorSet.has(node) && !isSelf;
|
|
384
|
+
const rect = node.getBoundingClientRect();
|
|
385
|
+
const positionY = Math.round(rect.top + window.scrollY - (isSelf ? targetTranslateY : 0));
|
|
386
|
+
const componentName = reactGrab ? await getSourceFromStack(node, reactGrab) : null;
|
|
387
|
+
const children = [];
|
|
388
|
+
if (isOnAncestorPath) {
|
|
389
|
+
const childElements = Array.from(node.children).filter((child) => child instanceof HTMLElement);
|
|
390
|
+
for (const child of childElements) {
|
|
391
|
+
if (nodeCount.value >= DOM_TREE_MAX_NODES) break;
|
|
392
|
+
const childNode = await buildTreeNode(child, ancestorSet, targetElement, targetTranslateY, reactGrab, nodeCount);
|
|
393
|
+
if (childNode) children.push(childNode);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
371
396
|
return {
|
|
372
|
-
|
|
373
|
-
|
|
397
|
+
selector: getSelector(node),
|
|
398
|
+
textPreview: getTextPreview(node),
|
|
399
|
+
componentName,
|
|
400
|
+
positionY,
|
|
401
|
+
isSelf,
|
|
402
|
+
children
|
|
374
403
|
};
|
|
375
404
|
};
|
|
376
405
|
const gatherRepositionContext = async (element, translateX, translateY) => {
|
|
377
|
-
const
|
|
378
|
-
if (
|
|
406
|
+
const ancestorPath = getAncestorPath(element);
|
|
407
|
+
if (ancestorPath.length === 0) return null;
|
|
408
|
+
const ancestorSet = new Set(ancestorPath);
|
|
379
409
|
const reactGrab = getReactGrabModule();
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
const
|
|
383
|
-
const
|
|
384
|
-
const
|
|
385
|
-
const layoutParts = [display];
|
|
386
|
-
if (display === "flex" || display === "inline-flex") {
|
|
387
|
-
layoutParts.push(flexDir);
|
|
388
|
-
if (parentStyle.gap && parentStyle.gap !== "normal" && parentStyle.gap !== "0px") layoutParts.push(`gap: ${parentStyle.gap}`);
|
|
389
|
-
}
|
|
390
|
-
if (display === "grid" || display === "inline-grid") {
|
|
391
|
-
if (parentStyle.gap && parentStyle.gap !== "normal" && parentStyle.gap !== "0px") layoutParts.push(`gap: ${parentStyle.gap}`);
|
|
392
|
-
}
|
|
393
|
-
let parentComponentName = null;
|
|
394
|
-
let parentSourceFile = null;
|
|
395
|
-
if (reactGrab) {
|
|
396
|
-
const source = await getSourceFromStack(parent, reactGrab);
|
|
397
|
-
parentComponentName = source.componentName;
|
|
398
|
-
parentSourceFile = source.sourceFile;
|
|
399
|
-
}
|
|
400
|
-
const children = Array.from(parent.children).filter((child) => child instanceof HTMLElement);
|
|
401
|
-
const siblings = [];
|
|
402
|
-
for (const child of children) {
|
|
403
|
-
const childRect = child.getBoundingClientRect();
|
|
404
|
-
const isSelf = child === element;
|
|
405
|
-
const pos = isHorizontal ? childRect.left : childRect.top;
|
|
406
|
-
let componentName = null;
|
|
407
|
-
let sourceFile = null;
|
|
408
|
-
if (reactGrab) {
|
|
409
|
-
const source = await getSourceFromStack(child, reactGrab);
|
|
410
|
-
componentName = source.componentName;
|
|
411
|
-
sourceFile = source.sourceFile;
|
|
412
|
-
}
|
|
413
|
-
siblings.push({
|
|
414
|
-
selector: getSelector(child),
|
|
415
|
-
textPreview: getTextPreview(child),
|
|
416
|
-
componentName,
|
|
417
|
-
sourceFile,
|
|
418
|
-
position: Math.round(isSelf ? pos : pos),
|
|
419
|
-
isSelf
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
const selfRect = element.getBoundingClientRect();
|
|
423
|
-
const currentPos = Math.round(isHorizontal ? selfRect.left : selfRect.top);
|
|
424
|
-
const originalPos = Math.round(isHorizontal ? selfRect.left - translateX : selfRect.top - translateY);
|
|
425
|
-
const newPos = currentPos;
|
|
426
|
-
const positionsForSort = siblings.map((sibling) => ({
|
|
427
|
-
...sibling,
|
|
428
|
-
sortPosition: sibling.isSelf ? newPos : sibling.position
|
|
429
|
-
}));
|
|
430
|
-
positionsForSort.sort((a, b) => a.sortPosition - b.sortPosition);
|
|
431
|
-
const suggestedIndex = positionsForSort.findIndex((s) => s.isSelf);
|
|
410
|
+
const tree = await buildTreeNode(ancestorPath[0], ancestorSet, element, translateY, reactGrab, { value: 0 });
|
|
411
|
+
if (!tree) return null;
|
|
412
|
+
const rect = element.getBoundingClientRect();
|
|
413
|
+
const currentY = Math.round(rect.top + window.scrollY);
|
|
414
|
+
const originalY = Math.round(currentY - translateY);
|
|
432
415
|
return {
|
|
433
416
|
translateX: Math.round(translateX),
|
|
434
417
|
translateY: Math.round(translateY),
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
parentSelector: getSelector(parent),
|
|
439
|
-
parentComponentName,
|
|
440
|
-
parentSourceFile,
|
|
441
|
-
parentLayout: layoutParts.join(", "),
|
|
442
|
-
siblings,
|
|
443
|
-
suggestedIndex
|
|
418
|
+
originalPositionY: originalY,
|
|
419
|
+
newPositionY: currentY,
|
|
420
|
+
tree
|
|
444
421
|
};
|
|
445
422
|
};
|
|
446
423
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/gray-scales.ts","../src/constants.ts","../src/utils/color.ts","../src/utils/dom.ts","../src/utils/modification.ts","../src/utils/prompt.ts","../src/utils/nearby.ts","../src/tweaker.tsx"],"sourcesContent":["import type { GrayScale } from \"./types\";\n\nexport const GRAY_SCALES: Record<string, GrayScale> = {\n neutral: {\n label: \"Neutral\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.97 0 0)\",\n \"200\": \"oklch(0.922 0 0)\",\n \"300\": \"oklch(0.87 0 0)\",\n \"400\": \"oklch(0.708 0 0)\",\n \"500\": \"oklch(0.556 0 0)\",\n \"600\": \"oklch(0.439 0 0)\",\n \"700\": \"oklch(0.371 0 0)\",\n \"800\": \"oklch(0.269 0 0)\",\n \"900\": \"oklch(0.205 0 0)\",\n \"950\": \"oklch(0.145 0 0)\",\n },\n },\n slate: {\n label: \"Slate\",\n shades: {\n \"50\": \"oklch(0.984 0.003 247.858)\",\n \"100\": \"oklch(0.968 0.007 247.896)\",\n \"200\": \"oklch(0.929 0.013 255.508)\",\n \"300\": \"oklch(0.869 0.022 252.894)\",\n \"400\": \"oklch(0.704 0.04 256.788)\",\n \"500\": \"oklch(0.554 0.046 257.417)\",\n \"600\": \"oklch(0.446 0.043 257.281)\",\n \"700\": \"oklch(0.372 0.044 257.287)\",\n \"800\": \"oklch(0.279 0.041 260.031)\",\n \"900\": \"oklch(0.208 0.042 265.755)\",\n \"950\": \"oklch(0.129 0.042 264.695)\",\n },\n },\n gray: {\n label: \"Gray\",\n shades: {\n \"50\": \"oklch(0.985 0.002 247.839)\",\n \"100\": \"oklch(0.967 0.003 264.542)\",\n \"200\": \"oklch(0.928 0.006 264.531)\",\n \"300\": \"oklch(0.872 0.01 258.338)\",\n \"400\": \"oklch(0.707 0.022 261.325)\",\n \"500\": \"oklch(0.551 0.027 264.364)\",\n \"600\": \"oklch(0.446 0.03 256.802)\",\n \"700\": \"oklch(0.373 0.034 259.733)\",\n \"800\": \"oklch(0.278 0.033 256.848)\",\n \"900\": \"oklch(0.21 0.034 264.665)\",\n \"950\": \"oklch(0.13 0.028 261.692)\",\n },\n },\n zinc: {\n label: \"Zinc\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.967 0.001 286.375)\",\n \"200\": \"oklch(0.92 0.004 286.32)\",\n \"300\": \"oklch(0.871 0.006 286.286)\",\n \"400\": \"oklch(0.705 0.015 286.067)\",\n \"500\": \"oklch(0.552 0.016 285.938)\",\n \"600\": \"oklch(0.442 0.017 285.786)\",\n \"700\": \"oklch(0.37 0.013 285.805)\",\n \"800\": \"oklch(0.274 0.006 286.033)\",\n \"900\": \"oklch(0.21 0.006 285.885)\",\n \"950\": \"oklch(0.141 0.005 285.823)\",\n },\n },\n stone: {\n label: \"Stone\",\n shades: {\n \"50\": \"oklch(0.985 0.001 106.423)\",\n \"100\": \"oklch(0.97 0.001 106.424)\",\n \"200\": \"oklch(0.923 0.003 48.717)\",\n \"300\": \"oklch(0.869 0.005 56.366)\",\n \"400\": \"oklch(0.709 0.01 56.259)\",\n \"500\": \"oklch(0.553 0.013 58.071)\",\n \"600\": \"oklch(0.444 0.011 73.639)\",\n \"700\": \"oklch(0.374 0.01 67.558)\",\n \"800\": \"oklch(0.268 0.007 34.298)\",\n \"900\": \"oklch(0.216 0.006 56.043)\",\n \"950\": \"oklch(0.147 0.004 49.25)\",\n },\n },\n mauve: {\n label: \"Mauve\",\n shades: {\n \"50\": \"oklch(0.985 0.003 310)\",\n \"100\": \"oklch(0.968 0.006 310)\",\n \"200\": \"oklch(0.925 0.011 310)\",\n \"300\": \"oklch(0.87 0.017 310)\",\n \"400\": \"oklch(0.708 0.03 310)\",\n \"500\": \"oklch(0.556 0.03 310)\",\n \"600\": \"oklch(0.44 0.028 310)\",\n \"700\": \"oklch(0.372 0.025 310)\",\n \"800\": \"oklch(0.27 0.02 310)\",\n \"900\": \"oklch(0.208 0.018 310)\",\n \"950\": \"oklch(0.145 0.014 310)\",\n },\n },\n olive: {\n label: \"Olive\",\n shades: {\n \"50\": \"oklch(0.985 0.003 130)\",\n \"100\": \"oklch(0.968 0.006 130)\",\n \"200\": \"oklch(0.925 0.011 130)\",\n \"300\": \"oklch(0.87 0.017 130)\",\n \"400\": \"oklch(0.708 0.028 130)\",\n \"500\": \"oklch(0.556 0.028 130)\",\n \"600\": \"oklch(0.44 0.024 130)\",\n \"700\": \"oklch(0.372 0.02 130)\",\n \"800\": \"oklch(0.27 0.016 130)\",\n \"900\": \"oklch(0.208 0.014 130)\",\n \"950\": \"oklch(0.145 0.01 130)\",\n },\n },\n};\n","export const SLIDER_MAX = 10;\nexport const TEXT_PREVIEW_MAX_LENGTH = 30;\nexport const TYPING_RESET_DELAY_MS = 1500;\nexport const SHADE_KEYS = [\"50\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"950\"];\nexport const FONT_SIZE_MIN_PX = 1;\nexport const FONT_SIZE_MAX_PX = 200;\nexport const PADDING_MIN_PX = -200;\nexport const PADDING_MAX_PX = 200;\nexport const MOUSE_COLOR_SENSITIVITY = 0.02;\nexport const MOUSE_SIZE_SENSITIVITY = 0.1;\nexport const MOUSE_PADDING_SENSITIVITY = 0.2;\nexport const MINIMAP_WIDTH_PX = 160;\nexport const MINIMAP_HEIGHT_PX = 100;\nexport const THUMB_SIZE_PX = 10;\nexport const NEARBY_SAMPLE_OFFSET_PX = 20;\n","import type { OKLCH } from \"../types\";\nimport { SHADE_KEYS, SLIDER_MAX } from \"../constants\";\nimport type { GrayScale } from \"../types\";\n\nexport const parseOklch = (oklchStr: string): OKLCH => {\n const match = oklchStr.match(/oklch\\(([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)\\)/);\n if (!match) return [0, 0, 0];\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n};\n\nexport const lerpOklch = (colorA: OKLCH, colorB: OKLCH, interpolation: number): OKLCH => [\n colorA[0] + (colorB[0] - colorA[0]) * interpolation,\n colorA[1] + (colorB[1] - colorA[1]) * interpolation,\n colorA[2] + (colorB[2] - colorA[2]) * interpolation,\n];\n\nexport const formatOklch = (oklch: OKLCH): string =>\n `oklch(${oklch[0].toFixed(3)} ${oklch[1].toFixed(3)} ${oklch[2].toFixed(1)})`;\n\nexport const oklchToCssString = (oklch: OKLCH): string =>\n `oklch(${oklch[0]} ${oklch[1]} ${oklch[2]})`;\n\nexport const getColorAtPosition = (scales: Record<string, GrayScale>, scaleKey: string, position: number): OKLCH => {\n const scale = scales[scaleKey];\n if (!scale) return [0.5, 0, 0];\n\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.min(Math.floor(segment), SHADE_KEYS.length - 2);\n const interpolation = segment - index;\n\n const lower = parseOklch(scale.shades[SHADE_KEYS[index]]);\n const upper = parseOklch(scale.shades[SHADE_KEYS[index + 1]]);\n\n return lerpOklch(lower, upper, interpolation);\n};\n\nexport const getClosestShadeLabel = (position: number): string => {\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.round(segment);\n return SHADE_KEYS[Math.min(index, SHADE_KEYS.length - 1)];\n};\n\nexport const parseRgb = (color: string): [number, number, number, number] => {\n const match = color.match(\n /rgba?\\(\\s*([\\d.]+),\\s*([\\d.]+),\\s*([\\d.]+)(?:,\\s*([\\d.]+))?\\s*\\)/\n );\n if (!match) return [0, 0, 0, 0];\n return [\n Number(match[1]),\n Number(match[2]),\n Number(match[3]),\n match[4] !== undefined ? Number(match[4]) : 1,\n ];\n};\n\nexport const rgbToOklch = (red: number, green: number, blue: number): OKLCH => {\n const linearize = (channel: number): number => {\n const normalized = channel / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n };\n const linearRed = linearize(red);\n const linearGreen = linearize(green);\n const linearBlue = linearize(blue);\n\n const lmsL = Math.cbrt(0.4122214708 * linearRed + 0.5363325363 * linearGreen + 0.0514459929 * linearBlue);\n const lmsM = Math.cbrt(0.2119034982 * linearRed + 0.6806995451 * linearGreen + 0.1073969566 * linearBlue);\n const lmsS = Math.cbrt(0.0883024619 * linearRed + 0.2817188376 * linearGreen + 0.6299787005 * linearBlue);\n\n const lightness = 0.2104542553 * lmsL + 0.793617785 * lmsM - 0.0040720468 * lmsS;\n const labA = 1.9779984951 * lmsL - 2.428592205 * lmsM + 0.4505937099 * lmsS;\n const labB = 0.0259040371 * lmsL + 0.7827717662 * lmsM - 0.808675766 * lmsS;\n\n const chroma = Math.sqrt(labA * labA + labB * labB);\n const hue = Math.atan2(labB, labA) * (180 / Math.PI);\n\n return [lightness, chroma, hue < 0 ? hue + 360 : hue];\n};\n\nexport const findClosestPosition = (scales: Record<string, GrayScale>, scaleKey: string, targetOklch: OKLCH): number => {\n let bestPosition = 0;\n let bestDistance = Infinity;\n\n for (let position = 0; position <= SLIDER_MAX; position++) {\n const color = getColorAtPosition(scales, scaleKey, position);\n const distance =\n (color[0] - targetOklch[0]) ** 2 +\n (color[1] - targetOklch[1]) ** 2 +\n ((color[2] - targetOklch[2]) / 360) ** 2;\n if (distance < bestDistance) {\n bestDistance = distance;\n bestPosition = position;\n }\n }\n\n return bestPosition;\n};\n","import { TEXT_PREVIEW_MAX_LENGTH } from \"../constants\";\n\nexport const getSelector = (element: HTMLElement): string => {\n const tag = element.tagName.toLowerCase();\n const classes = Array.from(element.classList)\n .filter((className) => !className.startsWith(\"__\"))\n .slice(0, 2)\n .join(\".\");\n return classes ? `${tag}.${classes}` : tag;\n};\n\nexport const getTextPreview = (element: HTMLElement): string => {\n const text = element.textContent?.trim() || \"\";\n return text.length > TEXT_PREVIEW_MAX_LENGTH\n ? `${text.slice(0, TEXT_PREVIEW_MAX_LENGTH)}…`\n : text;\n};\n","import type { GrayScale, Modification } from \"../types\";\nimport { getColorAtPosition, oklchToCssString } from \"./color\";\n\nexport const applyModification = (\n modification: Modification,\n scales: Record<string, GrayScale>,\n scaleKey: string,\n) => {\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const colorValue = oklchToCssString(oklch);\n if (modification.property === \"bg\") {\n modification.element.style.backgroundColor = colorValue;\n } else if (modification.property === \"text\") {\n modification.element.style.color = colorValue;\n } else {\n modification.element.style.borderColor = colorValue;\n }\n modification.element.style.fontSize = `${modification.fontSize}px`;\n\n const paddingY = Math.round(modification.paddingY);\n\n modification.element.style.paddingTop = `${Math.max(0, paddingY)}px`;\n modification.element.style.paddingBottom = `${Math.max(0, paddingY)}px`;\n\n modification.element.style.marginTop = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginTop;\n modification.element.style.marginBottom = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginBottom;\n\n if (modification.translateX !== 0 || modification.translateY !== 0) {\n modification.element.style.transform = `translate(${modification.translateX}px, ${modification.translateY}px)`;\n } else {\n modification.element.style.transform = modification.originalInlineTransform;\n }\n};\n\nexport const restoreModification = (modification: Modification) => {\n modification.element.style.backgroundColor = modification.originalInlineBg;\n modification.element.style.color = modification.originalInlineColor;\n modification.element.style.borderColor = modification.originalInlineBorderColor;\n modification.element.style.fontSize = modification.originalInlineFontSize;\n modification.element.style.paddingTop = modification.originalInlinePaddingTop;\n modification.element.style.paddingBottom = modification.originalInlinePaddingBottom;\n modification.element.style.marginTop = modification.originalInlineMarginTop;\n modification.element.style.marginBottom = modification.originalInlineMarginBottom;\n modification.element.style.transform = modification.originalInlineTransform;\n};\n\nexport const roundToStep = (value: number): number =>\n parseFloat((Math.round(value * 10) / 10).toFixed(1));\n\nexport const roundToHalf = (value: number): number =>\n Math.round(value * 2) / 2;\n","import type { GrayScale, Modification } from \"../types\";\nimport type { RepositionContext } from \"./nearby\";\nimport { formatOklch, getColorAtPosition, getClosestShadeLabel } from \"./color\";\n\nconst describeModification = (modification: Modification): string => {\n const nameParts = [modification.selector];\n if (modification.componentName) nameParts.unshift(`<${modification.componentName}>`);\n if (modification.textPreview) nameParts.push(`(\"${modification.textPreview}\")`);\n return nameParts.join(\" \");\n};\n\nconst describeSibling = (sibling: { componentName: string | null; selector: string; textPreview: string }): string => {\n const parts: string[] = [];\n if (sibling.componentName) parts.push(`<${sibling.componentName}>`);\n parts.push(sibling.selector);\n if (sibling.textPreview) parts.push(`(\"${sibling.textPreview}\")`);\n return parts.join(\" \");\n};\n\nexport const generatePrompt = (\n modifications: Modification[],\n scales: Record<string, GrayScale>,\n scaleKey: string,\n repositionContexts?: Map<number, RepositionContext>,\n): string => {\n if (modifications.length === 0) return \"\";\n\n const scaleName = scales[scaleKey]?.label || scaleKey;\n const colorLines: string[] = [];\n const sizeLines: string[] = [];\n const paddingLines: string[] = [];\n const positionLines: string[] = [];\n\n modifications.forEach((modification, index) => {\n const description = describeModification(modification);\n\n const shade = getClosestShadeLabel(modification.position);\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const property =\n modification.property === \"bg\"\n ? \"background color\"\n : modification.property === \"text\"\n ? \"text color\"\n : \"border color\";\n colorLines.push(`- ${property} of ${description} → ${scaleName} ${shade} (${formatOklch(oklch)})`);\n if (modification.sourceFile) colorLines.push(` Source: ${modification.sourceFile}`);\n\n sizeLines.push(`- font-size of ${description} → ${modification.fontSize}px`);\n if (modification.sourceFile) sizeLines.push(` Source: ${modification.sourceFile}`);\n\n paddingLines.push(`- vertical padding of ${description} → ${Math.round(modification.paddingY)}px`);\n if (modification.sourceFile) paddingLines.push(` Source: ${modification.sourceFile}`);\n\n const context = repositionContexts?.get(index);\n if (context && (modification.translateX !== 0 || modification.translateY !== 0)) {\n const axisLabel = context.axis === \"x\" ? \"X\" : \"Y\";\n positionLines.push(`- ${description}`);\n if (modification.sourceFile) positionLines.push(` Source: ${modification.sourceFile}`);\n positionLines.push(` Dragged from ${axisLabel}=${context.originalPosition} to ${axisLabel}=${context.newPosition} (offset: ${context.translateX}px horizontal, ${context.translateY}px vertical)`);\n positionLines.push(\"\");\n positionLines.push(` Parent: ${context.parentComponentName ? `<${context.parentComponentName}> ` : \"\"}${context.parentSelector}`);\n positionLines.push(` Layout: ${context.parentLayout}`);\n if (context.parentSourceFile) positionLines.push(` Source: ${context.parentSourceFile}`);\n positionLines.push(\"\");\n positionLines.push(` Siblings in current DOM order (${axisLabel} positions):`);\n\n context.siblings.forEach((sibling, siblingIndex) => {\n const marker = sibling.isSelf ? \"★\" : \" \";\n const dragNote = sibling.isSelf\n ? ` → DRAGGED TO ${axisLabel}=${context.newPosition}`\n : \"\";\n positionLines.push(` ${marker} ${siblingIndex + 1}. ${describeSibling(sibling)} — ${axisLabel}=${sibling.position}${dragNote}`);\n if (sibling.sourceFile) positionLines.push(` Source: ${sibling.sourceFile}`);\n });\n\n positionLines.push(\"\");\n positionLines.push(` → Move this element to position ${context.suggestedIndex + 1} in the JSX (re-order the JSX elements in the source file to match).`);\n }\n });\n\n const sections: string[] = [];\n\n if (colorLines.length > 0) {\n sections.push(\n \"Change the following colors using the design system's gray scale:\",\n \"\",\n ...colorLines,\n );\n }\n\n if (sizeLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following font sizes:\", \"\", ...sizeLines);\n }\n\n if (paddingLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following padding:\", \"\", ...paddingLines);\n }\n\n if (positionLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\n \"Reposition the following element in the source code (do NOT use CSS transforms — re-order the JSX):\",\n \"\",\n ...positionLines,\n );\n }\n\n return sections.join(\"\\n\");\n};\n","import { getSelector, getTextPreview } from \"./dom\";\n\ninterface StackFrame {\n fileName?: string;\n lineNumber?: number;\n functionName?: string;\n}\n\ninterface ReactGrabModule {\n getStack: (element: Element) => Promise<StackFrame[]>;\n}\n\nexport interface SiblingInfo {\n selector: string;\n textPreview: string;\n componentName: string | null;\n sourceFile: string | null;\n position: number;\n isSelf: boolean;\n}\n\nexport interface RepositionContext {\n translateX: number;\n translateY: number;\n originalPosition: number;\n newPosition: number;\n axis: \"y\" | \"x\";\n parentSelector: string;\n parentComponentName: string | null;\n parentSourceFile: string | null;\n parentLayout: string;\n siblings: SiblingInfo[];\n suggestedIndex: number;\n}\n\nconst getReactGrabModule = (): ReactGrabModule | null => {\n const module = (window as unknown as Record<string, unknown>)\n .__REACT_GRAB_MODULE__ as ReactGrabModule | undefined;\n if (module && typeof module.getStack === \"function\") {\n return module;\n }\n return null;\n};\n\nconst getSourceFromStack = async (\n element: Element,\n reactGrab: ReactGrabModule,\n): Promise<{ componentName: string | null; sourceFile: string | null }> => {\n try {\n const stack = await reactGrab.getStack(element);\n if (stack) {\n for (const frame of stack) {\n if (frame.fileName && !frame.fileName.includes(\"node_modules\")) {\n return {\n sourceFile: frame.fileName,\n componentName:\n frame.functionName && /^[A-Z]/.test(frame.functionName)\n ? frame.functionName\n : null,\n };\n }\n }\n }\n } catch {}\n return { componentName: null, sourceFile: null };\n};\n\nexport const gatherRepositionContext = async (\n element: HTMLElement,\n translateX: number,\n translateY: number,\n): Promise<RepositionContext | null> => {\n const parent = element.parentElement;\n if (!parent) return null;\n\n const reactGrab = getReactGrabModule();\n const parentStyle = getComputedStyle(parent);\n const display = parentStyle.display;\n const flexDir = parentStyle.flexDirection;\n\n const isHorizontal =\n (display === \"flex\" || display === \"inline-flex\") &&\n (flexDir === \"row\" || flexDir === \"row-reverse\");\n const axis = isHorizontal ? \"x\" : \"y\";\n\n const layoutParts: string[] = [display];\n if (display === \"flex\" || display === \"inline-flex\") {\n layoutParts.push(flexDir);\n if (parentStyle.gap && parentStyle.gap !== \"normal\" && parentStyle.gap !== \"0px\") {\n layoutParts.push(`gap: ${parentStyle.gap}`);\n }\n }\n if (display === \"grid\" || display === \"inline-grid\") {\n if (parentStyle.gap && parentStyle.gap !== \"normal\" && parentStyle.gap !== \"0px\") {\n layoutParts.push(`gap: ${parentStyle.gap}`);\n }\n }\n\n let parentComponentName: string | null = null;\n let parentSourceFile: string | null = null;\n if (reactGrab) {\n const source = await getSourceFromStack(parent, reactGrab);\n parentComponentName = source.componentName;\n parentSourceFile = source.sourceFile;\n }\n\n const children = Array.from(parent.children).filter(\n (child): child is HTMLElement => child instanceof HTMLElement,\n );\n\n const siblings: SiblingInfo[] = [];\n for (const child of children) {\n const childRect = child.getBoundingClientRect();\n const isSelf = child === element;\n const pos = isHorizontal ? childRect.left : childRect.top;\n\n let componentName: string | null = null;\n let sourceFile: string | null = null;\n if (reactGrab) {\n const source = await getSourceFromStack(child, reactGrab);\n componentName = source.componentName;\n sourceFile = source.sourceFile;\n }\n\n siblings.push({\n selector: getSelector(child),\n textPreview: getTextPreview(child),\n componentName,\n sourceFile,\n position: Math.round(isSelf ? pos : pos),\n isSelf,\n });\n }\n\n const selfRect = element.getBoundingClientRect();\n const currentPos = Math.round(isHorizontal ? selfRect.left : selfRect.top);\n const originalPos = Math.round(\n isHorizontal ? selfRect.left - translateX : selfRect.top - translateY,\n );\n const newPos = currentPos;\n\n const positionsForSort = siblings.map((sibling) => ({\n ...sibling,\n sortPosition: sibling.isSelf ? newPos : sibling.position,\n }));\n positionsForSort.sort((a, b) => a.sortPosition - b.sortPosition);\n const suggestedIndex = positionsForSort.findIndex((s) => s.isSelf);\n\n return {\n translateX: Math.round(translateX),\n translateY: Math.round(translateY),\n originalPosition: originalPos,\n newPosition: newPos,\n axis,\n parentSelector: getSelector(parent),\n parentComponentName,\n parentSourceFile,\n parentLayout: layoutParts.join(\", \"),\n siblings,\n suggestedIndex,\n };\n};\n","import { useState, useCallback, useEffect, useRef } from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { Modification, TweakerProps } from \"./types\";\nimport { GRAY_SCALES } from \"./gray-scales\";\nimport { SLIDER_MAX, TYPING_RESET_DELAY_MS, FONT_SIZE_MIN_PX, FONT_SIZE_MAX_PX, PADDING_MIN_PX, PADDING_MAX_PX, MOUSE_COLOR_SENSITIVITY, MOUSE_SIZE_SENSITIVITY, MOUSE_PADDING_SENSITIVITY, MINIMAP_WIDTH_PX, MINIMAP_HEIGHT_PX, THUMB_SIZE_PX } from \"./constants\";\nimport { getColorAtPosition, oklchToCssString, parseRgb, rgbToOklch, findClosestPosition } from \"./utils/color\";\nimport { getSelector, getTextPreview } from \"./utils/dom\";\nimport { applyModification, restoreModification, roundToStep, roundToHalf } from \"./utils/modification\";\nimport { generatePrompt } from \"./utils/prompt\";\nimport { gatherRepositionContext } from \"./utils/nearby\";\nimport type { RepositionContext } from \"./utils/nearby\";\n\nconst requestLock = () => {\n if (!document.pointerLockElement) {\n document.body.requestPointerLock();\n }\n};\n\nconst releaseLock = () => {\n if (document.pointerLockElement) {\n document.exitPointerLock();\n }\n};\n\nexport const Tweaker = ({ scales = GRAY_SCALES, activeScale = \"neutral\" }: TweakerProps) => {\n const [picking, setPicking] = useState(false);\n const [modifications, setModifications] = useState<Modification[]>([]);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [inputValue, setInputValue] = useState(\"\");\n const [shiftHeld, setShiftHeld] = useState(false);\n const [spaceHeld, setSpaceHeld] = useState(false);\n const [controlHeld, setControlHeld] = useState(false);\n const typingBuffer = useRef(\"\");\n const typingTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const activeMod = activeIndex >= 0 ? modifications[activeIndex] : null;\n const hasModifications = modifications.length > 0;\n\n const activeIndexRef = useRef(activeIndex);\n const activeScaleRef = useRef(activeScale);\n const modificationsRef = useRef(modifications);\n const scalesRef = useRef(scales);\n activeIndexRef.current = activeIndex;\n activeScaleRef.current = activeScale;\n modificationsRef.current = modifications;\n scalesRef.current = scales;\n\n const updateActivePosition = useCallback(\n (newPosition: number) => {\n if (activeIndex < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n updated[activeIndex] = { ...updated[activeIndex], position: newPosition };\n applyModification(updated[activeIndex], scales, activeScale);\n return updated;\n });\n },\n [activeIndex, activeScale, scales],\n );\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(true);\n if (event.key === \"Control\") setControlHeld(true);\n };\n const handleKeyUp = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(false);\n if (event.key === \"Control\") setControlHeld(false);\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"keyup\", handleKeyUp);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"keyup\", handleKeyUp);\n };\n }, []);\n\n useEffect(() => {\n if (!hasModifications || picking) return;\n\n const handleMouseMove = (event: MouseEvent) => {\n if (!document.pointerLockElement) return;\n const index = activeIndexRef.current;\n if (index < 0) return;\n\n setModifications((previous) => {\n const updated = [...previous];\n const current = updated[index];\n\n if (event.ctrlKey) {\n updated[index] = {\n ...current,\n translateX: current.translateX + event.movementX,\n translateY: current.translateY + event.movementY,\n };\n } else if (event.shiftKey) {\n const newPaddingY = Math.max(PADDING_MIN_PX, Math.min(PADDING_MAX_PX, current.paddingY - event.movementY * MOUSE_PADDING_SENSITIVITY));\n updated[index] = { ...current, paddingY: Math.round(newPaddingY) };\n } else {\n const newPosition = Math.max(0, Math.min(SLIDER_MAX, current.position - event.movementY * MOUSE_COLOR_SENSITIVITY));\n const newSize = Math.max(FONT_SIZE_MIN_PX, Math.min(FONT_SIZE_MAX_PX, current.fontSize + event.movementX * MOUSE_SIZE_SENSITIVITY));\n updated[index] = { ...current, position: roundToStep(newPosition), fontSize: roundToHalf(newSize) };\n }\n\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n setInputValue(String(updated[index].position));\n return updated;\n });\n };\n\n requestLock();\n document.addEventListener(\"mousemove\", handleMouseMove, true);\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove, true);\n releaseLock();\n };\n }, [hasModifications, picking]);\n\n const gatherRepositionContexts = async (\n modifications: Modification[],\n ): Promise<Map<number, RepositionContext>> => {\n const contextMap = new Map<number, RepositionContext>();\n for (let index = 0; index < modifications.length; index++) {\n const modification = modifications[index];\n if (modification.translateX !== 0 || modification.translateY !== 0) {\n const context = await gatherRepositionContext(\n modification.element,\n modification.translateX,\n modification.translateY,\n );\n if (context) contextMap.set(index, context);\n }\n }\n return contextMap;\n };\n\n useEffect(() => {\n if (!hasModifications) return;\n\n const handleKeyDown = async (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n releaseLock();\n const contextMap = await gatherRepositionContexts(modificationsRef.current);\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, contextMap);\n navigator.clipboard.writeText(prompt);\n modificationsRef.current.forEach(restoreModification);\n setModifications([]);\n setActiveIndex(-1);\n setInputValue(\"\");\n }\n\n if (event.key === \"Enter\") {\n event.preventDefault();\n releaseLock();\n const contextMap = await gatherRepositionContexts(modificationsRef.current);\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, contextMap);\n navigator.clipboard.writeText(prompt);\n setPicking(true);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [hasModifications]);\n\n useEffect(() => {\n if (!activeMod || picking) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"Escape\") return;\n\n if ((event.key >= \"0\" && event.key <= \"9\") || event.key === \".\") {\n event.preventDefault();\n const next = typingBuffer.current + event.key;\n\n if (event.key === \".\" && typingBuffer.current.includes(\".\")) return;\n\n const hasDecimal = typingBuffer.current.includes(\".\");\n if (hasDecimal && event.key !== \".\" && typingBuffer.current.split(\".\")[1]?.length >= 1) {\n return;\n }\n\n const parsed = parseFloat(next);\n if (!isNaN(parsed) && parsed > SLIDER_MAX) {\n typingBuffer.current = event.key === \".\" ? \".\" : event.key;\n } else {\n typingBuffer.current = next;\n }\n\n const value = parseFloat(typingBuffer.current);\n if (!isNaN(value)) {\n const clamped = Math.min(SLIDER_MAX, value);\n updateActivePosition(clamped);\n setInputValue(typingBuffer.current);\n }\n\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n\n if (event.key === \"Backspace\") {\n event.preventDefault();\n typingBuffer.current = typingBuffer.current.slice(0, -1);\n if (typingBuffer.current && typingBuffer.current !== \".\") {\n const value = Math.min(SLIDER_MAX, parseFloat(typingBuffer.current));\n updateActivePosition(value);\n setInputValue(typingBuffer.current);\n }\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n clearTimeout(typingTimeout.current);\n };\n }, [activeMod, picking, activeIndex, updateActivePosition]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"t\") {\n event.preventDefault();\n setPicking(true);\n }\n if (hasModifications && (event.key === \"b\" || event.key === \"f\" || event.key === \"d\")) {\n event.preventDefault();\n const property: \"bg\" | \"text\" | \"border\" =\n event.key === \"b\" ? \"bg\" : event.key === \"f\" ? \"text\" : \"border\";\n const index = activeIndexRef.current;\n if (index < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n restoreModification(updated[index]);\n updated[index] = { ...updated[index], property };\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n return updated;\n });\n }\n };\n\n const handleMiddleClick = (event: MouseEvent) => {\n if (event.button !== 1) return;\n event.preventDefault();\n setPicking(true);\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"mousedown\", handleMiddleClick, true);\n document.addEventListener(\"auxclick\", handleMiddleClick, true);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"mousedown\", handleMiddleClick, true);\n document.removeEventListener(\"auxclick\", handleMiddleClick, true);\n };\n }, [hasModifications]);\n\n useEffect(() => {\n return () => {\n modifications.forEach(restoreModification);\n releaseLock();\n };\n }, []);\n\n useEffect(() => {\n if (activeMod) {\n applyModification(activeMod, scales, activeScale);\n }\n }, [activeMod?.position, activeMod?.fontSize, activeMod?.paddingY, activeScale, scales]);\n\n useEffect(() => {\n if (!picking) return;\n\n let hoveredElement: HTMLElement | null = null;\n\n const handleMouseOver = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n hoveredElement = target;\n target.style.outline = \"2px solid #3b82f6\";\n target.style.outlineOffset = \"2px\";\n };\n\n const handleMouseOut = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n if (hoveredElement === target) hoveredElement = null;\n };\n\n const handleClick = async (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n\n const computed = getComputedStyle(target);\n const [bgRed, bgGreen, bgBlue, bgAlpha] = parseRgb(computed.backgroundColor);\n const [textRed, textGreen, textBlue] = parseRgb(computed.color);\n const [borderRed, borderGreen, borderBlue, borderAlpha] = parseRgb(computed.borderColor);\n const hasBorder = borderAlpha > 0 && parseFloat(computed.borderWidth) > 0;\n\n const hasBackground = bgAlpha > 0;\n const defaultProperty: \"bg\" | \"text\" | \"border\" = hasBackground ? \"bg\" : hasBorder ? \"border\" : \"text\";\n const targetOklch =\n defaultProperty === \"bg\"\n ? rgbToOklch(bgRed, bgGreen, bgBlue)\n : defaultProperty === \"border\"\n ? rgbToOklch(borderRed, borderGreen, borderBlue)\n : rgbToOklch(textRed, textGreen, textBlue);\n\n const position = findClosestPosition(scales, activeScale, targetOklch);\n const currentSize = parseFloat(computed.fontSize) || 16;\n const currentPaddingY = parseFloat(computed.paddingTop) || 0;\n\n let componentName: string | null = null;\n let sourceFile: string | null = null;\n try {\n const reactGrab = (window as unknown as Record<string, unknown>).__REACT_GRAB_MODULE__ as {\n getStack: (element: Element) => Promise<Array<{ fileName?: string; lineNumber?: number; functionName?: string }>>;\n } | undefined;\n if (reactGrab?.getStack) {\n const stack = await reactGrab.getStack(target);\n if (stack) {\n for (const frame of stack) {\n if (frame.fileName && !frame.fileName.includes(\"node_modules\")) {\n sourceFile = frame.fileName;\n if (frame.functionName && /^[A-Z]/.test(frame.functionName)) {\n componentName = frame.functionName;\n }\n break;\n }\n }\n }\n }\n } catch {}\n\n const newModification: Modification = {\n element: target,\n selector: getSelector(target),\n componentName,\n sourceFile,\n textPreview: getTextPreview(target),\n originalInlineBg: target.style.backgroundColor,\n originalInlineColor: target.style.color,\n originalInlineBorderColor: target.style.borderColor,\n originalInlineFontSize: target.style.fontSize,\n originalInlinePaddingTop: target.style.paddingTop,\n originalInlinePaddingBottom: target.style.paddingBottom,\n originalInlineMarginTop: target.style.marginTop,\n originalInlineMarginBottom: target.style.marginBottom,\n originalInlineTransform: target.style.transform,\n property: defaultProperty,\n position,\n fontSize: currentSize,\n paddingY: currentPaddingY,\n translateX: 0,\n translateY: 0,\n };\n\n setModifications((previous) => [...previous, newModification]);\n setActiveIndex(modifications.length);\n setInputValue(String(position));\n setPicking(false);\n };\n\n document.addEventListener(\"mouseover\", handleMouseOver, true);\n document.addEventListener(\"mouseout\", handleMouseOut, true);\n document.addEventListener(\"click\", handleClick, true);\n\n return () => {\n document.removeEventListener(\"mouseover\", handleMouseOver, true);\n document.removeEventListener(\"mouseout\", handleMouseOut, true);\n document.removeEventListener(\"click\", handleClick, true);\n if (hoveredElement) {\n hoveredElement.style.outline = \"\";\n hoveredElement.style.outlineOffset = \"\";\n }\n };\n }, [picking, activeScale, scales, modifications.length]);\n\n const fillColor = activeMod\n ? oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position))\n : scales[activeScale]?.shades[\"500\"] ?? \"rgba(255,255,255,0.3)\";\n\n const propertyLabel =\n activeMod?.property === \"text\" ? \"F\" : activeMod?.property === \"border\" ? \"D\" : \"B\";\n\n const isPaddingMode = shiftHeld && hasModifications && !picking;\n const isDragMode = controlHeld && hasModifications && !picking;\n\n const guideRect = activeMod && !picking && !spaceHeld ? activeMod.element.getBoundingClientRect() : null;\n\n const thumbX = activeMod\n ? isPaddingMode\n ? (MINIMAP_WIDTH_PX - THUMB_SIZE_PX) / 2\n : ((activeMod.fontSize - FONT_SIZE_MIN_PX) / (FONT_SIZE_MAX_PX - FONT_SIZE_MIN_PX)) * (MINIMAP_WIDTH_PX - THUMB_SIZE_PX)\n : 0;\n const thumbY = activeMod\n ? isPaddingMode\n ? (1 - (activeMod.paddingY - PADDING_MIN_PX) / (PADDING_MAX_PX - PADDING_MIN_PX)) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : (1 - activeMod.position / SLIDER_MAX) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : MINIMAP_HEIGHT_PX - THUMB_SIZE_PX;\n\n return (\n <>\n {guideRect && activeMod && (\n <div data-tweaker style={guidelinesContainerStyle}>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: guideRect.height,\n boxSizing: \"border-box\",\n border: \"1px solid rgba(59, 130, 246, 0.5)\",\n borderRadius: 1,\n }}\n />\n {activeMod.paddingY > 0 && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderBottom: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.bottom - Math.min(activeMod.paddingY, guideRect.height / 2),\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderTop: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n </>\n )}\n <div\n style={{\n position: \"absolute\",\n left: guideRect.right + 8,\n top: guideRect.top,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n pointerEvents: \"none\",\n }}\n >\n <span style={guidelineLabelStyle}>\n ↕ {activeMod.paddingY}px\n </span>\n <span style={{ ...guidelineLabelStyle, color: \"rgba(59, 130, 246, 0.8)\", background: \"rgba(59, 130, 246, 0.06)\" }}>\n {activeMod.fontSize}px\n </span>\n {(activeMod.translateX !== 0 || activeMod.translateY !== 0) && (\n <span style={{ ...guidelineLabelStyle, color: \"rgba(168, 85, 247, 0.9)\", background: \"rgba(168, 85, 247, 0.08)\" }}>\n {Math.round(activeMod.translateX)}, {Math.round(activeMod.translateY)}\n </span>\n )}\n </div>\n </div>\n )}\n <AnimatePresence>\n {(hasModifications || picking) && (\n <motion.div\n key=\"minimap\"\n data-tweaker\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.2 }}\n style={minimapContainerStyle}\n >\n <div style={minimapFieldStyle}>\n <div\n style={{\n position: \"absolute\",\n left: thumbX,\n top: thumbY,\n width: THUMB_SIZE_PX,\n height: THUMB_SIZE_PX,\n borderRadius: \"50%\",\n background: fillColor,\n border: \"2px solid rgba(255,255,255,0.9)\",\n boxShadow: \"0 1px 4px rgba(0,0,0,0.4)\",\n transition: \"left 50ms, top 50ms\",\n }}\n />\n </div>\n <div style={minimapModeStyle}>\n <span style={minimapLabelStyle}>\n {isDragMode ? \"⌃ Move\" : isPaddingMode ? \"⇧ Padding\" : \"Style\"}\n </span>\n </div>\n <div style={minimapValuesStyle}>\n <span style={minimapLabelStyle}>\n {picking\n ? \"Picking…\"\n : isDragMode\n ? `x: ${activeMod?.translateX ?? 0}`\n : isPaddingMode\n ? `↕ ${activeMod?.paddingY ?? 0}px`\n : `${propertyLabel} ${inputValue || \"0\"}`}\n </span>\n {!picking && activeMod && isDragMode && (\n <span style={minimapLabelStyle}>\n {`y: ${activeMod.translateY}`}\n </span>\n )}\n {!picking && activeMod && !isPaddingMode && !isDragMode && (\n <span style={minimapLabelStyle}>\n {`${activeMod.fontSize}px`}\n </span>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </>\n );\n};\n\nconst baseTextStyle: React.CSSProperties = {\n fontFamily: \"system-ui, sans-serif\",\n fontWeight: 500,\n letterSpacing: \"-0.03em\",\n fontSynthesis: \"none\",\n WebkitFontSmoothing: \"antialiased\",\n};\n\nconst minimapContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n left: 16,\n bottom: 16,\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n};\n\nconst minimapFieldStyle: React.CSSProperties = {\n position: \"relative\",\n width: MINIMAP_WIDTH_PX,\n height: MINIMAP_HEIGHT_PX,\n borderRadius: 8,\n background: \"rgba(0,0,0,0.25)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n boxShadow: \"0 0 0 1px rgba(255,255,255,0.08) inset\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n};\n\nconst minimapModeStyle: React.CSSProperties = {\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapValuesStyle: React.CSSProperties = {\n display: \"flex\",\n justifyContent: \"space-between\",\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 11,\n color: \"rgba(255,255,255,0.6)\",\n whiteSpace: \"nowrap\",\n};\n\nconst guidelinesContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 9998,\n pointerEvents: \"none\",\n};\n\nconst guidelineLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 10,\n lineHeight: \"16px\",\n color: \"rgba(255, 99, 132, 0.9)\",\n background: \"rgba(255, 99, 132, 0.08)\",\n padding: \"0 5px\",\n borderRadius: 3,\n whiteSpace: \"nowrap\",\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/gray-scales.ts","../src/constants.ts","../src/utils/color.ts","../src/utils/dom.ts","../src/utils/modification.ts","../src/utils/prompt.ts","../src/utils/nearby.ts","../src/tweaker.tsx"],"sourcesContent":["import type { GrayScale } from \"./types\";\n\nexport const GRAY_SCALES: Record<string, GrayScale> = {\n neutral: {\n label: \"Neutral\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.97 0 0)\",\n \"200\": \"oklch(0.922 0 0)\",\n \"300\": \"oklch(0.87 0 0)\",\n \"400\": \"oklch(0.708 0 0)\",\n \"500\": \"oklch(0.556 0 0)\",\n \"600\": \"oklch(0.439 0 0)\",\n \"700\": \"oklch(0.371 0 0)\",\n \"800\": \"oklch(0.269 0 0)\",\n \"900\": \"oklch(0.205 0 0)\",\n \"950\": \"oklch(0.145 0 0)\",\n },\n },\n slate: {\n label: \"Slate\",\n shades: {\n \"50\": \"oklch(0.984 0.003 247.858)\",\n \"100\": \"oklch(0.968 0.007 247.896)\",\n \"200\": \"oklch(0.929 0.013 255.508)\",\n \"300\": \"oklch(0.869 0.022 252.894)\",\n \"400\": \"oklch(0.704 0.04 256.788)\",\n \"500\": \"oklch(0.554 0.046 257.417)\",\n \"600\": \"oklch(0.446 0.043 257.281)\",\n \"700\": \"oklch(0.372 0.044 257.287)\",\n \"800\": \"oklch(0.279 0.041 260.031)\",\n \"900\": \"oklch(0.208 0.042 265.755)\",\n \"950\": \"oklch(0.129 0.042 264.695)\",\n },\n },\n gray: {\n label: \"Gray\",\n shades: {\n \"50\": \"oklch(0.985 0.002 247.839)\",\n \"100\": \"oklch(0.967 0.003 264.542)\",\n \"200\": \"oklch(0.928 0.006 264.531)\",\n \"300\": \"oklch(0.872 0.01 258.338)\",\n \"400\": \"oklch(0.707 0.022 261.325)\",\n \"500\": \"oklch(0.551 0.027 264.364)\",\n \"600\": \"oklch(0.446 0.03 256.802)\",\n \"700\": \"oklch(0.373 0.034 259.733)\",\n \"800\": \"oklch(0.278 0.033 256.848)\",\n \"900\": \"oklch(0.21 0.034 264.665)\",\n \"950\": \"oklch(0.13 0.028 261.692)\",\n },\n },\n zinc: {\n label: \"Zinc\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.967 0.001 286.375)\",\n \"200\": \"oklch(0.92 0.004 286.32)\",\n \"300\": \"oklch(0.871 0.006 286.286)\",\n \"400\": \"oklch(0.705 0.015 286.067)\",\n \"500\": \"oklch(0.552 0.016 285.938)\",\n \"600\": \"oklch(0.442 0.017 285.786)\",\n \"700\": \"oklch(0.37 0.013 285.805)\",\n \"800\": \"oklch(0.274 0.006 286.033)\",\n \"900\": \"oklch(0.21 0.006 285.885)\",\n \"950\": \"oklch(0.141 0.005 285.823)\",\n },\n },\n stone: {\n label: \"Stone\",\n shades: {\n \"50\": \"oklch(0.985 0.001 106.423)\",\n \"100\": \"oklch(0.97 0.001 106.424)\",\n \"200\": \"oklch(0.923 0.003 48.717)\",\n \"300\": \"oklch(0.869 0.005 56.366)\",\n \"400\": \"oklch(0.709 0.01 56.259)\",\n \"500\": \"oklch(0.553 0.013 58.071)\",\n \"600\": \"oklch(0.444 0.011 73.639)\",\n \"700\": \"oklch(0.374 0.01 67.558)\",\n \"800\": \"oklch(0.268 0.007 34.298)\",\n \"900\": \"oklch(0.216 0.006 56.043)\",\n \"950\": \"oklch(0.147 0.004 49.25)\",\n },\n },\n mauve: {\n label: \"Mauve\",\n shades: {\n \"50\": \"oklch(0.985 0.003 310)\",\n \"100\": \"oklch(0.968 0.006 310)\",\n \"200\": \"oklch(0.925 0.011 310)\",\n \"300\": \"oklch(0.87 0.017 310)\",\n \"400\": \"oklch(0.708 0.03 310)\",\n \"500\": \"oklch(0.556 0.03 310)\",\n \"600\": \"oklch(0.44 0.028 310)\",\n \"700\": \"oklch(0.372 0.025 310)\",\n \"800\": \"oklch(0.27 0.02 310)\",\n \"900\": \"oklch(0.208 0.018 310)\",\n \"950\": \"oklch(0.145 0.014 310)\",\n },\n },\n olive: {\n label: \"Olive\",\n shades: {\n \"50\": \"oklch(0.985 0.003 130)\",\n \"100\": \"oklch(0.968 0.006 130)\",\n \"200\": \"oklch(0.925 0.011 130)\",\n \"300\": \"oklch(0.87 0.017 130)\",\n \"400\": \"oklch(0.708 0.028 130)\",\n \"500\": \"oklch(0.556 0.028 130)\",\n \"600\": \"oklch(0.44 0.024 130)\",\n \"700\": \"oklch(0.372 0.02 130)\",\n \"800\": \"oklch(0.27 0.016 130)\",\n \"900\": \"oklch(0.208 0.014 130)\",\n \"950\": \"oklch(0.145 0.01 130)\",\n },\n },\n};\n","export const SLIDER_MAX = 10;\nexport const TEXT_PREVIEW_MAX_LENGTH = 30;\nexport const TYPING_RESET_DELAY_MS = 1500;\nexport const SHADE_KEYS = [\"50\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"950\"];\nexport const FONT_SIZE_MIN_PX = 1;\nexport const FONT_SIZE_MAX_PX = 200;\nexport const PADDING_MIN_PX = -200;\nexport const PADDING_MAX_PX = 200;\nexport const MOUSE_COLOR_SENSITIVITY = 0.02;\nexport const MOUSE_SIZE_SENSITIVITY = 0.1;\nexport const MOUSE_PADDING_SENSITIVITY = 0.2;\nexport const MINIMAP_WIDTH_PX = 160;\nexport const MINIMAP_HEIGHT_PX = 100;\nexport const THUMB_SIZE_PX = 10;\nexport const DOM_TREE_MAX_NODES = 40;\n","import type { OKLCH } from \"../types\";\nimport { SHADE_KEYS, SLIDER_MAX } from \"../constants\";\nimport type { GrayScale } from \"../types\";\n\nexport const parseOklch = (oklchStr: string): OKLCH => {\n const match = oklchStr.match(/oklch\\(([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)\\)/);\n if (!match) return [0, 0, 0];\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n};\n\nexport const lerpOklch = (colorA: OKLCH, colorB: OKLCH, interpolation: number): OKLCH => [\n colorA[0] + (colorB[0] - colorA[0]) * interpolation,\n colorA[1] + (colorB[1] - colorA[1]) * interpolation,\n colorA[2] + (colorB[2] - colorA[2]) * interpolation,\n];\n\nexport const formatOklch = (oklch: OKLCH): string =>\n `oklch(${oklch[0].toFixed(3)} ${oklch[1].toFixed(3)} ${oklch[2].toFixed(1)})`;\n\nexport const oklchToCssString = (oklch: OKLCH): string =>\n `oklch(${oklch[0]} ${oklch[1]} ${oklch[2]})`;\n\nexport const getColorAtPosition = (scales: Record<string, GrayScale>, scaleKey: string, position: number): OKLCH => {\n const scale = scales[scaleKey];\n if (!scale) return [0.5, 0, 0];\n\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.min(Math.floor(segment), SHADE_KEYS.length - 2);\n const interpolation = segment - index;\n\n const lower = parseOklch(scale.shades[SHADE_KEYS[index]]);\n const upper = parseOklch(scale.shades[SHADE_KEYS[index + 1]]);\n\n return lerpOklch(lower, upper, interpolation);\n};\n\nexport const getClosestShadeLabel = (position: number): string => {\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.round(segment);\n return SHADE_KEYS[Math.min(index, SHADE_KEYS.length - 1)];\n};\n\nexport const parseRgb = (color: string): [number, number, number, number] => {\n const match = color.match(\n /rgba?\\(\\s*([\\d.]+),\\s*([\\d.]+),\\s*([\\d.]+)(?:,\\s*([\\d.]+))?\\s*\\)/\n );\n if (!match) return [0, 0, 0, 0];\n return [\n Number(match[1]),\n Number(match[2]),\n Number(match[3]),\n match[4] !== undefined ? Number(match[4]) : 1,\n ];\n};\n\nexport const rgbToOklch = (red: number, green: number, blue: number): OKLCH => {\n const linearize = (channel: number): number => {\n const normalized = channel / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n };\n const linearRed = linearize(red);\n const linearGreen = linearize(green);\n const linearBlue = linearize(blue);\n\n const lmsL = Math.cbrt(0.4122214708 * linearRed + 0.5363325363 * linearGreen + 0.0514459929 * linearBlue);\n const lmsM = Math.cbrt(0.2119034982 * linearRed + 0.6806995451 * linearGreen + 0.1073969566 * linearBlue);\n const lmsS = Math.cbrt(0.0883024619 * linearRed + 0.2817188376 * linearGreen + 0.6299787005 * linearBlue);\n\n const lightness = 0.2104542553 * lmsL + 0.793617785 * lmsM - 0.0040720468 * lmsS;\n const labA = 1.9779984951 * lmsL - 2.428592205 * lmsM + 0.4505937099 * lmsS;\n const labB = 0.0259040371 * lmsL + 0.7827717662 * lmsM - 0.808675766 * lmsS;\n\n const chroma = Math.sqrt(labA * labA + labB * labB);\n const hue = Math.atan2(labB, labA) * (180 / Math.PI);\n\n return [lightness, chroma, hue < 0 ? hue + 360 : hue];\n};\n\nexport const findClosestPosition = (scales: Record<string, GrayScale>, scaleKey: string, targetOklch: OKLCH): number => {\n let bestPosition = 0;\n let bestDistance = Infinity;\n\n for (let position = 0; position <= SLIDER_MAX; position++) {\n const color = getColorAtPosition(scales, scaleKey, position);\n const distance =\n (color[0] - targetOklch[0]) ** 2 +\n (color[1] - targetOklch[1]) ** 2 +\n ((color[2] - targetOklch[2]) / 360) ** 2;\n if (distance < bestDistance) {\n bestDistance = distance;\n bestPosition = position;\n }\n }\n\n return bestPosition;\n};\n","import { TEXT_PREVIEW_MAX_LENGTH } from \"../constants\";\n\nexport const getSelector = (element: HTMLElement): string => {\n const tag = element.tagName.toLowerCase();\n const classes = Array.from(element.classList)\n .filter((className) => !className.startsWith(\"__\"))\n .slice(0, 2)\n .join(\".\");\n return classes ? `${tag}.${classes}` : tag;\n};\n\nexport const getTextPreview = (element: HTMLElement): string => {\n const text = element.textContent?.trim() || \"\";\n return text.length > TEXT_PREVIEW_MAX_LENGTH\n ? `${text.slice(0, TEXT_PREVIEW_MAX_LENGTH)}…`\n : text;\n};\n","import type { GrayScale, Modification } from \"../types\";\nimport { getColorAtPosition, oklchToCssString } from \"./color\";\n\nexport const applyModification = (\n modification: Modification,\n scales: Record<string, GrayScale>,\n scaleKey: string,\n) => {\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const colorValue = oklchToCssString(oklch);\n if (modification.property === \"bg\") {\n modification.element.style.backgroundColor = colorValue;\n } else if (modification.property === \"text\") {\n modification.element.style.color = colorValue;\n } else {\n modification.element.style.borderColor = colorValue;\n }\n modification.element.style.fontSize = `${modification.fontSize}px`;\n\n const paddingY = Math.round(modification.paddingY);\n\n modification.element.style.paddingTop = `${Math.max(0, paddingY)}px`;\n modification.element.style.paddingBottom = `${Math.max(0, paddingY)}px`;\n\n modification.element.style.marginTop = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginTop;\n modification.element.style.marginBottom = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginBottom;\n\n if (modification.translateX !== 0 || modification.translateY !== 0) {\n modification.element.style.transform = `translate(${modification.translateX}px, ${modification.translateY}px)`;\n } else {\n modification.element.style.transform = modification.originalInlineTransform;\n }\n};\n\nexport const restoreModification = (modification: Modification) => {\n modification.element.style.backgroundColor = modification.originalInlineBg;\n modification.element.style.color = modification.originalInlineColor;\n modification.element.style.borderColor = modification.originalInlineBorderColor;\n modification.element.style.fontSize = modification.originalInlineFontSize;\n modification.element.style.paddingTop = modification.originalInlinePaddingTop;\n modification.element.style.paddingBottom = modification.originalInlinePaddingBottom;\n modification.element.style.marginTop = modification.originalInlineMarginTop;\n modification.element.style.marginBottom = modification.originalInlineMarginBottom;\n modification.element.style.transform = modification.originalInlineTransform;\n};\n\nexport const roundToStep = (value: number): number =>\n parseFloat((Math.round(value * 10) / 10).toFixed(1));\n\nexport const roundToHalf = (value: number): number =>\n Math.round(value * 2) / 2;\n","import type { GrayScale, Modification } from \"../types\";\nimport type { RepositionContext, TreeNode } from \"./nearby\";\nimport { formatOklch, getColorAtPosition, getClosestShadeLabel } from \"./color\";\n\nconst describeModification = (modification: Modification): string => {\n const nameParts = [modification.selector];\n if (modification.componentName) nameParts.unshift(`<${modification.componentName}>`);\n if (modification.textPreview) nameParts.push(`(\"${modification.textPreview}\")`);\n return nameParts.join(\" \");\n};\n\nconst formatTreeNode = (node: TreeNode, indent: number, newPositionY: number): string[] => {\n const prefix = \" \" + \" \".repeat(indent);\n const nameParts: string[] = [];\n if (node.componentName) nameParts.push(`<${node.componentName}>`);\n nameParts.push(node.selector);\n if (node.textPreview && node.children.length === 0) {\n nameParts.push(`(\"${node.textPreview}\")`);\n }\n const description = nameParts.join(\" \");\n const marker = node.isSelf ? \"★ \" : \"\";\n const dragSuffix = node.isSelf ? ` → DRAGGED TO Y=${newPositionY}` : \"\";\n\n const lines: string[] = [];\n lines.push(`${prefix}${marker}${description} — Y=${node.positionY}${dragSuffix}`);\n\n for (const child of node.children) {\n lines.push(...formatTreeNode(child, indent + 1, newPositionY));\n }\n\n return lines;\n};\n\nexport const generatePrompt = (\n modifications: Modification[],\n scales: Record<string, GrayScale>,\n scaleKey: string,\n repositionContexts?: Map<number, RepositionContext>,\n): string => {\n if (modifications.length === 0) return \"\";\n\n const scaleName = scales[scaleKey]?.label || scaleKey;\n const colorLines: string[] = [];\n const sizeLines: string[] = [];\n const paddingLines: string[] = [];\n const positionLines: string[] = [];\n\n modifications.forEach((modification, index) => {\n const description = describeModification(modification);\n\n const shade = getClosestShadeLabel(modification.position);\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const property =\n modification.property === \"bg\"\n ? \"background color\"\n : modification.property === \"text\"\n ? \"text color\"\n : \"border color\";\n colorLines.push(`- ${property} of ${description} → ${scaleName} ${shade} (${formatOklch(oklch)})`);\n if (modification.sourceFile) colorLines.push(` Source: ${modification.sourceFile}`);\n\n sizeLines.push(`- font-size of ${description} → ${modification.fontSize}px`);\n if (modification.sourceFile) sizeLines.push(` Source: ${modification.sourceFile}`);\n\n paddingLines.push(`- vertical padding of ${description} → ${Math.round(modification.paddingY)}px`);\n if (modification.sourceFile) paddingLines.push(` Source: ${modification.sourceFile}`);\n\n const context = repositionContexts?.get(index);\n if (context && (modification.translateX !== 0 || modification.translateY !== 0)) {\n positionLines.push(`- ${description}`);\n if (modification.sourceFile) positionLines.push(` Source: ${modification.sourceFile}`);\n positionLines.push(` Dragged from Y=${context.originalPositionY} to Y=${context.newPositionY} (offset: ${context.translateX}px horizontal, ${context.translateY}px vertical)`);\n positionLines.push(\"\");\n positionLines.push(` Page structure (Y = absolute position from document top):`);\n positionLines.push(...formatTreeNode(context.tree, 0, context.newPositionY));\n positionLines.push(\"\");\n positionLines.push(` → Based on the Y positions above, move this element to its closest logical position in the JSX source.`);\n }\n });\n\n const sections: string[] = [];\n\n if (colorLines.length > 0) {\n sections.push(\n \"Change the following colors using the design system's gray scale:\",\n \"\",\n ...colorLines,\n );\n }\n\n if (sizeLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following font sizes:\", \"\", ...sizeLines);\n }\n\n if (paddingLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following padding:\", \"\", ...paddingLines);\n }\n\n if (positionLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\n \"Reposition the following element in the source code (do NOT use CSS transforms — re-order the JSX):\",\n \"\",\n ...positionLines,\n );\n }\n\n return sections.join(\"\\n\");\n};\n","import { DOM_TREE_MAX_NODES } from \"../constants\";\nimport { getSelector, getTextPreview } from \"./dom\";\n\ninterface StackFrame {\n fileName?: string;\n lineNumber?: number;\n functionName?: string;\n}\n\ninterface ReactGrabModule {\n getStack: (element: Element) => Promise<StackFrame[]>;\n}\n\nexport interface TreeNode {\n selector: string;\n textPreview: string;\n componentName: string | null;\n positionY: number;\n isSelf: boolean;\n children: TreeNode[];\n}\n\nexport interface RepositionContext {\n translateX: number;\n translateY: number;\n originalPositionY: number;\n newPositionY: number;\n tree: TreeNode;\n}\n\nconst getReactGrabModule = (): ReactGrabModule | null => {\n const module = (window as unknown as Record<string, unknown>)\n .__REACT_GRAB_MODULE__ as ReactGrabModule | undefined;\n if (module && typeof module.getStack === \"function\") {\n return module;\n }\n return null;\n};\n\nconst getSourceFromStack = async (\n element: Element,\n reactGrab: ReactGrabModule,\n): Promise<string | null> => {\n try {\n const stack = await reactGrab.getStack(element);\n if (stack) {\n for (const frame of stack) {\n if (frame.fileName && !frame.fileName.includes(\"node_modules\")) {\n if (frame.functionName && /^[A-Z]/.test(frame.functionName)) {\n return frame.functionName;\n }\n }\n }\n }\n } catch {}\n return null;\n};\n\nconst getAncestorPath = (element: HTMLElement): HTMLElement[] => {\n const path: HTMLElement[] = [];\n let current: HTMLElement | null = element;\n while (current && current !== document.body && current !== document.documentElement) {\n path.unshift(current);\n current = current.parentElement;\n }\n return path;\n};\n\nconst buildTreeNode = async (\n node: HTMLElement,\n ancestorSet: Set<HTMLElement>,\n targetElement: HTMLElement,\n targetTranslateY: number,\n reactGrab: ReactGrabModule | null,\n nodeCount: { value: number },\n): Promise<TreeNode | null> => {\n if (nodeCount.value >= DOM_TREE_MAX_NODES) return null;\n nodeCount.value++;\n\n const isSelf = node === targetElement;\n const isOnAncestorPath = ancestorSet.has(node) && !isSelf;\n const rect = node.getBoundingClientRect();\n const positionY = Math.round(\n rect.top + window.scrollY - (isSelf ? targetTranslateY : 0),\n );\n\n const componentName = reactGrab\n ? await getSourceFromStack(node, reactGrab)\n : null;\n\n const children: TreeNode[] = [];\n if (isOnAncestorPath) {\n const childElements = Array.from(node.children).filter(\n (child): child is HTMLElement => child instanceof HTMLElement,\n );\n for (const child of childElements) {\n if (nodeCount.value >= DOM_TREE_MAX_NODES) break;\n const childNode = await buildTreeNode(\n child, ancestorSet, targetElement, targetTranslateY, reactGrab, nodeCount,\n );\n if (childNode) children.push(childNode);\n }\n }\n\n return {\n selector: getSelector(node),\n textPreview: getTextPreview(node),\n componentName,\n positionY,\n isSelf,\n children,\n };\n};\n\nexport const gatherRepositionContext = async (\n element: HTMLElement,\n translateX: number,\n translateY: number,\n): Promise<RepositionContext | null> => {\n const ancestorPath = getAncestorPath(element);\n if (ancestorPath.length === 0) return null;\n\n const ancestorSet = new Set(ancestorPath);\n const reactGrab = getReactGrabModule();\n const nodeCount = { value: 0 };\n\n const tree = await buildTreeNode(\n ancestorPath[0],\n ancestorSet,\n element,\n translateY,\n reactGrab,\n nodeCount,\n );\n if (!tree) return null;\n\n const rect = element.getBoundingClientRect();\n const currentY = Math.round(rect.top + window.scrollY);\n const originalY = Math.round(currentY - translateY);\n\n return {\n translateX: Math.round(translateX),\n translateY: Math.round(translateY),\n originalPositionY: originalY,\n newPositionY: currentY,\n tree,\n };\n};\n","import { useState, useCallback, useEffect, useRef } from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { Modification, TweakerProps } from \"./types\";\nimport { GRAY_SCALES } from \"./gray-scales\";\nimport { SLIDER_MAX, TYPING_RESET_DELAY_MS, FONT_SIZE_MIN_PX, FONT_SIZE_MAX_PX, PADDING_MIN_PX, PADDING_MAX_PX, MOUSE_COLOR_SENSITIVITY, MOUSE_SIZE_SENSITIVITY, MOUSE_PADDING_SENSITIVITY, MINIMAP_WIDTH_PX, MINIMAP_HEIGHT_PX, THUMB_SIZE_PX } from \"./constants\";\nimport { getColorAtPosition, oklchToCssString, parseRgb, rgbToOklch, findClosestPosition } from \"./utils/color\";\nimport { getSelector, getTextPreview } from \"./utils/dom\";\nimport { applyModification, restoreModification, roundToStep, roundToHalf } from \"./utils/modification\";\nimport { generatePrompt } from \"./utils/prompt\";\nimport { gatherRepositionContext } from \"./utils/nearby\";\nimport type { RepositionContext } from \"./utils/nearby\";\n\nconst requestLock = () => {\n if (!document.pointerLockElement) {\n document.body.requestPointerLock();\n }\n};\n\nconst releaseLock = () => {\n if (document.pointerLockElement) {\n document.exitPointerLock();\n }\n};\n\nexport const Tweaker = ({ scales = GRAY_SCALES, activeScale = \"neutral\" }: TweakerProps) => {\n const [picking, setPicking] = useState(false);\n const [modifications, setModifications] = useState<Modification[]>([]);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [inputValue, setInputValue] = useState(\"\");\n const [shiftHeld, setShiftHeld] = useState(false);\n const [spaceHeld, setSpaceHeld] = useState(false);\n const [controlHeld, setControlHeld] = useState(false);\n const typingBuffer = useRef(\"\");\n const typingTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const activeMod = activeIndex >= 0 ? modifications[activeIndex] : null;\n const hasModifications = modifications.length > 0;\n\n const activeIndexRef = useRef(activeIndex);\n const activeScaleRef = useRef(activeScale);\n const modificationsRef = useRef(modifications);\n const scalesRef = useRef(scales);\n activeIndexRef.current = activeIndex;\n activeScaleRef.current = activeScale;\n modificationsRef.current = modifications;\n scalesRef.current = scales;\n\n const updateActivePosition = useCallback(\n (newPosition: number) => {\n if (activeIndex < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n updated[activeIndex] = { ...updated[activeIndex], position: newPosition };\n applyModification(updated[activeIndex], scales, activeScale);\n return updated;\n });\n },\n [activeIndex, activeScale, scales],\n );\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(true);\n if (event.key === \"Control\") setControlHeld(true);\n };\n const handleKeyUp = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(false);\n if (event.key === \"Control\") setControlHeld(false);\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"keyup\", handleKeyUp);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"keyup\", handleKeyUp);\n };\n }, []);\n\n useEffect(() => {\n if (!hasModifications || picking) return;\n\n const handleMouseMove = (event: MouseEvent) => {\n if (!document.pointerLockElement) return;\n const index = activeIndexRef.current;\n if (index < 0) return;\n\n setModifications((previous) => {\n const updated = [...previous];\n const current = updated[index];\n\n if (event.ctrlKey) {\n updated[index] = {\n ...current,\n translateX: current.translateX + event.movementX,\n translateY: current.translateY + event.movementY,\n };\n } else if (event.shiftKey) {\n const newPaddingY = Math.max(PADDING_MIN_PX, Math.min(PADDING_MAX_PX, current.paddingY - event.movementY * MOUSE_PADDING_SENSITIVITY));\n updated[index] = { ...current, paddingY: Math.round(newPaddingY) };\n } else {\n const newPosition = Math.max(0, Math.min(SLIDER_MAX, current.position - event.movementY * MOUSE_COLOR_SENSITIVITY));\n const newSize = Math.max(FONT_SIZE_MIN_PX, Math.min(FONT_SIZE_MAX_PX, current.fontSize + event.movementX * MOUSE_SIZE_SENSITIVITY));\n updated[index] = { ...current, position: roundToStep(newPosition), fontSize: roundToHalf(newSize) };\n }\n\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n setInputValue(String(updated[index].position));\n return updated;\n });\n };\n\n requestLock();\n document.addEventListener(\"mousemove\", handleMouseMove, true);\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove, true);\n releaseLock();\n };\n }, [hasModifications, picking]);\n\n const gatherRepositionContexts = async (\n modifications: Modification[],\n ): Promise<Map<number, RepositionContext>> => {\n const contextMap = new Map<number, RepositionContext>();\n for (let index = 0; index < modifications.length; index++) {\n const modification = modifications[index];\n if (modification.translateX !== 0 || modification.translateY !== 0) {\n const context = await gatherRepositionContext(\n modification.element,\n modification.translateX,\n modification.translateY,\n );\n if (context) contextMap.set(index, context);\n }\n }\n return contextMap;\n };\n\n useEffect(() => {\n if (!hasModifications) return;\n\n const handleKeyDown = async (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n releaseLock();\n const contextMap = await gatherRepositionContexts(modificationsRef.current);\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, contextMap);\n navigator.clipboard.writeText(prompt);\n modificationsRef.current.forEach(restoreModification);\n setModifications([]);\n setActiveIndex(-1);\n setInputValue(\"\");\n }\n\n if (event.key === \"Enter\") {\n event.preventDefault();\n releaseLock();\n const contextMap = await gatherRepositionContexts(modificationsRef.current);\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, contextMap);\n navigator.clipboard.writeText(prompt);\n setPicking(true);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [hasModifications]);\n\n useEffect(() => {\n if (!activeMod || picking) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"Escape\") return;\n\n if ((event.key >= \"0\" && event.key <= \"9\") || event.key === \".\") {\n event.preventDefault();\n const next = typingBuffer.current + event.key;\n\n if (event.key === \".\" && typingBuffer.current.includes(\".\")) return;\n\n const hasDecimal = typingBuffer.current.includes(\".\");\n if (hasDecimal && event.key !== \".\" && typingBuffer.current.split(\".\")[1]?.length >= 1) {\n return;\n }\n\n const parsed = parseFloat(next);\n if (!isNaN(parsed) && parsed > SLIDER_MAX) {\n typingBuffer.current = event.key === \".\" ? \".\" : event.key;\n } else {\n typingBuffer.current = next;\n }\n\n const value = parseFloat(typingBuffer.current);\n if (!isNaN(value)) {\n const clamped = Math.min(SLIDER_MAX, value);\n updateActivePosition(clamped);\n setInputValue(typingBuffer.current);\n }\n\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n\n if (event.key === \"Backspace\") {\n event.preventDefault();\n typingBuffer.current = typingBuffer.current.slice(0, -1);\n if (typingBuffer.current && typingBuffer.current !== \".\") {\n const value = Math.min(SLIDER_MAX, parseFloat(typingBuffer.current));\n updateActivePosition(value);\n setInputValue(typingBuffer.current);\n }\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n clearTimeout(typingTimeout.current);\n };\n }, [activeMod, picking, activeIndex, updateActivePosition]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"t\") {\n event.preventDefault();\n setPicking(true);\n }\n if (hasModifications && (event.key === \"b\" || event.key === \"f\" || event.key === \"d\")) {\n event.preventDefault();\n const property: \"bg\" | \"text\" | \"border\" =\n event.key === \"b\" ? \"bg\" : event.key === \"f\" ? \"text\" : \"border\";\n const index = activeIndexRef.current;\n if (index < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n restoreModification(updated[index]);\n updated[index] = { ...updated[index], property };\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n return updated;\n });\n }\n };\n\n const handleMiddleClick = (event: MouseEvent) => {\n if (event.button !== 1) return;\n event.preventDefault();\n setPicking(true);\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"mousedown\", handleMiddleClick, true);\n document.addEventListener(\"auxclick\", handleMiddleClick, true);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"mousedown\", handleMiddleClick, true);\n document.removeEventListener(\"auxclick\", handleMiddleClick, true);\n };\n }, [hasModifications]);\n\n useEffect(() => {\n return () => {\n modifications.forEach(restoreModification);\n releaseLock();\n };\n }, []);\n\n useEffect(() => {\n if (activeMod) {\n applyModification(activeMod, scales, activeScale);\n }\n }, [activeMod?.position, activeMod?.fontSize, activeMod?.paddingY, activeScale, scales]);\n\n useEffect(() => {\n if (!picking) return;\n\n let hoveredElement: HTMLElement | null = null;\n\n const handleMouseOver = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n hoveredElement = target;\n target.style.outline = \"2px solid #3b82f6\";\n target.style.outlineOffset = \"2px\";\n };\n\n const handleMouseOut = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n if (hoveredElement === target) hoveredElement = null;\n };\n\n const handleClick = async (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n\n const computed = getComputedStyle(target);\n const [bgRed, bgGreen, bgBlue, bgAlpha] = parseRgb(computed.backgroundColor);\n const [textRed, textGreen, textBlue] = parseRgb(computed.color);\n const [borderRed, borderGreen, borderBlue, borderAlpha] = parseRgb(computed.borderColor);\n const hasBorder = borderAlpha > 0 && parseFloat(computed.borderWidth) > 0;\n\n const hasBackground = bgAlpha > 0;\n const defaultProperty: \"bg\" | \"text\" | \"border\" = hasBackground ? \"bg\" : hasBorder ? \"border\" : \"text\";\n const targetOklch =\n defaultProperty === \"bg\"\n ? rgbToOklch(bgRed, bgGreen, bgBlue)\n : defaultProperty === \"border\"\n ? rgbToOklch(borderRed, borderGreen, borderBlue)\n : rgbToOklch(textRed, textGreen, textBlue);\n\n const position = findClosestPosition(scales, activeScale, targetOklch);\n const currentSize = parseFloat(computed.fontSize) || 16;\n const currentPaddingY = parseFloat(computed.paddingTop) || 0;\n\n let componentName: string | null = null;\n let sourceFile: string | null = null;\n try {\n const reactGrab = (window as unknown as Record<string, unknown>).__REACT_GRAB_MODULE__ as {\n getStack: (element: Element) => Promise<Array<{ fileName?: string; lineNumber?: number; functionName?: string }>>;\n } | undefined;\n if (reactGrab?.getStack) {\n const stack = await reactGrab.getStack(target);\n if (stack) {\n for (const frame of stack) {\n if (frame.fileName && !frame.fileName.includes(\"node_modules\")) {\n sourceFile = frame.fileName;\n if (frame.functionName && /^[A-Z]/.test(frame.functionName)) {\n componentName = frame.functionName;\n }\n break;\n }\n }\n }\n }\n } catch {}\n\n const newModification: Modification = {\n element: target,\n selector: getSelector(target),\n componentName,\n sourceFile,\n textPreview: getTextPreview(target),\n originalInlineBg: target.style.backgroundColor,\n originalInlineColor: target.style.color,\n originalInlineBorderColor: target.style.borderColor,\n originalInlineFontSize: target.style.fontSize,\n originalInlinePaddingTop: target.style.paddingTop,\n originalInlinePaddingBottom: target.style.paddingBottom,\n originalInlineMarginTop: target.style.marginTop,\n originalInlineMarginBottom: target.style.marginBottom,\n originalInlineTransform: target.style.transform,\n property: defaultProperty,\n position,\n fontSize: currentSize,\n paddingY: currentPaddingY,\n translateX: 0,\n translateY: 0,\n };\n\n setModifications((previous) => [...previous, newModification]);\n setActiveIndex(modifications.length);\n setInputValue(String(position));\n setPicking(false);\n };\n\n document.addEventListener(\"mouseover\", handleMouseOver, true);\n document.addEventListener(\"mouseout\", handleMouseOut, true);\n document.addEventListener(\"click\", handleClick, true);\n\n return () => {\n document.removeEventListener(\"mouseover\", handleMouseOver, true);\n document.removeEventListener(\"mouseout\", handleMouseOut, true);\n document.removeEventListener(\"click\", handleClick, true);\n if (hoveredElement) {\n hoveredElement.style.outline = \"\";\n hoveredElement.style.outlineOffset = \"\";\n }\n };\n }, [picking, activeScale, scales, modifications.length]);\n\n const fillColor = activeMod\n ? oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position))\n : scales[activeScale]?.shades[\"500\"] ?? \"rgba(255,255,255,0.3)\";\n\n const propertyLabel =\n activeMod?.property === \"text\" ? \"F\" : activeMod?.property === \"border\" ? \"D\" : \"B\";\n\n const isPaddingMode = shiftHeld && hasModifications && !picking;\n const isDragMode = controlHeld && hasModifications && !picking;\n\n const guideRect = activeMod && !picking && !spaceHeld ? activeMod.element.getBoundingClientRect() : null;\n\n const thumbX = activeMod\n ? isPaddingMode\n ? (MINIMAP_WIDTH_PX - THUMB_SIZE_PX) / 2\n : ((activeMod.fontSize - FONT_SIZE_MIN_PX) / (FONT_SIZE_MAX_PX - FONT_SIZE_MIN_PX)) * (MINIMAP_WIDTH_PX - THUMB_SIZE_PX)\n : 0;\n const thumbY = activeMod\n ? isPaddingMode\n ? (1 - (activeMod.paddingY - PADDING_MIN_PX) / (PADDING_MAX_PX - PADDING_MIN_PX)) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : (1 - activeMod.position / SLIDER_MAX) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : MINIMAP_HEIGHT_PX - THUMB_SIZE_PX;\n\n return (\n <>\n {guideRect && activeMod && (\n <div data-tweaker style={guidelinesContainerStyle}>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: guideRect.height,\n boxSizing: \"border-box\",\n border: \"1px solid rgba(59, 130, 246, 0.5)\",\n borderRadius: 1,\n }}\n />\n {activeMod.paddingY > 0 && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderBottom: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.bottom - Math.min(activeMod.paddingY, guideRect.height / 2),\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderTop: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n </>\n )}\n <div\n style={{\n position: \"absolute\",\n left: guideRect.right + 8,\n top: guideRect.top,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n pointerEvents: \"none\",\n }}\n >\n <span style={guidelineLabelStyle}>\n ↕ {activeMod.paddingY}px\n </span>\n <span style={{ ...guidelineLabelStyle, color: \"rgba(59, 130, 246, 0.8)\", background: \"rgba(59, 130, 246, 0.06)\" }}>\n {activeMod.fontSize}px\n </span>\n {(activeMod.translateX !== 0 || activeMod.translateY !== 0) && (\n <span style={{ ...guidelineLabelStyle, color: \"rgba(168, 85, 247, 0.9)\", background: \"rgba(168, 85, 247, 0.08)\" }}>\n {Math.round(activeMod.translateX)}, {Math.round(activeMod.translateY)}\n </span>\n )}\n </div>\n </div>\n )}\n <AnimatePresence>\n {(hasModifications || picking) && (\n <motion.div\n key=\"minimap\"\n data-tweaker\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.2 }}\n style={minimapContainerStyle}\n >\n <div style={minimapFieldStyle}>\n <div\n style={{\n position: \"absolute\",\n left: thumbX,\n top: thumbY,\n width: THUMB_SIZE_PX,\n height: THUMB_SIZE_PX,\n borderRadius: \"50%\",\n background: fillColor,\n border: \"2px solid rgba(255,255,255,0.9)\",\n boxShadow: \"0 1px 4px rgba(0,0,0,0.4)\",\n transition: \"left 50ms, top 50ms\",\n }}\n />\n </div>\n <div style={minimapModeStyle}>\n <span style={minimapLabelStyle}>\n {isDragMode ? \"⌃ Move\" : isPaddingMode ? \"⇧ Padding\" : \"Style\"}\n </span>\n </div>\n <div style={minimapValuesStyle}>\n <span style={minimapLabelStyle}>\n {picking\n ? \"Picking…\"\n : isDragMode\n ? `x: ${activeMod?.translateX ?? 0}`\n : isPaddingMode\n ? `↕ ${activeMod?.paddingY ?? 0}px`\n : `${propertyLabel} ${inputValue || \"0\"}`}\n </span>\n {!picking && activeMod && isDragMode && (\n <span style={minimapLabelStyle}>\n {`y: ${activeMod.translateY}`}\n </span>\n )}\n {!picking && activeMod && !isPaddingMode && !isDragMode && (\n <span style={minimapLabelStyle}>\n {`${activeMod.fontSize}px`}\n </span>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </>\n );\n};\n\nconst baseTextStyle: React.CSSProperties = {\n fontFamily: \"system-ui, sans-serif\",\n fontWeight: 500,\n letterSpacing: \"-0.03em\",\n fontSynthesis: \"none\",\n WebkitFontSmoothing: \"antialiased\",\n};\n\nconst minimapContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n left: 16,\n bottom: 16,\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n};\n\nconst minimapFieldStyle: React.CSSProperties = {\n position: \"relative\",\n width: MINIMAP_WIDTH_PX,\n height: MINIMAP_HEIGHT_PX,\n borderRadius: 8,\n background: \"rgba(0,0,0,0.25)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n boxShadow: \"0 0 0 1px rgba(255,255,255,0.08) inset\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n};\n\nconst minimapModeStyle: React.CSSProperties = {\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapValuesStyle: React.CSSProperties = {\n display: \"flex\",\n justifyContent: \"space-between\",\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 11,\n color: \"rgba(255,255,255,0.6)\",\n whiteSpace: \"nowrap\",\n};\n\nconst guidelinesContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 9998,\n pointerEvents: \"none\",\n};\n\nconst guidelineLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 10,\n lineHeight: \"16px\",\n color: \"rgba(255, 99, 132, 0.9)\",\n background: \"rgba(255, 99, 132, 0.08)\",\n padding: \"0 5px\",\n borderRadius: 3,\n whiteSpace: \"nowrap\",\n};\n"],"mappings":"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"}
|