@style-capture/core 0.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/claude-export.ts","../src/messages.ts","../src/tailwind-mapper.ts"],"sourcesContent":["import type { TailwindMappingResult } from \"./tailwind-mapper.ts\";\nimport type {\n CaptureResult,\n ElementSnapshot,\n PseudoElementSnapshot,\n} from \"./types.ts\";\n\ninterface HtmlAnnotationResult {\n html: string;\n refs: Record<string, string>;\n selectors: Record<string, string>;\n}\n\ninterface ClaudePromptEntry {\n key: string;\n value: string;\n}\n\ninterface ClaudePromptMetadata {\n elementCount: number;\n mode: CaptureResult[\"settings\"][\"captureMode\"];\n pseudoCount: number;\n rootRef: string;\n rootSelector: string;\n url: string;\n}\n\nexport interface ClaudeCapturePrompt {\n cssCapture: string;\n htmlCapture: string;\n instruction: string;\n metadata: ClaudePromptMetadata;\n openQuestions: ClaudePromptEntry[];\n tailwindHints: ClaudePromptEntry[];\n}\n\nconst CAPTURE_NODE_ATTRIBUTE = \"data-lc\";\nconst MAX_TAILWIND_SUGGESTIONS = 6;\nconst MAX_OPEN_QUESTION_ITEMS = 8;\nconst CLAUDE_CAPTURE_INSTRUCTION =\n \"Recreate or refactor this UI faithfully. html_capture + css_capture are ground truth. Preserve structure unless simplifying is clearly better. Tailwind hints are hints. Use the smallest codebase-ready change and state ambiguities instead of inventing details.\";\n\nconst compactInlineText = (value: string): string =>\n value.replaceAll(/\\s+/g, \" \").trim();\n\nconst escapeXmlAttribute = (value: string): string =>\n value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\");\n\nconst compactSelector = (selector: string): string =>\n selector\n .replaceAll(/\\s*([>+~])\\s*/g, \"$1\")\n .replaceAll(/,\\s+/g, \",\")\n .replaceAll(/\\s+/g, \" \")\n .trim();\n\nconst buildCompactRefs = (order: string[]): Record<string, string> => {\n const refs: Record<string, string> = {};\n\n for (const [index, elementId] of order.entries()) {\n refs[elementId] = index.toString(36);\n }\n\n return refs;\n};\n\nconst buildCompactSelector = (ref: string): string =>\n `[${CAPTURE_NODE_ATTRIBUTE}=\"${ref}\"]`;\n\nconst buildFallbackSelectors = (\n capture: CaptureResult\n): Record<string, string> => {\n const selectors: Record<string, string> = {};\n\n for (const elementId of capture.order) {\n const snapshot = capture.elements[elementId];\n\n if (!snapshot) {\n continue;\n }\n\n selectors[elementId] = compactSelector(snapshot.selector);\n }\n\n return selectors;\n};\n\nconst stripCommentNodes = (root: Element): void => {\n const walker = root.ownerDocument.createTreeWalker(\n root,\n NodeFilter.SHOW_COMMENT\n );\n const comments: Comment[] = [];\n\n while (walker.nextNode()) {\n if (walker.currentNode instanceof Comment) {\n comments.push(walker.currentNode);\n }\n }\n\n for (const comment of comments) {\n comment.remove();\n }\n};\n\nconst minifyHtmlString = (html: string): string =>\n html\n .replaceAll(/<!--[\\s\\S]*?-->/g, \"\")\n .replaceAll(/>\\s+</g, \"><\")\n .trim();\n\nconst elementMatchesSnapshot = (\n element: Element,\n snapshot: ElementSnapshot\n): boolean => {\n if (element.tagName.toLowerCase() !== snapshot.tagName) {\n return false;\n }\n\n for (const className of snapshot.classList) {\n if (!element.classList.contains(className)) {\n return false;\n }\n }\n\n for (const [name, value] of Object.entries(snapshot.attributes)) {\n if (name === \"class\") {\n continue;\n }\n\n if (element.getAttribute(name) !== value) {\n return false;\n }\n }\n\n return true;\n};\n\nconst findMatchingElementIndex = (\n candidates: Element[],\n snapshot: ElementSnapshot,\n startIndex: number\n): number => {\n for (let index = startIndex; index < candidates.length; index += 1) {\n if (elementMatchesSnapshot(candidates[index], snapshot)) {\n return index;\n }\n }\n\n return -1;\n};\n\nconst annotateCaptureHtml = (capture: CaptureResult): HtmlAnnotationResult => {\n const refs = buildCompactRefs(capture.order);\n\n if (!capture.rootOuterHtml.trim()) {\n return {\n html: \"\",\n refs,\n selectors: buildFallbackSelectors(capture),\n };\n }\n\n if (typeof DOMParser === \"undefined\") {\n return {\n html: minifyHtmlString(capture.rootOuterHtml),\n refs,\n selectors: buildFallbackSelectors(capture),\n };\n }\n\n const parser = new DOMParser();\n const document = parser.parseFromString(capture.rootOuterHtml, \"text/html\");\n const root = document.body.firstElementChild;\n\n if (!root) {\n return {\n html: minifyHtmlString(capture.rootOuterHtml),\n refs,\n selectors: buildFallbackSelectors(capture),\n };\n }\n\n stripCommentNodes(root);\n\n const candidates = [root, ...root.querySelectorAll(\"*\")];\n const selectors = buildFallbackSelectors(capture);\n let searchStartIndex = 0;\n\n for (const elementId of capture.order) {\n const snapshot = capture.elements[elementId];\n const ref = refs[elementId];\n\n if (!(snapshot && ref)) {\n continue;\n }\n\n const matchIndex = findMatchingElementIndex(\n candidates,\n snapshot,\n searchStartIndex\n );\n\n if (matchIndex === -1) {\n continue;\n }\n\n const element = candidates[matchIndex];\n element.setAttribute(CAPTURE_NODE_ATTRIBUTE, ref);\n selectors[elementId] = buildCompactSelector(ref);\n searchStartIndex = matchIndex + 1;\n }\n\n return {\n html: minifyHtmlString(root.outerHTML),\n refs,\n selectors,\n };\n};\n\nconst formatCssPropertyName = (property: string): string => {\n if (property.includes(\"-\")) {\n return property;\n }\n\n return property.replaceAll(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n};\n\nconst formatDeclarationBlock = (styles: Record<string, string>): string =>\n Object.entries(styles)\n .filter(([, value]) => value.trim().length > 0)\n .toSorted(([left], [right]) => left.localeCompare(right))\n .map(\n ([property, value]) =>\n `${formatCssPropertyName(property)}:${compactInlineText(value)}`\n )\n .join(\";\");\n\nconst formatPseudoBlock = (\n selector: string,\n pseudo: PseudoElementSnapshot | undefined\n): string => {\n if (!pseudo) {\n return \"\";\n }\n\n const declarationBlock = formatDeclarationBlock(pseudo.styles);\n if (!declarationBlock) {\n return \"\";\n }\n\n return `${selector}::${pseudo.kind}{${declarationBlock}}`;\n};\n\nconst formatElementCssBlock = (\n snapshot: ElementSnapshot,\n selector: string\n): string => {\n const parts: string[] = [];\n const declarationBlock = formatDeclarationBlock(snapshot.styles);\n const beforeBlock = formatPseudoBlock(selector, snapshot.pseudo.before);\n const afterBlock = formatPseudoBlock(selector, snapshot.pseudo.after);\n\n if (declarationBlock) {\n parts.push(`${selector}{${declarationBlock}}`);\n }\n\n if (beforeBlock) {\n parts.push(beforeBlock);\n }\n\n if (afterBlock) {\n parts.push(afterBlock);\n }\n\n return parts.join(\"\");\n};\n\nconst formatCaptureCss = (\n capture: CaptureResult,\n selectors: Record<string, string>\n): string =>\n capture.order\n .map((elementId) => {\n const snapshot = capture.elements[elementId];\n\n if (!snapshot) {\n return \"\";\n }\n\n return formatElementCssBlock(\n snapshot,\n selectors[elementId] ?? snapshot.selector\n );\n })\n .filter(Boolean)\n .join(\"\");\n\nconst buildTailwindHintEntries = (\n capture: CaptureResult,\n mapping: TailwindMappingResult | null,\n refs: Record<string, string>\n): ClaudePromptEntry[] => {\n if (!mapping) {\n return [];\n }\n\n const entries: ClaudePromptEntry[] = [];\n const rootMapping = mapping.elements[capture.rootElementId];\n\n if (rootMapping?.suggestedClassName || rootMapping?.className) {\n entries.push({\n key: \"root\",\n value: rootMapping.suggestedClassName || rootMapping.className,\n });\n }\n\n const topSuggestions = capture.order\n .filter((elementId) => elementId !== capture.rootElementId)\n .map((elementId) => mapping.elements[elementId])\n .filter((element): element is NonNullable<typeof element> =>\n Boolean(element?.suggestedClassName || element?.className)\n )\n .slice(0, MAX_TAILWIND_SUGGESTIONS);\n\n for (const suggestion of topSuggestions) {\n entries.push({\n key: refs[suggestion.elementId] ?? suggestion.elementId,\n value: suggestion.suggestedClassName || suggestion.className,\n });\n }\n\n return entries;\n};\n\nconst buildOpenQuestionEntries = (\n mapping: TailwindMappingResult | null,\n refs: Record<string, string>\n): ClaudePromptEntry[] => {\n if (!mapping || mapping.reviewQueue.length === 0) {\n return [];\n }\n\n return mapping.reviewQueue.slice(0, MAX_OPEN_QUESTION_ITEMS).map((item) => ({\n key: refs[item.elementId] ?? item.elementId,\n value: item.reasons.join(\"; \"),\n }));\n};\n\nexport const buildClaudeCapturePrompt = (\n capture: CaptureResult,\n mapping: TailwindMappingResult | null\n): ClaudeCapturePrompt => {\n const annotation = annotateCaptureHtml(capture);\n const rootElement = capture.elements[capture.rootElementId];\n\n return {\n cssCapture: formatCaptureCss(capture, annotation.selectors),\n htmlCapture: annotation.html,\n instruction: CLAUDE_CAPTURE_INSTRUCTION,\n metadata: {\n elementCount: capture.summary.elementCount,\n mode: capture.settings.captureMode,\n pseudoCount: capture.summary.pseudoElementCount,\n rootRef: annotation.refs[capture.rootElementId] ?? capture.rootElementId,\n rootSelector: rootElement?.selector ?? \"Unavailable\",\n url: capture.metadata.url,\n },\n openQuestions: buildOpenQuestionEntries(mapping, annotation.refs),\n tailwindHints: buildTailwindHintEntries(capture, mapping, annotation.refs),\n };\n};\n\nexport const formatCaptureForClaudeMarkdown = (\n capture: CaptureResult,\n mapping: TailwindMappingResult | null\n): string => {\n const prompt = buildClaudeCapturePrompt(capture, mapping);\n\n const sections = [\n `<style_capture url=\"${escapeXmlAttribute(prompt.metadata.url)}\" mode=\"${prompt.metadata.mode}\" root_ref=\"${prompt.metadata.rootRef}\" root_selector=\"${escapeXmlAttribute(prompt.metadata.rootSelector)}\" elements=\"${prompt.metadata.elementCount}\" pseudos=\"${prompt.metadata.pseudoCount}\">`,\n prompt.instruction,\n `<html_capture>${prompt.htmlCapture}</html_capture>`,\n `<css_capture>${prompt.cssCapture}</css_capture>`,\n ];\n\n if (prompt.tailwindHints.length > 0) {\n sections.push(\n \"<tailwind_hints>\",\n ...prompt.tailwindHints.map(\n (entry) => `${entry.key}=${compactInlineText(entry.value)}`\n ),\n \"</tailwind_hints>\"\n );\n }\n\n if (prompt.openQuestions.length > 0) {\n sections.push(\n \"<open_questions>\",\n ...prompt.openQuestions.map(\n (entry) => `${entry.key}:${compactInlineText(entry.value)}`\n ),\n \"</open_questions>\"\n );\n }\n\n sections.push(\"</style_capture>\");\n return sections.join(\"\\n\").trim();\n};\n","import type { CaptureResult, CaptureSettings } from \"./types.ts\";\n\nexport const MESSAGE_TYPE_CAPTURE_COMPLETED = \"capture/completed\";\nexport const MESSAGE_TYPE_CAPTURE_CANCELLED = \"capture/cancelled\";\nexport const MESSAGE_TYPE_CAPTURE_FAILED = \"capture/failed\";\n\nexport interface CaptureCompletedMessage {\n capture: CaptureResult;\n type: typeof MESSAGE_TYPE_CAPTURE_COMPLETED;\n}\n\nexport interface CaptureCancelledMessage {\n reason: string;\n type: typeof MESSAGE_TYPE_CAPTURE_CANCELLED;\n}\n\nexport interface CaptureFailedMessage {\n error: string;\n type: typeof MESSAGE_TYPE_CAPTURE_FAILED;\n}\n\nexport type ExtensionMessage =\n | CaptureCancelledMessage\n | CaptureCompletedMessage\n | CaptureFailedMessage;\n\nexport const createDefaultSettings = (): CaptureSettings => ({\n captureMode: \"curated\",\n includeHiddenElements: false,\n includePseudoElements: true,\n});\n","import type { CaptureResult, ElementSnapshot } from \"./types.ts\";\n\ntype TailwindConfidenceLabel = \"high\" | \"medium\" | \"low\";\ntype TailwindMatchStrategy = \"arbitrary\" | \"heuristic\" | \"scale\" | \"semantic\";\n\nexport interface TailwindElementMapping {\n className: string;\n confidence: number;\n confidenceLabel: TailwindConfidenceLabel;\n elementId: string;\n matchCount: number;\n matches: TailwindMatch[];\n reviewClassName: string;\n reviewMatchCount: number;\n selector: string;\n suggestedClassName: string;\n suggestedMatchCount: number;\n tagName: string;\n unsupported: TailwindUnsupportedProperty[];\n}\n\nexport interface TailwindMappingResult {\n elements: Record<string, TailwindElementMapping>;\n order: string[];\n reviewQueue: TailwindReviewItem[];\n summary: TailwindMappingSummary;\n}\n\nexport interface TailwindMappingSummary {\n averageConfidence: number;\n cleanUtilityCount: number;\n elementCount: number;\n lowConfidenceElementCount: number;\n mappedElementCount: number;\n reviewCount: number;\n reviewUtilityCount: number;\n unsupportedPropertyCount: number;\n utilityCount: number;\n}\n\ninterface TailwindMatch {\n confidence: number;\n label: TailwindConfidenceLabel;\n notes: string[];\n sourceProperties: string[];\n sourceValues: string[];\n strategy: TailwindMatchStrategy;\n utility: string;\n}\n\nexport interface TailwindReviewItem {\n confidence: number;\n confidenceLabel: TailwindConfidenceLabel;\n elementId: string;\n reasons: string[];\n selector: string;\n unsupportedCount: number;\n}\n\ninterface TailwindUnsupportedProperty {\n property: string;\n reason: string;\n value: string;\n}\n\ninterface MatchCandidate {\n confidence: number;\n notes?: string[];\n strategy: TailwindMatchStrategy;\n utility: string;\n}\n\ntype TailwindMatchInput = Omit<TailwindMatch, \"label\" | \"notes\"> & {\n notes?: string[];\n};\n\ninterface MappingAccumulator {\n classes: string[];\n classSet: Set<string>;\n matches: TailwindMatch[];\n unsupported: TailwindUnsupportedProperty[];\n}\n\ninterface MappingContext {\n element: ElementSnapshot;\n parent: ElementSnapshot | null;\n}\n\ntype MappingStep = (\n context: MappingContext,\n accumulator: MappingAccumulator\n) => void;\n\nconst HIGH_CONFIDENCE = 0.92;\nconst MEDIUM_CONFIDENCE = 0.72;\nconst LOW_CONFIDENCE = 0.45;\nconst PASSIVE_CONFIDENCE = 0.84;\n\nconst LENGTH_PATTERN = /^(-?\\d*\\.?\\d+)(px|rem|em|%|vh|vw)?$/;\nconst RGB_PATTERN = /^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([0-9.]+))?\\)$/;\nconst WHITESPACE_SPLIT_PATTERN = /\\s+/;\n\nconst SPACING_SCALE = new Map<number, string>([\n [0, \"0\"],\n [1, \"px\"],\n [2, \"0.5\"],\n [4, \"1\"],\n [6, \"1.5\"],\n [8, \"2\"],\n [10, \"2.5\"],\n [12, \"3\"],\n [14, \"3.5\"],\n [16, \"4\"],\n [20, \"5\"],\n [24, \"6\"],\n [28, \"7\"],\n [32, \"8\"],\n [36, \"9\"],\n [40, \"10\"],\n [44, \"11\"],\n [48, \"12\"],\n [56, \"14\"],\n [64, \"16\"],\n [80, \"20\"],\n [96, \"24\"],\n [112, \"28\"],\n [128, \"32\"],\n [144, \"36\"],\n [160, \"40\"],\n [176, \"44\"],\n [192, \"48\"],\n [224, \"56\"],\n [256, \"64\"],\n [288, \"72\"],\n [320, \"80\"],\n [384, \"96\"],\n]);\n\nconst FONT_SIZE_SCALE = new Map<number, string>([\n [12, \"xs\"],\n [14, \"sm\"],\n [16, \"base\"],\n [18, \"lg\"],\n [20, \"xl\"],\n [24, \"2xl\"],\n [30, \"3xl\"],\n [36, \"4xl\"],\n [48, \"5xl\"],\n [60, \"6xl\"],\n [72, \"7xl\"],\n [96, \"8xl\"],\n [128, \"9xl\"],\n]);\n\nconst LINE_HEIGHT_SCALE = new Map<number, string>([\n [12, \"3\"],\n [16, \"4\"],\n [20, \"5\"],\n [24, \"6\"],\n [28, \"7\"],\n [32, \"8\"],\n [36, \"9\"],\n [40, \"10\"],\n]);\n\nconst RADIUS_SCALE = new Map<number, string>([\n [0, \"none\"],\n [2, \"sm\"],\n [4, \"\"],\n [6, \"md\"],\n [8, \"lg\"],\n [12, \"xl\"],\n [16, \"2xl\"],\n [24, \"3xl\"],\n]);\n\nconst BORDER_WIDTH_SCALE = new Map<number, string>([\n [1, \"\"],\n [2, \"2\"],\n [4, \"4\"],\n [8, \"8\"],\n]);\n\nconst Z_INDEX_SCALE = new Set([0, 10, 20, 30, 40, 50]);\nconst OPACITY_SCALE = new Set([\n 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95,\n 100,\n]);\n\nconst CLEAN_ARBITRARY_SOURCE_PROPERTIES = new Set([\n \"background-color\",\n \"border-color\",\n \"color\",\n \"text-decoration-color\",\n]);\n\nconst REVIEW_ONLY_SOURCE_PROPERTIES = new Set([\n \"background-image\",\n \"bottom\",\n \"font-family\",\n \"grid-template-columns\",\n \"grid-template-rows\",\n \"height\",\n \"left\",\n \"pseudo-elements\",\n \"right\",\n \"top\",\n \"transform\",\n \"transform-origin\",\n \"width\",\n]);\n\nconst DISPLAY_MAP = {\n contents: \"contents\",\n flex: \"flex\",\n \"flow-root\": \"flow-root\",\n grid: \"grid\",\n inline: \"inline\",\n \"inline-block\": \"inline-block\",\n \"inline-flex\": \"inline-flex\",\n \"inline-grid\": \"inline-grid\",\n none: \"hidden\",\n} satisfies Record<string, string>;\n\nconst POSITION_MAP = {\n absolute: \"absolute\",\n fixed: \"fixed\",\n relative: \"relative\",\n sticky: \"sticky\",\n} satisfies Record<string, string>;\n\nconst FLEX_DIRECTION_MAP = {\n column: \"flex-col\",\n \"column-reverse\": \"flex-col-reverse\",\n \"row-reverse\": \"flex-row-reverse\",\n} satisfies Record<string, string>;\n\nconst FLEX_WRAP_MAP = {\n wrap: \"flex-wrap\",\n \"wrap-reverse\": \"flex-wrap-reverse\",\n} satisfies Record<string, string>;\n\nconst ALIGN_ITEMS_MAP = {\n baseline: \"items-baseline\",\n center: \"items-center\",\n end: \"items-end\",\n \"flex-end\": \"items-end\",\n \"flex-start\": \"items-start\",\n start: \"items-start\",\n} satisfies Record<string, string>;\n\nconst JUSTIFY_CONTENT_MAP = {\n center: \"justify-center\",\n end: \"justify-end\",\n \"flex-end\": \"justify-end\",\n \"flex-start\": \"justify-start\",\n left: \"justify-start\",\n right: \"justify-end\",\n \"space-around\": \"justify-around\",\n \"space-between\": \"justify-between\",\n \"space-evenly\": \"justify-evenly\",\n start: \"justify-start\",\n} satisfies Record<string, string>;\n\nconst GRID_AUTO_FLOW_MAP = {\n column: \"grid-flow-col\",\n \"column dense\": \"grid-flow-col-dense\",\n dense: \"grid-flow-dense\",\n \"row dense\": \"grid-flow-row-dense\",\n} satisfies Record<string, string>;\n\nconst TEXT_ALIGN_MAP = {\n center: \"text-center\",\n end: \"text-end\",\n justify: \"text-justify\",\n right: \"text-right\",\n} satisfies Record<string, string>;\n\nconst TEXT_TRANSFORM_MAP = {\n capitalize: \"capitalize\",\n lowercase: \"lowercase\",\n uppercase: \"uppercase\",\n} satisfies Record<string, string>;\n\nconst WHITE_SPACE_MAP = {\n \"break-spaces\": \"whitespace-break-spaces\",\n nowrap: \"whitespace-nowrap\",\n pre: \"whitespace-pre\",\n \"pre-line\": \"whitespace-pre-line\",\n \"pre-wrap\": \"whitespace-pre-wrap\",\n} satisfies Record<string, string>;\n\nconst LIST_STYLE_MAP = {\n decimal: \"list-decimal\",\n none: \"list-none\",\n} satisfies Record<string, string>;\n\nconst OBJECT_FIT_MAP = {\n contain: \"object-contain\",\n cover: \"object-cover\",\n none: \"object-none\",\n \"scale-down\": \"object-scale-down\",\n} satisfies Record<string, string>;\n\nconst OVERFLOW_MAP = {\n auto: \"auto\",\n clip: \"clip\",\n hidden: \"hidden\",\n scroll: \"scroll\",\n visible: \"visible\",\n} satisfies Record<string, string>;\n\nconst BORDER_STYLE_MAP = {\n dashed: \"border-dashed\",\n dotted: \"border-dotted\",\n double: \"border-double\",\n} satisfies Record<string, string>;\n\nconst FONT_WEIGHT_MAP = {\n \"100\": \"thin\",\n \"200\": \"extralight\",\n \"300\": \"light\",\n \"500\": \"medium\",\n \"600\": \"semibold\",\n \"700\": \"bold\",\n \"800\": \"extrabold\",\n \"900\": \"black\",\n} satisfies Record<string, string>;\n\nconst POSITION_KEYWORD_MAP = {\n \"0% 0%\": \"top-left\",\n \"0% 100%\": \"bottom-left\",\n \"0% 50%\": \"left\",\n \"100% 0%\": \"top-right\",\n \"100% 100%\": \"bottom-right\",\n \"100% 50%\": \"right\",\n \"50% 0%\": \"top\",\n \"50% 100%\": \"bottom\",\n} satisfies Record<string, string>;\n\nconst DIMENSION_KEYWORD_MAP = {\n \"100%\": \"full\",\n \"100vh\": \"screen\",\n \"100vw\": \"screen\",\n \"fit-content\": \"fit\",\n \"max-content\": \"max\",\n \"min-content\": \"min\",\n} satisfies Record<string, string>;\n\nconst FONT_FAMILY_MAP = [\n { keyword: \"monospace\", utility: \"font-mono\" },\n { keyword: \"sans-serif\", utility: \"font-sans\" },\n { keyword: \"system-ui\", utility: \"font-sans\" },\n { keyword: \"serif\", utility: \"font-serif\" },\n] as const;\n\n// --- Primitive utility helpers ---\n\nconst roundToTwo = (value: number): number => Math.round(value * 100) / 100;\n\nconst dedupe = (values?: string[]): string[] => [\n ...new Set((values ?? []).filter(Boolean)),\n];\n\nconst allEqual = (values: string[]): boolean =>\n values.every((value) => value === values[0]);\n\nconst normalizeWhitespace = (value: string): string =>\n value.replaceAll(/\\s+/g, \" \").trim();\n\nconst parseLength = (value: string): { unit: string; value: number } | null => {\n const match = value.trim().match(LENGTH_PATTERN);\n if (!match) {\n return null;\n }\n\n return {\n unit: match[2] ?? \"px\",\n value: Number(match[1]),\n };\n};\n\nconst isZeroLength = (value: string): boolean => {\n const length = parseLength(value);\n return Boolean(length && Math.abs(length.value) <= 0.01);\n};\n\nconst isTransparentColor = (value: string): boolean => {\n const normalized = value.trim().replaceAll(/\\s+/g, \"\").toLowerCase();\n return normalized === \"rgba(0,0,0,0)\" || normalized === \"transparent\";\n};\n\nconst normalizeColor = (value: string): string => {\n const trimmed = value.trim().toLowerCase();\n if (trimmed === \"transparent\" || isTransparentColor(trimmed)) {\n return \"transparent\";\n }\n\n const rgbMatch = trimmed.match(RGB_PATTERN);\n if (!rgbMatch) {\n return trimmed;\n }\n\n const { 1: redRaw, 2: greenRaw, 3: blueRaw, 4: alpha } = rgbMatch;\n const red = Number(redRaw).toString(16).padStart(2, \"0\");\n const green = Number(greenRaw).toString(16).padStart(2, \"0\");\n const blue = Number(blueRaw).toString(16).padStart(2, \"0\");\n\n if (!alpha || alpha === \"1\") {\n return `#${red}${green}${blue}`;\n }\n\n return trimmed.replaceAll(/\\s+/g, \"\");\n};\n\nconst sanitizeArbitraryValue = (value: string): string =>\n value\n .trim()\n .replaceAll(/\\s*,\\s*/g, \",\")\n .replaceAll(/\\s*\\/\\s*/g, \"/\")\n .replaceAll(/\\s+/g, \"_\");\n\nconst createArbitraryUtility = (prefix: string, value: string): string =>\n `${prefix}-[${sanitizeArbitraryValue(value)}]`;\n\nconst createArbitraryPropertyClass = (\n property: string,\n value: string\n): string => `[${property}:${sanitizeArbitraryValue(value)}]`;\n\nconst lookupMappedUtility = (\n map: Record<string, string>,\n value: string\n): string | null => map[value] ?? null;\n\nconst labelFromConfidence = (confidence: number): TailwindConfidenceLabel => {\n if (confidence >= 0.85) {\n return \"high\";\n }\n\n if (confidence >= 0.62) {\n return \"medium\";\n }\n\n return \"low\";\n};\n\n// --- Accumulator mutation helpers ---\n\nconst addMatch = (\n accumulator: MappingAccumulator,\n match: TailwindMatchInput\n): void => {\n const utility = match.utility.trim();\n if (!utility) {\n return;\n }\n\n const nextMatch: TailwindMatch = {\n ...match,\n label: labelFromConfidence(match.confidence),\n notes: dedupe(match.notes),\n sourceProperties: dedupe(match.sourceProperties),\n sourceValues: dedupe(match.sourceValues),\n utility,\n };\n\n const existing = accumulator.matches.find(\n (entry) => entry.utility === utility\n );\n if (existing) {\n existing.confidence = Math.max(existing.confidence, nextMatch.confidence);\n existing.label = labelFromConfidence(existing.confidence);\n existing.notes = dedupe([...existing.notes, ...nextMatch.notes]);\n existing.sourceProperties = dedupe([\n ...existing.sourceProperties,\n ...nextMatch.sourceProperties,\n ]);\n existing.sourceValues = dedupe([\n ...existing.sourceValues,\n ...nextMatch.sourceValues,\n ]);\n } else {\n accumulator.matches.push(nextMatch);\n }\n\n if (accumulator.classSet.has(utility)) {\n return;\n }\n\n accumulator.classSet.add(utility);\n accumulator.classes.push(utility);\n};\n\nconst addUnsupported = (\n accumulator: MappingAccumulator,\n property: string,\n value: string,\n reason: string\n): void => {\n const key = `${property}:${value}:${reason}`;\n const exists = accumulator.unsupported.some(\n (entry) => `${entry.property}:${entry.value}:${entry.reason}` === key\n );\n if (exists) {\n return;\n }\n\n accumulator.unsupported.push({\n property,\n reason,\n value,\n });\n};\n\nconst addCandidateMatch = (\n accumulator: MappingAccumulator,\n property: string,\n value: string | undefined,\n candidate: MatchCandidate | null\n): void => {\n if (!(value && candidate)) {\n return;\n }\n\n addMatch(accumulator, {\n confidence: candidate.confidence,\n notes: candidate.notes ?? [],\n sourceProperties: property.includes(\"|\") ? property.split(\"|\") : [property],\n sourceValues: [value],\n strategy: candidate.strategy,\n utility: candidate.utility,\n });\n};\n\nconst addMappedUtility = (\n accumulator: MappingAccumulator,\n property: string,\n value: string | undefined,\n map: Record<string, string>,\n shouldAdd = true\n): void => {\n if (!(shouldAdd && value)) {\n return;\n }\n\n const utility = lookupMappedUtility(map, value);\n if (!utility) {\n addUnsupported(\n accumulator,\n property,\n value,\n `${property} needs manual review.`\n );\n return;\n }\n\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [property],\n sourceValues: [value],\n strategy: \"semantic\",\n utility,\n });\n};\n\nconst addArbitraryPropertyMatch = (\n accumulator: MappingAccumulator,\n property: string,\n value: string | undefined,\n note: string\n): void => {\n if (!value || value === \"none\") {\n return;\n }\n\n addMatch(accumulator, {\n confidence: LOW_CONFIDENCE,\n notes: [note],\n sourceProperties: [property],\n sourceValues: [value],\n strategy: \"arbitrary\",\n utility: createArbitraryPropertyClass(property, value),\n });\n};\n\n// --- Inherited value / dimension helpers ---\n\nconst shouldEmitInheritedValue = (\n property: string,\n value: string | undefined,\n parentValue: string | undefined\n): boolean => {\n if (!value) {\n return false;\n }\n\n if (!parentValue) {\n return true;\n }\n\n if (property === \"color\") {\n return normalizeColor(value) !== normalizeColor(parentValue);\n }\n\n return value !== parentValue;\n};\n\nconst shouldMapDimension = (\n property: string,\n value: string | undefined\n): value is string => {\n if (!value) {\n return false;\n }\n\n if (property.startsWith(\"min-\")) {\n return value !== \"0px\" && value !== \"auto\";\n }\n\n if (property.startsWith(\"max-\")) {\n return value !== \"none\";\n }\n\n return value !== \"auto\";\n};\n\n// --- Candidate builders ---\n\nconst buildSpacingCandidate = (\n prefix: string,\n value: string,\n allowNegative: boolean\n): MatchCandidate | null => {\n if (isZeroLength(value)) {\n return null;\n }\n\n if (value === \"auto\" && prefix.startsWith(\"m\")) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"semantic\",\n utility: `${prefix}-auto`,\n };\n }\n\n const length = parseLength(value);\n if (!length) {\n return {\n confidence: MEDIUM_CONFIDENCE,\n notes: [\"Spacing required an arbitrary value.\"],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, value),\n };\n }\n\n if (length.value < 0 && !allowNegative) {\n return null;\n }\n\n const token =\n length.unit === \"px\" ? SPACING_SCALE.get(Math.abs(length.value)) : null;\n if (!token) {\n return {\n confidence: MEDIUM_CONFIDENCE,\n notes: [\"Spacing required an arbitrary value.\"],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, value),\n };\n }\n\n const baseUtility = token === \"px\" ? `${prefix}-px` : `${prefix}-${token}`;\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"scale\",\n utility: length.value < 0 ? `-${baseUtility}` : baseUtility,\n };\n};\n\nconst buildDimensionCandidate = (\n prefix: string,\n value: string,\n options: { confidence: number; note?: string }\n): MatchCandidate => {\n if (value === \"auto\") {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"semantic\",\n utility: `${prefix}-auto`,\n };\n }\n\n const keywordSuffix =\n DIMENSION_KEYWORD_MAP[value as keyof typeof DIMENSION_KEYWORD_MAP];\n if (keywordSuffix) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"semantic\",\n utility: `${prefix}-${keywordSuffix}`,\n };\n }\n\n const length = parseLength(value);\n const token =\n length && length.unit === \"px\"\n ? SPACING_SCALE.get(Math.abs(length.value))\n : null;\n if (token) {\n return {\n confidence: options.confidence,\n notes: options.note ? [options.note] : [],\n strategy: \"scale\",\n utility: token === \"px\" ? `${prefix}-px` : `${prefix}-${token}`,\n };\n }\n\n return {\n confidence: options.confidence,\n notes: options.note\n ? [options.note]\n : [\"Length required an arbitrary value.\"],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, value),\n };\n};\n\nconst buildScaleCandidate = (\n prefix: string,\n value: string,\n scale: Map<number, string>,\n note: string\n): MatchCandidate => {\n const length = parseLength(value);\n const token = length && length.unit === \"px\" ? scale.get(length.value) : null;\n\n if (token) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"scale\",\n utility: `${prefix}-${token}`,\n };\n }\n\n return {\n confidence: MEDIUM_CONFIDENCE,\n notes: [note],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, value),\n };\n};\n\nconst buildColorCandidate = (\n prefix: \"bg\" | \"border\" | \"decoration\" | \"text\",\n value: string\n): MatchCandidate => {\n const normalized = normalizeColor(value);\n let semanticUtility: string | null = null;\n if (normalized === \"transparent\") {\n semanticUtility = `${prefix}-transparent`;\n } else if (normalized === \"#000000\") {\n semanticUtility = `${prefix}-black`;\n } else if (normalized === \"#ffffff\") {\n semanticUtility = `${prefix}-white`;\n }\n\n if (semanticUtility) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"semantic\",\n utility: semanticUtility,\n };\n }\n\n return {\n confidence: MEDIUM_CONFIDENCE,\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, normalized),\n };\n};\n\nconst buildFontFamilyCandidate = (value: string): MatchCandidate => {\n const normalized = value.toLowerCase();\n\n for (const { keyword, utility } of FONT_FAMILY_MAP) {\n if (normalized.includes(keyword)) {\n return {\n confidence: MEDIUM_CONFIDENCE,\n notes: [\"Mapped to the nearest generic Tailwind family.\"],\n strategy: \"heuristic\",\n utility,\n };\n }\n }\n\n return {\n confidence: LOW_CONFIDENCE,\n notes: [\"Font family required an arbitrary property utility.\"],\n strategy: \"arbitrary\",\n utility: createArbitraryPropertyClass(\"font-family\", value),\n };\n};\n\nconst buildBorderWidthCandidate = (\n prefix: string,\n value: string\n): MatchCandidate => {\n const length = parseLength(value);\n const token =\n length && length.unit === \"px\"\n ? BORDER_WIDTH_SCALE.get(length.value)\n : null;\n\n if (token !== undefined) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"scale\",\n utility: token ? `${prefix}-${token}` : prefix,\n };\n }\n\n return {\n confidence: MEDIUM_CONFIDENCE,\n notes: [\"Border width required an arbitrary value.\"],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, value),\n };\n};\n\nconst buildBorderColorCandidate = (value: string): MatchCandidate =>\n buildColorCandidate(\"border\", value);\n\nconst buildRadiusCandidate = (\n prefix: string,\n value: string\n): MatchCandidate => {\n const length = parseLength(value);\n if (length && length.value >= 9999) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"semantic\",\n utility: `${prefix}-full`,\n };\n }\n\n const token =\n length && length.unit === \"px\" ? RADIUS_SCALE.get(length.value) : null;\n if (token !== undefined) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"scale\",\n utility: token ? `${prefix}-${token}` : prefix,\n };\n }\n\n return {\n confidence: MEDIUM_CONFIDENCE,\n notes: [\"Border radius required an arbitrary value.\"],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, value),\n };\n};\n\nconst buildZIndexCandidate = (value: string): MatchCandidate => {\n const numericValue = Number(value);\n if (Number.isFinite(numericValue) && Z_INDEX_SCALE.has(numericValue)) {\n return {\n confidence: HIGH_CONFIDENCE,\n strategy: \"scale\",\n utility: `z-${numericValue}`,\n };\n }\n\n return {\n confidence: MEDIUM_CONFIDENCE,\n notes: [\"Resolved z-index required an arbitrary value.\"],\n strategy: \"arbitrary\",\n utility: `z-[${sanitizeArbitraryValue(value)}]`,\n };\n};\n\n// --- Specific add*Match helpers ---\n\nconst addGapMatches = (\n accumulator: MappingAccumulator,\n gap: string | undefined,\n rowGap: string | undefined,\n columnGap: string | undefined\n): void => {\n if (gap && gap !== \"normal\" && !isZeroLength(gap)) {\n addCandidateMatch(\n accumulator,\n \"gap\",\n gap,\n buildSpacingCandidate(\"gap\", gap, false)\n );\n return;\n }\n\n addCandidateMatch(\n accumulator,\n \"row-gap\",\n rowGap,\n rowGap ? buildSpacingCandidate(\"gap-y\", rowGap, false) : null\n );\n addCandidateMatch(\n accumulator,\n \"column-gap\",\n columnGap,\n columnGap ? buildSpacingCandidate(\"gap-x\", columnGap, false) : null\n );\n};\n\nconst addFlexNumberMatch = (\n accumulator: MappingAccumulator,\n property: \"flex-grow\" | \"flex-shrink\",\n value: string | undefined,\n prefix: \"grow\" | \"shrink\"\n): void => {\n if (!value) {\n return;\n }\n\n let utility = createArbitraryUtility(prefix, value);\n if (value === \"1\") {\n utility = prefix;\n } else if (value === \"0\") {\n utility = `${prefix}-0`;\n }\n\n const confidence =\n value === \"0\" || value === \"1\" ? HIGH_CONFIDENCE : LOW_CONFIDENCE;\n const strategy: TailwindMatchStrategy =\n value === \"0\" || value === \"1\" ? \"semantic\" : \"arbitrary\";\n const notes =\n strategy === \"semantic\" ? [] : [`${property} required an arbitrary value.`];\n\n addMatch(accumulator, {\n confidence,\n notes,\n sourceProperties: [property],\n sourceValues: [value],\n strategy,\n utility,\n });\n};\n\nconst addAxisSpacingMatch = (\n accumulator: MappingAccumulator,\n prefix: string,\n first: [string, string | undefined],\n second: [string, string | undefined],\n allowNegative: boolean\n): void => {\n if (!(first[1] && second[1]) || first[1] !== second[1]) {\n return;\n }\n\n addCandidateMatch(\n accumulator,\n `${first[0]}|${second[0]}`,\n first[1],\n buildSpacingCandidate(prefix, first[1], allowNegative)\n );\n};\n\nconst addEdgeSpacingMatch = (\n accumulator: MappingAccumulator,\n prefix: string,\n entry: [string, string | undefined],\n allowNegative: boolean\n): void => {\n if (!entry[1] || isZeroLength(entry[1])) {\n return;\n }\n\n addCandidateMatch(\n accumulator,\n entry[0],\n entry[1],\n buildSpacingCandidate(prefix, entry[1], allowNegative)\n );\n};\n\nconst addBoxSpacingMatches = (\n accumulator: MappingAccumulator,\n prefix: \"m\" | \"p\",\n entries: [string, string | undefined][]\n): void => {\n const values = entries.map((entry) => entry[1]);\n if (values.some((value) => !value)) {\n return;\n }\n\n const normalizedValues = values as string[];\n if (normalizedValues.every((value) => isZeroLength(value))) {\n return;\n }\n\n if (allEqual(normalizedValues)) {\n addCandidateMatch(\n accumulator,\n entries[0][0],\n normalizedValues[0],\n buildSpacingCandidate(prefix, normalizedValues[0], prefix === \"m\")\n );\n return;\n }\n\n addAxisSpacingMatch(\n accumulator,\n `${prefix}y`,\n entries[0],\n entries[2],\n prefix === \"m\"\n );\n addAxisSpacingMatch(\n accumulator,\n `${prefix}x`,\n entries[1],\n entries[3],\n prefix === \"m\"\n );\n\n addEdgeSpacingMatch(accumulator, `${prefix}t`, entries[0], prefix === \"m\");\n addEdgeSpacingMatch(accumulator, `${prefix}r`, entries[1], prefix === \"m\");\n addEdgeSpacingMatch(accumulator, `${prefix}b`, entries[2], prefix === \"m\");\n addEdgeSpacingMatch(accumulator, `${prefix}l`, entries[3], prefix === \"m\");\n};\n\nconst addColorMatch = (\n accumulator: MappingAccumulator,\n prefix: \"bg\" | \"decoration\" | \"text\",\n property: string,\n value: string | undefined,\n shouldAdd: boolean\n): void => {\n if (!(shouldAdd && value)) {\n return;\n }\n\n addCandidateMatch(\n accumulator,\n property,\n value,\n buildColorCandidate(prefix, value)\n );\n};\n\nconst addFontFamilyMatch = (\n accumulator: MappingAccumulator,\n value: string | undefined,\n shouldAdd: boolean\n): void => {\n if (!(shouldAdd && value)) {\n return;\n }\n\n addCandidateMatch(\n accumulator,\n \"font-family\",\n value,\n buildFontFamilyCandidate(value)\n );\n};\n\nconst addScaleMatch = (\n accumulator: MappingAccumulator,\n property: string,\n value: string | undefined,\n shouldAdd: boolean,\n scale: Map<number, string>,\n prefix: string,\n note: string\n): void => {\n if (!(shouldAdd && value)) {\n return;\n }\n\n addCandidateMatch(\n accumulator,\n property,\n value,\n buildScaleCandidate(prefix, value, scale, note)\n );\n};\n\nconst addFontWeightMatch = (\n accumulator: MappingAccumulator,\n value: string | undefined,\n shouldAdd: boolean\n): void => {\n if (!(shouldAdd && value) || value === \"400\") {\n return;\n }\n\n const utility = lookupMappedUtility(FONT_WEIGHT_MAP, value);\n addMatch(accumulator, {\n confidence: utility ? HIGH_CONFIDENCE : LOW_CONFIDENCE,\n notes: utility ? [] : [\"Font weight required an arbitrary value.\"],\n sourceProperties: [\"font-weight\"],\n sourceValues: [value],\n strategy: utility ? \"semantic\" : \"arbitrary\",\n utility: utility\n ? `font-${utility}`\n : createArbitraryUtility(\"font\", value),\n });\n};\n\nconst addFontStyleMatch = (\n accumulator: MappingAccumulator,\n value: string | undefined,\n shouldAdd: boolean\n): void => {\n if (!(shouldAdd && value) || value === \"normal\") {\n return;\n }\n\n const utility = value === \"italic\" ? \"italic\" : \"not-italic\";\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"font-style\"],\n sourceValues: [value],\n strategy: \"semantic\",\n utility,\n });\n};\n\nconst addTrackingMatch = (\n accumulator: MappingAccumulator,\n value: string | undefined,\n shouldAdd: boolean\n): void => {\n if (!(shouldAdd && value) || value === \"normal\" || isZeroLength(value)) {\n return;\n }\n\n addMatch(accumulator, {\n confidence: LOW_CONFIDENCE,\n notes: [\"Letter spacing required an arbitrary value.\"],\n sourceProperties: [\"letter-spacing\"],\n sourceValues: [value],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(\"tracking\", value),\n });\n};\n\nconst addDecorationLineMatches = (\n accumulator: MappingAccumulator,\n value: string | undefined\n): void => {\n if (!value || value === \"none\") {\n return;\n }\n\n for (const part of value.split(WHITESPACE_SPLIT_PATTERN)) {\n const utility =\n {\n \"line-through\": \"line-through\",\n overline: \"overline\",\n underline: \"underline\",\n }[part] ?? null;\n\n if (!utility) {\n continue;\n }\n\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"text-decoration-line\"],\n sourceValues: [value],\n strategy: \"semantic\",\n utility,\n });\n }\n};\n\nconst addUniformBorderMatch = (\n element: ElementSnapshot,\n accumulator: MappingAccumulator\n): void => {\n const widths = [\n element.styles[\"border-top-width\"],\n element.styles[\"border-right-width\"],\n element.styles[\"border-bottom-width\"],\n element.styles[\"border-left-width\"],\n ];\n const styles = [\n element.styles[\"border-top-style\"],\n element.styles[\"border-right-style\"],\n element.styles[\"border-bottom-style\"],\n element.styles[\"border-left-style\"],\n ];\n const colors = [\n element.styles[\"border-top-color\"],\n element.styles[\"border-right-color\"],\n element.styles[\"border-bottom-color\"],\n element.styles[\"border-left-color\"],\n ];\n\n if (\n widths.some((value) => !value || isZeroLength(value)) ||\n styles.some((value) => !value || value === \"none\")\n ) {\n return;\n }\n\n if (\n !(\n allEqual(widths as string[]) &&\n allEqual(styles as string[]) &&\n allEqual(colors as string[])\n )\n ) {\n addUnsupported(\n accumulator,\n \"border\",\n \"mixed sides\",\n \"Per-side border variations need manual review.\"\n );\n return;\n }\n\n const width = widths[0] as string;\n const borderStyle = styles[0] as string;\n const color = colors[0] as string;\n\n addCandidateMatch(\n accumulator,\n \"border-width\",\n width,\n buildBorderWidthCandidate(\"border\", width)\n );\n\n if (borderStyle !== \"solid\") {\n const utility = lookupMappedUtility(BORDER_STYLE_MAP, borderStyle);\n if (utility) {\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"border-style\"],\n sourceValues: [borderStyle],\n strategy: \"semantic\",\n utility,\n });\n } else {\n addUnsupported(\n accumulator,\n \"border-style\",\n borderStyle,\n \"Border style needs manual review.\"\n );\n }\n }\n\n addCandidateMatch(\n accumulator,\n \"border-color\",\n color,\n buildBorderColorCandidate(color)\n );\n};\n\nconst addRadiusMatches = (\n element: ElementSnapshot,\n accumulator: MappingAccumulator\n): void => {\n const values = [\n element.styles[\"border-top-left-radius\"],\n element.styles[\"border-top-right-radius\"],\n element.styles[\"border-bottom-right-radius\"],\n element.styles[\"border-bottom-left-radius\"],\n ];\n\n if (\n values.some((value) => !value) ||\n values.every((value) => isZeroLength(value as string))\n ) {\n return;\n }\n\n const radiusValues = values as string[];\n if (allEqual(radiusValues)) {\n addCandidateMatch(\n accumulator,\n \"border-radius\",\n radiusValues[0],\n buildRadiusCandidate(\"rounded\", radiusValues[0])\n );\n return;\n }\n\n addUnsupported(\n accumulator,\n \"border-radius\",\n radiusValues.join(\", \"),\n \"Mixed corner radii need manual review.\"\n );\n};\n\nconst addShadowMatch = (\n accumulator: MappingAccumulator,\n value: string | undefined\n): void => {\n if (!value || value === \"none\") {\n return;\n }\n\n addMatch(accumulator, {\n confidence: MEDIUM_CONFIDENCE,\n sourceProperties: [\"box-shadow\"],\n sourceValues: [value],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(\"shadow\", value),\n });\n};\n\nconst addOpacityMatch = (\n accumulator: MappingAccumulator,\n value: string | undefined\n): void => {\n if (!value || value === \"1\") {\n return;\n }\n\n const numericValue = Number(value);\n if (!Number.isFinite(numericValue)) {\n return;\n }\n\n const percent = Math.round(numericValue * 100);\n const semantic = OPACITY_SCALE.has(percent);\n addMatch(accumulator, {\n confidence: semantic ? MEDIUM_CONFIDENCE : LOW_CONFIDENCE,\n notes: semantic ? [] : [\"Opacity required an arbitrary value.\"],\n sourceProperties: [\"opacity\"],\n sourceValues: [value],\n strategy: semantic ? \"scale\" : \"arbitrary\",\n utility: semantic\n ? `opacity-${percent}`\n : createArbitraryUtility(\"opacity\", value),\n });\n};\n\nconst addPositionMatch = (\n accumulator: MappingAccumulator,\n prefix: string,\n property: string,\n value: string | undefined\n): void => {\n if (!value || value === \"50% 50%\") {\n return;\n }\n\n const keyword =\n POSITION_KEYWORD_MAP[\n normalizeWhitespace(value) as keyof typeof POSITION_KEYWORD_MAP\n ];\n const named = keyword ? `${prefix}-${keyword}` : null;\n\n addMatch(accumulator, {\n confidence: named ? HIGH_CONFIDENCE : MEDIUM_CONFIDENCE,\n notes: named ? [] : [`${property} required an arbitrary value.`],\n sourceProperties: [property],\n sourceValues: [value],\n strategy: named ? \"semantic\" : \"arbitrary\",\n utility: named ?? createArbitraryUtility(prefix, value),\n });\n};\n\nconst addOverflowAxisMatch = (\n accumulator: MappingAccumulator,\n property: \"overflow-x\" | \"overflow-y\",\n value: string\n): void => {\n if (value === \"visible\") {\n return;\n }\n\n const suffix = lookupMappedUtility(OVERFLOW_MAP, value);\n if (!suffix) {\n addUnsupported(\n accumulator,\n property,\n value,\n \"Overflow needs manual review.\"\n );\n return;\n }\n\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [property],\n sourceValues: [value],\n strategy: \"semantic\",\n utility: `${property}-${suffix}`,\n });\n};\n\nconst addObjectPositionMatch = (\n accumulator: MappingAccumulator,\n value: string | undefined\n): void => {\n addPositionMatch(accumulator, \"object\", \"object-position\", value);\n};\n\n// --- Mapping step functions ---\n\nconst mapDisplay = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { display } = context.element.styles;\n if (!display || display === \"block\") {\n return;\n }\n\n const utility = lookupMappedUtility(DISPLAY_MAP, display);\n if (utility) {\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"display\"],\n sourceValues: [display],\n strategy: \"semantic\",\n utility,\n });\n return;\n }\n\n addUnsupported(\n accumulator,\n \"display\",\n display,\n \"Display needs manual review.\"\n );\n};\n\nconst mapPositioning = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { styles } = context.element;\n const { position } = styles;\n if (position && position !== \"static\") {\n const utility = lookupMappedUtility(POSITION_MAP, position);\n if (utility) {\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"position\"],\n sourceValues: [position],\n strategy: \"semantic\",\n utility,\n });\n }\n }\n\n if (!position || position === \"static\") {\n return;\n }\n\n for (const property of [\"top\", \"right\", \"bottom\", \"left\"] as const) {\n const value = styles[property];\n if (!value || value === \"auto\") {\n continue;\n }\n\n const candidate = buildDimensionCandidate(property, value, {\n confidence: LOW_CONFIDENCE,\n note: \"Computed insets are layout-derived and need review.\",\n });\n addCandidateMatch(accumulator, property, value, candidate);\n }\n\n const zIndex = styles[\"z-index\"];\n if (!zIndex || zIndex === \"auto\") {\n return;\n }\n\n addCandidateMatch(\n accumulator,\n \"z-index\",\n zIndex,\n buildZIndexCandidate(zIndex)\n );\n};\n\nconst mapFlexLayout = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { styles } = context.element;\n const { display } = styles;\n if (display !== \"flex\" && display !== \"inline-flex\") {\n return;\n }\n\n addMappedUtility(\n accumulator,\n \"flex-direction\",\n styles[\"flex-direction\"],\n FLEX_DIRECTION_MAP\n );\n addMappedUtility(\n accumulator,\n \"flex-wrap\",\n styles[\"flex-wrap\"],\n FLEX_WRAP_MAP\n );\n addMappedUtility(\n accumulator,\n \"justify-content\",\n styles[\"justify-content\"],\n JUSTIFY_CONTENT_MAP\n );\n addMappedUtility(\n accumulator,\n \"align-items\",\n styles[\"align-items\"],\n ALIGN_ITEMS_MAP\n );\n addGapMatches(\n accumulator,\n styles.gap,\n styles[\"row-gap\"],\n styles[\"column-gap\"]\n );\n addFlexNumberMatch(accumulator, \"flex-grow\", styles[\"flex-grow\"], \"grow\");\n addFlexNumberMatch(\n accumulator,\n \"flex-shrink\",\n styles[\"flex-shrink\"],\n \"shrink\"\n );\n\n const basis = styles[\"flex-basis\"];\n if (!basis || basis === \"auto\") {\n return;\n }\n\n addCandidateMatch(\n accumulator,\n \"flex-basis\",\n basis,\n buildDimensionCandidate(\"basis\", basis, {\n confidence: MEDIUM_CONFIDENCE,\n })\n );\n};\n\nconst mapGridLayout = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { styles } = context.element;\n const { display } = styles;\n if (display !== \"grid\" && display !== \"inline-grid\") {\n return;\n }\n\n addGapMatches(\n accumulator,\n styles.gap,\n styles[\"row-gap\"],\n styles[\"column-gap\"]\n );\n addMappedUtility(\n accumulator,\n \"grid-auto-flow\",\n styles[\"grid-auto-flow\"],\n GRID_AUTO_FLOW_MAP\n );\n\n for (const [property, prefix] of [\n [\"grid-column-start\", \"col-start\"],\n [\"grid-column-end\", \"col-end\"],\n [\"grid-row-start\", \"row-start\"],\n [\"grid-row-end\", \"row-end\"],\n ] as const) {\n const value = styles[property];\n if (!value || value === \"auto\") {\n continue;\n }\n\n addMatch(accumulator, {\n confidence: MEDIUM_CONFIDENCE,\n sourceProperties: [property],\n sourceValues: [value],\n strategy: \"arbitrary\",\n utility: createArbitraryUtility(prefix, value),\n });\n }\n\n addArbitraryPropertyMatch(\n accumulator,\n \"grid-template-columns\",\n styles[\"grid-template-columns\"],\n \"Computed grid tracks lose authored repeat syntax.\"\n );\n addArbitraryPropertyMatch(\n accumulator,\n \"grid-template-rows\",\n styles[\"grid-template-rows\"],\n \"Computed grid tracks lose authored repeat syntax.\"\n );\n};\n\nconst mapSpacing = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n addBoxSpacingMatches(accumulator, \"p\", [\n [\"padding-top\", context.element.styles[\"padding-top\"]],\n [\"padding-right\", context.element.styles[\"padding-right\"]],\n [\"padding-bottom\", context.element.styles[\"padding-bottom\"]],\n [\"padding-left\", context.element.styles[\"padding-left\"]],\n ]);\n addBoxSpacingMatches(accumulator, \"m\", [\n [\"margin-top\", context.element.styles[\"margin-top\"]],\n [\"margin-right\", context.element.styles[\"margin-right\"]],\n [\"margin-bottom\", context.element.styles[\"margin-bottom\"]],\n [\"margin-left\", context.element.styles[\"margin-left\"]],\n ]);\n};\n\nconst mapSizing = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { styles } = context.element;\n\n for (const [property, prefix, confidence] of [\n [\"min-width\", \"min-w\", MEDIUM_CONFIDENCE],\n [\"min-height\", \"min-h\", MEDIUM_CONFIDENCE],\n [\"max-width\", \"max-w\", MEDIUM_CONFIDENCE],\n [\"max-height\", \"max-h\", MEDIUM_CONFIDENCE],\n [\"width\", \"w\", LOW_CONFIDENCE],\n [\"height\", \"h\", LOW_CONFIDENCE],\n ] as const) {\n const value = styles[property];\n if (!shouldMapDimension(property, value)) {\n continue;\n }\n\n addCandidateMatch(\n accumulator,\n property,\n value,\n buildDimensionCandidate(prefix, value, {\n confidence,\n note:\n property === \"width\" || property === \"height\"\n ? \"Computed size values are often layout-dependent.\"\n : undefined,\n })\n );\n }\n};\n\nconst mapTypographyBasics = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { element, parent } = context;\n\n addColorMatch(\n accumulator,\n \"text\",\n \"color\",\n element.styles.color,\n shouldEmitInheritedValue(\n \"color\",\n element.styles.color,\n parent?.styles.color\n )\n );\n addFontFamilyMatch(\n accumulator,\n element.styles[\"font-family\"],\n shouldEmitInheritedValue(\n \"font-family\",\n element.styles[\"font-family\"],\n parent?.styles[\"font-family\"]\n )\n );\n addScaleMatch(\n accumulator,\n \"font-size\",\n element.styles[\"font-size\"],\n shouldEmitInheritedValue(\n \"font-size\",\n element.styles[\"font-size\"],\n parent?.styles[\"font-size\"]\n ),\n FONT_SIZE_SCALE,\n \"text\",\n \"Font size required an arbitrary value.\"\n );\n addFontWeightMatch(\n accumulator,\n element.styles[\"font-weight\"],\n shouldEmitInheritedValue(\n \"font-weight\",\n element.styles[\"font-weight\"],\n parent?.styles[\"font-weight\"]\n )\n );\n addFontStyleMatch(\n accumulator,\n element.styles[\"font-style\"],\n shouldEmitInheritedValue(\n \"font-style\",\n element.styles[\"font-style\"],\n parent?.styles[\"font-style\"]\n )\n );\n addScaleMatch(\n accumulator,\n \"line-height\",\n element.styles[\"line-height\"],\n shouldEmitInheritedValue(\n \"line-height\",\n element.styles[\"line-height\"],\n parent?.styles[\"line-height\"]\n ) && element.styles[\"line-height\"] !== \"normal\",\n LINE_HEIGHT_SCALE,\n \"leading\",\n \"Line height required an arbitrary value.\"\n );\n addTrackingMatch(\n accumulator,\n element.styles[\"letter-spacing\"],\n shouldEmitInheritedValue(\n \"letter-spacing\",\n element.styles[\"letter-spacing\"],\n parent?.styles[\"letter-spacing\"]\n )\n );\n};\n\nconst mapTypographyPresentation = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { element, parent } = context;\n\n addMappedUtility(\n accumulator,\n \"text-align\",\n element.styles[\"text-align\"],\n TEXT_ALIGN_MAP,\n shouldEmitInheritedValue(\n \"text-align\",\n element.styles[\"text-align\"],\n parent?.styles[\"text-align\"]\n ) && ![\"left\", \"start\"].includes(element.styles[\"text-align\"] ?? \"\")\n );\n addMappedUtility(\n accumulator,\n \"text-transform\",\n element.styles[\"text-transform\"],\n TEXT_TRANSFORM_MAP,\n shouldEmitInheritedValue(\n \"text-transform\",\n element.styles[\"text-transform\"],\n parent?.styles[\"text-transform\"]\n ) && element.styles[\"text-transform\"] !== \"none\"\n );\n addMappedUtility(\n accumulator,\n \"white-space\",\n element.styles[\"white-space\"],\n WHITE_SPACE_MAP,\n shouldEmitInheritedValue(\n \"white-space\",\n element.styles[\"white-space\"],\n parent?.styles[\"white-space\"]\n ) && element.styles[\"white-space\"] !== \"normal\"\n );\n addMappedUtility(\n accumulator,\n \"list-style-type\",\n element.styles[\"list-style-type\"],\n LIST_STYLE_MAP,\n shouldEmitInheritedValue(\n \"list-style-type\",\n element.styles[\"list-style-type\"],\n parent?.styles[\"list-style-type\"]\n ) && element.styles[\"list-style-type\"] !== \"disc\"\n );\n addDecorationLineMatches(accumulator, element.styles[\"text-decoration-line\"]);\n addColorMatch(\n accumulator,\n \"decoration\",\n \"text-decoration-color\",\n element.styles[\"text-decoration-color\"],\n element.styles[\"text-decoration-line\"] !== \"none\" &&\n Boolean(element.styles[\"text-decoration-color\"])\n );\n};\n\nconst mapBackground = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n addColorMatch(\n accumulator,\n \"bg\",\n \"background-color\",\n context.element.styles[\"background-color\"],\n !isTransparentColor(context.element.styles[\"background-color\"] ?? \"\")\n );\n addArbitraryPropertyMatch(\n accumulator,\n \"background-image\",\n context.element.styles[\"background-image\"],\n \"Background images are emitted as arbitrary properties.\"\n );\n};\n\nconst mapBorder = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n addUniformBorderMatch(context.element, accumulator);\n addRadiusMatches(context.element, accumulator);\n};\n\nconst mapEffects = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const { styles } = context.element;\n addShadowMatch(accumulator, styles[\"box-shadow\"]);\n addOpacityMatch(accumulator, styles.opacity);\n addArbitraryPropertyMatch(\n accumulator,\n \"transform\",\n styles.transform,\n \"Computed transforms are emitted as raw properties.\"\n );\n addPositionMatch(\n accumulator,\n \"origin\",\n \"transform-origin\",\n styles[\"transform-origin\"]\n );\n\n if (styles.visibility === \"hidden\") {\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"visibility\"],\n sourceValues: [\"hidden\"],\n strategy: \"semantic\",\n utility: \"invisible\",\n });\n }\n};\n\nconst mapOverflow = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const overflowX = context.element.styles[\"overflow-x\"];\n const overflowY = context.element.styles[\"overflow-y\"];\n if (!(overflowX && overflowY)) {\n return;\n }\n\n if (overflowX === overflowY && overflowX !== \"visible\") {\n const suffix = lookupMappedUtility(OVERFLOW_MAP, overflowX);\n if (suffix) {\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"overflow-x\", \"overflow-y\"],\n sourceValues: [overflowX, overflowY],\n strategy: \"semantic\",\n utility: `overflow-${suffix}`,\n });\n }\n return;\n }\n\n addOverflowAxisMatch(accumulator, \"overflow-x\", overflowX);\n addOverflowAxisMatch(accumulator, \"overflow-y\", overflowY);\n};\n\nconst mapObjectLayout = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const objectFit = context.element.styles[\"object-fit\"];\n if (objectFit && objectFit !== \"fill\") {\n const utility = lookupMappedUtility(OBJECT_FIT_MAP, objectFit);\n if (utility) {\n addMatch(accumulator, {\n confidence: HIGH_CONFIDENCE,\n sourceProperties: [\"object-fit\"],\n sourceValues: [objectFit],\n strategy: \"semantic\",\n utility,\n });\n }\n }\n\n addObjectPositionMatch(\n accumulator,\n context.element.styles[\"object-position\"]\n );\n};\n\nconst mapPseudoElements = (\n context: MappingContext,\n accumulator: MappingAccumulator\n): void => {\n const pseudoKinds = Object.keys(context.element.pseudo);\n if (pseudoKinds.length === 0) {\n return;\n }\n\n addUnsupported(\n accumulator,\n \"pseudo-elements\",\n pseudoKinds.join(\", \"),\n \"Pseudo-elements were captured, but Tailwind output still needs manual content utilities.\"\n );\n};\n\n// --- Review and confidence helpers ---\n\nconst isReviewOnlyNote = (note: string): boolean => {\n const normalizedNote = note.toLowerCase();\n\n return (\n normalizedNote.includes(\"manual review\") ||\n normalizedNote.includes(\"layout-dependent\") ||\n normalizedNote.includes(\"layout-derived\") ||\n normalizedNote.includes(\"arbitrary property utility\") ||\n normalizedNote.includes(\"required an arbitrary value\") ||\n normalizedNote.includes(\"computed transforms\") ||\n normalizedNote.includes(\"lose authored repeat syntax\")\n );\n};\n\nconst shouldMoveMatchToReview = (match: TailwindMatch): boolean => {\n if (match.label === \"low\" || match.utility.startsWith(\"[\")) {\n return true;\n }\n\n if (\n match.sourceProperties.some((property) =>\n REVIEW_ONLY_SOURCE_PROPERTIES.has(property)\n )\n ) {\n return true;\n }\n\n if (\n match.strategy === \"arbitrary\" &&\n !match.sourceProperties.every((property) =>\n CLEAN_ARBITRARY_SOURCE_PROPERTIES.has(property)\n )\n ) {\n return true;\n }\n\n return match.notes.some((note) => isReviewOnlyNote(note));\n};\n\nconst splitMatchesForSuggestion = (\n matches: TailwindMatch[]\n): {\n reviewMatches: TailwindMatch[];\n suggestedMatches: TailwindMatch[];\n} => {\n const reviewMatches: TailwindMatch[] = [];\n const suggestedMatches: TailwindMatch[] = [];\n\n for (const match of matches) {\n if (shouldMoveMatchToReview(match)) {\n reviewMatches.push(match);\n } else {\n suggestedMatches.push(match);\n }\n }\n\n return {\n reviewMatches,\n suggestedMatches,\n };\n};\n\nconst calculateElementConfidence = (\n accumulator: MappingAccumulator\n): number => {\n if (accumulator.matches.length === 0) {\n return accumulator.unsupported.length > 0\n ? LOW_CONFIDENCE\n : PASSIVE_CONFIDENCE;\n }\n\n const total = accumulator.matches.reduce(\n (sum, match) => sum + match.confidence,\n 0\n );\n const average = total / accumulator.matches.length;\n\n if (accumulator.unsupported.length === 0) {\n return roundToTwo(average);\n }\n\n return roundToTwo(Math.max(LOW_CONFIDENCE, average - 0.12));\n};\n\nconst buildReviewFallbackNote = (match: TailwindMatch): string => {\n if (match.label === \"low\") {\n return \"Low-confidence utility needs manual review.\";\n }\n\n if (\n match.sourceProperties.some((property) =>\n REVIEW_ONLY_SOURCE_PROPERTIES.has(property)\n )\n ) {\n return \"Computed layout or custom CSS was kept out of the clean suggestion.\";\n }\n\n if (match.strategy === \"arbitrary\") {\n return \"Arbitrary utility was kept out of the clean suggestion.\";\n }\n\n return \"Utility was kept out of the clean suggestion for review.\";\n};\n\nconst buildReviewItem = (\n mapping: TailwindElementMapping\n): TailwindReviewItem | null => {\n const reasons = [\n ...mapping.unsupported.map((entry) => `${entry.property}: ${entry.reason}`),\n ...mapping.matches\n .filter((match) => shouldMoveMatchToReview(match))\n .flatMap((match) => {\n const notes = match.notes.length\n ? match.notes\n : [buildReviewFallbackNote(match)];\n return notes.map((note) => `${match.utility}: ${note}`);\n }),\n ];\n\n if (reasons.length === 0) {\n return null;\n }\n\n return {\n confidence: mapping.confidence,\n confidenceLabel: mapping.confidenceLabel,\n elementId: mapping.elementId,\n reasons: dedupe(reasons).slice(0, 6),\n selector: mapping.selector,\n unsupportedCount: mapping.unsupported.length,\n };\n};\n\n// --- Core mapping orchestration ---\n\nconst createAccumulator = (): MappingAccumulator => ({\n classSet: new Set<string>(),\n classes: [],\n matches: [],\n unsupported: [],\n});\n\nconst MAPPING_STEPS: MappingStep[] = [\n mapDisplay,\n mapPositioning,\n mapFlexLayout,\n mapGridLayout,\n mapSpacing,\n mapSizing,\n mapTypographyBasics,\n mapTypographyPresentation,\n mapBackground,\n mapBorder,\n mapEffects,\n mapOverflow,\n mapObjectLayout,\n mapPseudoElements,\n];\n\nconst mapElementSnapshot = (\n context: MappingContext\n): TailwindElementMapping => {\n const accumulator = createAccumulator();\n\n for (const step of MAPPING_STEPS) {\n step(context, accumulator);\n }\n\n const confidence = calculateElementConfidence(accumulator);\n const { reviewMatches, suggestedMatches } = splitMatchesForSuggestion(\n accumulator.matches\n );\n\n return {\n className: accumulator.classes.join(\" \"),\n confidence,\n confidenceLabel: labelFromConfidence(confidence),\n elementId: context.element.id,\n matchCount: accumulator.matches.length,\n matches: accumulator.matches,\n reviewClassName: reviewMatches.map((match) => match.utility).join(\" \"),\n reviewMatchCount: reviewMatches.length,\n selector: context.element.selector,\n suggestedClassName: suggestedMatches\n .map((match) => match.utility)\n .join(\" \"),\n suggestedMatchCount: suggestedMatches.length,\n tagName: context.element.tagName,\n unsupported: accumulator.unsupported,\n };\n};\n\nexport const mapCaptureToTailwind = (\n capture: CaptureResult\n): TailwindMappingResult => {\n const elements: Record<string, TailwindElementMapping> = {};\n const reviewQueue: TailwindReviewItem[] = [];\n let cleanUtilityCount = 0;\n let confidenceSum = 0;\n let lowConfidenceElementCount = 0;\n let mappedElementCount = 0;\n let reviewUtilityCount = 0;\n let unsupportedPropertyCount = 0;\n let utilityCount = 0;\n\n for (const elementId of capture.order) {\n const element = capture.elements[elementId];\n if (!element) {\n continue;\n }\n\n const parent =\n element.parentId === null\n ? null\n : (capture.elements[element.parentId] ?? null);\n const mapping = mapElementSnapshot({\n element,\n parent,\n });\n elements[elementId] = mapping;\n\n confidenceSum += mapping.confidence;\n if (mapping.confidenceLabel === \"low\") {\n lowConfidenceElementCount += 1;\n }\n if (mapping.matchCount > 0) {\n mappedElementCount += 1;\n }\n\n unsupportedPropertyCount += mapping.unsupported.length;\n cleanUtilityCount += mapping.suggestedMatchCount;\n reviewUtilityCount += mapping.reviewMatchCount;\n utilityCount += mapping.matches.length;\n\n const reviewItem = buildReviewItem(mapping);\n if (reviewItem) {\n reviewQueue.push(reviewItem);\n }\n }\n\n reviewQueue.sort((left, right) => {\n if (left.confidence !== right.confidence) {\n return left.confidence - right.confidence;\n }\n\n return right.unsupportedCount - left.unsupportedCount;\n });\n\n const elementCount = capture.order.length;\n\n return {\n elements,\n order: capture.order,\n reviewQueue,\n summary: {\n averageConfidence: elementCount\n ? roundToTwo(confidenceSum / elementCount)\n : 0,\n cleanUtilityCount,\n elementCount,\n lowConfidenceElementCount,\n mappedElementCount,\n reviewCount: reviewQueue.length,\n reviewUtilityCount,\n unsupportedPropertyCount,\n utilityCount,\n },\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { CaptureResult, CaptureSettings } from "./types.ts";
2
+ export declare const MESSAGE_TYPE_CAPTURE_COMPLETED = "capture/completed";
3
+ export declare const MESSAGE_TYPE_CAPTURE_CANCELLED = "capture/cancelled";
4
+ export declare const MESSAGE_TYPE_CAPTURE_FAILED = "capture/failed";
5
+ export interface CaptureCompletedMessage {
6
+ capture: CaptureResult;
7
+ type: typeof MESSAGE_TYPE_CAPTURE_COMPLETED;
8
+ }
9
+ export interface CaptureCancelledMessage {
10
+ reason: string;
11
+ type: typeof MESSAGE_TYPE_CAPTURE_CANCELLED;
12
+ }
13
+ export interface CaptureFailedMessage {
14
+ error: string;
15
+ type: typeof MESSAGE_TYPE_CAPTURE_FAILED;
16
+ }
17
+ export type ExtensionMessage = CaptureCancelledMessage | CaptureCompletedMessage | CaptureFailedMessage;
18
+ export declare const createDefaultSettings: () => CaptureSettings;
@@ -0,0 +1,59 @@
1
+ import type { CaptureResult } from "./types.ts";
2
+ type TailwindConfidenceLabel = "high" | "medium" | "low";
3
+ type TailwindMatchStrategy = "arbitrary" | "heuristic" | "scale" | "semantic";
4
+ export interface TailwindElementMapping {
5
+ className: string;
6
+ confidence: number;
7
+ confidenceLabel: TailwindConfidenceLabel;
8
+ elementId: string;
9
+ matchCount: number;
10
+ matches: TailwindMatch[];
11
+ reviewClassName: string;
12
+ reviewMatchCount: number;
13
+ selector: string;
14
+ suggestedClassName: string;
15
+ suggestedMatchCount: number;
16
+ tagName: string;
17
+ unsupported: TailwindUnsupportedProperty[];
18
+ }
19
+ export interface TailwindMappingResult {
20
+ elements: Record<string, TailwindElementMapping>;
21
+ order: string[];
22
+ reviewQueue: TailwindReviewItem[];
23
+ summary: TailwindMappingSummary;
24
+ }
25
+ export interface TailwindMappingSummary {
26
+ averageConfidence: number;
27
+ cleanUtilityCount: number;
28
+ elementCount: number;
29
+ lowConfidenceElementCount: number;
30
+ mappedElementCount: number;
31
+ reviewCount: number;
32
+ reviewUtilityCount: number;
33
+ unsupportedPropertyCount: number;
34
+ utilityCount: number;
35
+ }
36
+ interface TailwindMatch {
37
+ confidence: number;
38
+ label: TailwindConfidenceLabel;
39
+ notes: string[];
40
+ sourceProperties: string[];
41
+ sourceValues: string[];
42
+ strategy: TailwindMatchStrategy;
43
+ utility: string;
44
+ }
45
+ export interface TailwindReviewItem {
46
+ confidence: number;
47
+ confidenceLabel: TailwindConfidenceLabel;
48
+ elementId: string;
49
+ reasons: string[];
50
+ selector: string;
51
+ unsupportedCount: number;
52
+ }
53
+ interface TailwindUnsupportedProperty {
54
+ property: string;
55
+ reason: string;
56
+ value: string;
57
+ }
58
+ export declare const mapCaptureToTailwind: (capture: CaptureResult) => TailwindMappingResult;
59
+ export {};
@@ -0,0 +1,53 @@
1
+ export type CaptureMode = "curated" | "full";
2
+ export type PseudoElementKind = "before" | "after";
3
+ export interface CaptureSettings {
4
+ captureMode: CaptureMode;
5
+ includeHiddenElements: boolean;
6
+ includePseudoElements: boolean;
7
+ }
8
+ export interface BoundingBox {
9
+ bottom: number;
10
+ height: number;
11
+ left: number;
12
+ right: number;
13
+ top: number;
14
+ width: number;
15
+ x: number;
16
+ y: number;
17
+ }
18
+ export interface PseudoElementSnapshot {
19
+ kind: PseudoElementKind;
20
+ styles: Record<string, string>;
21
+ }
22
+ export interface ElementSnapshot {
23
+ attributes: Record<string, string>;
24
+ boundingBox: BoundingBox;
25
+ children: string[];
26
+ classList: string[];
27
+ id: string;
28
+ parentId: string | null;
29
+ pseudo: Partial<Record<PseudoElementKind, PseudoElementSnapshot>>;
30
+ selector: string;
31
+ styles: Record<string, string>;
32
+ tagName: string;
33
+ }
34
+ export interface CaptureSummary {
35
+ elementCount: number;
36
+ pseudoElementCount: number;
37
+ }
38
+ export interface CaptureMetadata {
39
+ capturedAt?: string;
40
+ title?: string;
41
+ url: string;
42
+ userAgent?: string;
43
+ }
44
+ export interface CaptureResult {
45
+ elements: Record<string, ElementSnapshot>;
46
+ metadata: CaptureMetadata;
47
+ order: string[];
48
+ rootElementId: string;
49
+ rootOuterHtml: string;
50
+ settings: CaptureSettings;
51
+ summary: CaptureSummary;
52
+ version: 1;
53
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@style-capture/core",
3
+ "version": "0.0.1",
4
+ "description": "Shared capture mapping and Claude export helpers for Style Capture",
5
+ "keywords": [
6
+ "ai",
7
+ "claude",
8
+ "css",
9
+ "html",
10
+ "style-capture",
11
+ "tailwind"
12
+ ],
13
+ "homepage": "https://github.com/mblode/style-capture/tree/main/packages/core",
14
+ "bugs": {
15
+ "url": "https://github.com/mblode/style-capture/issues"
16
+ },
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/mblode/style-capture.git",
21
+ "directory": "packages/core"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "LICENSE.md"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "main": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js",
36
+ "default": "./dist/index.js"
37
+ }
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "scripts": {
43
+ "build": "npm run build:js && npm run build:types",
44
+ "build:js": "tsdown",
45
+ "build:types": "tsc -p tsconfig.build.json",
46
+ "dev": "tsdown --watch",
47
+ "check-types": "tsc --noEmit",
48
+ "lint": "oxlint --ignore-path .oxlintignore .",
49
+ "lint:fix": "oxlint --ignore-path .oxlintignore --fix .",
50
+ "format": "oxfmt --ignore-path .oxfmtignore --write .",
51
+ "format:check": "oxfmt --ignore-path .oxfmtignore --check .",
52
+ "check": "npm run lint && npm run format:check && npm run check-types",
53
+ "fix": "npm run format && npm run lint:fix",
54
+ "test": "vitest run"
55
+ },
56
+ "devDependencies": {
57
+ "@types/node": "^24.12.0",
58
+ "jsdom": "^27.0.1",
59
+ "oxfmt": "^0.40.0",
60
+ "oxlint": "^1.55.0",
61
+ "tsdown": "^0.12.0",
62
+ "typescript": "~5.9.3",
63
+ "vitest": "^4.1.0"
64
+ }
65
+ }