@agent-native/core 0.119.0 → 0.119.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.
Files changed (64) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +8 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/ingestion/figma-node-to-html.ts +20 -99
  5. package/corpus/core/src/ingestion/figma-paint-math.ts +371 -0
  6. package/corpus/core/src/ingestion/index.ts +20 -0
  7. package/corpus/templates/assets/app/routes/library.tsx +17 -9
  8. package/corpus/templates/design/AGENTS.md +18 -5
  9. package/corpus/templates/design/FIGMA_INTEROPERABILITY.md +25 -12
  10. package/corpus/templates/design/actions/hydrate-figma-paste-images.ts +115 -0
  11. package/corpus/templates/design/actions/import-figma-clipboard.ts +83 -18
  12. package/corpus/templates/design/actions/import-figma-frame.ts +34 -21
  13. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +28 -1
  14. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +106 -11
  15. package/corpus/templates/design/app/components/design/FigmaHydrationDialog.tsx +273 -0
  16. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +7 -7
  17. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +57 -9
  18. package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +10 -0
  19. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +8 -1
  20. package/corpus/templates/design/app/components/design/multi-screen/types.ts +3 -0
  21. package/corpus/templates/design/app/i18n-data.ts +150 -2
  22. package/corpus/templates/design/app/lib/design-file-upload.ts +85 -0
  23. package/corpus/templates/design/app/lib/design-import.ts +19 -1
  24. package/corpus/templates/design/app/lib/figma-clipboard.ts +110 -10
  25. package/corpus/templates/design/changelog/2026-07-20-paste-figma-frames-directly-onto-the-canvas-no-token-needed.md +6 -0
  26. package/corpus/templates/design/changelog/2026-07-21-fig-upload-frame-url-and-rate-limit-errors.md +5 -0
  27. package/corpus/templates/design/changelog/2026-07-22-connecting-a-figma-token-now-actually-fills-in-a-pasted-desi.md +6 -0
  28. package/corpus/templates/design/changelog/2026-07-22-figma-line-arrow-vectors-and-stroked-icons-now-render-instea.md +6 -0
  29. package/corpus/templates/design/changelog/2026-07-22-fill-a-no-token-figma-paste-s-images-by-dropping-the-origina.md +6 -0
  30. package/corpus/templates/design/changelog/2026-07-22-imported-and-pasted-figma-frames-now-render-faithfully-fixed.md +6 -0
  31. package/corpus/templates/design/server/handlers/import-design-file.ts +50 -0
  32. package/corpus/templates/design/server/lib/fig-file-decoder.ts +90 -49
  33. package/corpus/templates/design/server/lib/fig-file-import.ts +19 -5
  34. package/corpus/templates/design/server/lib/fig-file-to-html.ts +583 -78
  35. package/corpus/templates/design/server/lib/figma-clipboard-local-decode.ts +238 -0
  36. package/corpus/templates/design/server/lib/figma-image-hydration.ts +389 -0
  37. package/corpus/templates/design/server/lib/figma-node-import.ts +136 -36
  38. package/corpus/templates/design/server/register-secrets.ts +14 -2
  39. package/dist/collab/awareness.d.ts +2 -2
  40. package/dist/collab/awareness.d.ts.map +1 -1
  41. package/dist/collab/struct-routes.d.ts +1 -1
  42. package/dist/ingestion/figma-node-to-html.d.ts.map +1 -1
  43. package/dist/ingestion/figma-node-to-html.js +14 -88
  44. package/dist/ingestion/figma-node-to-html.js.map +1 -1
  45. package/dist/ingestion/figma-paint-math.d.ts +157 -0
  46. package/dist/ingestion/figma-paint-math.d.ts.map +1 -0
  47. package/dist/ingestion/figma-paint-math.js +274 -0
  48. package/dist/ingestion/figma-paint-math.js.map +1 -0
  49. package/dist/ingestion/index.d.ts +1 -0
  50. package/dist/ingestion/index.d.ts.map +1 -1
  51. package/dist/ingestion/index.js +1 -0
  52. package/dist/ingestion/index.js.map +1 -1
  53. package/dist/observability/routes.d.ts +5 -5
  54. package/dist/progress/routes.d.ts +1 -1
  55. package/dist/provider-api/actions/custom-provider-registration.d.ts +12 -12
  56. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  57. package/dist/resources/handlers.d.ts +1 -1
  58. package/dist/secrets/routes.d.ts +3 -3
  59. package/dist/server/realtime-token.d.ts +1 -1
  60. package/dist/server/transcribe-voice.d.ts +1 -1
  61. package/package.json +1 -1
  62. package/src/ingestion/figma-node-to-html.ts +20 -99
  63. package/src/ingestion/figma-paint-math.ts +371 -0
  64. package/src/ingestion/index.ts +20 -0
