@easybits.cloud/html-tailwind-generator 0.2.19 → 0.2.20

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.
@@ -220,6 +220,32 @@ function getIframeScript() {
220
220
  return parts.join(' > ');
221
221
  }
222
222
 
223
+ function getCleanSectionHtml(sectionEl) {
224
+ var els = sectionEl.querySelectorAll('*');
225
+ var saved = [];
226
+ for (var i = 0; i < els.length; i++) {
227
+ var s = els[i].style;
228
+ saved.push({ outline: s.outline, outlineOffset: s.outlineOffset, ce: els[i].contentEditable });
229
+ s.outline = '';
230
+ s.outlineOffset = '';
231
+ if (els[i].contentEditable === 'true') els[i].removeAttribute('contenteditable');
232
+ }
233
+ // Also clean the section root
234
+ var rootOutline = sectionEl.style.outline;
235
+ var rootOffset = sectionEl.style.outlineOffset;
236
+ sectionEl.style.outline = '';
237
+ sectionEl.style.outlineOffset = '';
238
+ var html = sectionEl.innerHTML;
239
+ sectionEl.style.outline = rootOutline;
240
+ sectionEl.style.outlineOffset = rootOffset;
241
+ for (var i = 0; i < els.length; i++) {
242
+ els[i].style.outline = saved[i].outline;
243
+ els[i].style.outlineOffset = saved[i].outlineOffset;
244
+ if (saved[i].ce === 'true') els[i].contentEditable = 'true';
245
+ }
246
+ return html;
247
+ }
248
+
223
249
  function isTextElement(el) {
224
250
  var textTags = ['H1','H2','H3','H4','H5','H6','P','SPAN','LI','A','BLOCKQUOTE','LABEL','TD','TH','FIGCAPTION','BUTTON'];
225
251
  return textTags.indexOf(el.tagName) !== -1;
@@ -325,7 +351,7 @@ function getIframeScript() {
325
351
  sectionId: sid,
326
352
  elementPath: getElementPath(el),
327
353
  newText: el.innerHTML,
328
- sectionHtml: sectionEl ? sectionEl.innerHTML : null,
354
+ sectionHtml: sectionEl ? getCleanSectionHtml(sectionEl) : null,
329
355
  }, '*');
330
356
 
331
357
  selectedEl = null;
@@ -405,7 +431,7 @@ function getIframeScript() {
405
431
  window.parent.postMessage({
406
432
  type: 'section-html-updated',
407
433
  sectionId: msg.sectionId,
408
- sectionHtml: sectionEl.innerHTML,
434
+ sectionHtml: getCleanSectionHtml(sectionEl),
409
435
  }, '*');
410
436
  }
411
437
  }
@@ -536,4 +562,4 @@ export {
536
562
  buildPreviewHtml,
537
563
  buildDeployHtml
538
564
  };