@@ -1 +1 @@
1
- {"version":3,"file":"figma-node-to-html.js","sourceRoot":"","sources":["../../src/ingestion/figma-node-to-html.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Figma node JSON -> HTML mapper.\n *\n * Input is the `document` subtree returned by\n * `GET /v1/files/:fileKey/nodes?ids=...&geometry=paths` (or the file's root\n * `document` node). Output is a self-contained HTML fragment using absolute\n * positioning + inline styles, matching Figma's own canvas model 1:1 rather\n * than reconstructing a semantic/Tailwind layout — the goal is pixel fidelity\n * for an imported snapshot, not idiomatic hand-authored markup.\n *\n * This module is pure and synchronous: it never calls the network. The\n * caller (an action) is responsible for:\n * 1. Fetching the node JSON from the Figma REST API.\n * 2. Calling `collectFallbackNodeIds` / `collectImageFillRefs` to find out\n * which nodes need a rendered PNG fallback and which image fills need\n * resolved URLs.\n * 3. Fetching those via `/v1/images/:fileKey` (fallback renders) and\n * `/v1/files/:fileKey/images` (fill ref -> URL map).\n * 4. Calling `mapFigmaNodeToHtml` with the resulting maps.\n *\n * ## Pixel-perfect property coverage\n *\n * | Property | Fidelity | Notes |\n * | ------------------------------------------- | ------------- | ----- |\n * | Position/size (absoluteBoundingBox) | exact | frame-relative |\n * | Auto-layout (flex*) | exact | Figma auto-layout IS flexbox |\n * | Text font/size/weight/case/decoration/align | exact | |\n * | Line-height (px vs percent-of-font-size) | exact | resolved to px |\n * | Letter-spacing | exact | already px in REST API |\n * | Solid fills | exact | |\n * | Gradient fills (angle/position) | exact (linear)/approximated (radial/angular/diamond) | derived from gradientHandlePositions, not a default angle |\n * | Multiple fills (layering) | exact | reversed to match CSS background-image stacking |\n * | Image fills (scale modes) | exact (FILL/FIT/TILE/STRETCH-axis-aligned) / approximated (skewed imageTransform) | |\n * | Strokes (uniform, align) | exact | CENTER via outline+negative offset, INSIDE via inset box-shadow, OUTSIDE via outline |\n * | Strokes (per-side weights) | approximated | CSS has no per-side outline; falls back to per-side `border` (inside-only) |\n * | Corner radii (uniform + per-corner) | exact | |\n * | Effects: drop/inner shadow | exact | |\n * | Effects: layer/background blur | approximated | Figma <-> CSS blur radius scale is not publicly specified as 1:1 |\n * | Opacity | exact | |\n * | Blend modes (CSS-supported) | exact | |\n * | Blend modes (Figma-only: LINEAR_BURN/DODGE/LIGHTER/DARKER) | approximated | mapped to closest CSS equivalent |\n * | clipsContent | exact | overflow: hidden |\n * | Rotation | approximated | pivots about the bounding-box center (see below) |\n * | Vector networks / boolean ops / unsupported types | image fallback | never approximated structurally |\n *\n * ### Rotation caveat\n * The REST API docs describe `rotation` as being in degrees, but the field\n * is empirically returned in RADIANS (verified against known authored\n * rotations via the Plugin API); this mapper converts it to degrees before\n * use. `absoluteBoundingBox` is the *already-rotated* axis-aligned bounding\n * box —\n * Figma does not expose the pre-rotation box directly. We reconstruct the\n * unrotated box by treating the AABB's center as invariant under rotation\n * (true for a shape rotated about its own center) and rotate the CSS element\n * about `transform-origin: center` by `-rotation` degrees (Figma's rotation\n * is clockwise-negative relative to CSS's clockwise-positive convention).\n * This is exact when Figma pivots rotation about the shape's center and only\n * approximated if Figma's internal pivot differs (rare in practice; visually\n * indistinguishable in the overwhelming majority of designs). A fully exact\n * alternative would consume `relativeTransform` as a CSS `matrix()` directly,\n * which is a documented follow-up if a specific design surfaces a visible\n * mismatch.\n */\n\nexport interface FigmaColor {\n r: number;\n g: number;\n b: number;\n a?: number;\n}\n\nexport interface FigmaColorStop {\n position: number;\n color: FigmaColor;\n}\n\nexport interface FigmaImageFilter {\n exposure?: number;\n contrast?: number;\n saturation?: number;\n temperature?: number;\n tint?: number;\n highlights?: number;\n shadows?: number;\n}\n\nexport interface FigmaPaint {\n type:\n | \"SOLID\"\n | \"GRADIENT_LINEAR\"\n | \"GRADIENT_RADIAL\"\n | \"GRADIENT_ANGULAR\"\n | \"GRADIENT_DIAMOND\"\n | \"IMAGE\"\n | \"EMOJI\"\n | \"VIDEO\";\n visible?: boolean;\n opacity?: number;\n color?: FigmaColor;\n gradientHandlePositions?: Array<{ x: number; y: number }>;\n gradientStops?: FigmaColorStop[];\n imageRef?: string;\n scaleMode?: \"FILL\" | \"FIT\" | \"TILE\" | \"STRETCH\";\n imageTransform?: [[number, number, number], [number, number, number]];\n filters?: FigmaImageFilter;\n blendMode?: string;\n}\n\nexport interface FigmaEffect {\n type: \"DROP_SHADOW\" | \"INNER_SHADOW\" | \"LAYER_BLUR\" | \"BACKGROUND_BLUR\";\n visible?: boolean;\n radius?: number;\n spread?: number;\n color?: FigmaColor;\n offset?: { x: number; y: number };\n blendMode?: string;\n}\n\nexport interface FigmaTypeStyle {\n fontFamily?: string;\n fontPostScriptName?: string;\n fontWeight?: number;\n fontSize?: number;\n italic?: boolean;\n letterSpacing?: number;\n lineHeightPx?: number;\n lineHeightPercent?: number;\n lineHeightPercentFontSize?: number;\n lineHeightUnit?: \"PIXELS\" | \"FONT_SIZE_%\" | \"INTRINSIC_%\";\n textCase?: \"ORIGINAL\" | \"UPPER\" | \"LOWER\" | \"TITLE\";\n textDecoration?: \"NONE\" | \"UNDERLINE\" | \"STRIKETHROUGH\";\n textAlignHorizontal?: \"LEFT\" | \"RIGHT\" | \"CENTER\" | \"JUSTIFIED\";\n textAlignVertical?: \"TOP\" | \"CENTER\" | \"BOTTOM\";\n textAutoResize?: \"NONE\" | \"WIDTH_AND_HEIGHT\" | \"HEIGHT\" | \"TRUNCATE\";\n paragraphSpacing?: number;\n paragraphIndent?: number;\n listSpacing?: number;\n hangingPunctuation?: boolean;\n hangingList?: boolean;\n opentypeFlags?: Record<string, number>;\n hyperlink?: unknown;\n fills?: FigmaPaint[];\n}\n\nexport interface FigmaIndividualStrokeWeights {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\nexport interface FigmaBoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface FigmaNode {\n id: string;\n name?: string;\n type: string;\n visible?: boolean;\n opacity?: number;\n blendMode?: string;\n rotation?: number;\n absoluteBoundingBox?: FigmaBoundingBox;\n relativeTransform?: [[number, number, number], [number, number, number]];\n /**\n * The node's actual visual extent, INCLUDING stroke/effect overflow --\n * e.g. an OUTSIDE-aligned stroke or a drop shadow makes this larger than\n * `absoluteBoundingBox` (the purely geometric fill bounds). Figma's own\n * `/v1/images` renders for a node are cropped to this box, not to\n * `absoluteBoundingBox` -- sizing an image-fallback `<img>` using the\n * geometric box instead squishes/crops the rendered PNG to the wrong\n * aspect ratio whenever a fallback node has stroke/effect overflow.\n */\n absoluteRenderBounds?: FigmaBoundingBox;\n size?: { x: number; y: number };\n clipsContent?: boolean;\n isMask?: boolean;\n maskType?: \"ALPHA\" | \"VECTOR\" | \"LUMINANCE\";\n arcData?: {\n startingAngle?: number;\n endingAngle?: number;\n innerRadius?: number;\n };\n characters?: string;\n style?: FigmaTypeStyle;\n characterStyleOverrides?: number[];\n styleOverrideTable?: Record<string, FigmaTypeStyle>;\n lineTypes?: string[];\n lineIndentations?: number[];\n fills?: FigmaPaint[];\n strokes?: FigmaPaint[];\n strokeWeight?: number;\n strokeAlign?: \"INSIDE\" | \"OUTSIDE\" | \"CENTER\";\n individualStrokeWeights?: FigmaIndividualStrokeWeights;\n strokeDashes?: number[];\n cornerRadius?: number;\n rectangleCornerRadii?: [number, number, number, number];\n effects?: FigmaEffect[];\n layoutMode?: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\" | \"GRID\";\n layoutPositioning?: \"AUTO\" | \"ABSOLUTE\";\n primaryAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"SPACE_BETWEEN\";\n counterAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"BASELINE\";\n layoutSizingHorizontal?: \"FIXED\" | \"HUG\" | \"FILL\";\n layoutSizingVertical?: \"FIXED\" | \"HUG\" | \"FILL\";\n layoutWrap?: \"NO_WRAP\" | \"WRAP\";\n itemSpacing?: number;\n counterAxisSpacing?: number;\n paddingLeft?: number;\n paddingRight?: number;\n paddingTop?: number;\n paddingBottom?: number;\n minWidth?: number | null;\n maxWidth?: number | null;\n minHeight?: number | null;\n maxHeight?: number | null;\n componentId?: string;\n componentProperties?: Record<string, unknown>;\n boundVariables?: Record<string, unknown>;\n interactions?: unknown[];\n children?: FigmaNode[];\n}\n\nexport type FidelityLevel = \"exact\" | \"approximated\" | \"image-fallback\";\n\nexport interface FidelityEntry {\n nodeId: string;\n nodeName: string;\n nodeType: string;\n level: FidelityLevel;\n notes: string[];\n}\n\nexport interface FidelityReport {\n entries: FidelityEntry[];\n summary: {\n exact: number;\n approximated: number;\n imageFallback: number;\n };\n}\n\nexport interface MapFigmaNodeOptions {\n /** imageRef hash -> resolved public URL, from `/v1/files/:key/images`. */\n imageFillUrls?: Record<string, string>;\n /** nodeId -> rendered PNG URL, from `/v1/images/:key` for fallback subtrees. */\n fallbackImageUrls?: Record<string, string>;\n /** Node ids that should be rendered as an image regardless of type. */\n forceImageFallbackNodeIds?: Set<string>;\n}\n\nexport interface MapFigmaNodeResult {\n html: string;\n fidelity: FidelityReport;\n}\n\nconst UNSUPPORTED_STRUCTURAL_TYPES = new Set([\n \"BOOLEAN_OPERATION\",\n \"VECTOR\",\n \"STAR\",\n \"REGULAR_POLYGON\",\n \"SLICE\",\n \"STICKY\",\n \"SHAPE_WITH_TEXT\",\n \"CONNECTOR\",\n \"WASHI_TAPE\",\n \"TABLE\",\n]);\n\nconst SUPPORTED_CONTAINER_TYPES = new Set([\n \"FRAME\",\n \"GROUP\",\n \"COMPONENT\",\n \"COMPONENT_SET\",\n \"INSTANCE\",\n \"SECTION\",\n]);\n\nconst MAX_FIGMA_NODE_COUNT = 75_000;\nconst MAX_FIGMA_NODE_DEPTH = 256;\nconst MAX_METADATA_ATTRIBUTE_CHARS = 16_384;\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction round(value: number, precision = 2): number {\n const factor = 10 ** precision;\n return Math.round(value * factor) / factor;\n}\n\nfunction px(value: number | undefined, precision = 2): string | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return `${round(value, precision)}px`;\n}\n\nfunction colorToCss(\n color: FigmaColor | undefined,\n opacityMul = 1,\n): string | null {\n if (!color) return null;\n const r = Math.round((color.r ?? 0) * 255);\n const g = Math.round((color.g ?? 0) * 255);\n const b = Math.round((color.b ?? 0) * 255);\n const a = round((color.a ?? 1) * opacityMul, 4);\n return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction escapeAttr(value: string): string {\n return escapeHtml(value);\n}\n\nfunction metadataAttr(\n name: string,\n value: unknown,\n node: FigmaNode,\n tracker: FidelityTracker,\n): string {\n if (value === undefined || value === null) return \"\";\n let serialized: string;\n try {\n serialized = typeof value === \"string\" ? value : JSON.stringify(value);\n } catch {\n tracker.record(\n node,\n \"approximated\",\n `${name} metadata could not be serialized and was omitted.`,\n );\n return \"\";\n }\n if (serialized.length > MAX_METADATA_ATTRIBUTE_CHARS) {\n tracker.record(\n node,\n \"approximated\",\n `${name} metadata exceeded ${MAX_METADATA_ATTRIBUTE_CHARS} characters and was omitted.`,\n );\n return \"\";\n }\n return ` ${name}=\"${escapeAttr(serialized)}\"`;\n}\n\n/**\n * Builds the CSS text for a `style=\"...\"` attribute AND escapes it for HTML\n * attribute context. This matters because at least one style value we emit\n * legitimately contains a literal double-quote character: font-family values\n * are built as `\"Inter\", sans-serif` (CSS requires quoting family names with\n * spaces). Without escaping here, that embedded `\"` prematurely terminates\n * the enclosing `style=\"...\"` attribute the moment a browser (or any other\n * HTML parser) reads it -- silently dropping every style declared after\n * font-family in object-key order (font-size, font-weight, line-height,\n * text-align, and the text node's own `display: flex` used to emulate\n * vertical alignment). The visible symptom is text rendering at the\n * browser's default font/size instead of the mapped Figma typography, with\n * no error anywhere -- caught here via a real headless-browser render that\n * showed a Figma TEXT node's own style attribute silently truncated at\n * `font-family: \"`.\n */\nfunction styleAttr(styles: Record<string, string | undefined>): string {\n const parts = Object.entries(styles)\n .filter((entry): entry is [string, string] => typeof entry[1] === \"string\")\n .map(([key, value]) => `${key}: ${value}`);\n return escapeAttr(parts.join(\"; \"));\n}\n\n// ---------------------------------------------------------------------------\n// Fidelity report builder\n// ---------------------------------------------------------------------------\n\nclass FidelityTracker {\n private entries = new Map<string, FidelityEntry>();\n\n record(node: FigmaNode, level: FidelityLevel, note: string) {\n const existing = this.entries.get(node.id);\n if (existing) {\n // Never downgrade an image-fallback entry, and never upgrade below the\n // worst level recorded for this node.\n const rank: Record<FidelityLevel, number> = {\n exact: 0,\n approximated: 1,\n \"image-fallback\": 2,\n };\n if (rank[level] > rank[existing.level]) existing.level = level;\n existing.notes.push(note);\n return;\n }\n this.entries.set(node.id, {\n nodeId: node.id,\n nodeName: node.name ?? node.id,\n nodeType: node.type,\n level,\n notes: [note],\n });\n }\n\n build(): FidelityReport {\n const entries = [...this.entries.values()];\n const summary = entries.reduce(\n (acc, entry) => {\n if (entry.level === \"exact\") acc.exact += 1;\n else if (entry.level === \"approximated\") acc.approximated += 1;\n else acc.imageFallback += 1;\n return acc;\n },\n { exact: 0, approximated: 0, imageFallback: 0 },\n );\n return { entries, summary };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Gradient angle / position derivation\n// ---------------------------------------------------------------------------\n\ninterface GradientGeometry {\n start: { x: number; y: number };\n end: { x: number; y: number };\n width: { x: number; y: number };\n}\n\nfunction resolveGradientGeometry(paint: FigmaPaint): GradientGeometry | null {\n const handles = paint.gradientHandlePositions;\n if (!handles || handles.length < 3) return null;\n return { start: handles[0]!, end: handles[1]!, width: handles[2]! };\n}\n\n/**\n * Derive a CSS `linear-gradient()` angle (degrees) from Figma's normalized\n * `gradientHandlePositions`. Handle positions are normalized independently in\n * x and y (0..1 relative to the node's bounding box), so the angle must be\n * computed in actual pixel space using the node's real width/height —\n * otherwise a non-square box silently distorts the angle.\n *\n * Verified against Figma's documented identity handles\n * (start=(0,0.5), end=(1,0.5), width=(1,0), i.e. a plain left-to-right\n * gradient) which must resolve to CSS `90deg` (\"to right\"):\n * dx = 1*w, dy = 0 -> atan2(0, dx) = 0deg -> +90 = 90deg. Matches.\n * And a top-to-bottom gradient (start=(0.5,0), end=(0.5,1)) must resolve to\n * CSS `180deg` (\"to bottom\"):\n * dx = 0, dy = 1*h -> atan2(dy, 0) = 90deg -> +90 = 180deg. Matches.\n */\nexport function gradientAngleDegrees(\n paint: FigmaPaint,\n box: { width: number; height: number },\n): number | null {\n const geometry = resolveGradientGeometry(paint);\n if (!geometry) return null;\n const dx = (geometry.end.x - geometry.start.x) * box.width;\n const dy = (geometry.end.y - geometry.start.y) * box.height;\n const angleRad = Math.atan2(dy, dx);\n const angleDeg = (angleRad * 180) / Math.PI + 90;\n return ((angleDeg % 360) + 360) % 360;\n}\n\nfunction gradientStopsCss(\n paint: FigmaPaint,\n remapPosition?: (position: number) => number,\n): string {\n const stops = paint.gradientStops ?? [];\n return stops\n .map((stop) => {\n const color = colorToCss(stop.color, paint.opacity ?? 1) ?? \"transparent\";\n const position = remapPosition\n ? remapPosition(stop.position)\n : stop.position;\n return `${color} ${round(position * 100, 2)}%`;\n })\n .join(\", \");\n}\n\n/**\n * CSS `linear-gradient(angle, ...)` always stretches its 0%/100% stops\n * across the box's FULL diagonal extent at that angle (the CSS spec's\n * \"gradient line\" always spans corner-to-corner) -- it has no way to say\n * \"start partway in, end partway in\" the way Figma's actual gradient handles\n * can (a designer can drag the start/end handles anywhere, including short\n * of the shape's edges, or past them). Figma's own stop positions are\n * fractions of the literal start-handle-to-end-handle distance, which only\n * happens to coincide with the CSS full-box span when the handles are\n * dragged exactly corner-to-corner -- a common case, but far from the only\n * one, and the divergence gets worse the more the box's aspect ratio departs\n * from square (rotated/skewed handles included, e.g. gradientTransform-authored\n * paints). This projects each Figma stop's real pixel position onto the same\n * angle CSS will use and re-expresses it as a percentage of the CSS line's\n * length, so a partial/offset gradient renders at the same actual pixel\n * positions Figma draws it at instead of silently stretching to fill the box.\n */\nfunction remapLinearStopPosition(\n geometry: GradientGeometry,\n box: { width: number; height: number },\n angleDeg: number,\n): (position: number) => number {\n const angleRad = (angleDeg * Math.PI) / 180;\n const ux = Math.sin(angleRad);\n const uy = -Math.cos(angleRad);\n const lineLength = box.width * Math.abs(ux) + box.height * Math.abs(uy);\n if (lineLength < 1e-6) return (position) => position;\n const startPx = {\n x: geometry.start.x * box.width,\n y: geometry.start.y * box.height,\n };\n const endPx = {\n x: geometry.end.x * box.width,\n y: geometry.end.y * box.height,\n };\n const centerX = box.width / 2;\n const centerY = box.height / 2;\n return (position: number) => {\n const pointX = startPx.x + position * (endPx.x - startPx.x);\n const pointY = startPx.y + position * (endPx.y - startPx.y);\n const projected = (pointX - centerX) * ux + (pointY - centerY) * uy;\n return (projected + lineLength / 2) / lineLength;\n };\n}\n\nfunction vectorLength(\n from: { x: number; y: number },\n to: { x: number; y: number },\n box: { width: number; height: number },\n): number {\n const dx = (to.x - from.x) * box.width;\n const dy = (to.y - from.y) * box.height;\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * Convert one Figma paint layer to a CSS `background-image` value (or plain\n * color for a SOLID paint used standalone). Returns null for paints that\n * cannot be expressed as a background-image (handled elsewhere).\n */\nfunction paintToCssImage(\n paint: FigmaPaint,\n box: { width: number; height: number },\n tracker: FidelityTracker,\n node: FigmaNode,\n): string | null {\n if (paint.visible === false) return null;\n const stops = gradientStopsCss(paint);\n if (!stops) return null;\n\n switch (paint.type) {\n case \"GRADIENT_LINEAR\": {\n const angle = gradientAngleDegrees(paint, box);\n const geometry = resolveGradientGeometry(paint);\n // Re-express Figma's handle-relative stop positions as percentages of\n // CSS's own full-box gradient line (see remapLinearStopPosition) so a\n // gradient whose handles don't span exactly corner-to-corner still\n // lands its color transitions at the same real pixel positions Figma\n // draws them at, instead of being stretched to fill the whole box.\n const linearStops =\n angle !== null && geometry\n ? gradientStopsCss(\n paint,\n remapLinearStopPosition(geometry, box, angle),\n )\n : stops;\n tracker.record(\n node,\n \"exact\",\n \"Linear gradient angle and stop offsets derived from gradientHandlePositions.\",\n );\n return `linear-gradient(${round(angle ?? 90, 2)}deg, ${linearStops})`;\n }\n case \"GRADIENT_RADIAL\": {\n const geometry = resolveGradientGeometry(paint);\n if (!geometry) return `radial-gradient(${stops})`;\n const cx = round(geometry.start.x * 100, 2);\n const cy = round(geometry.start.y * 100, 2);\n // Figma's handle[1] (\"end\") is the radius vector along the gradient's\n // own primary axis; handle[2] (\"width\") is the perpendicular radius.\n // For an axis-aligned box those map directly to the ellipse's\n // horizontal/vertical radii -- swapping them (as a prior version of\n // this code did) silently rotates the ellipse 90 degrees, which is\n // invisible for a square box but produces a badly wrong bowtie-shaped\n // gradient for any non-square rectangle (the common case).\n const radiusX = vectorLength(geometry.start, geometry.end, box);\n const radiusY = vectorLength(geometry.start, geometry.width, box);\n tracker.record(\n node,\n \"approximated\",\n \"Radial gradient rendered as an axis-aligned ellipse sized from gradientHandlePositions; rotated/skewed radial gradients are not expressible in CSS radial-gradient().\",\n );\n return `radial-gradient(ellipse ${round(radiusX, 2)}px ${round(radiusY, 2)}px at ${cx}% ${cy}%, ${stops})`;\n }\n case \"GRADIENT_ANGULAR\": {\n const geometry = resolveGradientGeometry(paint);\n const cx = geometry ? round(geometry.start.x * 100, 2) : 50;\n const cy = geometry ? round(geometry.start.y * 100, 2) : 50;\n const fromAngle = geometry ? gradientAngleDegrees(paint, box) : 0;\n tracker.record(\n node,\n \"approximated\",\n \"Conic (angular) gradient start angle derived from gradientHandlePositions using the same angle formula as linear gradients; CSS conic-gradient() has no elliptical distortion so non-uniform boxes may render slightly differently than Figma.\",\n );\n return `conic-gradient(from ${round(fromAngle ?? 0, 2)}deg at ${cx}% ${cy}%, ${stops})`;\n }\n case \"GRADIENT_DIAMOND\": {\n const geometry = resolveGradientGeometry(paint);\n const cx = geometry ? round(geometry.start.x * 100, 2) : 50;\n const cy = geometry ? round(geometry.start.y * 100, 2) : 50;\n // Same handle-to-axis mapping fix as GRADIENT_RADIAL above: handle[1]\n // (\"end\") is the primary-axis radius, handle[2] (\"width\") the\n // perpendicular one.\n const radiusX = geometry\n ? vectorLength(geometry.start, geometry.end, box)\n : box.width / 2;\n const radiusY = geometry\n ? vectorLength(geometry.start, geometry.width, box)\n : box.height / 2;\n tracker.record(\n node,\n \"approximated\",\n \"Diamond gradient has no CSS equivalent; approximated as an axis-aligned elliptical radial-gradient sized from gradientHandlePositions. True diamond (rotated-square) falloff is not reproduced.\",\n );\n return `radial-gradient(ellipse ${round(radiusX, 2)}px ${round(radiusY, 2)}px at ${cx}% ${cy}%, ${stops})`;\n }\n default:\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Fills -> background\n// ---------------------------------------------------------------------------\n\ninterface BackgroundResult {\n backgroundColor?: string;\n backgroundImage?: string;\n backgroundSize?: string;\n backgroundPosition?: string;\n backgroundRepeat?: string;\n color?: string; // for TEXT nodes, fill paints color the glyphs, not a background\n}\n\nfunction imageScaleModeCss(\n paint: FigmaPaint,\n node: FigmaNode,\n tracker: FidelityTracker,\n): { size: string; position: string; repeat: string } {\n const transform = paint.imageTransform;\n const isAxisAligned =\n !transform ||\n (Math.abs(transform[0][1]) < 1e-6 && Math.abs(transform[1][0]) < 1e-6);\n if (!isAxisAligned) {\n tracker.record(\n node,\n \"approximated\",\n \"Image fill has a non-axis-aligned imageTransform (rotated/skewed crop); approximated using the scale-mode-only CSS mapping without the transform matrix.\",\n );\n }\n switch (paint.scaleMode) {\n case \"FILL\":\n return { size: \"cover\", position: \"center\", repeat: \"no-repeat\" };\n case \"FIT\":\n return { size: \"contain\", position: \"center\", repeat: \"no-repeat\" };\n case \"TILE\":\n return { size: \"auto\", position: \"top left\", repeat: \"repeat\" };\n case \"STRETCH\":\n return { size: \"100% 100%\", position: \"center\", repeat: \"no-repeat\" };\n default:\n return { size: \"cover\", position: \"center\", repeat: \"no-repeat\" };\n }\n}\n\n/**\n * Build the background-* properties for a node's fill stack. Figma paints\n * fills bottom-to-top (index 0 is the bottommost layer); CSS\n * `background-image` layers top-to-bottom (first value on top), so the\n * stack is reversed here to preserve visual order. A solid fill above other\n * layers is expressed as a flat `linear-gradient(color, color)` since CSS\n * `background-color` always paints *beneath every* background-image and\n * cannot be interleaved mid-stack.\n */\nfunction buildFills(\n node: FigmaNode,\n fills: FigmaPaint[] | undefined,\n box: { width: number; height: number },\n options: MapFigmaNodeOptions,\n tracker: FidelityTracker,\n isTextNode: boolean,\n): BackgroundResult {\n const visible = (fills ?? []).filter((fill) => fill.visible !== false);\n if (visible.length === 0) return {};\n\n if (isTextNode) {\n // Text color comes from the topmost visible SOLID fill; gradient/image\n // text fills are a CSS `background-clip: text` trick we intentionally\n // skip for now (rare in practice) and record as approximated.\n const solid = [...visible].reverse().find((fill) => fill.type === \"SOLID\");\n if (solid) {\n return {\n color: colorToCss(solid.color, solid.opacity ?? 1) ?? undefined,\n };\n }\n tracker.record(\n node,\n \"approximated\",\n \"Text fill is a gradient/image, not a solid color; rendered with the default text color instead of a background-clip: text gradient.\",\n );\n return {};\n }\n\n const images: string[] = [];\n const sizes: string[] = [];\n const positions: string[] = [];\n const repeats: string[] = [];\n let backgroundColor: string | undefined;\n\n // Reverse so the topmost Figma fill becomes the first (topmost) CSS layer.\n const ordered = [...visible].reverse();\n for (let index = 0; index < ordered.length; index += 1) {\n const fill = ordered[index]!;\n const isBottommost = index === ordered.length - 1;\n\n if (fill.type === \"SOLID\") {\n const color = colorToCss(fill.color, fill.opacity ?? 1);\n if (!color) continue;\n if (isBottommost) {\n // A bottom-most solid always paints beneath every background-image\n // layer, so it can always become plain backgroundColor regardless of\n // how many gradient/image layers are stacked above it.\n backgroundColor = color;\n } else {\n // Solid above other layers: express as a flat gradient so it stacks\n // in the correct z-order alongside gradient/image layers.\n images.push(`linear-gradient(${color}, ${color})`);\n sizes.push(\"100% 100%\");\n positions.push(\"center\");\n repeats.push(\"no-repeat\");\n }\n continue;\n }\n\n if (fill.type === \"IMAGE\") {\n const url = fill.imageRef\n ? options.imageFillUrls?.[fill.imageRef]\n : undefined;\n if (!url) {\n tracker.record(\n node,\n \"approximated\",\n `Image fill imageRef \"${fill.imageRef ?? \"unknown\"}\" had no resolved URL; layer omitted.`,\n );\n continue;\n }\n const mode = imageScaleModeCss(fill, node, tracker);\n images.push(`url(\"${url}\")`);\n sizes.push(mode.size);\n positions.push(mode.position);\n repeats.push(mode.repeat);\n continue;\n }\n\n const cssImage = paintToCssImage(fill, box, tracker, node);\n if (cssImage) {\n images.push(cssImage);\n sizes.push(\"100% 100%\");\n positions.push(\"center\");\n repeats.push(\"no-repeat\");\n }\n }\n\n const result: BackgroundResult = {};\n if (backgroundColor) result.backgroundColor = backgroundColor;\n if (images.length > 0) {\n result.backgroundImage = images.join(\", \");\n result.backgroundSize = sizes.join(\", \");\n result.backgroundPosition = positions.join(\", \");\n result.backgroundRepeat = repeats.join(\", \");\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Strokes -> border / outline / box-shadow\n// ---------------------------------------------------------------------------\n\ninterface StrokeResult {\n styles: Record<string, string | undefined>;\n insetShadow?: string;\n}\n\nfunction buildStrokes(node: FigmaNode, tracker: FidelityTracker): StrokeResult {\n const strokes = (node.strokes ?? []).filter(\n (stroke) => stroke.visible !== false,\n );\n if (strokes.length === 0) return { styles: {} };\n\n const first = strokes[0]!;\n const color =\n colorToCss(first.color, first.opacity ?? 1) ?? \"rgba(0, 0, 0, 1)\";\n const iw = node.individualStrokeWeights;\n const hasPerSide =\n iw &&\n (iw.top !== undefined ||\n iw.right !== undefined ||\n iw.bottom !== undefined ||\n iw.left !== undefined);\n const uniformWeight = node.strokeWeight ?? 0;\n\n if (hasPerSide) {\n // CSS `outline`/inset-`box-shadow` tricks are single-weight only; per-side\n // stroke weights can only be expressed as a real per-side `border`, which\n // always renders fully inside the border-box regardless of strokeAlign.\n // This is exact for INSIDE and an approximation for CENTER/OUTSIDE.\n const top = iw?.top ?? uniformWeight;\n const right = iw?.right ?? uniformWeight;\n const bottom = iw?.bottom ?? uniformWeight;\n const left = iw?.left ?? uniformWeight;\n tracker.record(\n node,\n node.strokeAlign === \"INSIDE\" || !node.strokeAlign\n ? \"exact\"\n : \"approximated\",\n `Per-side stroke weights rendered as CSS border (inside-aligned); strokeAlign=\"${node.strokeAlign ?? \"INSIDE\"}\" cannot vary per-side with outline tricks.`,\n );\n return {\n styles: {\n \"border-top\": top ? `${px(top)} solid ${color}` : undefined,\n \"border-right\": right ? `${px(right)} solid ${color}` : undefined,\n \"border-bottom\": bottom ? `${px(bottom)} solid ${color}` : undefined,\n \"border-left\": left ? `${px(left)} solid ${color}` : undefined,\n },\n };\n }\n\n if (!uniformWeight) return { styles: {} };\n\n switch (node.strokeAlign) {\n case \"OUTSIDE\":\n tracker.record(\n node,\n \"exact\",\n \"OUTSIDE stroke rendered via outline (offset 0).\",\n );\n return {\n styles: {\n outline: `${px(uniformWeight)} solid ${color}`,\n \"outline-offset\": \"0px\",\n },\n };\n case \"INSIDE\":\n tracker.record(\n node,\n \"exact\",\n \"INSIDE stroke rendered via inset box-shadow.\",\n );\n return {\n styles: {},\n insetShadow: `inset 0 0 0 ${px(uniformWeight)} ${color}`,\n };\n case \"CENTER\":\n default:\n // outline-offset of -half the weight pulls the outline half inside,\n // half outside the border-box edge -- reproducing Figma's CENTER\n // straddle exactly (plain CSS `border` cannot straddle the edge).\n tracker.record(\n node,\n \"exact\",\n \"CENTER stroke rendered via outline with outline-offset = -weight/2 (straddles the edge like Figma).\",\n );\n return {\n styles: {\n outline: `${px(uniformWeight)} solid ${color}`,\n \"outline-offset\": px(-uniformWeight / 2),\n },\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Corner radii\n// ---------------------------------------------------------------------------\n\nfunction buildCornerRadius(node: FigmaNode): string | undefined {\n if (node.rectangleCornerRadii) {\n const [tl, tr, br, bl] = node.rectangleCornerRadii;\n return `${px(tl) ?? \"0px\"} ${px(tr) ?? \"0px\"} ${px(br) ?? \"0px\"} ${px(bl) ?? \"0px\"}`;\n }\n if (typeof node.cornerRadius === \"number\" && node.cornerRadius > 0) {\n return px(node.cornerRadius);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Effects -> box-shadow / filter / backdrop-filter\n// ---------------------------------------------------------------------------\n\ninterface EffectResult {\n boxShadowLayers: string[];\n filter?: string;\n backdropFilter?: string;\n}\n\nfunction buildEffects(\n node: FigmaNode,\n isTextNode: boolean,\n tracker: FidelityTracker,\n): EffectResult {\n const effects = (node.effects ?? []).filter(\n (effect) => effect.visible !== false,\n );\n const boxShadowLayers: string[] = [];\n let filter: string | undefined;\n let backdropFilter: string | undefined;\n\n for (const effect of effects) {\n if (effect.type === \"DROP_SHADOW\" || effect.type === \"INNER_SHADOW\") {\n const color = colorToCss(effect.color, 1) ?? \"rgba(0, 0, 0, 1)\";\n const x = px(effect.offset?.x ?? 0) ?? \"0px\";\n const y = px(effect.offset?.y ?? 0) ?? \"0px\";\n const blur = px(effect.radius ?? 0) ?? \"0px\";\n const spread =\n !isTextNode && typeof effect.spread === \"number\"\n ? ` ${px(effect.spread)}`\n : \"\";\n const inset = effect.type === \"INNER_SHADOW\" ? \"inset \" : \"\";\n boxShadowLayers.push(`${inset}${x} ${y} ${blur}${spread} ${color}`);\n tracker.record(\n node,\n \"exact\",\n `${effect.type} rendered as ${isTextNode ? \"text-shadow\" : \"box-shadow\"}.`,\n );\n } else if (effect.type === \"LAYER_BLUR\") {\n const radius = px(effect.radius ?? 0) ?? \"0px\";\n filter = filter ? `${filter} blur(${radius})` : `blur(${radius})`;\n tracker.record(\n node,\n \"approximated\",\n \"LAYER_BLUR mapped 1:1 to CSS filter: blur(); Figma's blur radius-to-CSS-stdDeviation scale is not publicly documented, so the rendered softness may differ slightly.\",\n );\n } else if (effect.type === \"BACKGROUND_BLUR\") {\n const radius = px(effect.radius ?? 0) ?? \"0px\";\n backdropFilter = backdropFilter\n ? `${backdropFilter} blur(${radius})`\n : `blur(${radius})`;\n tracker.record(\n node,\n \"approximated\",\n \"BACKGROUND_BLUR mapped 1:1 to CSS backdrop-filter: blur(); same radius-scale caveat as LAYER_BLUR.\",\n );\n }\n }\n\n return { boxShadowLayers, filter, backdropFilter };\n}\n\n// ---------------------------------------------------------------------------\n// Blend modes\n// ---------------------------------------------------------------------------\n\nconst CSS_BLEND_MODES = new Set([\n \"multiply\",\n \"screen\",\n \"overlay\",\n \"darken\",\n \"lighten\",\n \"color-dodge\",\n \"color-burn\",\n \"hard-light\",\n \"soft-light\",\n \"difference\",\n \"exclusion\",\n \"hue\",\n \"saturation\",\n \"color\",\n \"luminosity\",\n]);\n\nconst FIGMA_ONLY_BLEND_MODE_FALLBACK: Record<string, string> = {\n LINEAR_BURN: \"multiply\",\n LINEAR_DODGE: \"plus-lighter\",\n LIGHTER: \"plus-lighter\",\n DARKER: \"darken\",\n};\n\nfunction buildBlendMode(\n node: FigmaNode,\n tracker: FidelityTracker,\n): string | undefined {\n const mode = node.blendMode;\n if (!mode || mode === \"PASS_THROUGH\" || mode === \"NORMAL\") return undefined;\n const cssMode = mode.toLowerCase().replace(/_/g, \"-\");\n if (CSS_BLEND_MODES.has(cssMode)) return cssMode;\n const fallback = FIGMA_ONLY_BLEND_MODE_FALLBACK[mode];\n if (fallback) {\n tracker.record(\n node,\n \"approximated\",\n `Figma blend mode \"${mode}\" has no CSS equivalent; approximated as mix-blend-mode: ${fallback}.`,\n );\n return fallback;\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Text styling\n// ---------------------------------------------------------------------------\n\nfunction resolveLineHeight(style: FigmaTypeStyle): string | undefined {\n if (\n typeof style.lineHeightPx === \"number\" &&\n style.lineHeightUnit !== \"FONT_SIZE_%\"\n ) {\n return px(style.lineHeightPx);\n }\n if (\n typeof style.lineHeightPercentFontSize === \"number\" &&\n typeof style.fontSize === \"number\"\n ) {\n // lineHeightPercentFontSize is literally \"percent of the font's nominal\n // size\" -- resolve to an exact px value rather than a unitless ratio so\n // the rendered line box matches Figma regardless of font metrics.\n return px(style.fontSize * (style.lineHeightPercentFontSize / 100));\n }\n if (typeof style.lineHeightPx === \"number\") {\n return px(style.lineHeightPx);\n }\n return undefined;\n}\n\nfunction textTransformCss(\n textCase: FigmaTypeStyle[\"textCase\"],\n): string | undefined {\n switch (textCase) {\n case \"UPPER\":\n return \"uppercase\";\n case \"LOWER\":\n return \"lowercase\";\n case \"TITLE\":\n return \"capitalize\";\n default:\n return undefined;\n }\n}\n\nfunction textDecorationCss(\n decoration: FigmaTypeStyle[\"textDecoration\"],\n): string | undefined {\n switch (decoration) {\n case \"UNDERLINE\":\n return \"underline\";\n case \"STRIKETHROUGH\":\n return \"line-through\";\n default:\n return undefined;\n }\n}\n\nfunction textAlignCss(\n align: FigmaTypeStyle[\"textAlignHorizontal\"],\n): string | undefined {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"RIGHT\":\n return \"right\";\n case \"JUSTIFIED\":\n return \"justify\";\n case \"LEFT\":\n return \"left\";\n default:\n return undefined;\n }\n}\n\nfunction verticalAlignJustifyContent(\n align: FigmaTypeStyle[\"textAlignVertical\"],\n): string {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"BOTTOM\":\n return \"flex-end\";\n default:\n return \"flex-start\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Auto-layout\n// ---------------------------------------------------------------------------\n\nfunction primaryAxisJustify(align: FigmaNode[\"primaryAxisAlignItems\"]): string {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"MAX\":\n return \"flex-end\";\n case \"SPACE_BETWEEN\":\n return \"space-between\";\n default:\n return \"flex-start\";\n }\n}\n\nfunction counterAxisAlign(align: FigmaNode[\"counterAxisAlignItems\"]): string {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"MAX\":\n return \"flex-end\";\n case \"BASELINE\":\n return \"baseline\";\n default:\n return \"flex-start\";\n }\n}\n\nfunction buildAutoLayoutStyles(\n node: FigmaNode,\n): Record<string, string | undefined> {\n if (\n !node.layoutMode ||\n node.layoutMode === \"NONE\" ||\n node.layoutMode === \"GRID\"\n ) {\n return {};\n }\n const isHorizontal = node.layoutMode === \"HORIZONTAL\";\n const styles: Record<string, string | undefined> = {\n display: \"flex\",\n \"flex-direction\": isHorizontal ? \"row\" : \"column\",\n \"justify-content\": primaryAxisJustify(node.primaryAxisAlignItems),\n \"align-items\": counterAxisAlign(node.counterAxisAlignItems),\n };\n if (node.layoutWrap === \"WRAP\") styles[\"flex-wrap\"] = \"wrap\";\n if (typeof node.itemSpacing === \"number\" && node.itemSpacing !== 0) {\n styles[isHorizontal ? \"column-gap\" : \"row-gap\"] = px(node.itemSpacing);\n }\n if (\n typeof node.counterAxisSpacing === \"number\" &&\n node.counterAxisSpacing !== 0\n ) {\n styles[isHorizontal ? \"row-gap\" : \"column-gap\"] = px(\n node.counterAxisSpacing,\n );\n }\n const padTop = node.paddingTop ?? 0;\n const padRight = node.paddingRight ?? 0;\n const padBottom = node.paddingBottom ?? 0;\n const padLeft = node.paddingLeft ?? 0;\n if (padTop || padRight || padBottom || padLeft) {\n styles.padding = `${px(padTop)} ${px(padRight)} ${px(padBottom)} ${px(padLeft)}`;\n }\n return styles;\n}\n\n/**\n * \"FILL\" sizing must map to different CSS depending on which axis is the\n * flex *main* axis for this node's parent: main-axis FILL grows via\n * `flex-grow`/`flex-basis` (row parent -> horizontal FILL, column parent ->\n * vertical FILL); cross-axis FILL stretches via `align-self: stretch` (row\n * parent -> vertical FILL, column parent -> horizontal FILL). Passing only a\n * `parentHasAutoLayout` boolean (as this used to) loses the row/column\n * direction and always mapped horizontal-FILL to flex-grow — correct for row\n * parents but wrong for column parents, where a FILL-width text/rect child\n * got `width: auto` with no stretch and overflowed to its content width.\n */\nfunction buildChildSizingStyles(\n node: FigmaNode,\n parentLayoutMode: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\",\n): Record<string, string | undefined> {\n if (parentLayoutMode === \"NONE\") return {};\n const parentIsHorizontal = parentLayoutMode === \"HORIZONTAL\";\n const styles: Record<string, string | undefined> = {};\n if (node.layoutSizingHorizontal === \"FILL\") {\n if (parentIsHorizontal) {\n styles[\"flex-grow\"] = \"1\";\n styles[\"flex-basis\"] = \"0%\";\n } else {\n styles[\"align-self\"] = \"stretch\";\n }\n styles.width = \"auto\";\n } else if (node.layoutSizingHorizontal === \"HUG\") {\n styles.width = \"auto\";\n }\n if (node.layoutSizingVertical === \"FILL\") {\n if (parentIsHorizontal) {\n styles[\"align-self\"] = \"stretch\";\n } else {\n styles[\"flex-grow\"] = \"1\";\n styles[\"flex-basis\"] = \"0%\";\n }\n styles.height = \"auto\";\n } else if (node.layoutSizingVertical === \"HUG\") {\n styles.height = \"auto\";\n }\n return styles;\n}\n\n// ---------------------------------------------------------------------------\n// Node type classification\n// ---------------------------------------------------------------------------\n\nfunction needsImageFallback(\n node: FigmaNode,\n options: MapFigmaNodeOptions,\n): boolean {\n if (options.forceImageFallbackNodeIds?.has(node.id)) return true;\n if (UNSUPPORTED_STRUCTURAL_TYPES.has(node.type)) return true;\n // A Figma mask affects its following siblings, not just the mask node. CSS\n // cannot reproduce that sibling-range operation on an arbitrary DOM tree,\n // so render the smallest containing subtree rather than importing a visibly\n // wrong unmasked composition. A mask imported as the root is also rendered.\n if (node.isMask || node.children?.some((child) => child.isMask)) return true;\n // A CSS div with an outline is not a Figma line. Partial/ring ellipses also\n // need real path geometry, which this structural mapper intentionally does\n // not request because geometry=paths makes ordinary REST payloads enormous.\n if (node.type === \"LINE\") return true;\n if (node.type === \"ELLIPSE\" && node.arcData) {\n const start = node.arcData.startingAngle ?? 0;\n const end = node.arcData.endingAngle ?? Math.PI * 2;\n const span = Math.abs(end - start);\n const isFullCircle =\n Math.abs(span - Math.PI * 2) < 1e-4 &&\n Math.abs(node.arcData.innerRadius ?? 0) < 1e-4;\n if (!isFullCircle) return true;\n }\n const visibleStrokes = (node.strokes ?? []).filter(\n (stroke) => stroke.visible !== false,\n );\n if (\n visibleStrokes.length > 1 ||\n visibleStrokes.some((stroke) => stroke.type !== \"SOLID\") ||\n (node.strokeDashes?.length ?? 0) > 0\n ) {\n return true;\n }\n const visibleFills = (node.fills ?? []).filter(\n (fill) => fill.visible !== false,\n );\n if (\n visibleFills.some(\n (fill) =>\n fill.type === \"VIDEO\" ||\n fill.type === \"EMOJI\" ||\n (fill.blendMode &&\n fill.blendMode !== \"NORMAL\" &&\n fill.blendMode !== \"PASS_THROUGH\") ||\n (fill.type === \"IMAGE\" &&\n ((fill.imageTransform &&\n (Math.abs(fill.imageTransform[0][1]) >= 1e-6 ||\n Math.abs(fill.imageTransform[1][0]) >= 1e-6)) ||\n Object.values(fill.filters ?? {}).some(\n (value) => typeof value === \"number\" && Math.abs(value) > 1e-6,\n ))),\n ) ||\n (node.type === \"TEXT\" && visibleFills.some((fill) => fill.type !== \"SOLID\"))\n ) {\n return true;\n }\n if (node.type === \"TEXT\") {\n const styles = [\n node.style,\n ...Object.values(node.styleOverrideTable ?? {}),\n ].filter((style): style is FigmaTypeStyle => Boolean(style));\n const hasAdvancedTypography = styles.some(\n (style) =>\n Math.abs(style.paragraphSpacing ?? 0) > 1e-6 ||\n Math.abs(style.paragraphIndent ?? 0) > 1e-6 ||\n Math.abs(style.listSpacing ?? 0) > 1e-6 ||\n style.hangingPunctuation === true ||\n style.hangingList === true ||\n style.hyperlink !== undefined ||\n Object.values(style.opentypeFlags ?? {}).some((value) => value !== 0),\n );\n if (\n hasAdvancedTypography ||\n // Figma's REST API always returns one `lineTypes` entry per line —\n // ordinary non-list text comes back as `[\"NONE\", \"NONE\", ...]`, not an\n // empty array. Checking `.length > 0` alone treats every multi-line\n // text node in existence as an unsupported list and routes it to an\n // image fallback; only a line whose type is actually \"ORDERED\" or\n // \"UNORDERED\" means the text uses real list formatting.\n (node.lineTypes?.some((type) => type !== \"NONE\") ?? false) ||\n (node.lineIndentations?.some((value) => value !== 0) ?? false)\n ) {\n return true;\n }\n }\n if (\n (node.effects ?? []).some(\n (effect) =>\n effect.visible !== false &&\n effect.blendMode &&\n effect.blendMode !== \"NORMAL\" &&\n effect.blendMode !== \"PASS_THROUGH\",\n )\n ) {\n return true;\n }\n if (\n !SUPPORTED_CONTAINER_TYPES.has(node.type) &&\n node.type !== \"RECTANGLE\" &&\n node.type !== \"ELLIPSE\" &&\n node.type !== \"TEXT\"\n ) {\n return true;\n }\n return false;\n}\n\n/** Fail clearly before recursive rendering can overflow or lock the worker. */\nexport function assertFigmaNodeTreeComplexity(node: FigmaNode): void {\n const stack: Array<{ node: FigmaNode; depth: number }> = [{ node, depth: 1 }];\n const ancestors = new WeakSet<object>();\n let count = 0;\n while (stack.length > 0) {\n const current = stack.pop()!;\n count += 1;\n if (count > MAX_FIGMA_NODE_COUNT) {\n throw new Error(\n `Figma node tree is too large (max ${MAX_FIGMA_NODE_COUNT.toLocaleString(\"en-US\")} nodes). Import a smaller frame or selection.`,\n );\n }\n if (current.depth > MAX_FIGMA_NODE_DEPTH) {\n throw new Error(\n `Figma node tree is nested too deeply (max ${MAX_FIGMA_NODE_DEPTH} levels). Import a smaller frame or selection.`,\n );\n }\n if (ancestors.has(current.node)) {\n throw new Error(\"Figma node tree contains a cyclic child reference.\");\n }\n ancestors.add(current.node);\n for (const child of current.node.children ?? []) {\n stack.push({ node: child, depth: current.depth + 1 });\n }\n }\n}\n\n/**\n * Walk a node tree and return the ids of every subtree that will render as a\n * PNG image fallback (vector networks, boolean ops, and any node type this\n * mapper does not model structurally). Call this before fetching node data\n * so the caller can request rendered images for exactly these ids via\n * `GET /v1/images/:fileKey?ids=...&scale=2`.\n */\nexport function collectFallbackNodeIds(\n node: FigmaNode,\n options: MapFigmaNodeOptions = {},\n): string[] {\n assertFigmaNodeTreeComplexity(node);\n const ids: string[] = [];\n const visit = (current: FigmaNode) => {\n if (current.visible === false || current.opacity === 0) return;\n if (needsImageFallback(current, options)) {\n ids.push(current.id);\n return; // Don't recurse into a subtree that's rendered as one image.\n }\n for (const child of current.children ?? []) visit(child);\n };\n visit(node);\n return ids;\n}\n\n/**\n * Walk a node tree and return every distinct `imageRef` used by IMAGE fills\n * (on fills or strokes) so the caller can resolve them to URLs via\n * `GET /v1/files/:fileKey/images` before mapping.\n */\nexport function collectImageFillRefs(\n node: FigmaNode,\n options: MapFigmaNodeOptions = {},\n): string[] {\n assertFigmaNodeTreeComplexity(node);\n const refs = new Set<string>();\n const visitPaints = (paints: FigmaPaint[] | undefined) => {\n for (const paint of paints ?? []) {\n if (paint.type === \"IMAGE\" && paint.imageRef) refs.add(paint.imageRef);\n }\n };\n const visit = (current: FigmaNode) => {\n if (current.visible === false || current.opacity === 0) return;\n if (needsImageFallback(current, options)) return;\n visitPaints(current.fills);\n visitPaints(current.strokes);\n for (const child of current.children ?? []) visit(child);\n };\n visit(node);\n return [...refs];\n}\n\nexport interface FigmaFontUsage {\n family: string;\n weight: number;\n italic: boolean;\n}\n\nfunction recordFontUsage(\n style: FigmaTypeStyle | undefined,\n usage: Map<string, FigmaFontUsage>,\n): void {\n if (!style?.fontFamily) return;\n const weight = typeof style.fontWeight === \"number\" ? style.fontWeight : 400;\n const italic = Boolean(style.italic);\n const key = `${style.fontFamily}|${weight}|${italic ? 1 : 0}`;\n if (!usage.has(key))\n usage.set(key, { family: style.fontFamily, weight, italic });\n}\n\n/**\n * Walk a node tree and return every distinct (font family, weight, italic)\n * combination used by TEXT nodes -- including per-run character style\n * overrides -- so the caller can request the actual web font (e.g. from\n * Google Fonts) before the imported HTML is saved. Without this, an imported\n * screen's CSS correctly names the intended font-family, but the browser has\n * no way to load it and silently falls back to a generic sans-serif with\n * different glyph advance widths -- individually invisible per character but\n * compounding into a growing horizontal drift across any wrapped or\n * multi-word line, worst on text-dense imports.\n */\nexport function collectFontUsage(node: FigmaNode): FigmaFontUsage[] {\n assertFigmaNodeTreeComplexity(node);\n const usage = new Map<string, FigmaFontUsage>();\n const visit = (current: FigmaNode) => {\n if (current.visible === false || current.opacity === 0) return;\n if (current.type === \"TEXT\") {\n recordFontUsage(current.style, usage);\n for (const style of Object.values(current.styleOverrideTable ?? {})) {\n recordFontUsage(style, usage);\n }\n }\n for (const child of current.children ?? []) visit(child);\n };\n visit(node);\n return [...usage.values()];\n}\n\nfunction textOverrideCss(\n style: FigmaTypeStyle | undefined,\n): Record<string, string | undefined> {\n const solidFill = [...(style?.fills ?? [])]\n .reverse()\n .find((fill) => fill.visible !== false && fill.type === \"SOLID\");\n return {\n \"font-family\": style?.fontFamily\n ? `\"${style.fontFamily.replace(/\"/g, \"\")}\", sans-serif`\n : undefined,\n \"font-size\": px(style?.fontSize),\n \"font-weight\":\n typeof style?.fontWeight === \"number\"\n ? String(style.fontWeight)\n : undefined,\n \"font-style\": style?.italic ? \"italic\" : undefined,\n \"line-height\": style ? resolveLineHeight(style) : undefined,\n \"letter-spacing\":\n typeof style?.letterSpacing === \"number\"\n ? px(style.letterSpacing)\n : undefined,\n \"text-transform\": textTransformCss(style?.textCase),\n \"text-decoration\": textDecorationCss(style?.textDecoration),\n color: solidFill\n ? (colorToCss(solidFill.color, solidFill.opacity ?? 1) ?? undefined)\n : undefined,\n };\n}\n\n/** Render contiguous Figma character-style override runs as inline spans. */\nfunction buildMixedTextHtml(\n node: FigmaNode,\n characters: string,\n tracker: FidelityTracker,\n): string {\n const overrideIds = node.characterStyleOverrides ?? [];\n const table = node.styleOverrideTable ?? {};\n if (\n characters.length === 0 ||\n !overrideIds.some((id) => id !== 0 && table[String(id)])\n ) {\n return escapeHtml(characters);\n }\n\n const runs: Array<{ id: number; text: string }> = [];\n for (let index = 0; index < characters.length; index += 1) {\n const id = overrideIds[index] ?? 0;\n const previous = runs[runs.length - 1];\n if (previous?.id === id) previous.text += characters[index] ?? \"\";\n else runs.push({ id, text: characters[index] ?? \"\" });\n }\n\n tracker.record(\n node,\n \"exact\",\n \"Mixed character style overrides were preserved as inline text runs.\",\n );\n return runs\n .map((run) => {\n if (run.id === 0) return escapeHtml(run.text);\n const style = table[String(run.id)];\n if (!style) return escapeHtml(run.text);\n return `<span style=\"${styleAttr(textOverrideCss(style))}\">${escapeHtml(run.text)}</span>`;\n })\n .join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Main mapper\n// ---------------------------------------------------------------------------\n\nfunction frameRelativeBox(\n node: FigmaNode,\n parentBox: FigmaBoundingBox | null,\n): { left: number; top: number; width: number; height: number } {\n const box = node.absoluteBoundingBox;\n if (!box) return { left: 0, top: 0, width: 0, height: 0 };\n return {\n left: box.x - (parentBox?.x ?? box.x),\n top: box.y - (parentBox?.y ?? box.y),\n width: box.width,\n height: box.height,\n };\n}\n\n/**\n * Figma's `absoluteBoundingBox` for a rotated node is the axis-aligned\n * bounding box of the ALREADY-ROTATED shape, not the shape's own (pre-\n * rotation) width/height -- e.g. a 120x80 rectangle rotated 15 degrees comes\n * back with an ~136.6x108.3 bounding box. Applying a CSS `rotate()` on TOP\n * of a div already sized to that expanded AABB rotates an oversized box,\n * producing a visibly wrong (too-large, wrong-aspect-ratio) rotated shape.\n * This inverts the AABB formula (`W' = W*|cos| + H*|sin|`,\n * `H' = W*|sin| + H*|cos|`) to recover the true pre-rotation width/height,\n * then re-centers the (smaller) box at the same center point the AABB had --\n * matching this module's existing \"rotate about the AABB center\" pivot\n * assumption, so the CSS `rotate()` reproduces the original box exactly.\n */\nfunction unrotateBox(\n box: { left: number; top: number; width: number; height: number },\n rotationDeg: number,\n): { left: number; top: number; width: number; height: number } {\n const theta = (rotationDeg * Math.PI) / 180;\n const c = Math.abs(Math.cos(theta));\n const s = Math.abs(Math.sin(theta));\n const det = c * c - s * s;\n // Near +-45/+-135 degrees the AABB<->true-size system is near-singular\n // (many different true sizes produce almost the same AABB); fall back to\n // the AABB dimensions rather than dividing by ~zero and producing a huge\n // or negative \"true\" size.\n if (Math.abs(det) < 0.05) return box;\n const trueWidth = (c * box.width - s * box.height) / det;\n const trueHeight = (c * box.height - s * box.width) / det;\n if (\n !Number.isFinite(trueWidth) ||\n !Number.isFinite(trueHeight) ||\n trueWidth <= 0 ||\n trueHeight <= 0\n ) {\n return box;\n }\n const centerX = box.left + box.width / 2;\n const centerY = box.top + box.height / 2;\n return {\n left: centerX - trueWidth / 2,\n top: centerY - trueHeight / 2,\n width: trueWidth,\n height: trueHeight,\n };\n}\n\n/**\n * Same as `frameRelativeBox` but sized/positioned from `absoluteRenderBounds`\n * (falling back to `absoluteBoundingBox` when Figma didn't return render\n * bounds). Used only for image-fallback `<img>` geometry -- see the\n * `absoluteRenderBounds` field doc for why the geometric box is wrong there.\n */\nfunction frameRelativeRenderBox(\n node: FigmaNode,\n parentBox: FigmaBoundingBox | null,\n): { left: number; top: number; width: number; height: number } {\n const box = node.absoluteRenderBounds ?? node.absoluteBoundingBox;\n if (!box) return { left: 0, top: 0, width: 0, height: 0 };\n return {\n left: box.x - (parentBox?.x ?? box.x),\n top: box.y - (parentBox?.y ?? box.y),\n width: box.width,\n height: box.height,\n };\n}\n\nfunction buildNode(\n node: FigmaNode,\n parentBox: FigmaBoundingBox | null,\n parentLayoutMode: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\",\n options: MapFigmaNodeOptions,\n tracker: FidelityTracker,\n isRoot: boolean,\n): string {\n const parentHasAutoLayout = parentLayoutMode !== \"NONE\";\n if (node.visible === false || node.opacity === 0) return \"\";\n\n let box = frameRelativeBox(node, parentBox);\n // The Figma REST API's file-node-types docs describe `rotation` as\n // \"in degrees\", but empirically (verified against known authored values\n // via the Plugin API -- e.g. an authored 15deg/20deg rotation comes back\n // as 0.2617993.../0.3490658... here) the REST API actually returns\n // RADIANS. Treating that value as degrees silently shrinks every rotation\n // by a factor of ~57 (pi/180), rendering rotated content as visually\n // unrotated. Convert to degrees before using it anywhere below.\n const rotationDeg =\n typeof node.rotation === \"number\"\n ? (node.rotation * 180) / Math.PI\n : undefined;\n const rotation =\n rotationDeg !== undefined && Math.abs(rotationDeg) > 0.001\n ? rotationDeg\n : undefined;\n if (rotation !== undefined) {\n // `box` (from absoluteBoundingBox) is the rotated shape's AABB; recover\n // the true pre-rotation width/height/position so fills/effects/strokes\n // below -- and the CSS `rotate()` applied later -- operate on the\n // correct box instead of an oversized one. See `unrotateBox`.\n box = unrotateBox(box, rotation);\n }\n const nameAttr = node.name\n ? ` data-agent-native-layer-name=\"${escapeAttr(node.name)}\"`\n : \"\";\n const idAttr = ` data-figma-node-id=\"${escapeAttr(node.id)}\"`;\n const typeAttr = ` data-figma-node-type=\"${escapeAttr(node.type)}\"`;\n const semanticAttrs =\n metadataAttr(\"data-figma-component-id\", node.componentId, node, tracker) +\n metadataAttr(\n \"data-figma-component-properties\",\n node.componentProperties,\n node,\n tracker,\n ) +\n metadataAttr(\n \"data-figma-bound-variables\",\n node.boundVariables,\n node,\n tracker,\n ) +\n metadataAttr(\"data-figma-interactions\", node.interactions, node, tracker);\n if (node.componentId || node.componentProperties) {\n tracker.record(\n node,\n \"approximated\",\n \"Figma component/instance provenance was preserved as metadata, but the imported HTML is not linked to the original Figma component master.\",\n );\n }\n if (node.boundVariables && Object.keys(node.boundVariables).length > 0) {\n tracker.record(\n node,\n \"approximated\",\n \"Figma variable bindings were preserved as metadata; resolved visual values are imported, but bindings are not live Design tokens.\",\n );\n }\n if (node.interactions && node.interactions.length > 0) {\n tracker.record(\n node,\n \"approximated\",\n \"Prototype interactions were preserved as inert metadata and do not execute or navigate inside the editor preview.\",\n );\n }\n\n if (needsImageFallback(node, options)) {\n const imageUrl = options.fallbackImageUrls?.[node.id];\n if (!imageUrl) {\n tracker.record(\n node,\n \"image-fallback\",\n `Node type \"${node.type}\" requires an image fallback but no rendered URL was provided; nothing was rendered for this node.`,\n );\n return \"\";\n }\n tracker.record(\n node,\n \"image-fallback\",\n `Node type \"${node.type}\" cannot be reproduced structurally (vector network / boolean op / unsupported type); rendered as an exact PNG (scale=2) instead of an approximated structural guess.`,\n );\n const isFlowChild =\n !isRoot && parentHasAutoLayout && node.layoutPositioning !== \"ABSOLUTE\";\n // Use render bounds (not the geometric box) so a fallback PNG whose\n // stroke/effects overflow the node's own bounding box (e.g. an\n // OUTSIDE-aligned stroke) is placed at its natural size instead of being\n // squished/cropped into the smaller geometric box.\n const renderBox = frameRelativeRenderBox(node, parentBox);\n const styles: Record<string, string | undefined> = {\n position: isRoot || isFlowChild ? \"relative\" : \"absolute\",\n left: isRoot || isFlowChild ? undefined : px(renderBox.left),\n top: isRoot || isFlowChild ? undefined : px(renderBox.top),\n width: px(renderBox.width),\n height: px(renderBox.height),\n opacity:\n typeof node.opacity === \"number\" && node.opacity !== 1\n ? String(round(node.opacity, 4))\n : undefined,\n };\n return `<img${idAttr}${typeAttr}${nameAttr}${semanticAttrs} src=\"${escapeAttr(imageUrl)}\" alt=\"${escapeAttr(node.name ?? \"\")}\" style=\"${styleAttr(styles)}\" />`;\n }\n\n const isTextNode = node.type === \"TEXT\";\n const isEllipse = node.type === \"ELLIPSE\";\n const box2 = { width: box.width, height: box.height };\n\n const fills = buildFills(\n node,\n node.fills,\n box2,\n options,\n tracker,\n isTextNode,\n );\n const strokeResult = buildStrokes(node, tracker);\n const effects = buildEffects(node, isTextNode, tracker);\n const cornerRadius = isEllipse ? \"50%\" : buildCornerRadius(node);\n const blendMode = buildBlendMode(node, tracker);\n\n const boxShadowParts = [...effects.boxShadowLayers];\n if (strokeResult.insetShadow) boxShadowParts.push(strokeResult.insetShadow);\n\n if (rotation !== undefined) {\n tracker.record(\n node,\n \"approximated\",\n `Rotation (${round(rotation, 2)}deg) reconstructed by pivoting the unrotated box about the absoluteBoundingBox center; exact only when Figma's internal pivot is also the shape's center.`,\n );\n }\n\n const autoLayoutStyles = buildAutoLayoutStyles(node);\n const childSizingStyles = buildChildSizingStyles(node, parentLayoutMode);\n const hasAutoLayout = Boolean(autoLayoutStyles.display);\n // A node is positioned relative to its parent's free canvas (absolute,\n // left/top from absoluteBoundingBox) unless its *parent* is an auto-layout\n // container, in which case it's a normal flex item (relative, no left/top)\n // -- this mirrors Figma's own rule that auto-layout children give up\n // manual x/y in favor of flex flow.\n const isFlexChild =\n !isRoot && parentHasAutoLayout && node.layoutPositioning !== \"ABSOLUTE\";\n\n const baseStyles: Record<string, string | undefined> = {\n position: isRoot ? \"relative\" : isFlexChild ? \"relative\" : \"absolute\",\n left: isRoot || isFlexChild ? undefined : px(box.left),\n top: isRoot || isFlexChild ? undefined : px(box.top),\n width: childSizingStyles.width ?? px(box.width),\n height: childSizingStyles.height ?? px(box.height),\n \"background-color\": fills.backgroundColor,\n \"background-image\": fills.backgroundImage,\n \"background-size\": fills.backgroundSize,\n \"background-position\": fills.backgroundPosition,\n \"background-repeat\": fills.backgroundRepeat,\n color: fills.color,\n \"border-radius\": cornerRadius,\n \"box-shadow\":\n boxShadowParts.length > 0 ? boxShadowParts.join(\", \") : undefined,\n filter: effects.filter,\n \"backdrop-filter\": effects.backdropFilter,\n \"-webkit-backdrop-filter\": effects.backdropFilter,\n opacity:\n typeof node.opacity === \"number\" && node.opacity !== 1\n ? String(round(node.opacity, 4))\n : undefined,\n \"mix-blend-mode\": blendMode,\n overflow: node.clipsContent ? \"hidden\" : undefined,\n transform:\n rotation !== undefined ? `rotate(${round(-rotation, 3)}deg)` : undefined,\n \"transform-origin\": rotation !== undefined ? \"center\" : undefined,\n \"min-width\": px(node.minWidth ?? undefined),\n \"max-width\": px(node.maxWidth ?? undefined),\n \"min-height\": px(node.minHeight ?? undefined),\n \"max-height\": px(node.maxHeight ?? undefined),\n ...autoLayoutStyles,\n ...strokeResult.styles,\n ...childSizingStyles,\n };\n\n if (isTextNode) {\n const style = node.style ?? {};\n baseStyles[\"font-family\"] = style.fontFamily\n ? `\"${style.fontFamily.replace(/\"/g, \"\")}\", sans-serif`\n : undefined;\n baseStyles[\"font-size\"] = px(style.fontSize);\n baseStyles[\"font-weight\"] =\n typeof style.fontWeight === \"number\"\n ? String(style.fontWeight)\n : undefined;\n baseStyles[\"font-style\"] = style.italic ? \"italic\" : undefined;\n baseStyles[\"line-height\"] = resolveLineHeight(style);\n baseStyles[\"letter-spacing\"] =\n typeof style.letterSpacing === \"number\" && style.letterSpacing !== 0\n ? px(style.letterSpacing)\n : undefined;\n baseStyles[\"text-transform\"] = textTransformCss(style.textCase);\n baseStyles[\"text-decoration\"] = textDecorationCss(style.textDecoration);\n baseStyles[\"text-align\"] = textAlignCss(style.textAlignHorizontal);\n if (style.textAutoResize === \"TRUNCATE\") {\n baseStyles[\"white-space\"] = \"nowrap\";\n baseStyles.overflow = \"hidden\";\n baseStyles[\"text-overflow\"] = \"ellipsis\";\n } else {\n // Figma preserves explicit newlines and repeated spaces. Normal HTML\n // whitespace collapsing changes both wrapping and measured geometry.\n baseStyles[\"white-space\"] = \"pre-wrap\";\n }\n baseStyles.display = \"flex\";\n baseStyles[\"flex-direction\"] = \"column\";\n baseStyles[\"justify-content\"] = verticalAlignJustifyContent(\n style.textAlignVertical,\n );\n tracker.record(node, \"exact\", \"Text styling mapped from TypeStyle fields.\");\n\n const characters = node.characters ?? \"\";\n const textHtml = buildMixedTextHtml(node, characters, tracker);\n return `<div${idAttr}${typeAttr}${nameAttr}${semanticAttrs} style=\"${styleAttr(baseStyles)}\"><span>${textHtml}</span></div>`;\n }\n\n tracker.record(\n node,\n \"exact\",\n \"Position, size, fills, strokes, and effects mapped 1:1.\",\n );\n\n // hasAutoLayout guarantees node.layoutMode is \"HORIZONTAL\" or \"VERTICAL\"\n // (buildAutoLayoutStyles returns {} -- no `display` -- for \"NONE\"/\"GRID\").\n const childParentLayoutMode: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\" =\n hasAutoLayout ? (node.layoutMode as \"HORIZONTAL\" | \"VERTICAL\") : \"NONE\";\n const childrenHtml = (node.children ?? [])\n .map((child) =>\n buildNode(\n child,\n node.absoluteBoundingBox ?? null,\n childParentLayoutMode,\n options,\n tracker,\n false,\n ),\n )\n .filter(Boolean)\n .join(\"\\n\");\n\n return `<div${idAttr}${typeAttr}${nameAttr}${semanticAttrs} style=\"${styleAttr(baseStyles)}\">\\n${childrenHtml}\\n</div>`;\n}\n\n/**\n * Map a Figma node (and its subtree) to an HTML fragment plus a fidelity\n * report describing which properties were exact, approximated, or rendered\n * as an image fallback.\n */\nexport function mapFigmaNodeToHtml(\n node: FigmaNode,\n options: MapFigmaNodeOptions = {},\n): MapFigmaNodeResult {\n assertFigmaNodeTreeComplexity(node);\n const tracker = new FidelityTracker();\n const html = buildNode(node, null, \"NONE\", options, tracker, true);\n return { html, fidelity: tracker.build() };\n}\n"]}
1
+ {"version":3,"file":"figma-node-to-html.js","sourceRoot":"","sources":["../../src/ingestion/figma-node-to-html.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Figma node JSON -> HTML mapper.\n *\n * Input is the `document` subtree returned by\n * `GET /v1/files/:fileKey/nodes?ids=...&geometry=paths` (or the file's root\n * `document` node). Output is a self-contained HTML fragment using absolute\n * positioning + inline styles, matching Figma's own canvas model 1:1 rather\n * than reconstructing a semantic/Tailwind layout — the goal is pixel fidelity\n * for an imported snapshot, not idiomatic hand-authored markup.\n *\n * This module is pure and synchronous: it never calls the network. The\n * caller (an action) is responsible for:\n * 1. Fetching the node JSON from the Figma REST API.\n * 2. Calling `collectFallbackNodeIds` / `collectImageFillRefs` to find out\n * which nodes need a rendered PNG fallback and which image fills need\n * resolved URLs.\n * 3. Fetching those via `/v1/images/:fileKey` (fallback renders) and\n * `/v1/files/:fileKey/images` (fill ref -> URL map).\n * 4. Calling `mapFigmaNodeToHtml` with the resulting maps.\n *\n * ## Pixel-perfect property coverage\n *\n * | Property | Fidelity | Notes |\n * | ------------------------------------------- | ------------- | ----- |\n * | Position/size (absoluteBoundingBox) | exact | frame-relative |\n * | Auto-layout (flex*) | exact | Figma auto-layout IS flexbox |\n * | Text font/size/weight/case/decoration/align | exact | |\n * | Line-height (px vs percent-of-font-size) | exact | resolved to px |\n * | Letter-spacing | exact | already px in REST API |\n * | Solid fills | exact | |\n * | Gradient fills (angle/position) | exact (linear)/approximated (radial/angular/diamond) | derived from gradientHandlePositions, not a default angle |\n * | Multiple fills (layering) | exact | reversed to match CSS background-image stacking |\n * | Image fills (scale modes) | exact (FILL/FIT/TILE/STRETCH-axis-aligned) / approximated (skewed imageTransform) | |\n * | Strokes (uniform, align) | exact | CENTER via outline+negative offset, INSIDE via inset box-shadow, OUTSIDE via outline |\n * | Strokes (per-side weights) | approximated | CSS has no per-side outline; falls back to per-side `border` (inside-only) |\n * | Corner radii (uniform + per-corner) | exact | |\n * | Effects: drop/inner shadow | exact | |\n * | Effects: layer/background blur | approximated | Figma <-> CSS blur radius scale is not publicly specified as 1:1 |\n * | Opacity | exact | |\n * | Blend modes (CSS-supported) | exact | |\n * | Blend modes (Figma-only: LINEAR_BURN/DODGE/LIGHTER/DARKER) | approximated | mapped to closest CSS equivalent |\n * | clipsContent | exact | overflow: hidden |\n * | Rotation | approximated | pivots about the bounding-box center (see below) |\n * | Vector networks / boolean ops / unsupported types | image fallback | never approximated structurally |\n *\n * ### Rotation caveat\n * The REST API docs describe `rotation` as being in degrees, but the field\n * is empirically returned in RADIANS (verified against known authored\n * rotations via the Plugin API); this mapper converts it to degrees before\n * use. `absoluteBoundingBox` is the *already-rotated* axis-aligned bounding\n * box —\n * Figma does not expose the pre-rotation box directly. We reconstruct the\n * unrotated box by treating the AABB's center as invariant under rotation\n * (true for a shape rotated about its own center) and rotate the CSS element\n * about `transform-origin: center` by `-rotation` degrees (Figma's rotation\n * is clockwise-negative relative to CSS's clockwise-positive convention).\n * This is exact when Figma pivots rotation about the shape's center and only\n * approximated if Figma's internal pivot differs (rare in practice; visually\n * indistinguishable in the overwhelming majority of designs). A fully exact\n * alternative would consume `relativeTransform` as a CSS `matrix()` directly,\n * which is a documented follow-up if a specific design surfaces a visible\n * mismatch.\n */\n\nimport {\n cssBlendMode,\n gradientAngleDegrees as gradientAngleDegreesMath,\n remapLinearStopPosition as remapLinearStopPositionMath,\n resolveGradientHandles,\n vectorLength,\n type GradientHandles,\n} from \"./figma-paint-math.js\";\n\nexport interface FigmaColor {\n r: number;\n g: number;\n b: number;\n a?: number;\n}\n\nexport interface FigmaColorStop {\n position: number;\n color: FigmaColor;\n}\n\nexport interface FigmaImageFilter {\n exposure?: number;\n contrast?: number;\n saturation?: number;\n temperature?: number;\n tint?: number;\n highlights?: number;\n shadows?: number;\n}\n\nexport interface FigmaPaint {\n type:\n | \"SOLID\"\n | \"GRADIENT_LINEAR\"\n | \"GRADIENT_RADIAL\"\n | \"GRADIENT_ANGULAR\"\n | \"GRADIENT_DIAMOND\"\n | \"IMAGE\"\n | \"EMOJI\"\n | \"VIDEO\";\n visible?: boolean;\n opacity?: number;\n color?: FigmaColor;\n gradientHandlePositions?: Array<{ x: number; y: number }>;\n gradientStops?: FigmaColorStop[];\n imageRef?: string;\n scaleMode?: \"FILL\" | \"FIT\" | \"TILE\" | \"STRETCH\";\n imageTransform?: [[number, number, number], [number, number, number]];\n filters?: FigmaImageFilter;\n blendMode?: string;\n}\n\nexport interface FigmaEffect {\n type: \"DROP_SHADOW\" | \"INNER_SHADOW\" | \"LAYER_BLUR\" | \"BACKGROUND_BLUR\";\n visible?: boolean;\n radius?: number;\n spread?: number;\n color?: FigmaColor;\n offset?: { x: number; y: number };\n blendMode?: string;\n}\n\nexport interface FigmaTypeStyle {\n fontFamily?: string;\n fontPostScriptName?: string;\n fontWeight?: number;\n fontSize?: number;\n italic?: boolean;\n letterSpacing?: number;\n lineHeightPx?: number;\n lineHeightPercent?: number;\n lineHeightPercentFontSize?: number;\n lineHeightUnit?: \"PIXELS\" | \"FONT_SIZE_%\" | \"INTRINSIC_%\";\n textCase?: \"ORIGINAL\" | \"UPPER\" | \"LOWER\" | \"TITLE\";\n textDecoration?: \"NONE\" | \"UNDERLINE\" | \"STRIKETHROUGH\";\n textAlignHorizontal?: \"LEFT\" | \"RIGHT\" | \"CENTER\" | \"JUSTIFIED\";\n textAlignVertical?: \"TOP\" | \"CENTER\" | \"BOTTOM\";\n textAutoResize?: \"NONE\" | \"WIDTH_AND_HEIGHT\" | \"HEIGHT\" | \"TRUNCATE\";\n paragraphSpacing?: number;\n paragraphIndent?: number;\n listSpacing?: number;\n hangingPunctuation?: boolean;\n hangingList?: boolean;\n opentypeFlags?: Record<string, number>;\n hyperlink?: unknown;\n fills?: FigmaPaint[];\n}\n\nexport interface FigmaIndividualStrokeWeights {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\nexport interface FigmaBoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface FigmaNode {\n id: string;\n name?: string;\n type: string;\n visible?: boolean;\n opacity?: number;\n blendMode?: string;\n rotation?: number;\n absoluteBoundingBox?: FigmaBoundingBox;\n relativeTransform?: [[number, number, number], [number, number, number]];\n /**\n * The node's actual visual extent, INCLUDING stroke/effect overflow --\n * e.g. an OUTSIDE-aligned stroke or a drop shadow makes this larger than\n * `absoluteBoundingBox` (the purely geometric fill bounds). Figma's own\n * `/v1/images` renders for a node are cropped to this box, not to\n * `absoluteBoundingBox` -- sizing an image-fallback `<img>` using the\n * geometric box instead squishes/crops the rendered PNG to the wrong\n * aspect ratio whenever a fallback node has stroke/effect overflow.\n */\n absoluteRenderBounds?: FigmaBoundingBox;\n size?: { x: number; y: number };\n clipsContent?: boolean;\n isMask?: boolean;\n maskType?: \"ALPHA\" | \"VECTOR\" | \"LUMINANCE\";\n arcData?: {\n startingAngle?: number;\n endingAngle?: number;\n innerRadius?: number;\n };\n characters?: string;\n style?: FigmaTypeStyle;\n characterStyleOverrides?: number[];\n styleOverrideTable?: Record<string, FigmaTypeStyle>;\n lineTypes?: string[];\n lineIndentations?: number[];\n fills?: FigmaPaint[];\n strokes?: FigmaPaint[];\n strokeWeight?: number;\n strokeAlign?: \"INSIDE\" | \"OUTSIDE\" | \"CENTER\";\n individualStrokeWeights?: FigmaIndividualStrokeWeights;\n strokeDashes?: number[];\n cornerRadius?: number;\n rectangleCornerRadii?: [number, number, number, number];\n effects?: FigmaEffect[];\n layoutMode?: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\" | \"GRID\";\n layoutPositioning?: \"AUTO\" | \"ABSOLUTE\";\n primaryAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"SPACE_BETWEEN\";\n counterAxisAlignItems?: \"MIN\" | \"CENTER\" | \"MAX\" | \"BASELINE\";\n layoutSizingHorizontal?: \"FIXED\" | \"HUG\" | \"FILL\";\n layoutSizingVertical?: \"FIXED\" | \"HUG\" | \"FILL\";\n layoutWrap?: \"NO_WRAP\" | \"WRAP\";\n itemSpacing?: number;\n counterAxisSpacing?: number;\n paddingLeft?: number;\n paddingRight?: number;\n paddingTop?: number;\n paddingBottom?: number;\n minWidth?: number | null;\n maxWidth?: number | null;\n minHeight?: number | null;\n maxHeight?: number | null;\n componentId?: string;\n componentProperties?: Record<string, unknown>;\n boundVariables?: Record<string, unknown>;\n interactions?: unknown[];\n children?: FigmaNode[];\n}\n\nexport type FidelityLevel = \"exact\" | \"approximated\" | \"image-fallback\";\n\nexport interface FidelityEntry {\n nodeId: string;\n nodeName: string;\n nodeType: string;\n level: FidelityLevel;\n notes: string[];\n}\n\nexport interface FidelityReport {\n entries: FidelityEntry[];\n summary: {\n exact: number;\n approximated: number;\n imageFallback: number;\n };\n}\n\nexport interface MapFigmaNodeOptions {\n /** imageRef hash -> resolved public URL, from `/v1/files/:key/images`. */\n imageFillUrls?: Record<string, string>;\n /** nodeId -> rendered PNG URL, from `/v1/images/:key` for fallback subtrees. */\n fallbackImageUrls?: Record<string, string>;\n /** Node ids that should be rendered as an image regardless of type. */\n forceImageFallbackNodeIds?: Set<string>;\n}\n\nexport interface MapFigmaNodeResult {\n html: string;\n fidelity: FidelityReport;\n}\n\nconst UNSUPPORTED_STRUCTURAL_TYPES = new Set([\n \"BOOLEAN_OPERATION\",\n \"VECTOR\",\n \"STAR\",\n \"REGULAR_POLYGON\",\n \"SLICE\",\n \"STICKY\",\n \"SHAPE_WITH_TEXT\",\n \"CONNECTOR\",\n \"WASHI_TAPE\",\n \"TABLE\",\n]);\n\nconst SUPPORTED_CONTAINER_TYPES = new Set([\n \"FRAME\",\n \"GROUP\",\n \"COMPONENT\",\n \"COMPONENT_SET\",\n \"INSTANCE\",\n \"SECTION\",\n]);\n\nconst MAX_FIGMA_NODE_COUNT = 75_000;\nconst MAX_FIGMA_NODE_DEPTH = 256;\nconst MAX_METADATA_ATTRIBUTE_CHARS = 16_384;\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\nfunction round(value: number, precision = 2): number {\n const factor = 10 ** precision;\n return Math.round(value * factor) / factor;\n}\n\nfunction px(value: number | undefined, precision = 2): string | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return `${round(value, precision)}px`;\n}\n\nfunction colorToCss(\n color: FigmaColor | undefined,\n opacityMul = 1,\n): string | null {\n if (!color) return null;\n const r = Math.round((color.r ?? 0) * 255);\n const g = Math.round((color.g ?? 0) * 255);\n const b = Math.round((color.b ?? 0) * 255);\n const a = round((color.a ?? 1) * opacityMul, 4);\n return `rgba(${r}, ${g}, ${b}, ${a})`;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nfunction escapeAttr(value: string): string {\n return escapeHtml(value);\n}\n\nfunction metadataAttr(\n name: string,\n value: unknown,\n node: FigmaNode,\n tracker: FidelityTracker,\n): string {\n if (value === undefined || value === null) return \"\";\n let serialized: string;\n try {\n serialized = typeof value === \"string\" ? value : JSON.stringify(value);\n } catch {\n tracker.record(\n node,\n \"approximated\",\n `${name} metadata could not be serialized and was omitted.`,\n );\n return \"\";\n }\n if (serialized.length > MAX_METADATA_ATTRIBUTE_CHARS) {\n tracker.record(\n node,\n \"approximated\",\n `${name} metadata exceeded ${MAX_METADATA_ATTRIBUTE_CHARS} characters and was omitted.`,\n );\n return \"\";\n }\n return ` ${name}=\"${escapeAttr(serialized)}\"`;\n}\n\n/**\n * Builds the CSS text for a `style=\"...\"` attribute AND escapes it for HTML\n * attribute context. This matters because at least one style value we emit\n * legitimately contains a literal double-quote character: font-family values\n * are built as `\"Inter\", sans-serif` (CSS requires quoting family names with\n * spaces). Without escaping here, that embedded `\"` prematurely terminates\n * the enclosing `style=\"...\"` attribute the moment a browser (or any other\n * HTML parser) reads it -- silently dropping every style declared after\n * font-family in object-key order (font-size, font-weight, line-height,\n * text-align, and the text node's own `display: flex` used to emulate\n * vertical alignment). The visible symptom is text rendering at the\n * browser's default font/size instead of the mapped Figma typography, with\n * no error anywhere -- caught here via a real headless-browser render that\n * showed a Figma TEXT node's own style attribute silently truncated at\n * `font-family: \"`.\n */\nfunction styleAttr(styles: Record<string, string | undefined>): string {\n const parts = Object.entries(styles)\n .filter((entry): entry is [string, string] => typeof entry[1] === \"string\")\n .map(([key, value]) => `${key}: ${value}`);\n return escapeAttr(parts.join(\"; \"));\n}\n\n// ---------------------------------------------------------------------------\n// Fidelity report builder\n// ---------------------------------------------------------------------------\n\nclass FidelityTracker {\n private entries = new Map<string, FidelityEntry>();\n\n record(node: FigmaNode, level: FidelityLevel, note: string) {\n const existing = this.entries.get(node.id);\n if (existing) {\n // Never downgrade an image-fallback entry, and never upgrade below the\n // worst level recorded for this node.\n const rank: Record<FidelityLevel, number> = {\n exact: 0,\n approximated: 1,\n \"image-fallback\": 2,\n };\n if (rank[level] > rank[existing.level]) existing.level = level;\n existing.notes.push(note);\n return;\n }\n this.entries.set(node.id, {\n nodeId: node.id,\n nodeName: node.name ?? node.id,\n nodeType: node.type,\n level,\n notes: [note],\n });\n }\n\n build(): FidelityReport {\n const entries = [...this.entries.values()];\n const summary = entries.reduce(\n (acc, entry) => {\n if (entry.level === \"exact\") acc.exact += 1;\n else if (entry.level === \"approximated\") acc.approximated += 1;\n else acc.imageFallback += 1;\n return acc;\n },\n { exact: 0, approximated: 0, imageFallback: 0 },\n );\n return { entries, summary };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Gradient angle / position derivation\n// ---------------------------------------------------------------------------\n\nfunction resolveGradientGeometry(paint: FigmaPaint): GradientHandles | null {\n return resolveGradientHandles(paint.gradientHandlePositions);\n}\n\n/**\n * Derive a CSS `linear-gradient()` angle (degrees) from Figma's normalized\n * `gradientHandlePositions`. Handle positions are normalized independently in\n * x and y (0..1 relative to the node's bounding box), so the angle must be\n * computed in actual pixel space using the node's real width/height —\n * otherwise a non-square box silently distorts the angle.\n *\n * Verified against Figma's documented identity handles\n * (start=(0,0.5), end=(1,0.5), width=(1,0), i.e. a plain left-to-right\n * gradient) which must resolve to CSS `90deg` (\"to right\"):\n * dx = 1*w, dy = 0 -> atan2(0, dx) = 0deg -> +90 = 90deg. Matches.\n * And a top-to-bottom gradient (start=(0.5,0), end=(0.5,1)) must resolve to\n * CSS `180deg` (\"to bottom\"):\n * dx = 0, dy = 1*h -> atan2(dy, 0) = 90deg -> +90 = 180deg. Matches.\n */\nexport function gradientAngleDegrees(\n paint: FigmaPaint,\n box: { width: number; height: number },\n): number | null {\n return gradientAngleDegreesMath(paint, box);\n}\n\nfunction gradientStopsCss(\n paint: FigmaPaint,\n remapPosition?: (position: number) => number,\n): string {\n const stops = paint.gradientStops ?? [];\n return stops\n .map((stop) => {\n const color = colorToCss(stop.color, paint.opacity ?? 1) ?? \"transparent\";\n const position = remapPosition\n ? remapPosition(stop.position)\n : stop.position;\n return `${color} ${round(position * 100, 2)}%`;\n })\n .join(\", \");\n}\n\nfunction remapLinearStopPosition(\n geometry: GradientHandles,\n box: { width: number; height: number },\n angleDeg: number,\n): (position: number) => number {\n return remapLinearStopPositionMath(geometry, box, angleDeg);\n}\n\n/**\n * Convert one Figma paint layer to a CSS `background-image` value (or plain\n * color for a SOLID paint used standalone). Returns null for paints that\n * cannot be expressed as a background-image (handled elsewhere).\n */\nfunction paintToCssImage(\n paint: FigmaPaint,\n box: { width: number; height: number },\n tracker: FidelityTracker,\n node: FigmaNode,\n): string | null {\n if (paint.visible === false) return null;\n const stops = gradientStopsCss(paint);\n if (!stops) return null;\n\n switch (paint.type) {\n case \"GRADIENT_LINEAR\": {\n const angle = gradientAngleDegrees(paint, box);\n const geometry = resolveGradientGeometry(paint);\n // Re-express Figma's handle-relative stop positions as percentages of\n // CSS's own full-box gradient line (see remapLinearStopPosition) so a\n // gradient whose handles don't span exactly corner-to-corner still\n // lands its color transitions at the same real pixel positions Figma\n // draws them at, instead of being stretched to fill the whole box.\n const linearStops =\n angle !== null && geometry\n ? gradientStopsCss(\n paint,\n remapLinearStopPosition(geometry, box, angle),\n )\n : stops;\n tracker.record(\n node,\n \"exact\",\n \"Linear gradient angle and stop offsets derived from gradientHandlePositions.\",\n );\n return `linear-gradient(${round(angle ?? 90, 2)}deg, ${linearStops})`;\n }\n case \"GRADIENT_RADIAL\": {\n const geometry = resolveGradientGeometry(paint);\n if (!geometry) return `radial-gradient(${stops})`;\n const cx = round(geometry.start.x * 100, 2);\n const cy = round(geometry.start.y * 100, 2);\n // Figma's handle[1] (\"end\") is the radius vector along the gradient's\n // own primary axis; handle[2] (\"width\") is the perpendicular radius.\n // For an axis-aligned box those map directly to the ellipse's\n // horizontal/vertical radii -- swapping them (as a prior version of\n // this code did) silently rotates the ellipse 90 degrees, which is\n // invisible for a square box but produces a badly wrong bowtie-shaped\n // gradient for any non-square rectangle (the common case).\n const radiusX = vectorLength(geometry.start, geometry.end, box);\n const radiusY = vectorLength(geometry.start, geometry.width, box);\n tracker.record(\n node,\n \"approximated\",\n \"Radial gradient rendered as an axis-aligned ellipse sized from gradientHandlePositions; rotated/skewed radial gradients are not expressible in CSS radial-gradient().\",\n );\n return `radial-gradient(ellipse ${round(radiusX, 2)}px ${round(radiusY, 2)}px at ${cx}% ${cy}%, ${stops})`;\n }\n case \"GRADIENT_ANGULAR\": {\n const geometry = resolveGradientGeometry(paint);\n const cx = geometry ? round(geometry.start.x * 100, 2) : 50;\n const cy = geometry ? round(geometry.start.y * 100, 2) : 50;\n const fromAngle = geometry ? gradientAngleDegrees(paint, box) : 0;\n tracker.record(\n node,\n \"approximated\",\n \"Conic (angular) gradient start angle derived from gradientHandlePositions using the same angle formula as linear gradients; CSS conic-gradient() has no elliptical distortion so non-uniform boxes may render slightly differently than Figma.\",\n );\n return `conic-gradient(from ${round(fromAngle ?? 0, 2)}deg at ${cx}% ${cy}%, ${stops})`;\n }\n case \"GRADIENT_DIAMOND\": {\n const geometry = resolveGradientGeometry(paint);\n const cx = geometry ? round(geometry.start.x * 100, 2) : 50;\n const cy = geometry ? round(geometry.start.y * 100, 2) : 50;\n // Same handle-to-axis mapping fix as GRADIENT_RADIAL above: handle[1]\n // (\"end\") is the primary-axis radius, handle[2] (\"width\") the\n // perpendicular one.\n const radiusX = geometry\n ? vectorLength(geometry.start, geometry.end, box)\n : box.width / 2;\n const radiusY = geometry\n ? vectorLength(geometry.start, geometry.width, box)\n : box.height / 2;\n tracker.record(\n node,\n \"approximated\",\n \"Diamond gradient has no CSS equivalent; approximated as an axis-aligned elliptical radial-gradient sized from gradientHandlePositions. True diamond (rotated-square) falloff is not reproduced.\",\n );\n return `radial-gradient(ellipse ${round(radiusX, 2)}px ${round(radiusY, 2)}px at ${cx}% ${cy}%, ${stops})`;\n }\n default:\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Fills -> background\n// ---------------------------------------------------------------------------\n\ninterface BackgroundResult {\n backgroundColor?: string;\n backgroundImage?: string;\n backgroundSize?: string;\n backgroundPosition?: string;\n backgroundRepeat?: string;\n color?: string; // for TEXT nodes, fill paints color the glyphs, not a background\n}\n\nfunction imageScaleModeCss(\n paint: FigmaPaint,\n node: FigmaNode,\n tracker: FidelityTracker,\n): { size: string; position: string; repeat: string } {\n const transform = paint.imageTransform;\n const isAxisAligned =\n !transform ||\n (Math.abs(transform[0][1]) < 1e-6 && Math.abs(transform[1][0]) < 1e-6);\n if (!isAxisAligned) {\n tracker.record(\n node,\n \"approximated\",\n \"Image fill has a non-axis-aligned imageTransform (rotated/skewed crop); approximated using the scale-mode-only CSS mapping without the transform matrix.\",\n );\n }\n switch (paint.scaleMode) {\n case \"FILL\":\n return { size: \"cover\", position: \"center\", repeat: \"no-repeat\" };\n case \"FIT\":\n return { size: \"contain\", position: \"center\", repeat: \"no-repeat\" };\n case \"TILE\":\n return { size: \"auto\", position: \"top left\", repeat: \"repeat\" };\n case \"STRETCH\":\n return { size: \"100% 100%\", position: \"center\", repeat: \"no-repeat\" };\n default:\n return { size: \"cover\", position: \"center\", repeat: \"no-repeat\" };\n }\n}\n\n/**\n * Build the background-* properties for a node's fill stack. Figma paints\n * fills bottom-to-top (index 0 is the bottommost layer); CSS\n * `background-image` layers top-to-bottom (first value on top), so the\n * stack is reversed here to preserve visual order. A solid fill above other\n * layers is expressed as a flat `linear-gradient(color, color)` since CSS\n * `background-color` always paints *beneath every* background-image and\n * cannot be interleaved mid-stack.\n */\nfunction buildFills(\n node: FigmaNode,\n fills: FigmaPaint[] | undefined,\n box: { width: number; height: number },\n options: MapFigmaNodeOptions,\n tracker: FidelityTracker,\n isTextNode: boolean,\n): BackgroundResult {\n const visible = (fills ?? []).filter((fill) => fill.visible !== false);\n if (visible.length === 0) return {};\n\n if (isTextNode) {\n // Text color comes from the topmost visible SOLID fill; gradient/image\n // text fills are a CSS `background-clip: text` trick we intentionally\n // skip for now (rare in practice) and record as approximated.\n const solid = [...visible].reverse().find((fill) => fill.type === \"SOLID\");\n if (solid) {\n return {\n color: colorToCss(solid.color, solid.opacity ?? 1) ?? undefined,\n };\n }\n tracker.record(\n node,\n \"approximated\",\n \"Text fill is a gradient/image, not a solid color; rendered with the default text color instead of a background-clip: text gradient.\",\n );\n return {};\n }\n\n const images: string[] = [];\n const sizes: string[] = [];\n const positions: string[] = [];\n const repeats: string[] = [];\n let backgroundColor: string | undefined;\n\n // Reverse so the topmost Figma fill becomes the first (topmost) CSS layer.\n const ordered = [...visible].reverse();\n for (let index = 0; index < ordered.length; index += 1) {\n const fill = ordered[index]!;\n const isBottommost = index === ordered.length - 1;\n\n if (fill.type === \"SOLID\") {\n const color = colorToCss(fill.color, fill.opacity ?? 1);\n if (!color) continue;\n if (isBottommost) {\n // A bottom-most solid always paints beneath every background-image\n // layer, so it can always become plain backgroundColor regardless of\n // how many gradient/image layers are stacked above it.\n backgroundColor = color;\n } else {\n // Solid above other layers: express as a flat gradient so it stacks\n // in the correct z-order alongside gradient/image layers.\n images.push(`linear-gradient(${color}, ${color})`);\n sizes.push(\"100% 100%\");\n positions.push(\"center\");\n repeats.push(\"no-repeat\");\n }\n continue;\n }\n\n if (fill.type === \"IMAGE\") {\n const url = fill.imageRef\n ? options.imageFillUrls?.[fill.imageRef]\n : undefined;\n if (!url) {\n tracker.record(\n node,\n \"approximated\",\n `Image fill imageRef \"${fill.imageRef ?? \"unknown\"}\" had no resolved URL; layer omitted.`,\n );\n continue;\n }\n const mode = imageScaleModeCss(fill, node, tracker);\n images.push(`url(\"${url}\")`);\n sizes.push(mode.size);\n positions.push(mode.position);\n repeats.push(mode.repeat);\n continue;\n }\n\n const cssImage = paintToCssImage(fill, box, tracker, node);\n if (cssImage) {\n images.push(cssImage);\n sizes.push(\"100% 100%\");\n positions.push(\"center\");\n repeats.push(\"no-repeat\");\n }\n }\n\n const result: BackgroundResult = {};\n if (backgroundColor) result.backgroundColor = backgroundColor;\n if (images.length > 0) {\n result.backgroundImage = images.join(\", \");\n result.backgroundSize = sizes.join(\", \");\n result.backgroundPosition = positions.join(\", \");\n result.backgroundRepeat = repeats.join(\", \");\n }\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Strokes -> border / outline / box-shadow\n// ---------------------------------------------------------------------------\n\ninterface StrokeResult {\n styles: Record<string, string | undefined>;\n insetShadow?: string;\n}\n\nfunction buildStrokes(node: FigmaNode, tracker: FidelityTracker): StrokeResult {\n const strokes = (node.strokes ?? []).filter(\n (stroke) => stroke.visible !== false,\n );\n if (strokes.length === 0) return { styles: {} };\n\n const first = strokes[0]!;\n const color =\n colorToCss(first.color, first.opacity ?? 1) ?? \"rgba(0, 0, 0, 1)\";\n const iw = node.individualStrokeWeights;\n const hasPerSide =\n iw &&\n (iw.top !== undefined ||\n iw.right !== undefined ||\n iw.bottom !== undefined ||\n iw.left !== undefined);\n const uniformWeight = node.strokeWeight ?? 0;\n\n if (hasPerSide) {\n // CSS `outline`/inset-`box-shadow` tricks are single-weight only; per-side\n // stroke weights can only be expressed as a real per-side `border`, which\n // always renders fully inside the border-box regardless of strokeAlign.\n // This is exact for INSIDE and an approximation for CENTER/OUTSIDE.\n const top = iw?.top ?? uniformWeight;\n const right = iw?.right ?? uniformWeight;\n const bottom = iw?.bottom ?? uniformWeight;\n const left = iw?.left ?? uniformWeight;\n tracker.record(\n node,\n node.strokeAlign === \"INSIDE\" || !node.strokeAlign\n ? \"exact\"\n : \"approximated\",\n `Per-side stroke weights rendered as CSS border (inside-aligned); strokeAlign=\"${node.strokeAlign ?? \"INSIDE\"}\" cannot vary per-side with outline tricks.`,\n );\n return {\n styles: {\n \"border-top\": top ? `${px(top)} solid ${color}` : undefined,\n \"border-right\": right ? `${px(right)} solid ${color}` : undefined,\n \"border-bottom\": bottom ? `${px(bottom)} solid ${color}` : undefined,\n \"border-left\": left ? `${px(left)} solid ${color}` : undefined,\n },\n };\n }\n\n if (!uniformWeight) return { styles: {} };\n\n switch (node.strokeAlign) {\n case \"OUTSIDE\":\n tracker.record(\n node,\n \"exact\",\n \"OUTSIDE stroke rendered via outline (offset 0).\",\n );\n return {\n styles: {\n outline: `${px(uniformWeight)} solid ${color}`,\n \"outline-offset\": \"0px\",\n },\n };\n case \"INSIDE\":\n tracker.record(\n node,\n \"exact\",\n \"INSIDE stroke rendered via inset box-shadow.\",\n );\n return {\n styles: {},\n insetShadow: `inset 0 0 0 ${px(uniformWeight)} ${color}`,\n };\n case \"CENTER\":\n default:\n // outline-offset of -half the weight pulls the outline half inside,\n // half outside the border-box edge -- reproducing Figma's CENTER\n // straddle exactly (plain CSS `border` cannot straddle the edge).\n tracker.record(\n node,\n \"exact\",\n \"CENTER stroke rendered via outline with outline-offset = -weight/2 (straddles the edge like Figma).\",\n );\n return {\n styles: {\n outline: `${px(uniformWeight)} solid ${color}`,\n \"outline-offset\": px(-uniformWeight / 2),\n },\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Corner radii\n// ---------------------------------------------------------------------------\n\nfunction buildCornerRadius(node: FigmaNode): string | undefined {\n if (node.rectangleCornerRadii) {\n const [tl, tr, br, bl] = node.rectangleCornerRadii;\n return `${px(tl) ?? \"0px\"} ${px(tr) ?? \"0px\"} ${px(br) ?? \"0px\"} ${px(bl) ?? \"0px\"}`;\n }\n if (typeof node.cornerRadius === \"number\" && node.cornerRadius > 0) {\n return px(node.cornerRadius);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Effects -> box-shadow / filter / backdrop-filter\n// ---------------------------------------------------------------------------\n\ninterface EffectResult {\n boxShadowLayers: string[];\n filter?: string;\n backdropFilter?: string;\n}\n\nfunction buildEffects(\n node: FigmaNode,\n isTextNode: boolean,\n tracker: FidelityTracker,\n): EffectResult {\n const effects = (node.effects ?? []).filter(\n (effect) => effect.visible !== false,\n );\n const boxShadowLayers: string[] = [];\n let filter: string | undefined;\n let backdropFilter: string | undefined;\n\n for (const effect of effects) {\n if (effect.type === \"DROP_SHADOW\" || effect.type === \"INNER_SHADOW\") {\n const color = colorToCss(effect.color, 1) ?? \"rgba(0, 0, 0, 1)\";\n const x = px(effect.offset?.x ?? 0) ?? \"0px\";\n const y = px(effect.offset?.y ?? 0) ?? \"0px\";\n const blur = px(effect.radius ?? 0) ?? \"0px\";\n const spread =\n !isTextNode && typeof effect.spread === \"number\"\n ? ` ${px(effect.spread)}`\n : \"\";\n const inset = effect.type === \"INNER_SHADOW\" ? \"inset \" : \"\";\n boxShadowLayers.push(`${inset}${x} ${y} ${blur}${spread} ${color}`);\n tracker.record(\n node,\n \"exact\",\n `${effect.type} rendered as ${isTextNode ? \"text-shadow\" : \"box-shadow\"}.`,\n );\n } else if (effect.type === \"LAYER_BLUR\") {\n const radius = px(effect.radius ?? 0) ?? \"0px\";\n filter = filter ? `${filter} blur(${radius})` : `blur(${radius})`;\n tracker.record(\n node,\n \"approximated\",\n \"LAYER_BLUR mapped 1:1 to CSS filter: blur(); Figma's blur radius-to-CSS-stdDeviation scale is not publicly documented, so the rendered softness may differ slightly.\",\n );\n } else if (effect.type === \"BACKGROUND_BLUR\") {\n const radius = px(effect.radius ?? 0) ?? \"0px\";\n backdropFilter = backdropFilter\n ? `${backdropFilter} blur(${radius})`\n : `blur(${radius})`;\n tracker.record(\n node,\n \"approximated\",\n \"BACKGROUND_BLUR mapped 1:1 to CSS backdrop-filter: blur(); same radius-scale caveat as LAYER_BLUR.\",\n );\n }\n }\n\n return { boxShadowLayers, filter, backdropFilter };\n}\n\n// ---------------------------------------------------------------------------\n// Blend modes\n// ---------------------------------------------------------------------------\n\nfunction buildBlendMode(\n node: FigmaNode,\n tracker: FidelityTracker,\n): string | undefined {\n const mode = node.blendMode;\n if (!mode) return undefined;\n const result = cssBlendMode(mode);\n if (!result) return undefined;\n if (result.verdict === \"approximated\") {\n tracker.record(\n node,\n \"approximated\",\n `Figma blend mode \"${mode}\" has no CSS equivalent; approximated as mix-blend-mode: ${result.cssMode}.`,\n );\n }\n return result.cssMode;\n}\n\n// ---------------------------------------------------------------------------\n// Text styling\n// ---------------------------------------------------------------------------\n\nfunction resolveLineHeight(style: FigmaTypeStyle): string | undefined {\n if (\n typeof style.lineHeightPx === \"number\" &&\n style.lineHeightUnit !== \"FONT_SIZE_%\"\n ) {\n return px(style.lineHeightPx);\n }\n if (\n typeof style.lineHeightPercentFontSize === \"number\" &&\n typeof style.fontSize === \"number\"\n ) {\n // lineHeightPercentFontSize is literally \"percent of the font's nominal\n // size\" -- resolve to an exact px value rather than a unitless ratio so\n // the rendered line box matches Figma regardless of font metrics.\n return px(style.fontSize * (style.lineHeightPercentFontSize / 100));\n }\n if (typeof style.lineHeightPx === \"number\") {\n return px(style.lineHeightPx);\n }\n return undefined;\n}\n\nfunction textTransformCss(\n textCase: FigmaTypeStyle[\"textCase\"],\n): string | undefined {\n switch (textCase) {\n case \"UPPER\":\n return \"uppercase\";\n case \"LOWER\":\n return \"lowercase\";\n case \"TITLE\":\n return \"capitalize\";\n default:\n return undefined;\n }\n}\n\nfunction textDecorationCss(\n decoration: FigmaTypeStyle[\"textDecoration\"],\n): string | undefined {\n switch (decoration) {\n case \"UNDERLINE\":\n return \"underline\";\n case \"STRIKETHROUGH\":\n return \"line-through\";\n default:\n return undefined;\n }\n}\n\nfunction textAlignCss(\n align: FigmaTypeStyle[\"textAlignHorizontal\"],\n): string | undefined {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"RIGHT\":\n return \"right\";\n case \"JUSTIFIED\":\n return \"justify\";\n case \"LEFT\":\n return \"left\";\n default:\n return undefined;\n }\n}\n\nfunction verticalAlignJustifyContent(\n align: FigmaTypeStyle[\"textAlignVertical\"],\n): string {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"BOTTOM\":\n return \"flex-end\";\n default:\n return \"flex-start\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Auto-layout\n// ---------------------------------------------------------------------------\n\nfunction primaryAxisJustify(align: FigmaNode[\"primaryAxisAlignItems\"]): string {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"MAX\":\n return \"flex-end\";\n case \"SPACE_BETWEEN\":\n return \"space-between\";\n default:\n return \"flex-start\";\n }\n}\n\nfunction counterAxisAlign(align: FigmaNode[\"counterAxisAlignItems\"]): string {\n switch (align) {\n case \"CENTER\":\n return \"center\";\n case \"MAX\":\n return \"flex-end\";\n case \"BASELINE\":\n return \"baseline\";\n default:\n return \"flex-start\";\n }\n}\n\nfunction buildAutoLayoutStyles(\n node: FigmaNode,\n): Record<string, string | undefined> {\n if (\n !node.layoutMode ||\n node.layoutMode === \"NONE\" ||\n node.layoutMode === \"GRID\"\n ) {\n return {};\n }\n const isHorizontal = node.layoutMode === \"HORIZONTAL\";\n const styles: Record<string, string | undefined> = {\n display: \"flex\",\n \"flex-direction\": isHorizontal ? \"row\" : \"column\",\n \"justify-content\": primaryAxisJustify(node.primaryAxisAlignItems),\n \"align-items\": counterAxisAlign(node.counterAxisAlignItems),\n };\n if (node.layoutWrap === \"WRAP\") styles[\"flex-wrap\"] = \"wrap\";\n if (typeof node.itemSpacing === \"number\" && node.itemSpacing !== 0) {\n styles[isHorizontal ? \"column-gap\" : \"row-gap\"] = px(node.itemSpacing);\n }\n if (\n typeof node.counterAxisSpacing === \"number\" &&\n node.counterAxisSpacing !== 0\n ) {\n styles[isHorizontal ? \"row-gap\" : \"column-gap\"] = px(\n node.counterAxisSpacing,\n );\n }\n const padTop = node.paddingTop ?? 0;\n const padRight = node.paddingRight ?? 0;\n const padBottom = node.paddingBottom ?? 0;\n const padLeft = node.paddingLeft ?? 0;\n if (padTop || padRight || padBottom || padLeft) {\n styles.padding = `${px(padTop)} ${px(padRight)} ${px(padBottom)} ${px(padLeft)}`;\n }\n return styles;\n}\n\n/**\n * \"FILL\" sizing must map to different CSS depending on which axis is the\n * flex *main* axis for this node's parent: main-axis FILL grows via\n * `flex-grow`/`flex-basis` (row parent -> horizontal FILL, column parent ->\n * vertical FILL); cross-axis FILL stretches via `align-self: stretch` (row\n * parent -> vertical FILL, column parent -> horizontal FILL). Passing only a\n * `parentHasAutoLayout` boolean (as this used to) loses the row/column\n * direction and always mapped horizontal-FILL to flex-grow — correct for row\n * parents but wrong for column parents, where a FILL-width text/rect child\n * got `width: auto` with no stretch and overflowed to its content width.\n */\nfunction buildChildSizingStyles(\n node: FigmaNode,\n parentLayoutMode: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\",\n): Record<string, string | undefined> {\n if (parentLayoutMode === \"NONE\") return {};\n const parentIsHorizontal = parentLayoutMode === \"HORIZONTAL\";\n const styles: Record<string, string | undefined> = {};\n if (node.layoutSizingHorizontal === \"FILL\") {\n if (parentIsHorizontal) {\n styles[\"flex-grow\"] = \"1\";\n styles[\"flex-basis\"] = \"0%\";\n } else {\n styles[\"align-self\"] = \"stretch\";\n }\n styles.width = \"auto\";\n } else if (node.layoutSizingHorizontal === \"HUG\") {\n styles.width = \"auto\";\n }\n if (node.layoutSizingVertical === \"FILL\") {\n if (parentIsHorizontal) {\n styles[\"align-self\"] = \"stretch\";\n } else {\n styles[\"flex-grow\"] = \"1\";\n styles[\"flex-basis\"] = \"0%\";\n }\n styles.height = \"auto\";\n } else if (node.layoutSizingVertical === \"HUG\") {\n styles.height = \"auto\";\n }\n return styles;\n}\n\n// ---------------------------------------------------------------------------\n// Node type classification\n// ---------------------------------------------------------------------------\n\nfunction needsImageFallback(\n node: FigmaNode,\n options: MapFigmaNodeOptions,\n): boolean {\n if (options.forceImageFallbackNodeIds?.has(node.id)) return true;\n if (UNSUPPORTED_STRUCTURAL_TYPES.has(node.type)) return true;\n // A Figma mask affects its following siblings, not just the mask node. CSS\n // cannot reproduce that sibling-range operation on an arbitrary DOM tree,\n // so render the smallest containing subtree rather than importing a visibly\n // wrong unmasked composition. A mask imported as the root is also rendered.\n if (node.isMask || node.children?.some((child) => child.isMask)) return true;\n // A CSS div with an outline is not a Figma line. Partial/ring ellipses also\n // need real path geometry, which this structural mapper intentionally does\n // not request because geometry=paths makes ordinary REST payloads enormous.\n if (node.type === \"LINE\") return true;\n if (node.type === \"ELLIPSE\" && node.arcData) {\n const start = node.arcData.startingAngle ?? 0;\n const end = node.arcData.endingAngle ?? Math.PI * 2;\n const span = Math.abs(end - start);\n const isFullCircle =\n Math.abs(span - Math.PI * 2) < 1e-4 &&\n Math.abs(node.arcData.innerRadius ?? 0) < 1e-4;\n if (!isFullCircle) return true;\n }\n const visibleStrokes = (node.strokes ?? []).filter(\n (stroke) => stroke.visible !== false,\n );\n if (\n visibleStrokes.length > 1 ||\n visibleStrokes.some((stroke) => stroke.type !== \"SOLID\") ||\n (node.strokeDashes?.length ?? 0) > 0\n ) {\n return true;\n }\n const visibleFills = (node.fills ?? []).filter(\n (fill) => fill.visible !== false,\n );\n if (\n visibleFills.some(\n (fill) =>\n fill.type === \"VIDEO\" ||\n fill.type === \"EMOJI\" ||\n (fill.blendMode &&\n fill.blendMode !== \"NORMAL\" &&\n fill.blendMode !== \"PASS_THROUGH\") ||\n (fill.type === \"IMAGE\" &&\n ((fill.imageTransform &&\n (Math.abs(fill.imageTransform[0][1]) >= 1e-6 ||\n Math.abs(fill.imageTransform[1][0]) >= 1e-6)) ||\n Object.values(fill.filters ?? {}).some(\n (value) => typeof value === \"number\" && Math.abs(value) > 1e-6,\n ))),\n ) ||\n (node.type === \"TEXT\" && visibleFills.some((fill) => fill.type !== \"SOLID\"))\n ) {\n return true;\n }\n if (node.type === \"TEXT\") {\n const styles = [\n node.style,\n ...Object.values(node.styleOverrideTable ?? {}),\n ].filter((style): style is FigmaTypeStyle => Boolean(style));\n const hasAdvancedTypography = styles.some(\n (style) =>\n Math.abs(style.paragraphSpacing ?? 0) > 1e-6 ||\n Math.abs(style.paragraphIndent ?? 0) > 1e-6 ||\n Math.abs(style.listSpacing ?? 0) > 1e-6 ||\n style.hangingPunctuation === true ||\n style.hangingList === true ||\n style.hyperlink !== undefined ||\n Object.values(style.opentypeFlags ?? {}).some((value) => value !== 0),\n );\n if (\n hasAdvancedTypography ||\n // Figma's REST API always returns one `lineTypes` entry per line —\n // ordinary non-list text comes back as `[\"NONE\", \"NONE\", ...]`, not an\n // empty array. Checking `.length > 0` alone treats every multi-line\n // text node in existence as an unsupported list and routes it to an\n // image fallback; only a line whose type is actually \"ORDERED\" or\n // \"UNORDERED\" means the text uses real list formatting.\n (node.lineTypes?.some((type) => type !== \"NONE\") ?? false) ||\n (node.lineIndentations?.some((value) => value !== 0) ?? false)\n ) {\n return true;\n }\n }\n if (\n (node.effects ?? []).some(\n (effect) =>\n effect.visible !== false &&\n effect.blendMode &&\n effect.blendMode !== \"NORMAL\" &&\n effect.blendMode !== \"PASS_THROUGH\",\n )\n ) {\n return true;\n }\n if (\n !SUPPORTED_CONTAINER_TYPES.has(node.type) &&\n node.type !== \"RECTANGLE\" &&\n node.type !== \"ELLIPSE\" &&\n node.type !== \"TEXT\"\n ) {\n return true;\n }\n return false;\n}\n\n/** Fail clearly before recursive rendering can overflow or lock the worker. */\nexport function assertFigmaNodeTreeComplexity(node: FigmaNode): void {\n const stack: Array<{ node: FigmaNode; depth: number }> = [{ node, depth: 1 }];\n const ancestors = new WeakSet<object>();\n let count = 0;\n while (stack.length > 0) {\n const current = stack.pop()!;\n count += 1;\n if (count > MAX_FIGMA_NODE_COUNT) {\n throw new Error(\n `Figma node tree is too large (max ${MAX_FIGMA_NODE_COUNT.toLocaleString(\"en-US\")} nodes). Import a smaller frame or selection.`,\n );\n }\n if (current.depth > MAX_FIGMA_NODE_DEPTH) {\n throw new Error(\n `Figma node tree is nested too deeply (max ${MAX_FIGMA_NODE_DEPTH} levels). Import a smaller frame or selection.`,\n );\n }\n if (ancestors.has(current.node)) {\n throw new Error(\"Figma node tree contains a cyclic child reference.\");\n }\n ancestors.add(current.node);\n for (const child of current.node.children ?? []) {\n stack.push({ node: child, depth: current.depth + 1 });\n }\n }\n}\n\n/**\n * Walk a node tree and return the ids of every subtree that will render as a\n * PNG image fallback (vector networks, boolean ops, and any node type this\n * mapper does not model structurally). Call this before fetching node data\n * so the caller can request rendered images for exactly these ids via\n * `GET /v1/images/:fileKey?ids=...&scale=2`.\n */\nexport function collectFallbackNodeIds(\n node: FigmaNode,\n options: MapFigmaNodeOptions = {},\n): string[] {\n assertFigmaNodeTreeComplexity(node);\n const ids: string[] = [];\n const visit = (current: FigmaNode) => {\n if (current.visible === false || current.opacity === 0) return;\n if (needsImageFallback(current, options)) {\n ids.push(current.id);\n return; // Don't recurse into a subtree that's rendered as one image.\n }\n for (const child of current.children ?? []) visit(child);\n };\n visit(node);\n return ids;\n}\n\n/**\n * Walk a node tree and return every distinct `imageRef` used by IMAGE fills\n * (on fills or strokes) so the caller can resolve them to URLs via\n * `GET /v1/files/:fileKey/images` before mapping.\n */\nexport function collectImageFillRefs(\n node: FigmaNode,\n options: MapFigmaNodeOptions = {},\n): string[] {\n assertFigmaNodeTreeComplexity(node);\n const refs = new Set<string>();\n const visitPaints = (paints: FigmaPaint[] | undefined) => {\n for (const paint of paints ?? []) {\n if (paint.type === \"IMAGE\" && paint.imageRef) refs.add(paint.imageRef);\n }\n };\n const visit = (current: FigmaNode) => {\n if (current.visible === false || current.opacity === 0) return;\n if (needsImageFallback(current, options)) return;\n visitPaints(current.fills);\n visitPaints(current.strokes);\n for (const child of current.children ?? []) visit(child);\n };\n visit(node);\n return [...refs];\n}\n\nexport interface FigmaFontUsage {\n family: string;\n weight: number;\n italic: boolean;\n}\n\nfunction recordFontUsage(\n style: FigmaTypeStyle | undefined,\n usage: Map<string, FigmaFontUsage>,\n): void {\n if (!style?.fontFamily) return;\n const weight = typeof style.fontWeight === \"number\" ? style.fontWeight : 400;\n const italic = Boolean(style.italic);\n const key = `${style.fontFamily}|${weight}|${italic ? 1 : 0}`;\n if (!usage.has(key))\n usage.set(key, { family: style.fontFamily, weight, italic });\n}\n\n/**\n * Walk a node tree and return every distinct (font family, weight, italic)\n * combination used by TEXT nodes -- including per-run character style\n * overrides -- so the caller can request the actual web font (e.g. from\n * Google Fonts) before the imported HTML is saved. Without this, an imported\n * screen's CSS correctly names the intended font-family, but the browser has\n * no way to load it and silently falls back to a generic sans-serif with\n * different glyph advance widths -- individually invisible per character but\n * compounding into a growing horizontal drift across any wrapped or\n * multi-word line, worst on text-dense imports.\n */\nexport function collectFontUsage(node: FigmaNode): FigmaFontUsage[] {\n assertFigmaNodeTreeComplexity(node);\n const usage = new Map<string, FigmaFontUsage>();\n const visit = (current: FigmaNode) => {\n if (current.visible === false || current.opacity === 0) return;\n if (current.type === \"TEXT\") {\n recordFontUsage(current.style, usage);\n for (const style of Object.values(current.styleOverrideTable ?? {})) {\n recordFontUsage(style, usage);\n }\n }\n for (const child of current.children ?? []) visit(child);\n };\n visit(node);\n return [...usage.values()];\n}\n\nfunction textOverrideCss(\n style: FigmaTypeStyle | undefined,\n): Record<string, string | undefined> {\n const solidFill = [...(style?.fills ?? [])]\n .reverse()\n .find((fill) => fill.visible !== false && fill.type === \"SOLID\");\n return {\n \"font-family\": style?.fontFamily\n ? `\"${style.fontFamily.replace(/\"/g, \"\")}\", sans-serif`\n : undefined,\n \"font-size\": px(style?.fontSize),\n \"font-weight\":\n typeof style?.fontWeight === \"number\"\n ? String(style.fontWeight)\n : undefined,\n \"font-style\": style?.italic ? \"italic\" : undefined,\n \"line-height\": style ? resolveLineHeight(style) : undefined,\n \"letter-spacing\":\n typeof style?.letterSpacing === \"number\"\n ? px(style.letterSpacing)\n : undefined,\n \"text-transform\": textTransformCss(style?.textCase),\n \"text-decoration\": textDecorationCss(style?.textDecoration),\n color: solidFill\n ? (colorToCss(solidFill.color, solidFill.opacity ?? 1) ?? undefined)\n : undefined,\n };\n}\n\n/** Render contiguous Figma character-style override runs as inline spans. */\nfunction buildMixedTextHtml(\n node: FigmaNode,\n characters: string,\n tracker: FidelityTracker,\n): string {\n const overrideIds = node.characterStyleOverrides ?? [];\n const table = node.styleOverrideTable ?? {};\n if (\n characters.length === 0 ||\n !overrideIds.some((id) => id !== 0 && table[String(id)])\n ) {\n return escapeHtml(characters);\n }\n\n const runs: Array<{ id: number; text: string }> = [];\n for (let index = 0; index < characters.length; index += 1) {\n const id = overrideIds[index] ?? 0;\n const previous = runs[runs.length - 1];\n if (previous?.id === id) previous.text += characters[index] ?? \"\";\n else runs.push({ id, text: characters[index] ?? \"\" });\n }\n\n tracker.record(\n node,\n \"exact\",\n \"Mixed character style overrides were preserved as inline text runs.\",\n );\n return runs\n .map((run) => {\n if (run.id === 0) return escapeHtml(run.text);\n const style = table[String(run.id)];\n if (!style) return escapeHtml(run.text);\n return `<span style=\"${styleAttr(textOverrideCss(style))}\">${escapeHtml(run.text)}</span>`;\n })\n .join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Main mapper\n// ---------------------------------------------------------------------------\n\nfunction frameRelativeBox(\n node: FigmaNode,\n parentBox: FigmaBoundingBox | null,\n): { left: number; top: number; width: number; height: number } {\n const box = node.absoluteBoundingBox;\n if (!box) return { left: 0, top: 0, width: 0, height: 0 };\n return {\n left: box.x - (parentBox?.x ?? box.x),\n top: box.y - (parentBox?.y ?? box.y),\n width: box.width,\n height: box.height,\n };\n}\n\n/**\n * Figma's `absoluteBoundingBox` for a rotated node is the axis-aligned\n * bounding box of the ALREADY-ROTATED shape, not the shape's own (pre-\n * rotation) width/height -- e.g. a 120x80 rectangle rotated 15 degrees comes\n * back with an ~136.6x108.3 bounding box. Applying a CSS `rotate()` on TOP\n * of a div already sized to that expanded AABB rotates an oversized box,\n * producing a visibly wrong (too-large, wrong-aspect-ratio) rotated shape.\n * This inverts the AABB formula (`W' = W*|cos| + H*|sin|`,\n * `H' = W*|sin| + H*|cos|`) to recover the true pre-rotation width/height,\n * then re-centers the (smaller) box at the same center point the AABB had --\n * matching this module's existing \"rotate about the AABB center\" pivot\n * assumption, so the CSS `rotate()` reproduces the original box exactly.\n */\nfunction unrotateBox(\n box: { left: number; top: number; width: number; height: number },\n rotationDeg: number,\n): { left: number; top: number; width: number; height: number } {\n const theta = (rotationDeg * Math.PI) / 180;\n const c = Math.abs(Math.cos(theta));\n const s = Math.abs(Math.sin(theta));\n const det = c * c - s * s;\n // Near +-45/+-135 degrees the AABB<->true-size system is near-singular\n // (many different true sizes produce almost the same AABB); fall back to\n // the AABB dimensions rather than dividing by ~zero and producing a huge\n // or negative \"true\" size.\n if (Math.abs(det) < 0.05) return box;\n const trueWidth = (c * box.width - s * box.height) / det;\n const trueHeight = (c * box.height - s * box.width) / det;\n if (\n !Number.isFinite(trueWidth) ||\n !Number.isFinite(trueHeight) ||\n trueWidth <= 0 ||\n trueHeight <= 0\n ) {\n return box;\n }\n const centerX = box.left + box.width / 2;\n const centerY = box.top + box.height / 2;\n return {\n left: centerX - trueWidth / 2,\n top: centerY - trueHeight / 2,\n width: trueWidth,\n height: trueHeight,\n };\n}\n\n/**\n * Same as `frameRelativeBox` but sized/positioned from `absoluteRenderBounds`\n * (falling back to `absoluteBoundingBox` when Figma didn't return render\n * bounds). Used only for image-fallback `<img>` geometry -- see the\n * `absoluteRenderBounds` field doc for why the geometric box is wrong there.\n */\nfunction frameRelativeRenderBox(\n node: FigmaNode,\n parentBox: FigmaBoundingBox | null,\n): { left: number; top: number; width: number; height: number } {\n const box = node.absoluteRenderBounds ?? node.absoluteBoundingBox;\n if (!box) return { left: 0, top: 0, width: 0, height: 0 };\n return {\n left: box.x - (parentBox?.x ?? box.x),\n top: box.y - (parentBox?.y ?? box.y),\n width: box.width,\n height: box.height,\n };\n}\n\nfunction buildNode(\n node: FigmaNode,\n parentBox: FigmaBoundingBox | null,\n parentLayoutMode: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\",\n options: MapFigmaNodeOptions,\n tracker: FidelityTracker,\n isRoot: boolean,\n): string {\n const parentHasAutoLayout = parentLayoutMode !== \"NONE\";\n if (node.visible === false || node.opacity === 0) return \"\";\n\n let box = frameRelativeBox(node, parentBox);\n // The Figma REST API's file-node-types docs describe `rotation` as\n // \"in degrees\", but empirically (verified against known authored values\n // via the Plugin API -- e.g. an authored 15deg/20deg rotation comes back\n // as 0.2617993.../0.3490658... here) the REST API actually returns\n // RADIANS. Treating that value as degrees silently shrinks every rotation\n // by a factor of ~57 (pi/180), rendering rotated content as visually\n // unrotated. Convert to degrees before using it anywhere below.\n const rotationDeg =\n typeof node.rotation === \"number\"\n ? (node.rotation * 180) / Math.PI\n : undefined;\n const rotation =\n rotationDeg !== undefined && Math.abs(rotationDeg) > 0.001\n ? rotationDeg\n : undefined;\n if (rotation !== undefined) {\n // `box` (from absoluteBoundingBox) is the rotated shape's AABB; recover\n // the true pre-rotation width/height/position so fills/effects/strokes\n // below -- and the CSS `rotate()` applied later -- operate on the\n // correct box instead of an oversized one. See `unrotateBox`.\n box = unrotateBox(box, rotation);\n }\n const nameAttr = node.name\n ? ` data-agent-native-layer-name=\"${escapeAttr(node.name)}\"`\n : \"\";\n const idAttr = ` data-figma-node-id=\"${escapeAttr(node.id)}\"`;\n const typeAttr = ` data-figma-node-type=\"${escapeAttr(node.type)}\"`;\n const semanticAttrs =\n metadataAttr(\"data-figma-component-id\", node.componentId, node, tracker) +\n metadataAttr(\n \"data-figma-component-properties\",\n node.componentProperties,\n node,\n tracker,\n ) +\n metadataAttr(\n \"data-figma-bound-variables\",\n node.boundVariables,\n node,\n tracker,\n ) +\n metadataAttr(\"data-figma-interactions\", node.interactions, node, tracker);\n if (node.componentId || node.componentProperties) {\n tracker.record(\n node,\n \"approximated\",\n \"Figma component/instance provenance was preserved as metadata, but the imported HTML is not linked to the original Figma component master.\",\n );\n }\n if (node.boundVariables && Object.keys(node.boundVariables).length > 0) {\n tracker.record(\n node,\n \"approximated\",\n \"Figma variable bindings were preserved as metadata; resolved visual values are imported, but bindings are not live Design tokens.\",\n );\n }\n if (node.interactions && node.interactions.length > 0) {\n tracker.record(\n node,\n \"approximated\",\n \"Prototype interactions were preserved as inert metadata and do not execute or navigate inside the editor preview.\",\n );\n }\n\n if (needsImageFallback(node, options)) {\n const imageUrl = options.fallbackImageUrls?.[node.id];\n if (!imageUrl) {\n tracker.record(\n node,\n \"image-fallback\",\n `Node type \"${node.type}\" requires an image fallback but no rendered URL was provided; nothing was rendered for this node.`,\n );\n return \"\";\n }\n tracker.record(\n node,\n \"image-fallback\",\n `Node type \"${node.type}\" cannot be reproduced structurally (vector network / boolean op / unsupported type); rendered as an exact PNG (scale=2) instead of an approximated structural guess.`,\n );\n const isFlowChild =\n !isRoot && parentHasAutoLayout && node.layoutPositioning !== \"ABSOLUTE\";\n // Use render bounds (not the geometric box) so a fallback PNG whose\n // stroke/effects overflow the node's own bounding box (e.g. an\n // OUTSIDE-aligned stroke) is placed at its natural size instead of being\n // squished/cropped into the smaller geometric box.\n const renderBox = frameRelativeRenderBox(node, parentBox);\n const styles: Record<string, string | undefined> = {\n position: isRoot || isFlowChild ? \"relative\" : \"absolute\",\n left: isRoot || isFlowChild ? undefined : px(renderBox.left),\n top: isRoot || isFlowChild ? undefined : px(renderBox.top),\n width: px(renderBox.width),\n height: px(renderBox.height),\n opacity:\n typeof node.opacity === \"number\" && node.opacity !== 1\n ? String(round(node.opacity, 4))\n : undefined,\n };\n return `<img${idAttr}${typeAttr}${nameAttr}${semanticAttrs} src=\"${escapeAttr(imageUrl)}\" alt=\"${escapeAttr(node.name ?? \"\")}\" style=\"${styleAttr(styles)}\" />`;\n }\n\n const isTextNode = node.type === \"TEXT\";\n const isEllipse = node.type === \"ELLIPSE\";\n const box2 = { width: box.width, height: box.height };\n\n const fills = buildFills(\n node,\n node.fills,\n box2,\n options,\n tracker,\n isTextNode,\n );\n const strokeResult = buildStrokes(node, tracker);\n const effects = buildEffects(node, isTextNode, tracker);\n const cornerRadius = isEllipse ? \"50%\" : buildCornerRadius(node);\n const blendMode = buildBlendMode(node, tracker);\n\n const boxShadowParts = [...effects.boxShadowLayers];\n if (strokeResult.insetShadow) boxShadowParts.push(strokeResult.insetShadow);\n\n if (rotation !== undefined) {\n tracker.record(\n node,\n \"approximated\",\n `Rotation (${round(rotation, 2)}deg) reconstructed by pivoting the unrotated box about the absoluteBoundingBox center; exact only when Figma's internal pivot is also the shape's center.`,\n );\n }\n\n const autoLayoutStyles = buildAutoLayoutStyles(node);\n const childSizingStyles = buildChildSizingStyles(node, parentLayoutMode);\n const hasAutoLayout = Boolean(autoLayoutStyles.display);\n // A node is positioned relative to its parent's free canvas (absolute,\n // left/top from absoluteBoundingBox) unless its *parent* is an auto-layout\n // container, in which case it's a normal flex item (relative, no left/top)\n // -- this mirrors Figma's own rule that auto-layout children give up\n // manual x/y in favor of flex flow.\n const isFlexChild =\n !isRoot && parentHasAutoLayout && node.layoutPositioning !== \"ABSOLUTE\";\n\n const baseStyles: Record<string, string | undefined> = {\n position: isRoot ? \"relative\" : isFlexChild ? \"relative\" : \"absolute\",\n left: isRoot || isFlexChild ? undefined : px(box.left),\n top: isRoot || isFlexChild ? undefined : px(box.top),\n width: childSizingStyles.width ?? px(box.width),\n height: childSizingStyles.height ?? px(box.height),\n \"background-color\": fills.backgroundColor,\n \"background-image\": fills.backgroundImage,\n \"background-size\": fills.backgroundSize,\n \"background-position\": fills.backgroundPosition,\n \"background-repeat\": fills.backgroundRepeat,\n color: fills.color,\n \"border-radius\": cornerRadius,\n \"box-shadow\":\n boxShadowParts.length > 0 ? boxShadowParts.join(\", \") : undefined,\n filter: effects.filter,\n \"backdrop-filter\": effects.backdropFilter,\n \"-webkit-backdrop-filter\": effects.backdropFilter,\n opacity:\n typeof node.opacity === \"number\" && node.opacity !== 1\n ? String(round(node.opacity, 4))\n : undefined,\n \"mix-blend-mode\": blendMode,\n overflow: node.clipsContent ? \"hidden\" : undefined,\n transform:\n rotation !== undefined ? `rotate(${round(-rotation, 3)}deg)` : undefined,\n \"transform-origin\": rotation !== undefined ? \"center\" : undefined,\n \"min-width\": px(node.minWidth ?? undefined),\n \"max-width\": px(node.maxWidth ?? undefined),\n \"min-height\": px(node.minHeight ?? undefined),\n \"max-height\": px(node.maxHeight ?? undefined),\n ...autoLayoutStyles,\n ...strokeResult.styles,\n ...childSizingStyles,\n };\n\n if (isTextNode) {\n const style = node.style ?? {};\n baseStyles[\"font-family\"] = style.fontFamily\n ? `\"${style.fontFamily.replace(/\"/g, \"\")}\", sans-serif`\n : undefined;\n baseStyles[\"font-size\"] = px(style.fontSize);\n baseStyles[\"font-weight\"] =\n typeof style.fontWeight === \"number\"\n ? String(style.fontWeight)\n : undefined;\n baseStyles[\"font-style\"] = style.italic ? \"italic\" : undefined;\n baseStyles[\"line-height\"] = resolveLineHeight(style);\n baseStyles[\"letter-spacing\"] =\n typeof style.letterSpacing === \"number\" && style.letterSpacing !== 0\n ? px(style.letterSpacing)\n : undefined;\n baseStyles[\"text-transform\"] = textTransformCss(style.textCase);\n baseStyles[\"text-decoration\"] = textDecorationCss(style.textDecoration);\n baseStyles[\"text-align\"] = textAlignCss(style.textAlignHorizontal);\n if (style.textAutoResize === \"TRUNCATE\") {\n baseStyles[\"white-space\"] = \"nowrap\";\n baseStyles.overflow = \"hidden\";\n baseStyles[\"text-overflow\"] = \"ellipsis\";\n } else {\n // Figma preserves explicit newlines and repeated spaces. Normal HTML\n // whitespace collapsing changes both wrapping and measured geometry.\n baseStyles[\"white-space\"] = \"pre-wrap\";\n }\n baseStyles.display = \"flex\";\n baseStyles[\"flex-direction\"] = \"column\";\n baseStyles[\"justify-content\"] = verticalAlignJustifyContent(\n style.textAlignVertical,\n );\n tracker.record(node, \"exact\", \"Text styling mapped from TypeStyle fields.\");\n\n const characters = node.characters ?? \"\";\n const textHtml = buildMixedTextHtml(node, characters, tracker);\n return `<div${idAttr}${typeAttr}${nameAttr}${semanticAttrs} style=\"${styleAttr(baseStyles)}\"><span>${textHtml}</span></div>`;\n }\n\n tracker.record(\n node,\n \"exact\",\n \"Position, size, fills, strokes, and effects mapped 1:1.\",\n );\n\n // hasAutoLayout guarantees node.layoutMode is \"HORIZONTAL\" or \"VERTICAL\"\n // (buildAutoLayoutStyles returns {} -- no `display` -- for \"NONE\"/\"GRID\").\n const childParentLayoutMode: \"NONE\" | \"HORIZONTAL\" | \"VERTICAL\" =\n hasAutoLayout ? (node.layoutMode as \"HORIZONTAL\" | \"VERTICAL\") : \"NONE\";\n const childrenHtml = (node.children ?? [])\n .map((child) =>\n buildNode(\n child,\n node.absoluteBoundingBox ?? null,\n childParentLayoutMode,\n options,\n tracker,\n false,\n ),\n )\n .filter(Boolean)\n .join(\"\\n\");\n\n return `<div${idAttr}${typeAttr}${nameAttr}${semanticAttrs} style=\"${styleAttr(baseStyles)}\">\\n${childrenHtml}\\n</div>`;\n}\n\n/**\n * Map a Figma node (and its subtree) to an HTML fragment plus a fidelity\n * report describing which properties were exact, approximated, or rendered\n * as an image fallback.\n */\nexport function mapFigmaNodeToHtml(\n node: FigmaNode,\n options: MapFigmaNodeOptions = {},\n): MapFigmaNodeResult {\n assertFigmaNodeTreeComplexity(node);\n const tracker = new FidelityTracker();\n const html = buildNode(node, null, \"NONE\", options, tracker, true);\n return { html, fidelity: tracker.build() };\n}\n"]}