539
- //# sourceMappingURL=chunk-MIJ7NO37.js.map
565
+ //# sourceMappingURL=chunk-4XZHBIQF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/themes.ts","../src/iframeScript.ts","../src/buildHtml.ts"],"sourcesContent":["export interface LandingTheme {\n id: string;\n label: string;\n colors: {\n primary: string;\n \"primary-light\": string;\n \"primary-dark\": string;\n secondary: string;\n accent: string;\n surface: string;\n \"surface-alt\": string;\n \"on-surface\": string;\n \"on-surface-muted\": string;\n \"on-primary\": string;\n };\n}\n\nexport const LANDING_THEMES: LandingTheme[] = [\n {\n id: \"minimal\",\n label: \"Minimal\",\n colors: {\n primary: \"#18181b\",\n \"primary-light\": \"#3f3f46\",\n \"primary-dark\": \"#09090b\",\n secondary: \"#71717a\",\n accent: \"#2563eb\",\n surface: \"#ffffff\",\n \"surface-alt\": \"#f4f4f5\",\n \"on-surface\": \"#18181b\",\n \"on-surface-muted\": \"#71717a\",\n \"on-primary\": \"#ffffff\",\n },\n },\n {\n id: \"calido\",\n label: \"Cálido\",\n colors: {\n primary: \"#9a3412\",\n \"primary-light\": \"#c2410c\",\n \"primary-dark\": \"#7c2d12\",\n secondary: \"#78716c\",\n accent: \"#d97706\",\n surface: \"#fafaf9\",\n \"surface-alt\": \"#f5f5f4\",\n \"on-surface\": \"#1c1917\",\n \"on-surface-muted\": \"#78716c\",\n \"on-primary\": \"#ffffff\",\n },\n },\n {\n id: \"oceano\",\n label: \"Océano\",\n colors: {\n primary: \"#0f4c75\",\n \"primary-light\": \"#1a6fa0\",\n \"primary-dark\": \"#0a3555\",\n secondary: \"#6b7280\",\n accent: \"#0d9488\",\n surface: \"#ffffff\",\n \"surface-alt\": \"#f0fdfa\",\n \"on-surface\": \"#0f172a\",\n \"on-surface-muted\": \"#64748b\",\n \"on-primary\": \"#ffffff\",\n },\n },\n {\n id: \"noche\",\n label: \"Noche\",\n colors: {\n primary: \"#a78bfa\",\n \"primary-light\": \"#c4b5fd\",\n \"primary-dark\": \"#8b5cf6\",\n secondary: \"#9ca3af\",\n accent: \"#a78bfa\",\n surface: \"#111827\",\n \"surface-alt\": \"#1f2937\",\n \"on-surface\": \"#f9fafb\",\n \"on-surface-muted\": \"#9ca3af\",\n \"on-primary\": \"#111827\",\n },\n },\n {\n id: \"bosque\",\n label: \"Bosque\",\n colors: {\n primary: \"#16a34a\",\n \"primary-light\": \"#22c55e\",\n \"primary-dark\": \"#15803d\",\n secondary: \"#a3a3a3\",\n accent: \"#16a34a\",\n surface: \"#0a0a0a\",\n \"surface-alt\": \"#171717\",\n \"on-surface\": \"#fafafa\",\n \"on-surface-muted\": \"#a3a3a3\",\n \"on-primary\": \"#000000\",\n },\n },\n {\n id: \"rosa\",\n label: \"Rosa\",\n colors: {\n primary: \"#be185d\",\n \"primary-light\": \"#db2777\",\n \"primary-dark\": \"#9d174d\",\n secondary: \"#6b7280\",\n accent: \"#be185d\",\n surface: \"#ffffff\",\n \"surface-alt\": \"#fdf2f8\",\n \"on-surface\": \"#1f2937\",\n \"on-surface-muted\": \"#6b7280\",\n \"on-primary\": \"#ffffff\",\n },\n },\n];\n\nexport interface CustomColors {\n primary: string;\n secondary?: string;\n accent?: string;\n surface?: string;\n}\n\nfunction parseHex(hex: string) {\n return {\n r: parseInt(hex.slice(1, 3), 16),\n g: parseInt(hex.slice(3, 5), 16),\n b: parseInt(hex.slice(5, 7), 16),\n };\n}\n\nfunction toHex(r: number, g: number, b: number) {\n return `#${[r, g, b].map((c) => Math.max(0, Math.min(255, c)).toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\nfunction luminance(hex: string) {\n const { r, g, b } = parseHex(hex);\n return (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n}\n\nfunction lighten(hex: string, amount = 40) {\n const { r, g, b } = parseHex(hex);\n return toHex(r + amount, g + amount, b + amount);\n}\n\nfunction darken(hex: string, amount = 40) {\n const { r, g, b } = parseHex(hex);\n return toHex(r - amount, g - amount, b - amount);\n}\n\nexport function buildCustomTheme(colors: CustomColors): LandingTheme {\n const { primary, secondary = \"#f59e0b\", accent = \"#06b6d4\", surface = \"#ffffff\" } = colors;\n\n const onPrimary = luminance(primary) > 0.5 ? \"#111827\" : \"#ffffff\";\n const surfaceLum = luminance(surface);\n const isDarkSurface = surfaceLum < 0.5;\n\n return {\n id: \"custom\",\n label: \"Custom\",\n colors: {\n primary,\n \"primary-light\": lighten(primary),\n \"primary-dark\": darken(primary),\n secondary,\n accent,\n surface,\n \"surface-alt\": isDarkSurface ? lighten(surface, 20) : darken(surface, 5),\n \"on-surface\": isDarkSurface ? \"#f1f5f9\" : \"#111827\",\n \"on-surface-muted\": isDarkSurface ? \"#94a3b8\" : \"#6b7280\",\n \"on-primary\": onPrimary,\n },\n };\n}\n\nexport function buildCustomThemeCss(colors: CustomColors): string {\n const theme = buildCustomTheme(colors);\n return `[data-theme=\"custom\"] {\\n${buildCssVars(theme.colors)}\\n}`;\n}\n\n/** CSS custom properties for a theme */\nfunction buildCssVars(colors: LandingTheme[\"colors\"]): string {\n return Object.entries(colors)\n .map(([k, v]) => ` --color-${k}: ${v};`)\n .join(\"\\n\");\n}\n\n/** Build the tailwind.config JS object string for TW v3 CDN */\nfunction buildTailwindConfig(): string {\n const colorEntries = Object.keys(LANDING_THEMES[0].colors)\n .map((k) => ` '${k}': 'var(--color-${k})'`)\n .join(\",\\n\");\n\n return `{\n theme: {\n extend: {\n colors: {\n${colorEntries}\n }\n }\n }\n }`;\n}\n\nexport function buildThemeCss(): { css: string; tailwindConfig: string } {\n const defaultTheme = LANDING_THEMES[0];\n\n const overrides = LANDING_THEMES.slice(1)\n .map((t) => `[data-theme=\"${t.id}\"] {\\n${buildCssVars(t.colors)}\\n}`)\n .join(\"\\n\\n\");\n\n const css = `:root {\\n${buildCssVars(defaultTheme.colors)}\\n}\\n\\n${overrides}`;\n return { css, tailwindConfig: buildTailwindConfig() };\n}\n\nexport function buildSingleThemeCss(themeId: string): { css: string; tailwindConfig: string } {\n const theme = LANDING_THEMES.find((t) => t.id === themeId) || LANDING_THEMES[0];\n const css = `:root {\\n${buildCssVars(theme.colors)}\\n}`;\n return { css, tailwindConfig: buildTailwindConfig() };\n}\n","/**\n * JavaScript injected into the landing v3 iframe.\n * Handles hover highlights, click selection, contentEditable text editing,\n * postMessage communication with the parent editor,\n * and incremental section injection from parent.\n */\nexport function getIframeScript(): string {\n return `\n(function() {\n let hoveredEl = null;\n let selectedEl = null;\n const OUTLINE_HOVER = '2px solid #3B82F6';\n const OUTLINE_SELECTED = '2px solid #8B5CF6';\n\n function getSectionId(el) {\n let node = el;\n while (node && node !== document.body) {\n if (node.dataset && node.dataset.sectionId) {\n return node.dataset.sectionId;\n }\n node = node.parentElement;\n }\n return null;\n }\n\n function getSectionElement(sectionId) {\n return document.querySelector('[data-section-id=\"' + sectionId + '\"]');\n }\n\n function getElementPath(el) {\n const parts = [];\n let node = el;\n while (node && node !== document.body) {\n let tag = node.tagName.toLowerCase();\n if (node.id) { tag += '#' + node.id; }\n const siblings = node.parentElement ? Array.from(node.parentElement.children).filter(function(c) { return c.tagName === node.tagName; }) : [];\n if (siblings.length > 1) { tag += ':nth(' + siblings.indexOf(node) + ')'; }\n parts.unshift(tag);\n node = node.parentElement;\n }\n return parts.join(' > ');\n }\n\n function getCleanSectionHtml(sectionEl) {\n var els = sectionEl.querySelectorAll('*');\n var saved = [];\n for (var i = 0; i < els.length; i++) {\n var s = els[i].style;\n saved.push({ outline: s.outline, outlineOffset: s.outlineOffset, ce: els[i].contentEditable });\n s.outline = '';\n s.outlineOffset = '';\n if (els[i].contentEditable === 'true') els[i].removeAttribute('contenteditable');\n }\n // Also clean the section root\n var rootOutline = sectionEl.style.outline;\n var rootOffset = sectionEl.style.outlineOffset;\n sectionEl.style.outline = '';\n sectionEl.style.outlineOffset = '';\n var html = sectionEl.innerHTML;\n sectionEl.style.outline = rootOutline;\n sectionEl.style.outlineOffset = rootOffset;\n for (var i = 0; i < els.length; i++) {\n els[i].style.outline = saved[i].outline;\n els[i].style.outlineOffset = saved[i].outlineOffset;\n if (saved[i].ce === 'true') els[i].contentEditable = 'true';\n }\n return html;\n }\n\n function isTextElement(el) {\n var textTags = ['H1','H2','H3','H4','H5','H6','P','SPAN','LI','A','BLOCKQUOTE','LABEL','TD','TH','FIGCAPTION','BUTTON'];\n return textTags.indexOf(el.tagName) !== -1;\n }\n\n // Hover\n document.addEventListener('mouseover', function(e) {\n var el = e.target;\n if (el === document.body || el === document.documentElement) return;\n if (el === selectedEl) return;\n if (hoveredEl && hoveredEl !== selectedEl) {\n hoveredEl.style.outline = '';\n hoveredEl.style.outlineOffset = '';\n }\n hoveredEl = el;\n if (el !== selectedEl) {\n el.style.outline = OUTLINE_HOVER;\n el.style.outlineOffset = '-2px';\n }\n });\n\n document.addEventListener('mouseout', function(e) {\n if (hoveredEl && hoveredEl !== selectedEl) {\n hoveredEl.style.outline = '';\n hoveredEl.style.outlineOffset = '';\n }\n hoveredEl = null;\n });\n\n // Click — select element\n document.addEventListener('click', function(e) {\n e.preventDefault();\n e.stopPropagation();\n var el = e.target;\n\n // Deselect previous\n if (selectedEl) {\n selectedEl.style.outline = '';\n selectedEl.style.outlineOffset = '';\n }\n\n if (selectedEl === el) {\n selectedEl = null;\n window.parent.postMessage({ type: 'element-deselected' }, '*');\n return;\n }\n\n selectedEl = el;\n\n // Clear hover styles BEFORE capturing openTag (so it matches source HTML)\n el.style.outline = '';\n el.style.outlineOffset = '';\n var openTag = el.outerHTML.substring(0, el.outerHTML.indexOf('>') + 1).substring(0, 120);\n\n el.style.outline = OUTLINE_SELECTED;\n el.style.outlineOffset = '-2px';\n\n var rect = el.getBoundingClientRect();\n var attrs = {};\n if (el.tagName === 'IMG') {\n attrs = { src: el.getAttribute('src') || '', alt: el.getAttribute('alt') || '' };\n }\n if (el.tagName === 'A') {\n attrs = { href: el.getAttribute('href') || '', target: el.getAttribute('target') || '' };\n }\n\n window.parent.postMessage({\n type: 'element-selected',\n sectionId: getSectionId(el),\n tagName: el.tagName,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n text: (el.textContent || '').substring(0, 200),\n openTag: openTag,\n elementPath: getElementPath(el),\n isSectionRoot: el.dataset && el.dataset.sectionId ? true : false,\n attrs: attrs,\n }, '*');\n }, true);\n\n // Double-click — contentEditable for text\n document.addEventListener('dblclick', function(e) {\n e.preventDefault();\n e.stopPropagation();\n var el = e.target;\n if (!isTextElement(el)) return;\n\n el.contentEditable = 'true';\n el.focus();\n el.style.outline = '2px dashed #F59E0B';\n el.style.outlineOffset = '-2px';\n\n function onBlur() {\n el.contentEditable = 'false';\n el.style.outline = '';\n el.style.outlineOffset = '';\n el.removeEventListener('blur', onBlur);\n el.removeEventListener('keydown', onKeydown);\n\n var sid = getSectionId(el);\n var sectionEl = sid ? getSectionElement(sid) : null;\n window.parent.postMessage({\n type: 'text-edited',\n sectionId: sid,\n elementPath: getElementPath(el),\n newText: el.innerHTML,\n sectionHtml: sectionEl ? getCleanSectionHtml(sectionEl) : null,\n }, '*');\n\n selectedEl = null;\n }\n\n function onKeydown(ev) {\n if (ev.key === 'Escape') {\n el.blur();\n }\n }\n\n el.addEventListener('blur', onBlur);\n el.addEventListener('keydown', onKeydown);\n }, true);\n\n // Listen for messages FROM parent (incremental section injection)\n window.addEventListener('message', function(e) {\n var msg = e.data;\n if (!msg || !msg.action) return;\n\n if (msg.action === 'add-section') {\n var wrapper = document.createElement('div');\n wrapper.setAttribute('data-section-id', msg.id);\n wrapper.innerHTML = msg.html;\n wrapper.style.animation = 'fadeInUp 0.4s ease-out';\n document.body.appendChild(wrapper);\n wrapper.scrollIntoView({ behavior: 'smooth', block: 'end' });\n }\n\n if (msg.action === 'update-section') {\n var el = getSectionElement(msg.id);\n if (el && typeof window.morphdom === 'function') {\n var tmp = document.createElement('div');\n tmp.innerHTML = msg.html;\n window.morphdom(el, tmp, {\n childrenOnly: true,\n onBeforeElUpdated: function(fromEl, toEl) {\n if (fromEl.isEqualNode(toEl)) return false;\n return true;\n }\n });\n } else if (el) {\n el.innerHTML = msg.html;\n }\n }\n\n if (msg.action === 'remove-section') {\n var el = getSectionElement(msg.id);\n if (el) { el.remove(); }\n }\n\n if (msg.action === 'reorder-sections') {\n // msg.order = [id1, id2, id3, ...]\n var order = msg.order;\n for (var i = 0; i < order.length; i++) {\n var el = getSectionElement(order[i]);\n if (el) { document.body.appendChild(el); }\n }\n }\n\n if (msg.action === 'update-attribute') {\n var sectionEl = getSectionElement(msg.sectionId);\n if (sectionEl) {\n var target = null;\n if (msg.elementPath) {\n // Find element by matching path\n var allEls = sectionEl.querySelectorAll(msg.tagName || '*');\n for (var i = 0; i < allEls.length; i++) {\n if (getElementPath(allEls[i]) === msg.elementPath) {\n target = allEls[i];\n break;\n }\n }\n }\n if (target) {\n target.setAttribute(msg.attr, msg.value);\n window.parent.postMessage({\n type: 'section-html-updated',\n sectionId: msg.sectionId,\n sectionHtml: getCleanSectionHtml(sectionEl),\n }, '*');\n }\n }\n }\n\n if (msg.action === 'set-theme') {\n if (msg.theme && msg.theme !== 'default') {\n document.documentElement.setAttribute('data-theme', msg.theme);\n } else {\n document.documentElement.removeAttribute('data-theme');\n }\n }\n\n if (msg.action === 'set-custom-css') {\n var customStyle = document.getElementById('custom-theme-css');\n if (!customStyle) {\n customStyle = document.createElement('style');\n customStyle.id = 'custom-theme-css';\n document.head.appendChild(customStyle);\n }\n customStyle.textContent = msg.css || '';\n }\n\n if (msg.action === 'scroll-to-section') {\n var el = getSectionElement(msg.id);\n if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }\n }\n\n if (msg.action === 'full-rewrite') {\n // Fallback: rewrite everything\n document.body.innerHTML = msg.html;\n }\n });\n\n // Inject animation keyframe\n var style = document.createElement('style');\n style.textContent = '@keyframes fadeInUp { from { opacity:0; transform:translateY(20px); } to { opacity:1; transform:translateY(0); } }';\n document.head.appendChild(style);\n\n // Notify parent we're ready\n window.parent.postMessage({ type: 'ready' }, '*');\n})();\n`;\n}\n","import type { Section3 } from \"./types\";\nimport { getIframeScript } from \"./iframeScript\";\nimport { buildThemeCss, buildSingleThemeCss, buildCustomTheme, type CustomColors } from \"./themes\";\n\n/**\n * Build the full HTML for the iframe preview (with editing script).\n */\nexport function buildPreviewHtml(sections: Section3[], theme?: string): string {\n const sorted = [...sections].sort((a, b) => a.order - b.order);\n const body = sorted\n .map((s) => `<div data-section-id=\"${s.id}\">${s.html}</div>`)\n .join(\"\\n\");\n\n const dataTheme = theme && theme !== \"default\" ? ` data-theme=\"${theme}\"` : \"\";\n const { css, tailwindConfig } = buildThemeCss();\n\n return `<!DOCTYPE html>\n<html lang=\"es\"${dataTheme}>\n<head>\n<meta charset=\"UTF-8\"/>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n<script src=\"https://cdn.tailwindcss.com\"></script>\n<script src=\"https://unpkg.com/morphdom@2.7.4/dist/morphdom-umd.min.js\"></script>\n<script>tailwind.config = ${tailwindConfig}</script>\n<style>\n${css}\n*{margin:0;padding:0;box-sizing:border-box}\nhtml{scroll-behavior:smooth}\nbody{font-family:system-ui,-apple-system,sans-serif;background-color:var(--color-surface);color:var(--color-on-surface)}\nimg{max-width:100%}\nsection{width:100%}\nsection>*{max-width:80rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}\n[contenteditable=\"true\"]{cursor:text}\n</style>\n</head>\n<body class=\"bg-surface text-on-surface\">\n${body}\n<script>${getIframeScript()}</script>\n</body>\n</html>`;\n}\n\n/**\n * Build the deploy HTML (no editing script, clean output).\n */\n/**\n * Remove editor artifacts (outline, outlineOffset, contenteditable) from HTML before deploy.\n */\nfunction stripEditorArtifacts(html: string): string {\n return html\n .replace(/\\s*outline:\\s*[^;\"]+;?/gi, \"\")\n .replace(/\\s*outline-offset:\\s*[^;\"]+;?/gi, \"\")\n .replace(/\\s*style=\"\\s*\"/gi, \"\")\n .replace(/\\s+contenteditable=\"[^\"]*\"/gi, \"\")\n .replace(/\\s+data-section-id=\"[^\"]*\"/gi, \"\")\n}\n\nexport function buildDeployHtml(sections: Section3[], theme?: string, customColors?: CustomColors, showBranding = true): string {\n const sorted = [...sections].sort((a, b) => a.order - b.order);\n const body = sorted.map((s) => stripEditorArtifacts(s.html)).join(\"\\n\");\n\n const isCustom = theme === \"custom\" && customColors;\n const dataTheme = theme && theme !== \"default\" && !isCustom ? ` data-theme=\"${theme}\"` : \"\";\n\n // For custom theme, build CSS from the custom colors directly (no data-theme needed, inject as :root)\n const { css: baseCss, tailwindConfig } = isCustom\n ? (() => {\n const ct = buildCustomTheme(customColors);\n const vars = Object.entries(ct.colors).map(([k, v]) => ` --color-${k}: ${v};`).join(\"\\n\");\n return { css: `:root {\\n${vars}\\n}`, tailwindConfig: buildSingleThemeCss(\"default\").tailwindConfig };\n })()\n : buildSingleThemeCss(theme || \"default\");\n\n return `<!DOCTYPE html>\n<html lang=\"es\"${dataTheme}>\n<head>\n<meta charset=\"UTF-8\"/>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n<title>Landing Page</title>\n<script src=\"https://cdn.tailwindcss.com\"></script>\n<script>tailwind.config = ${tailwindConfig}</script>\n<style>\n${baseCss}\n*{margin:0;padding:0;box-sizing:border-box}\nhtml{scroll-behavior:smooth}\nbody{font-family:system-ui,-apple-system,sans-serif;background-color:var(--color-surface);color:var(--color-on-surface)}\nsection{width:100%}\nsection>*{max-width:80rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}\n</style>\n</head>\n<body class=\"bg-surface text-on-surface\">\n${body}\n${showBranding ? `<div style=\"text-align:center;padding:16px 0 12px;font-size:12px\">\n <a href=\"https://easybits.cloud\" target=\"_blank\" rel=\"noopener\"\n style=\"color:#9ca3af;text-decoration:none\">\n Powered by easybits.cloud\n </a>\n</div>` : \"\"}\n</body>\n</html>`;\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmST;;;ACnSO,SAAS,iBAAiB,UAAsB,OAAwB;AAC7E,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC7D,QAAM,OAAO,OACV,IAAI,CAAC,MAAM,yBAAyB,EAAE,EAAE,KAAK,EAAE,IAAI,QAAQ,EAC3D,KAAK,IAAI;AAEZ,QAAM,YAAY,SAAS,UAAU,YAAY,gBAAgB,KAAK,MAAM;AAC5E,QAAM,EAAE,KAAK,eAAe,IAAI,cAAc;AAE9C,SAAO;AAAA,iBACQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAME,cAAc;AAAA;AAAA,EAExC,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWH,IAAI;AAAA,UACI,gBAAgB,CAAC;AAAA;AAAA;AAG3B;AAQA,SAAS,qBAAqB,MAAsB;AAClD,SAAO,KACJ,QAAQ,4BAA4B,EAAE,EACtC,QAAQ,mCAAmC,EAAE,EAC7C,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,gCAAgC,EAAE,EAC1C,QAAQ,gCAAgC,EAAE;AAC/C;AAEO,SAAS,gBAAgB,UAAsB,OAAgB,cAA6B,eAAe,MAAc;AAC9H,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC7D,QAAM,OAAO,OAAO,IAAI,CAAC,MAAM,qBAAqB,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI;AAEtE,QAAM,WAAW,UAAU,YAAY;AACvC,QAAM,YAAY,SAAS,UAAU,aAAa,CAAC,WAAW,gBAAgB,KAAK,MAAM;AAGzF,QAAM,EAAE,KAAK,SAAS,eAAe,IAAI,YACpC,MAAM;AACL,UAAM,KAAK,iBAAiB,YAAY;AACxC,UAAM,OAAO,OAAO,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,IAAI;AACzF,WAAO,EAAE,KAAK;AAAA,EAAY,IAAI;AAAA,IAAO,gBAAgB,oBAAoB,SAAS,EAAE,eAAe;AAAA,EACrG,GAAG,IACH,oBAAoB,SAAS,SAAS;AAE1C,SAAO;AAAA,iBACQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAME,cAAc;AAAA;AAAA,EAExC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASP,IAAI;AAAA,EACJ,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,UAKP,EAAE;AAAA;AAAA;AAGZ;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildDeployHtml
3
- } from "./chunk-MIJ7NO37.js";
3
+ } from "./chunk-4XZHBIQF.js";
4
4
 
5
5
  // src/deploy.ts
6
6
  async function deployToS3(options) {
@@ -39,4 +39,4 @@ export {
39
39
  deployToS3,
40
40
  deployToEasyBits
41
41
  };
42
- //# sourceMappingURL=chunk-SZZXKRJH.js.map
42
+ //# sourceMappingURL=chunk-NEJB6746.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  LANDING_THEMES,
3
3
  buildPreviewHtml
4
- } from "./chunk-MIJ7NO37.js";
4
+ } from "./chunk-4XZHBIQF.js";
5
5
 
6
6
  // src/components/Canvas.tsx
7
7
  import { useRef, useEffect, useCallback, useState, forwardRef, useImperativeHandle } from "react";
@@ -940,4 +940,4 @@ export {
940
940
  CodeEditor,
941
941
  ViewportToggle
942
942
  };
943
- //# sourceMappingURL=chunk-Z3QL2CI2.js.map
943
+ //# sourceMappingURL=chunk-NR67WZZZ.js.map
@@ -4,8 +4,8 @@ import {
4
4
  FloatingToolbar,
5
5
  SectionList,
6
6
  ViewportToggle
7
- } from "./chunk-Z3QL2CI2.js";
8
- import "./chunk-MIJ7NO37.js";
7
+ } from "./chunk-NR67WZZZ.js";
8
+ import "./chunk-4XZHBIQF.js";
9
9
  export {
10
10
  Canvas,
11
11
  CodeEditor,
package/dist/deploy.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  deployToEasyBits,
3
3
  deployToS3
4
- } from "./chunk-SZZXKRJH.js";
5
- import "./chunk-MIJ7NO37.js";
4
+ } from "./chunk-NEJB6746.js";
5
+ import "./chunk-4XZHBIQF.js";
6
6
  export {
7
7
  deployToEasyBits,
8
8
  deployToS3
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  FloatingToolbar,
5
5
  SectionList,
6
6
  ViewportToggle
7
- } from "./chunk-Z3QL2CI2.js";
7
+ } from "./chunk-NR67WZZZ.js";
8
8
  import "./chunk-RTGCZUNJ.js";
9
9
  import {
10
10
  PROMPT_SUFFIX,
@@ -25,7 +25,7 @@ import {
25
25
  import {
26
26
  deployToEasyBits,
27
27
  deployToS3
28
- } from "./chunk-SZZXKRJH.js";
28
+ } from "./chunk-NEJB6746.js";
29
29
  import {
30
30
  LANDING_THEMES,
31
31
  buildCustomTheme,
@@ -35,7 +35,7 @@ import {
35
35
  buildSingleThemeCss,
36
36
  buildThemeCss,
37
37
  getIframeScript
38
- } from "./chunk-MIJ7NO37.js";
38
+ } from "./chunk-4XZHBIQF.js";
39
39
  export {
40
40
  Canvas,
41
41
  CodeEditor,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easybits.cloud/html-tailwind-generator",
3
- "version": "0.2.19",
3
+ "version": "0.2.20",
4
4
  "description": "AI-powered landing page generator with Tailwind CSS — canvas editor, streaming generation, and one-click deploy",
5
5
  "license": "PolyForm-Noncommercial-1.0.0",
6
6
  "type": "module",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/themes.ts","../src/iframeScript.ts","../src/buildHtml.ts"],"sourcesContent":["export interface LandingTheme {\n id: string;\n label: string;\n colors: {\n primary: string;\n \"primary-light\": string;\n \"primary-dark\": string;\n secondary: string;\n accent: string;\n surface: string;\n \"surface-alt\": string;\n \"on-surface\": string;\n \"on-surface-muted\": string;\n \"on-primary\": string;\n };\n}\n\nexport const LANDING_THEMES: LandingTheme[] = [\n {\n id: \"minimal\",\n label: \"Minimal\",\n colors: {\n primary: \"#18181b\",\n \"primary-light\": \"#3f3f46\",\n \"primary-dark\": \"#09090b\",\n secondary: \"#71717a\",\n accent: \"#2563eb\",\n surface: \"#ffffff\",\n \"surface-alt\": \"#f4f4f5\",\n \"on-surface\": \"#18181b\",\n \"on-surface-muted\": \"#71717a\",\n \"on-primary\": \"#ffffff\",\n },\n },\n {\n id: \"calido\",\n label: \"Cálido\",\n colors: {\n primary: \"#9a3412\",\n \"primary-light\": \"#c2410c\",\n \"primary-dark\": \"#7c2d12\",\n secondary: \"#78716c\",\n accent: \"#d97706\",\n surface: \"#fafaf9\",\n \"surface-alt\": \"#f5f5f4\",\n \"on-surface\": \"#1c1917\",\n \"on-surface-muted\": \"#78716c\",\n \"on-primary\": \"#ffffff\",\n },\n },\n {\n id: \"oceano\",\n label: \"Océano\",\n colors: {\n primary: \"#0f4c75\",\n \"primary-light\": \"#1a6fa0\",\n \"primary-dark\": \"#0a3555\",\n secondary: \"#6b7280\",\n accent: \"#0d9488\",\n surface: \"#ffffff\",\n \"surface-alt\": \"#f0fdfa\",\n \"on-surface\": \"#0f172a\",\n \"on-surface-muted\": \"#64748b\",\n \"on-primary\": \"#ffffff\",\n },\n },\n {\n id: \"noche\",\n label: \"Noche\",\n colors: {\n primary: \"#a78bfa\",\n \"primary-light\": \"#c4b5fd\",\n \"primary-dark\": \"#8b5cf6\",\n secondary: \"#9ca3af\",\n accent: \"#a78bfa\",\n surface: \"#111827\",\n \"surface-alt\": \"#1f2937\",\n \"on-surface\": \"#f9fafb\",\n \"on-surface-muted\": \"#9ca3af\",\n \"on-primary\": \"#111827\",\n },\n },\n {\n id: \"bosque\",\n label: \"Bosque\",\n colors: {\n primary: \"#16a34a\",\n \"primary-light\": \"#22c55e\",\n \"primary-dark\": \"#15803d\",\n secondary: \"#a3a3a3\",\n accent: \"#16a34a\",\n surface: \"#0a0a0a\",\n \"surface-alt\": \"#171717\",\n \"on-surface\": \"#fafafa\",\n \"on-surface-muted\": \"#a3a3a3\",\n \"on-primary\": \"#000000\",\n },\n },\n {\n id: \"rosa\",\n label: \"Rosa\",\n colors: {\n primary: \"#be185d\",\n \"primary-light\": \"#db2777\",\n \"primary-dark\": \"#9d174d\",\n secondary: \"#6b7280\",\n accent: \"#be185d\",\n surface: \"#ffffff\",\n \"surface-alt\": \"#fdf2f8\",\n \"on-surface\": \"#1f2937\",\n \"on-surface-muted\": \"#6b7280\",\n \"on-primary\": \"#ffffff\",\n },\n },\n];\n\nexport interface CustomColors {\n primary: string;\n secondary?: string;\n accent?: string;\n surface?: string;\n}\n\nfunction parseHex(hex: string) {\n return {\n r: parseInt(hex.slice(1, 3), 16),\n g: parseInt(hex.slice(3, 5), 16),\n b: parseInt(hex.slice(5, 7), 16),\n };\n}\n\nfunction toHex(r: number, g: number, b: number) {\n return `#${[r, g, b].map((c) => Math.max(0, Math.min(255, c)).toString(16).padStart(2, \"0\")).join(\"\")}`;\n}\n\nfunction luminance(hex: string) {\n const { r, g, b } = parseHex(hex);\n return (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n}\n\nfunction lighten(hex: string, amount = 40) {\n const { r, g, b } = parseHex(hex);\n return toHex(r + amount, g + amount, b + amount);\n}\n\nfunction darken(hex: string, amount = 40) {\n const { r, g, b } = parseHex(hex);\n return toHex(r - amount, g - amount, b - amount);\n}\n\nexport function buildCustomTheme(colors: CustomColors): LandingTheme {\n const { primary, secondary = \"#f59e0b\", accent = \"#06b6d4\", surface = \"#ffffff\" } = colors;\n\n const onPrimary = luminance(primary) > 0.5 ? \"#111827\" : \"#ffffff\";\n const surfaceLum = luminance(surface);\n const isDarkSurface = surfaceLum < 0.5;\n\n return {\n id: \"custom\",\n label: \"Custom\",\n colors: {\n primary,\n \"primary-light\": lighten(primary),\n \"primary-dark\": darken(primary),\n secondary,\n accent,\n surface,\n \"surface-alt\": isDarkSurface ? lighten(surface, 20) : darken(surface, 5),\n \"on-surface\": isDarkSurface ? \"#f1f5f9\" : \"#111827\",\n \"on-surface-muted\": isDarkSurface ? \"#94a3b8\" : \"#6b7280\",\n \"on-primary\": onPrimary,\n },\n };\n}\n\nexport function buildCustomThemeCss(colors: CustomColors): string {\n const theme = buildCustomTheme(colors);\n return `[data-theme=\"custom\"] {\\n${buildCssVars(theme.colors)}\\n}`;\n}\n\n/** CSS custom properties for a theme */\nfunction buildCssVars(colors: LandingTheme[\"colors\"]): string {\n return Object.entries(colors)\n .map(([k, v]) => ` --color-${k}: ${v};`)\n .join(\"\\n\");\n}\n\n/** Build the tailwind.config JS object string for TW v3 CDN */\nfunction buildTailwindConfig(): string {\n const colorEntries = Object.keys(LANDING_THEMES[0].colors)\n .map((k) => ` '${k}': 'var(--color-${k})'`)\n .join(\",\\n\");\n\n return `{\n theme: {\n extend: {\n colors: {\n${colorEntries}\n }\n }\n }\n }`;\n}\n\nexport function buildThemeCss(): { css: string; tailwindConfig: string } {\n const defaultTheme = LANDING_THEMES[0];\n\n const overrides = LANDING_THEMES.slice(1)\n .map((t) => `[data-theme=\"${t.id}\"] {\\n${buildCssVars(t.colors)}\\n}`)\n .join(\"\\n\\n\");\n\n const css = `:root {\\n${buildCssVars(defaultTheme.colors)}\\n}\\n\\n${overrides}`;\n return { css, tailwindConfig: buildTailwindConfig() };\n}\n\nexport function buildSingleThemeCss(themeId: string): { css: string; tailwindConfig: string } {\n const theme = LANDING_THEMES.find((t) => t.id === themeId) || LANDING_THEMES[0];\n const css = `:root {\\n${buildCssVars(theme.colors)}\\n}`;\n return { css, tailwindConfig: buildTailwindConfig() };\n}\n","/**\n * JavaScript injected into the landing v3 iframe.\n * Handles hover highlights, click selection, contentEditable text editing,\n * postMessage communication with the parent editor,\n * and incremental section injection from parent.\n */\nexport function getIframeScript(): string {\n return `\n(function() {\n let hoveredEl = null;\n let selectedEl = null;\n const OUTLINE_HOVER = '2px solid #3B82F6';\n const OUTLINE_SELECTED = '2px solid #8B5CF6';\n\n function getSectionId(el) {\n let node = el;\n while (node && node !== document.body) {\n if (node.dataset && node.dataset.sectionId) {\n return node.dataset.sectionId;\n }\n node = node.parentElement;\n }\n return null;\n }\n\n function getSectionElement(sectionId) {\n return document.querySelector('[data-section-id=\"' + sectionId + '\"]');\n }\n\n function getElementPath(el) {\n const parts = [];\n let node = el;\n while (node && node !== document.body) {\n let tag = node.tagName.toLowerCase();\n if (node.id) { tag += '#' + node.id; }\n const siblings = node.parentElement ? Array.from(node.parentElement.children).filter(function(c) { return c.tagName === node.tagName; }) : [];\n if (siblings.length > 1) { tag += ':nth(' + siblings.indexOf(node) + ')'; }\n parts.unshift(tag);\n node = node.parentElement;\n }\n return parts.join(' > ');\n }\n\n function isTextElement(el) {\n var textTags = ['H1','H2','H3','H4','H5','H6','P','SPAN','LI','A','BLOCKQUOTE','LABEL','TD','TH','FIGCAPTION','BUTTON'];\n return textTags.indexOf(el.tagName) !== -1;\n }\n\n // Hover\n document.addEventListener('mouseover', function(e) {\n var el = e.target;\n if (el === document.body || el === document.documentElement) return;\n if (el === selectedEl) return;\n if (hoveredEl && hoveredEl !== selectedEl) {\n hoveredEl.style.outline = '';\n hoveredEl.style.outlineOffset = '';\n }\n hoveredEl = el;\n if (el !== selectedEl) {\n el.style.outline = OUTLINE_HOVER;\n el.style.outlineOffset = '-2px';\n }\n });\n\n document.addEventListener('mouseout', function(e) {\n if (hoveredEl && hoveredEl !== selectedEl) {\n hoveredEl.style.outline = '';\n hoveredEl.style.outlineOffset = '';\n }\n hoveredEl = null;\n });\n\n // Click — select element\n document.addEventListener('click', function(e) {\n e.preventDefault();\n e.stopPropagation();\n var el = e.target;\n\n // Deselect previous\n if (selectedEl) {\n selectedEl.style.outline = '';\n selectedEl.style.outlineOffset = '';\n }\n\n if (selectedEl === el) {\n selectedEl = null;\n window.parent.postMessage({ type: 'element-deselected' }, '*');\n return;\n }\n\n selectedEl = el;\n\n // Clear hover styles BEFORE capturing openTag (so it matches source HTML)\n el.style.outline = '';\n el.style.outlineOffset = '';\n var openTag = el.outerHTML.substring(0, el.outerHTML.indexOf('>') + 1).substring(0, 120);\n\n el.style.outline = OUTLINE_SELECTED;\n el.style.outlineOffset = '-2px';\n\n var rect = el.getBoundingClientRect();\n var attrs = {};\n if (el.tagName === 'IMG') {\n attrs = { src: el.getAttribute('src') || '', alt: el.getAttribute('alt') || '' };\n }\n if (el.tagName === 'A') {\n attrs = { href: el.getAttribute('href') || '', target: el.getAttribute('target') || '' };\n }\n\n window.parent.postMessage({\n type: 'element-selected',\n sectionId: getSectionId(el),\n tagName: el.tagName,\n rect: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },\n text: (el.textContent || '').substring(0, 200),\n openTag: openTag,\n elementPath: getElementPath(el),\n isSectionRoot: el.dataset && el.dataset.sectionId ? true : false,\n attrs: attrs,\n }, '*');\n }, true);\n\n // Double-click — contentEditable for text\n document.addEventListener('dblclick', function(e) {\n e.preventDefault();\n e.stopPropagation();\n var el = e.target;\n if (!isTextElement(el)) return;\n\n el.contentEditable = 'true';\n el.focus();\n el.style.outline = '2px dashed #F59E0B';\n el.style.outlineOffset = '-2px';\n\n function onBlur() {\n el.contentEditable = 'false';\n el.style.outline = '';\n el.style.outlineOffset = '';\n el.removeEventListener('blur', onBlur);\n el.removeEventListener('keydown', onKeydown);\n\n var sid = getSectionId(el);\n var sectionEl = sid ? getSectionElement(sid) : null;\n window.parent.postMessage({\n type: 'text-edited',\n sectionId: sid,\n elementPath: getElementPath(el),\n newText: el.innerHTML,\n sectionHtml: sectionEl ? sectionEl.innerHTML : null,\n }, '*');\n\n selectedEl = null;\n }\n\n function onKeydown(ev) {\n if (ev.key === 'Escape') {\n el.blur();\n }\n }\n\n el.addEventListener('blur', onBlur);\n el.addEventListener('keydown', onKeydown);\n }, true);\n\n // Listen for messages FROM parent (incremental section injection)\n window.addEventListener('message', function(e) {\n var msg = e.data;\n if (!msg || !msg.action) return;\n\n if (msg.action === 'add-section') {\n var wrapper = document.createElement('div');\n wrapper.setAttribute('data-section-id', msg.id);\n wrapper.innerHTML = msg.html;\n wrapper.style.animation = 'fadeInUp 0.4s ease-out';\n document.body.appendChild(wrapper);\n wrapper.scrollIntoView({ behavior: 'smooth', block: 'end' });\n }\n\n if (msg.action === 'update-section') {\n var el = getSectionElement(msg.id);\n if (el && typeof window.morphdom === 'function') {\n var tmp = document.createElement('div');\n tmp.innerHTML = msg.html;\n window.morphdom(el, tmp, {\n childrenOnly: true,\n onBeforeElUpdated: function(fromEl, toEl) {\n if (fromEl.isEqualNode(toEl)) return false;\n return true;\n }\n });\n } else if (el) {\n el.innerHTML = msg.html;\n }\n }\n\n if (msg.action === 'remove-section') {\n var el = getSectionElement(msg.id);\n if (el) { el.remove(); }\n }\n\n if (msg.action === 'reorder-sections') {\n // msg.order = [id1, id2, id3, ...]\n var order = msg.order;\n for (var i = 0; i < order.length; i++) {\n var el = getSectionElement(order[i]);\n if (el) { document.body.appendChild(el); }\n }\n }\n\n if (msg.action === 'update-attribute') {\n var sectionEl = getSectionElement(msg.sectionId);\n if (sectionEl) {\n var target = null;\n if (msg.elementPath) {\n // Find element by matching path\n var allEls = sectionEl.querySelectorAll(msg.tagName || '*');\n for (var i = 0; i < allEls.length; i++) {\n if (getElementPath(allEls[i]) === msg.elementPath) {\n target = allEls[i];\n break;\n }\n }\n }\n if (target) {\n target.setAttribute(msg.attr, msg.value);\n window.parent.postMessage({\n type: 'section-html-updated',\n sectionId: msg.sectionId,\n sectionHtml: sectionEl.innerHTML,\n }, '*');\n }\n }\n }\n\n if (msg.action === 'set-theme') {\n if (msg.theme && msg.theme !== 'default') {\n document.documentElement.setAttribute('data-theme', msg.theme);\n } else {\n document.documentElement.removeAttribute('data-theme');\n }\n }\n\n if (msg.action === 'set-custom-css') {\n var customStyle = document.getElementById('custom-theme-css');\n if (!customStyle) {\n customStyle = document.createElement('style');\n customStyle.id = 'custom-theme-css';\n document.head.appendChild(customStyle);\n }\n customStyle.textContent = msg.css || '';\n }\n\n if (msg.action === 'scroll-to-section') {\n var el = getSectionElement(msg.id);\n if (el) { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }\n }\n\n if (msg.action === 'full-rewrite') {\n // Fallback: rewrite everything\n document.body.innerHTML = msg.html;\n }\n });\n\n // Inject animation keyframe\n var style = document.createElement('style');\n style.textContent = '@keyframes fadeInUp { from { opacity:0; transform:translateY(20px); } to { opacity:1; transform:translateY(0); } }';\n document.head.appendChild(style);\n\n // Notify parent we're ready\n window.parent.postMessage({ type: 'ready' }, '*');\n})();\n`;\n}\n","import type { Section3 } from \"./types\";\nimport { getIframeScript } from \"./iframeScript\";\nimport { buildThemeCss, buildSingleThemeCss, buildCustomTheme, type CustomColors } from \"./themes\";\n\n/**\n * Build the full HTML for the iframe preview (with editing script).\n */\nexport function buildPreviewHtml(sections: Section3[], theme?: string): string {\n const sorted = [...sections].sort((a, b) => a.order - b.order);\n const body = sorted\n .map((s) => `<div data-section-id=\"${s.id}\">${s.html}</div>`)\n .join(\"\\n\");\n\n const dataTheme = theme && theme !== \"default\" ? ` data-theme=\"${theme}\"` : \"\";\n const { css, tailwindConfig } = buildThemeCss();\n\n return `<!DOCTYPE html>\n<html lang=\"es\"${dataTheme}>\n<head>\n<meta charset=\"UTF-8\"/>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n<script src=\"https://cdn.tailwindcss.com\"></script>\n<script src=\"https://unpkg.com/morphdom@2.7.4/dist/morphdom-umd.min.js\"></script>\n<script>tailwind.config = ${tailwindConfig}</script>\n<style>\n${css}\n*{margin:0;padding:0;box-sizing:border-box}\nhtml{scroll-behavior:smooth}\nbody{font-family:system-ui,-apple-system,sans-serif;background-color:var(--color-surface);color:var(--color-on-surface)}\nimg{max-width:100%}\nsection{width:100%}\nsection>*{max-width:80rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}\n[contenteditable=\"true\"]{cursor:text}\n</style>\n</head>\n<body class=\"bg-surface text-on-surface\">\n${body}\n<script>${getIframeScript()}</script>\n</body>\n</html>`;\n}\n\n/**\n * Build the deploy HTML (no editing script, clean output).\n */\n/**\n * Remove editor artifacts (outline, outlineOffset, contenteditable) from HTML before deploy.\n */\nfunction stripEditorArtifacts(html: string): string {\n return html\n .replace(/\\s*outline:\\s*[^;\"]+;?/gi, \"\")\n .replace(/\\s*outline-offset:\\s*[^;\"]+;?/gi, \"\")\n .replace(/\\s*style=\"\\s*\"/gi, \"\")\n .replace(/\\s+contenteditable=\"[^\"]*\"/gi, \"\")\n .replace(/\\s+data-section-id=\"[^\"]*\"/gi, \"\")\n}\n\nexport function buildDeployHtml(sections: Section3[], theme?: string, customColors?: CustomColors, showBranding = true): string {\n const sorted = [...sections].sort((a, b) => a.order - b.order);\n const body = sorted.map((s) => stripEditorArtifacts(s.html)).join(\"\\n\");\n\n const isCustom = theme === \"custom\" && customColors;\n const dataTheme = theme && theme !== \"default\" && !isCustom ? ` data-theme=\"${theme}\"` : \"\";\n\n // For custom theme, build CSS from the custom colors directly (no data-theme needed, inject as :root)\n const { css: baseCss, tailwindConfig } = isCustom\n ? (() => {\n const ct = buildCustomTheme(customColors);\n const vars = Object.entries(ct.colors).map(([k, v]) => ` --color-${k}: ${v};`).join(\"\\n\");\n return { css: `:root {\\n${vars}\\n}`, tailwindConfig: buildSingleThemeCss(\"default\").tailwindConfig };\n })()\n : buildSingleThemeCss(theme || \"default\");\n\n return `<!DOCTYPE html>\n<html lang=\"es\"${dataTheme}>\n<head>\n<meta charset=\"UTF-8\"/>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n<title>Landing Page</title>\n<script src=\"https://cdn.tailwindcss.com\"></script>\n<script>tailwind.config = ${tailwindConfig}</script>\n<style>\n${baseCss}\n*{margin:0;padding:0;box-sizing:border-box}\nhtml{scroll-behavior:smooth}\nbody{font-family:system-ui,-apple-system,sans-serif;background-color:var(--color-surface);color:var(--color-on-surface)}\nsection{width:100%}\nsection>*{max-width:80rem;margin-left:auto;margin-right:auto;padding-left:1rem;padding-right:1rem}\n</style>\n</head>\n<body class=\"bg-surface text-on-surface\">\n${body}\n${showBranding ? `<div style=\"text-align:center;padding:16px 0 12px;font-size:12px\">\n <a href=\"https://easybits.cloud\" target=\"_blank\" rel=\"noopener\"\n style=\"color:#9ca3af;text-decoration:none\">\n Powered by easybits.cloud\n </a>\n</div>` : \"\"}\n</body>\n</html>`;\n}\n"],"mappings":";AAiBO,IAAM,iBAAiC;AAAA,EAC5C;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe;AAAA,MACf,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe;AAAA,MACf,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe;AAAA,MACf,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe;AAAA,MACf,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe;AAAA,MACf,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,eAAe;AAAA,MACf,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,cAAc;AAAA,IAChB;AAAA,EACF;AACF;AASA,SAAS,SAAS,KAAa;AAC7B,SAAO;AAAA,IACL,GAAG,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC/B,GAAG,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IAC/B,GAAG,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,EACjC;AACF;AAEA,SAAS,MAAM,GAAW,GAAW,GAAW;AAC9C,SAAO,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AACvG;AAEA,SAAS,UAAU,KAAa;AAC9B,QAAM,EAAE,GAAG,GAAG,EAAE,IAAI,SAAS,GAAG;AAChC,UAAQ,QAAQ,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAC/C;AAEA,SAAS,QAAQ,KAAa,SAAS,IAAI;AACzC,QAAM,EAAE,GAAG,GAAG,EAAE,IAAI,SAAS,GAAG;AAChC,SAAO,MAAM,IAAI,QAAQ,IAAI,QAAQ,IAAI,MAAM;AACjD;AAEA,SAAS,OAAO,KAAa,SAAS,IAAI;AACxC,QAAM,EAAE,GAAG,GAAG,EAAE,IAAI,SAAS,GAAG;AAChC,SAAO,MAAM,IAAI,QAAQ,IAAI,QAAQ,IAAI,MAAM;AACjD;AAEO,SAAS,iBAAiB,QAAoC;AACnE,QAAM,EAAE,SAAS,YAAY,WAAW,SAAS,WAAW,UAAU,UAAU,IAAI;AAEpF,QAAM,YAAY,UAAU,OAAO,IAAI,MAAM,YAAY;AACzD,QAAM,aAAa,UAAU,OAAO;AACpC,QAAM,gBAAgB,aAAa;AAEnC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ;AAAA,MACN;AAAA,MACA,iBAAiB,QAAQ,OAAO;AAAA,MAChC,gBAAgB,OAAO,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe,gBAAgB,QAAQ,SAAS,EAAE,IAAI,OAAO,SAAS,CAAC;AAAA,MACvE,cAAc,gBAAgB,YAAY;AAAA,MAC1C,oBAAoB,gBAAgB,YAAY;AAAA,MAChD,cAAc;AAAA,IAChB;AAAA,EACF;AACF;AAEO,SAAS,oBAAoB,QAA8B;AAChE,QAAM,QAAQ,iBAAiB,MAAM;AACrC,SAAO;AAAA,EAA4B,aAAa,MAAM,MAAM,CAAC;AAAA;AAC/D;AAGA,SAAS,aAAa,QAAwC;AAC5D,SAAO,OAAO,QAAQ,MAAM,EACzB,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,EACvC,KAAK,IAAI;AACd;AAGA,SAAS,sBAA8B;AACrC,QAAM,eAAe,OAAO,KAAK,eAAe,CAAC,EAAE,MAAM,EACtD,IAAI,CAAC,MAAM,cAAc,CAAC,mBAAmB,CAAC,IAAI,EAClD,KAAK,KAAK;AAEb,SAAO;AAAA;AAAA;AAAA;AAAA,EAIP,YAAY;AAAA;AAAA;AAAA;AAAA;AAKd;AAEO,SAAS,gBAAyD;AACvE,QAAM,eAAe,eAAe,CAAC;AAErC,QAAM,YAAY,eAAe,MAAM,CAAC,EACrC,IAAI,CAAC,MAAM,gBAAgB,EAAE,EAAE;AAAA,EAAS,aAAa,EAAE,MAAM,CAAC;AAAA,EAAK,EACnE,KAAK,MAAM;AAEd,QAAM,MAAM;AAAA,EAAY,aAAa,aAAa,MAAM,CAAC;AAAA;AAAA;AAAA,EAAU,SAAS;AAC5E,SAAO,EAAE,KAAK,gBAAgB,oBAAoB,EAAE;AACtD;AAEO,SAAS,oBAAoB,SAA0D;AAC5F,QAAM,QAAQ,eAAe,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,KAAK,eAAe,CAAC;AAC9E,QAAM,MAAM;AAAA,EAAY,aAAa,MAAM,MAAM,CAAC;AAAA;AAClD,SAAO,EAAE,KAAK,gBAAgB,oBAAoB,EAAE;AACtD;;;ACrNO,SAAS,kBAA0B;AACxC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyQT;;;ACzQO,SAAS,iBAAiB,UAAsB,OAAwB;AAC7E,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC7D,QAAM,OAAO,OACV,IAAI,CAAC,MAAM,yBAAyB,EAAE,EAAE,KAAK,EAAE,IAAI,QAAQ,EAC3D,KAAK,IAAI;AAEZ,QAAM,YAAY,SAAS,UAAU,YAAY,gBAAgB,KAAK,MAAM;AAC5E,QAAM,EAAE,KAAK,eAAe,IAAI,cAAc;AAE9C,SAAO;AAAA,iBACQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAME,cAAc;AAAA;AAAA,EAExC,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWH,IAAI;AAAA,UACI,gBAAgB,CAAC;AAAA;AAAA;AAG3B;AAQA,SAAS,qBAAqB,MAAsB;AAClD,SAAO,KACJ,QAAQ,4BAA4B,EAAE,EACtC,QAAQ,mCAAmC,EAAE,EAC7C,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,gCAAgC,EAAE,EAC1C,QAAQ,gCAAgC,EAAE;AAC/C;AAEO,SAAS,gBAAgB,UAAsB,OAAgB,cAA6B,eAAe,MAAc;AAC9H,QAAM,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC7D,QAAM,OAAO,OAAO,IAAI,CAAC,MAAM,qBAAqB,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI;AAEtE,QAAM,WAAW,UAAU,YAAY;AACvC,QAAM,YAAY,SAAS,UAAU,aAAa,CAAC,WAAW,gBAAgB,KAAK,MAAM;AAGzF,QAAM,EAAE,KAAK,SAAS,eAAe,IAAI,YACpC,MAAM;AACL,UAAM,KAAK,iBAAiB,YAAY;AACxC,UAAM,OAAO,OAAO,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,IAAI;AACzF,WAAO,EAAE,KAAK;AAAA,EAAY,IAAI;AAAA,IAAO,gBAAgB,oBAAoB,SAAS,EAAE,eAAe;AAAA,EACrG,GAAG,IACH,oBAAoB,SAAS,SAAS;AAE1C,SAAO;AAAA,iBACQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAME,cAAc;AAAA;AAAA,EAExC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASP,IAAI;AAAA,EACJ,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA,UAKP,EAAE;AAAA;AAAA;AAGZ;","names":[]}