@emabuild/core 0.4.0 → 0.4.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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-2S5kBS5_.js","sources":["../src/utils/store-controller.ts","../src/sidebar/a11y-checker.ts","../src/utils/id-generator.ts","../src/utils/event-emitter.ts","../src/state/history-manager.ts","../src/state/design-factory.ts","../src/state/design-lookup.ts","../src/state/editor-store.ts","../src/tools/tool-registry.ts","../src/dnd/drag-state.ts","../src/dnd/drop-indicator.ts","../src/dnd/shadow-dom-utils.ts","../src/dnd/drag-manager.ts","../src/tools/helpers/value-extractor.ts","../src/tools/helpers/email-html.ts","../src/tools/built-in/shared-options.ts","../src/tools/built-in/text-tool.ts","../src/tools/built-in/heading-tool.ts","../src/tools/built-in/paragraph-tool.ts","../src/tools/built-in/image-tool.ts","../src/tools/built-in/button-tool.ts","../src/tools/built-in/divider-tool.ts","../src/tools/built-in/tool-manifest.ts","../../email-renderer/dist/index.js","../src/compat/unlayer-adapter.ts","../src/canvas/inline-toolbar.ts","../src/canvas/content-renderer.ts","../src/canvas/column-renderer.ts","../src/canvas/row-renderer.ts","../src/canvas/editor-canvas.ts","../src/sidebar/body-settings.ts","../src/sidebar/editor-sidebar.ts","../src/properties/widgets/color-picker-widget.ts","../src/properties/widgets/dropdown-widget.ts","../src/properties/widgets/alignment-widget.ts","../src/properties/widgets/padding-widget.ts","../src/properties/widgets/toggle-widget.ts","../src/properties/widgets/text-input-widget.ts","../src/properties/widgets/textarea-widget.ts","../src/properties/widgets/number-unit-widget.ts","../src/properties/widgets/image-upload-widget.ts","../src/properties/property-panel.ts","../src/mail-editor.ts","../src/register-elements.ts"],"sourcesContent":["/**\n * @module StoreController\n *\n * Lit reactive controller that subscribes to specific store channels.\n * Replaces the blanket StoreSubscriber mixin which re-rendered on ALL changes.\n *\n * @example\n * ```ts\n * class MyComponent extends LitElement {\n * private storeCtrl = new StoreController(this, ['design']);\n *\n * set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n * get store() { return this.storeCtrl.store!; }\n * }\n * ```\n */\n\nimport type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport type { EditorStore, StoreChannel } from '../state/editor-store.js';\n\nexport class StoreController implements ReactiveController {\n private host: ReactiveControllerHost;\n private channels: StoreChannel[];\n private unsub?: () => void;\n store: EditorStore | null = null;\n\n /**\n * @param host - The Lit component that owns this controller\n * @param channels - Which store channels to subscribe to\n */\n constructor(host: ReactiveControllerHost, channels: StoreChannel[]) {\n this.host = host;\n this.channels = channels;\n host.addController(this);\n }\n\n /** Set or change the store reference. Re-subscribes automatically. */\n setStore(store: EditorStore): void {\n if (this.store === store) return;\n this.unsub?.();\n this.store = store;\n this.subscribe();\n }\n\n hostConnected(): void {\n this.subscribe();\n }\n\n hostDisconnected(): void {\n this.unsub?.();\n this.unsub = undefined;\n }\n\n private subscribe(): void {\n if (!this.store) return;\n this.unsub = this.store.subscribeChannels(this.channels, () => {\n this.host.requestUpdate();\n });\n }\n}\n","/**\n * @module A11yChecker\n *\n * Accessibility checker panel that analyzes the current email design\n * for WCAG 2.1 AA compliance. Checks performed:\n *\n * - Color contrast (text, buttons, links) — WCAG 1.4.3\n * - Image alt text — WCAG 1.1.1\n * - Empty links / buttons — WCAG 2.4.4\n * - Heading hierarchy — WCAG 1.3.1\n * - Font size minimums — WCAG 1.4.4\n * - Touch target size — WCAG 2.5.5\n * - Language / preheader — best practices\n * - Text alignment readability\n * - Line height / letter spacing — WCAG 1.4.12\n */\n\nimport { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry } from '../tools/tool-registry.js';\nimport { StoreController } from '../utils/store-controller.js';\n\nexport interface A11yIssue {\n severity: 'error' | 'warning' | 'info';\n rule: string;\n message: string;\n element?: string;\n elementId?: string;\n}\n\n// ── Color utilities ──────────────────────────────────────────\n\nfunction parseColor(color: string): { r: number; g: number; b: number } | null {\n if (!color || color === 'transparent' || color === '' || color === 'none') return null;\n const s = color.trim().toLowerCase();\n\n // Named colors (common ones used in email)\n const named: Record<string, string> = {\n white: '#ffffff', black: '#000000', red: '#ff0000', blue: '#0000ff',\n green: '#008000', yellow: '#ffff00', gray: '#808080', grey: '#808080',\n };\n if (named[s]) return parseColor(named[s]);\n\n if (s.startsWith('#')) {\n let h = s.slice(1);\n if (h.length === 3) h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n if (h.length !== 6) return null;\n const n = parseInt(h, 16);\n if (isNaN(n)) return null;\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\n }\n\n const m = s.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)/);\n if (m) return { r: +m[1], g: +m[2], b: +m[3] };\n\n return null;\n}\n\nfunction luminance(r: number, g: number, b: number): number {\n const [rs, gs, bs] = [r, g, b].map((c) => {\n const v = c / 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\nfunction contrastRatio(fg: string, bg: string): number | null {\n const c1 = parseColor(fg);\n const c2 = parseColor(bg);\n if (!c1 || !c2) return null;\n const l1 = luminance(c1.r, c1.g, c1.b);\n const l2 = luminance(c2.r, c2.g, c2.b);\n return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);\n}\n\n/** Check if a color string is a real, parseable color (not empty/transparent) */\nfunction isRealColor(c: unknown): c is string {\n if (typeof c !== 'string') return false;\n const s = c.trim().toLowerCase();\n return s !== '' && s !== 'transparent' && s !== 'none' && s !== 'inherit';\n}\n\n/** Resolve effective background from a chain of values, skipping transparent/empty */\nfunction resolveBackground(...colors: unknown[]): string {\n for (const c of colors) {\n if (isRealColor(c)) return c;\n }\n return '#ffffff';\n}\n\nfunction parsePx(value: unknown, fallback = 0): number {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') return parseInt(value, 10) || fallback;\n return fallback;\n}\n\nfunction parseLineHeight(value: unknown): number | null {\n if (!value || value === '') return null;\n const s = String(value);\n if (s.endsWith('%')) return parseFloat(s) / 100;\n const n = parseFloat(s);\n return isNaN(n) ? null : (n > 5 ? n / 100 : n); // handle \"140%\" as 1.4\n}\n\n// ── Component ────────────────────────────────────────────────\n\n@customElement('me-a11y-checker')\nexport class A11yChecker extends LitElement {\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n\n .summary {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-bottom: 12px;\n }\n .score-pill {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 20px;\n font-size: 11px;\n font-weight: 600;\n }\n .score-pill.errors { background: #fef2f2; color: #dc2626; border: 1px solid #fecaca; }\n .score-pill.warnings { background: #fffbeb; color: #d97706; border: 1px solid #fde68a; }\n .score-pill.infos { background: #EDF5FF; color: #245A7F; border: 1px solid #bfdbfe; }\n .score-pill.pass { background: #f0fdf4; color: #16a34a; border: 1px solid #bbf7d0; }\n .score-dot { width: 6px; height: 6px; border-radius: 50%; }\n .score-dot.error { background: #dc2626; }\n .score-dot.warning { background: #d97706; }\n .score-dot.info { background: #245A7F; }\n .score-dot.pass { background: #16a34a; }\n\n .section-title {\n font-size: 10px; font-weight: 700; text-transform: uppercase;\n letter-spacing: 0.06em; color: #245A7F;\n padding: 6px 0 4px; margin-top: 8px;\n border-bottom: 1px solid #EDF5FF;\n }\n .section-title:first-of-type { margin-top: 0; }\n\n .issues-list {\n display: flex;\n flex-direction: column;\n gap: 3px;\n margin-top: 6px;\n }\n .issue {\n display: flex;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n border: 1px solid #f3f4f6;\n transition: all 150ms ease;\n cursor: pointer;\n }\n .issue:hover { background: #f9fafb; border-color: #e5e7eb; }\n .issue.error { border-left: 3px solid #dc2626; }\n .issue.warning { border-left: 3px solid #d97706; }\n .issue.info { border-left: 3px solid #5d768b; }\n .issue-icon {\n flex-shrink: 0;\n width: 16px; height: 16px;\n display: flex; align-items: center; justify-content: center;\n font-size: 10px; font-weight: 700;\n border-radius: 50%;\n margin-top: 1px;\n }\n .issue-icon.error { background: #fef2f2; color: #dc2626; }\n .issue-icon.warning { background: #fffbeb; color: #d97706; }\n .issue-icon.info { background: #EDF5FF; color: #245A7F; }\n .issue-body { flex: 1; min-width: 0; }\n .issue-rule {\n font-size: 9px; font-weight: 600; text-transform: uppercase;\n letter-spacing: 0.04em; color: #9ca3af;\n }\n .issue-msg { font-size: 11px; color: #374151; line-height: 1.4; margin-top: 1px; }\n .issue-element {\n font-size: 10px; color: #5d768b; margin-top: 2px;\n cursor: pointer;\n }\n .issue-element:hover { text-decoration: underline; }\n .issue-fix {\n display: inline-flex; align-items: center; gap: 3px;\n margin-top: 4px; padding: 2px 8px;\n background: #f0fdf4; color: #16a34a; border: 1px solid #bbf7d0;\n border-radius: 4px; font-size: 10px; font-weight: 600;\n cursor: pointer; transition: all 150ms ease;\n }\n .issue-fix:hover { background: #dcfce7; border-color: #86efac; }\n\n .all-clear {\n text-align: center;\n padding: 24px 16px;\n }\n .all-clear-icon {\n width: 36px; height: 36px; border-radius: 50%;\n background: #f0fdf4; margin: 0 auto 8px;\n display: flex; align-items: center; justify-content: center;\n font-size: 18px; color: #16a34a;\n }\n .all-clear-text { font-size: 12px; font-weight: 600; color: #16a34a; }\n .all-clear-sub { font-size: 11px; color: #9ca3af; margin-top: 4px; }\n `;\n\n private storeCtrl = new StoreController(this, ['design']);\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n @property({ attribute: false }) toolRegistry!: ToolRegistry;\n\n private checkAccessibility(): A11yIssue[] {\n return checkA11y(this.store);\n }\n\n private handleIssueClick(elementId?: string) {\n if (elementId) this.store.select(elementId);\n }\n\n private handleIssueHover(elementId?: string) {\n this.store.hover(elementId ?? null);\n }\n\n private handleFixPreheader(e: Event) {\n e.stopPropagation();\n // Switch to Body tab\n this.store.setActiveTab('body');\n // Wait for render, then highlight preheader field\n requestAnimationFrame(() => {\n setTimeout(() => {\n const sidebar = document.querySelector('mail-editor')?.shadowRoot?.querySelector('me-editor-sidebar');\n const bodySettings = sidebar?.shadowRoot?.querySelector('me-body-settings') as any;\n bodySettings?.highlightPreheader?.();\n }, 100);\n });\n }\n\n private handleFixHeading(e: Event) {\n e.stopPropagation();\n const row = this.store.createRow([1]);\n const addedRow = this.store.addRow(row, 0);\n const colId = addedRow.columns[0].id;\n const defaults = this.toolRegistry.getDefaultValues('heading');\n const content = this.store.createContent('heading', defaults);\n this.store.addContent(colId, content);\n this.store.select(content.id);\n }\n\n render() {\n const issues = this.checkAccessibility();\n const errors = issues.filter((i) => i.severity === 'error');\n const warnings = issues.filter((i) => i.severity === 'warning');\n const infos = issues.filter((i) => i.severity === 'info');\n\n return html`\n <div class=\"summary\">\n ${errors.length > 0\n ? html`<span class=\"score-pill errors\"><span class=\"score-dot error\"></span>${errors.length}</span>`\n : nothing}\n ${warnings.length > 0\n ? html`<span class=\"score-pill warnings\"><span class=\"score-dot warning\"></span>${warnings.length}</span>`\n : nothing}\n ${infos.length > 0\n ? html`<span class=\"score-pill infos\"><span class=\"score-dot info\"></span>${infos.length}</span>`\n : nothing}\n ${errors.length === 0 && warnings.length === 0\n ? html`<span class=\"score-pill pass\"><span class=\"score-dot pass\"></span>Pass</span>`\n : nothing}\n </div>\n\n ${issues.length === 0 ? html`\n <div class=\"all-clear\">\n <div class=\"all-clear-icon\">✓</div>\n <div class=\"all-clear-text\">Accessible</div>\n <div class=\"all-clear-sub\">No issues detected</div>\n </div>\n ` : html`\n ${errors.length > 0 ? html`\n <div class=\"section-title\">Errors</div>\n <div class=\"issues-list\">${errors.map((i) => this.renderIssue(i))}</div>\n ` : nothing}\n ${warnings.length > 0 ? html`\n <div class=\"section-title\">Warnings</div>\n <div class=\"issues-list\">${warnings.map((i) => this.renderIssue(i))}</div>\n ` : nothing}\n ${infos.length > 0 ? html`\n <div class=\"section-title\">Info</div>\n <div class=\"issues-list\">${infos.map((i) => this.renderIssue(i))}</div>\n ` : nothing}\n `}\n `;\n }\n\n private renderIssue(issue: A11yIssue) {\n return html`\n <div class=\"issue ${issue.severity}\"\n @click=${() => this.handleIssueClick(issue.elementId)}\n @mouseenter=${() => this.handleIssueHover(issue.elementId)}\n @mouseleave=${() => this.handleIssueHover(undefined)}>\n <div class=\"issue-icon ${issue.severity}\">\n ${issue.severity === 'error' ? '✕' : issue.severity === 'warning' ? '!' : 'i'}\n </div>\n <div class=\"issue-body\">\n <div class=\"issue-rule\">${issue.rule}</div>\n <div class=\"issue-msg\">${issue.message}</div>\n ${issue.element ? html`<div class=\"issue-element\">${issue.element}</div>` : nothing}\n ${issue.rule === 'heading-structure' ? html`<button class=\"issue-fix\" @click=${this.handleFixHeading}>+ Add heading</button>` : nothing}\n ${issue.rule === 'preheader' ? html`<button class=\"issue-fix\" @click=${this.handleFixPreheader}>Fix</button>` : nothing}\n </div>\n </div>\n `;\n }\n}\n\n/** Standalone a11y check — used by both the A11yChecker component and the sidebar tab badge */\nexport function checkA11y(store: EditorStore): A11yIssue[] {\n const issues: A11yIssue[] = [];\n const design = store.getDesign();\n const bodyValues = store.getBodyValues();\n const bodyBg = (bodyValues.backgroundColor as string) || '#ffffff';\n const bodyTextColor = (bodyValues.textColor as string) || '#000000';\n\n let hasHeading = false;\n const headingTypes: string[] = [];\n\n for (const row of design.body.rows) {\n const rowBg = (row.values.backgroundColor as string) || '';\n const colsBg = (row.values.columnsBackgroundColor as string) || '';\n\n for (const col of row.columns) {\n const effectiveBg = resolveBackground(col.values.backgroundColor, colsBg, rowBg, bodyBg);\n\n for (const content of col.contents) {\n const v = content.values;\n const type = content.type;\n const label = `${type} #${content.id.split('_').pop()}`;\n\n if (type === 'image') {\n const alt = (v.alt as string) || '';\n const src = (v.src as string) || '';\n if (src && !alt.trim()) {\n issues.push({ severity: 'error', rule: 'img-alt', message: 'Missing alt text.', element: label, elementId: content.id });\n } else if (alt && alt.length > 125) {\n issues.push({ severity: 'warning', rule: 'img-alt-length', message: `Alt text ${alt.length} chars (max 125).`, element: label, elementId: content.id });\n }\n }\n\n if (type === 'text' || type === 'heading' || type === 'paragraph') {\n const textColor = isRealColor(v.color) ? v.color : bodyTextColor;\n const bg = resolveBackground(v.backgroundColor, effectiveBg);\n const ratio = contrastRatio(textColor, bg);\n if (ratio !== null) {\n const fontSize = parsePx(v.fontSize, 14);\n const isBold = ['700', '800', '900'].includes((v.fontWeight as string) || '');\n const isLarge = fontSize >= 18 || (fontSize >= 14 && isBold);\n const min = isLarge ? 3 : 4.5;\n if (ratio < min) {\n issues.push({ severity: ratio < 3 ? 'error' : 'warning', rule: 'color-contrast', message: `Ratio ${ratio.toFixed(1)}:1 (min ${min}:1). \"${textColor}\" on \"${bg}\".`, element: label, elementId: content.id });\n }\n }\n const fs = parsePx(v.fontSize, 14);\n if (type !== 'heading' && fs > 0 && fs < 12) {\n issues.push({ severity: 'warning', rule: 'font-size', message: `Font size ${fs}px below 12px minimum.`, element: label, elementId: content.id });\n }\n const lh = parseLineHeight(v.lineHeight);\n if (lh !== null && lh < 1.2 && type !== 'heading') {\n issues.push({ severity: 'warning', rule: 'line-height', message: `Line height ${String(v.lineHeight)} too tight (min 1.5x).`, element: label, elementId: content.id });\n }\n if ((v.textAlign as string) === 'justify') {\n issues.push({ severity: 'warning', rule: 'text-justify', message: 'Justified text reduces readability.', element: label, elementId: content.id });\n }\n }\n\n if (type === 'button') {\n const btnBg = (v.backgroundColor as string) || '#3b82f6';\n const btnText = (v.textColor as string) || '#ffffff';\n const ratio = contrastRatio(btnText, btnBg);\n if (ratio !== null && ratio < 4.5) {\n issues.push({ severity: ratio < 3 ? 'error' : 'warning', rule: 'color-contrast', message: `Button contrast ${ratio.toFixed(1)}:1 (min 4.5:1).`, element: label, elementId: content.id });\n }\n const btnRowRatio = contrastRatio(btnBg, effectiveBg);\n if (btnRowRatio !== null && btnRowRatio < 3) {\n issues.push({ severity: 'warning', rule: 'btn-visibility', message: `Button blends with background (${btnRowRatio.toFixed(1)}:1).`, element: label, elementId: content.id });\n }\n if (!((v.text as string) || '').trim()) {\n issues.push({ severity: 'error', rule: 'link-text', message: 'Button has no visible text.', element: label, elementId: content.id });\n }\n const padParts = ((v.buttonPadding as string) || '10px 20px').split(/\\s+/);\n const estH = parsePx(v.fontSize, 14) + parsePx(padParts[0], 10) * 2;\n if (estH < 44) {\n issues.push({ severity: 'info', rule: 'touch-target', message: `Button height ~${estH}px (min 44px).`, element: label, elementId: content.id });\n }\n }\n\n if (type === 'heading') { hasHeading = true; headingTypes.push((v.headingType as string) || 'h1'); }\n\n if (type === 'text' || type === 'paragraph') {\n const txt = (v.text as string) || '';\n const empty = txt.match(/<a[^>]*>(\\s|&nbsp;)*<\\/a>/gi);\n if (empty) issues.push({ severity: 'error', rule: 'link-text', message: `${empty.length} empty link(s).`, element: label, elementId: content.id });\n const generic = txt.match(/<a[^>]*>(click here|here|link|read more)<\\/a>/gi);\n if (generic) issues.push({ severity: 'warning', rule: 'link-purpose', message: `${generic.length} generic link text(s).`, element: label, elementId: content.id });\n }\n\n if (type === 'social') {\n issues.push({ severity: 'info', rule: 'social-alt', message: 'Verify social icons have alt text.', element: label, elementId: content.id });\n }\n }\n }\n }\n\n const totalContent = design.body.rows.reduce((s, r) => s + r.columns.reduce((a, c) => a + c.contents.length, 0), 0);\n if (totalContent > 0 && !hasHeading) issues.push({ severity: 'warning', rule: 'heading-structure', message: 'No heading in email.' });\n\n if (headingTypes.length > 1) {\n const lvls = headingTypes.map((h) => parseInt(h.replace('h', ''), 10)).filter((n) => !isNaN(n));\n for (let i = 1; i < lvls.length; i++) {\n if (lvls[i] > lvls[i - 1] + 1) { issues.push({ severity: 'warning', rule: 'heading-skip', message: `Heading jumps h${lvls[i - 1]} → h${lvls[i]}.` }); break; }\n }\n }\n\n const bodyRatio = contrastRatio(bodyTextColor, bodyBg);\n if (bodyRatio !== null && bodyRatio < 4.5) issues.push({ severity: 'warning', rule: 'color-contrast', message: `Body text contrast ${bodyRatio.toFixed(1)}:1 (min 4.5:1).` });\n\n const linkColor = (bodyValues.linkStyle as any)?.linkColor;\n if (linkColor) {\n const lr = contrastRatio(linkColor, bodyBg);\n if (lr !== null && lr < 4.5) issues.push({ severity: 'warning', rule: 'link-contrast', message: `Link contrast ${lr.toFixed(1)}:1 (min 4.5:1).` });\n const lvt = contrastRatio(linkColor, bodyTextColor);\n if (lvt !== null && lvt < 3 && !(bodyValues.linkStyle as any)?.linkUnderline) {\n issues.push({ severity: 'warning', rule: 'link-distinguish', message: 'Links not underlined and low contrast vs text.' });\n }\n }\n\n if (!((bodyValues.preheaderText as string) || '').trim()) issues.push({ severity: 'info', rule: 'preheader', message: 'No preheader text set.' });\n if (totalContent === 0) issues.push({ severity: 'info', rule: 'empty-email', message: 'Email has no content.' });\n\n issues.sort((a, b) => ({ error: 0, warning: 1, info: 2 }[a.severity] - { error: 0, warning: 1, info: 2 }[b.severity]));\n return issues;\n}\n","/**\n * Unique ID generator and counter manager.\n *\n * The counter manager tracks incrementing IDs per prefix\n * (e.g. `u_row`, `u_column`, `u_content_text`) to match\n * email editor's `counters` field in the design JSON.\n */\n\nlet instanceCounter = 0;\n\n/** Generate a unique ID for internal use (not email editor-compatible) */\nexport function generateId(): string {\n return `me_${Date.now().toString(36)}_${(instanceCounter++).toString(36)}`;\n}\n\n/** Counter manager return type */\nexport interface CounterManager {\n /** Get a snapshot of all current counters */\n getCounters(): Record<string, number>;\n /** Replace all counters (used when loading a design) */\n setCounters(counters: Record<string, number>): void;\n /** Increment and return the next value for a given prefix */\n next(prefix: string): number;\n}\n\n/** Create an counter manager for ID generation */\nexport function createCounterManager(): CounterManager {\n const counters: Record<string, number> = {};\n\n return {\n getCounters(): Record<string, number> {\n return { ...counters };\n },\n\n setCounters(c: Record<string, number>): void {\n for (const key of Object.keys(counters)) {\n delete counters[key];\n }\n Object.assign(counters, c);\n },\n\n next(prefix: string): number {\n const current = counters[prefix] ?? 0;\n counters[prefix] = current + 1;\n return counters[prefix];\n },\n };\n}\n","/**\n * Type-safe event emitter with error isolation.\n *\n * Each listener is wrapped in a try/catch so a failing listener\n * doesn't break other listeners or the emitting code.\n */\n\n/** Map of event names to their payload types */\nexport interface EditorEventMap {\n 'design:loaded': { design: unknown };\n 'design:updated': { type: string; item?: unknown; changes?: unknown };\n 'editor:ready': void;\n 'image:uploaded': { url: string; width?: number; height?: number };\n}\n\ntype EventName = keyof EditorEventMap | (string & {});\ntype Listener<T = unknown> = (payload: T) => void;\n\nexport class EventEmitter {\n private listeners = new Map<string, Set<Listener>>();\n\n /** Register a listener for an event */\n on<K extends EventName>(event: K, listener: Listener<K extends keyof EditorEventMap ? EditorEventMap[K] : unknown>): void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n this.listeners.get(event)!.add(listener as Listener);\n }\n\n /** Remove a specific listener */\n off<K extends EventName>(event: K, listener: Listener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n /** Emit an event with a payload. Errors in listeners are caught and logged. */\n emit<K extends EventName>(event: K, payload?: K extends keyof EditorEventMap ? EditorEventMap[K] : unknown): void {\n this.listeners.get(event)?.forEach((fn) => {\n try {\n fn(payload);\n } catch (e) {\n console.error(`[emabuild] Error in \"${event}\" listener:`, e);\n }\n });\n }\n\n /** Remove all listeners, optionally scoped to a single event */\n removeAllListeners(event?: string): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n","/**\n * Undo/redo history manager with configurable stack depth.\n *\n * Stores immutable snapshots of the design state using `structuredClone`.\n * Each push creates a new entry and clears the redo stack.\n */\n\nimport type { EmailDesign } from '@emabuild/types';\n\nexport class HistoryManager {\n private undoStack: EmailDesign[] = [];\n private redoStack: EmailDesign[] = [];\n private readonly maxHistory: number;\n\n constructor(maxHistory = 50) {\n this.maxHistory = maxHistory;\n }\n\n /** Whether there are states to undo to */\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n /** Whether there are states to redo to */\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n /** Save current design to the undo stack before a mutation */\n push(design: EmailDesign): void {\n this.undoStack.push(structuredClone(design));\n if (this.undoStack.length > this.maxHistory) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n }\n\n /** Restore the previous state, pushing current state to redo. Returns the restored design or undefined. */\n undo(currentDesign: EmailDesign): EmailDesign | undefined {\n const prev = this.undoStack.pop();\n if (!prev) return undefined;\n this.redoStack.push(structuredClone(currentDesign));\n return structuredClone(prev);\n }\n\n /** Restore the next state, pushing current state to undo. Returns the restored design or undefined. */\n redo(currentDesign: EmailDesign): EmailDesign | undefined {\n const next = this.redoStack.pop();\n if (!next) return undefined;\n this.undoStack.push(structuredClone(currentDesign));\n return structuredClone(next);\n }\n\n /** Clear all history (e.g. when loading a new design) */\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n }\n}\n","/**\n * Factory functions for creating design entities.\n *\n * All functions produce properly structured objects matching\n * the design JSON schema with correct `_meta` fields.\n */\n\nimport type { EmailDesign, DesignRow, DesignContent } from '@emabuild/types';\nimport type { CounterManager } from '../utils/id-generator.js';\n\n/** Create a blank design */\nexport function createEmptyDesign(): EmailDesign {\n return {\n counters: { u_row: 0, u_column: 0 },\n body: {\n id: 'u_body',\n rows: [],\n headers: [],\n footers: [],\n values: {\n backgroundColor: '#e7e7e7',\n contentAlign: 'center',\n contentVerticalAlign: 'center',\n contentWidth: '600px',\n fontFamily: { label: 'Arial', value: 'arial,helvetica,sans-serif' },\n textColor: '#000000',\n linkStyle: {\n body: true,\n linkColor: '#0000ee',\n linkHoverColor: '#0000ee',\n linkUnderline: true,\n linkHoverUnderline: true,\n },\n preheaderText: '',\n popupPosition: 'center',\n popupWidth: '600px',\n popupHeight: 'auto',\n borderRadius: '10px',\n popupBackgroundColor: '#FFFFFF',\n popupBackgroundImage: { url: '', fullWidth: true, repeat: 'no-repeat', center: true, cover: true },\n popupOverlay_backgroundColor: 'rgba(0, 0, 0, 0.1)',\n popupCloseButton_position: 'top-right',\n popupCloseButton_backgroundColor: '#DDDDDD',\n popupCloseButton_iconColor: '#000000',\n popupCloseButton_borderRadius: '0px',\n popupCloseButton_margin: '0px',\n popupCloseButton_action: {\n name: 'close_popup',\n attrs: { onClick: \"document.querySelector('.u-popup-container').style.display = 'none';\" },\n },\n _meta: { htmlID: 'u_body', htmlClassNames: 'u_body' },\n },\n },\n schemaVersion: 16,\n };\n}\n\n/** Create a new row with the given column proportions (e.g. [1,1] for 50/50) */\nexport function createRow(cm: CounterManager, cellProportions: number[]): DesignRow {\n const rowNum = cm.next('u_row');\n\n const columns = cellProportions.map(() => {\n const colNum = cm.next('u_column');\n return {\n id: `u_column_${colNum}`,\n contents: [],\n values: {\n backgroundColor: '',\n padding: '0px',\n border: {},\n borderRadius: '0px',\n _meta: { htmlID: `u_column_${colNum}`, htmlClassNames: 'u_column' },\n },\n };\n });\n\n return {\n id: `u_row_${rowNum}`,\n cells: cellProportions,\n columns,\n values: {\n displayCondition: null,\n columns: false,\n backgroundColor: '',\n columnsBackgroundColor: '',\n backgroundImage: { url: '', fullWidth: true, repeat: false, center: true, cover: false },\n padding: '0px',\n anchor: '',\n hideDesktop: false,\n hideMobile: false,\n _meta: { htmlID: `u_row_${rowNum}`, htmlClassNames: 'u_row' },\n },\n };\n}\n\n/** Create a new content block for the given tool type */\nexport function createContent(cm: CounterManager, type: string, values: Record<string, unknown> = {}): DesignContent {\n const counter = cm.next(`u_content_${type}`);\n const id = `u_content_${type}_${counter}`;\n\n return {\n id,\n type,\n values: {\n containerPadding: '10px',\n anchor: '',\n hideDesktop: false,\n hideMobile: false,\n displayCondition: null,\n _meta: { htmlID: id, htmlClassNames: `u_content_${type}` },\n ...values,\n },\n };\n}\n","/**\n * Pure lookup functions for traversing the design tree.\n *\n * All functions are stateless — they take the design (or body rows)\n * as input and return references to the matching nodes.\n */\n\nimport type { EmailDesign, DesignRow, DesignColumn, DesignContent } from '@emabuild/types';\n\n/** Find a row by ID */\nexport function findRow(design: EmailDesign, rowId: string): DesignRow | undefined {\n return design.body.rows.find((r) => r.id === rowId);\n}\n\n/** Find a column by ID across all rows */\nexport function findColumn(design: EmailDesign, columnId: string): DesignColumn | undefined {\n for (const row of design.body.rows) {\n const col = row.columns.find((c) => c.id === columnId);\n if (col) return col;\n }\n return undefined;\n}\n\n/** Find a content block by ID across all rows and columns */\nexport function findContent(design: EmailDesign, contentId: string): DesignContent | undefined {\n for (const row of design.body.rows) {\n for (const col of row.columns) {\n const content = col.contents.find((c) => c.id === contentId);\n if (content) return content;\n }\n }\n return undefined;\n}\n\n/** Find the column that contains a given content block */\nexport function findParentColumn(design: EmailDesign, contentId: string): DesignColumn | undefined {\n for (const row of design.body.rows) {\n for (const col of row.columns) {\n if (col.contents.some((c) => c.id === contentId)) return col;\n }\n }\n return undefined;\n}\n\n/** Find the row that contains a given column */\nexport function findParentRow(design: EmailDesign, columnId: string): DesignRow | undefined {\n for (const row of design.body.rows) {\n if (row.columns.some((c) => c.id === columnId)) return row;\n }\n return undefined;\n}\n\n/** Get the index of a row within the design */\nexport function getRowIndex(design: EmailDesign, rowId: string): number {\n return design.body.rows.findIndex((r) => r.id === rowId);\n}\n","/**\n * @module EditorStore\n *\n * Central state management for the mail editor.\n * Orchestrates design mutations, selection, history, and event emission.\n * Delegates to HistoryManager, design-lookup, and design-factory for specifics.\n *\n * @example\n * ```ts\n * const store = new EditorStore();\n * store.loadDesign(myDesign);\n * store.subscribeChannels(['design'], () => console.log('design changed'));\n * store.addRow(store.createRow([1, 1]));\n * ```\n */\n\nimport type {\n EmailDesign,\n DesignBody,\n DesignRow,\n DesignColumn,\n DesignContent,\n BodyValues,\n RowValues,\n ColumnValues,\n ContentValues,\n DesignUpdatedEvent,\n MergeTagGroup,\n} from '@emabuild/types';\nimport { createCounterManager, type CounterManager } from '../utils/id-generator.js';\nimport { EventEmitter } from '../utils/event-emitter.js';\nimport { HistoryManager } from './history-manager.js';\nimport { createEmptyDesign, createRow, createContent } from './design-factory.js';\nimport * as lookup from './design-lookup.js';\n\nexport type StoreSubscriber = () => void;\n\n/**\n * Notification channels for fine-grained reactivity.\n * Components subscribe only to the channels they care about,\n * avoiding unnecessary re-renders.\n *\n * - `design` — row/column/content mutations, body value changes, undo/redo, load\n * - `selection` — selected element changed\n * - `hover` — hovered element changed\n * - `viewMode` — desktop/mobile toggle\n * - `activeTab` — sidebar tab switch\n */\nexport type StoreChannel = 'design' | 'selection' | 'hover' | 'viewMode' | 'activeTab';\n\nexport class EditorStore {\n private design: EmailDesign;\n private history = new HistoryManager();\n private counterManager: CounterManager = createCounterManager();\n\n /** Channel-based subscribers: only notified on specific changes */\n private channelSubscribers = new Map<StoreChannel, Set<StoreSubscriber>>();\n\n /** Public event emitter for design:loaded, design:updated, etc. */\n readonly events = new EventEmitter();\n\n // --- Merge tags ---\n private _mergeTags: MergeTagGroup[] = [];\n\n // --- Callbacks ---\n private _callbacks = new Map<string, Function>();\n setCallback(type: string, fn: Function): void { this._callbacks.set(type, fn); }\n getCallback(type: string): Function | undefined { return this._callbacks.get(type); }\n\n // --- A11y issue tracking ---\n private _a11yIssueIds = new Set<string>();\n get a11yIssueIds(): Set<string> { return this._a11yIssueIds; }\n setA11yIssueIds(ids: Set<string>): void { this._a11yIssueIds = ids; }\n\n // --- UI state ---\n private _selectedId: string | null = null;\n private _hoveredId: string | null = null;\n private _viewMode: 'desktop' | 'mobile' = 'desktop';\n private _activeTab = 'content';\n\n constructor() {\n this.design = createEmptyDesign();\n }\n\n // ── Subscriptions ──────────────────────────────────────────\n\n /**\n * Subscribe to specific channels only. The callback is invoked only\n * when one of the listed channels fires. Returns an unsubscribe function.\n *\n * @example\n * ```ts\n * // Only re-render when the design changes, not on hover/selection\n * store.subscribeChannels(['design'], () => this.requestUpdate());\n * ```\n */\n subscribeChannels(channels: StoreChannel[], fn: StoreSubscriber): () => void {\n for (const ch of channels) {\n let subs = this.channelSubscribers.get(ch);\n if (!subs) {\n subs = new Set();\n this.channelSubscribers.set(ch, subs);\n }\n subs.add(fn);\n }\n return () => {\n for (const ch of channels) {\n const subs = this.channelSubscribers.get(ch);\n if (!subs) continue;\n subs.delete(fn);\n if (subs.size === 0) this.channelSubscribers.delete(ch);\n }\n };\n }\n\n /** @deprecated Use subscribeChannels instead */\n subscribe(fn: StoreSubscriber): () => void {\n const ALL_CHANNELS: StoreChannel[] = ['design', 'selection', 'hover', 'viewMode', 'activeTab'];\n return this.subscribeChannels(ALL_CHANNELS, fn);\n }\n\n /** Batched notification — coalesces multiple channels into one rAF cycle */\n private pendingChannels = new Set<StoreChannel>();\n private rafId: number | null = null;\n\n private notifyChannels(...channels: StoreChannel[]): void {\n for (const ch of channels) this.pendingChannels.add(ch);\n if (this.rafId === null) {\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null;\n const toNotify = new Set<StoreSubscriber>();\n for (const ch of this.pendingChannels) {\n const subs = this.channelSubscribers.get(ch);\n if (subs) for (const fn of subs) toNotify.add(fn);\n }\n this.pendingChannels.clear();\n for (const fn of toNotify) fn();\n });\n }\n }\n\n // ── Getters ────────────────────────────────────────────────\n\n /** Get the full design document */\n getDesign(): EmailDesign { return this.design; }\n /** Get the design body */\n getBody(): DesignBody { return this.design.body; }\n /** Get all rows */\n getRows(): DesignRow[] { return this.design.body.rows; }\n /** Get body-level values (background, fonts, etc.) */\n getBodyValues(): BodyValues { return this.design.body.values; }\n\n get selectedId(): string | null { return this._selectedId; }\n get hoveredId(): string | null { return this._hoveredId; }\n get viewMode(): 'desktop' | 'mobile' { return this._viewMode; }\n get activeTab(): string { return this._activeTab; }\n get mergeTags(): MergeTagGroup[] { return this._mergeTags; }\n get canUndo(): boolean { return this.history.canUndo; }\n get canRedo(): boolean { return this.history.canRedo; }\n\n // ── Design Loading ─────────────────────────────────────────\n\n /** Load a design document, resetting history and selection */\n loadDesign(design: EmailDesign): void {\n this.design = structuredClone(design);\n this.counterManager.setCounters(this.design.counters);\n this.history.clear();\n this._selectedId = null;\n this.notifyChannels('design', 'selection');\n this.events.emit('design:loaded', { design: this.design });\n }\n\n // ── Undo / Redo ────────────────────────────────────────────\n\n undo(): void {\n const prev = this.history.undo(this.design);\n if (!prev) return;\n this.design = prev;\n this.counterManager.setCounters(this.design.counters);\n this.notifyChannels('design');\n this.emitUpdate('content_updated');\n }\n\n redo(): void {\n const next = this.history.redo(this.design);\n if (!next) return;\n this.design = next;\n this.counterManager.setCounters(this.design.counters);\n this.notifyChannels('design');\n this.emitUpdate('content_updated');\n }\n\n // ── Selection / UI State ───────────────────────────────────\n\n setMergeTags(tags: MergeTagGroup[]): void { this._mergeTags = tags; this.notifyChannels('design'); }\n select(id: string | null): void { this._selectedId = id; this.notifyChannels('selection'); }\n hover(id: string | null): void {\n this._hoveredId = id;\n // Hover is synchronous for immediate visual feedback (not batched)\n const subs = this.channelSubscribers.get('hover');\n if (subs) for (const fn of subs) fn();\n }\n setViewMode(mode: 'desktop' | 'mobile'): void { this._viewMode = mode; this.notifyChannels('viewMode'); }\n setActiveTab(tab: string): void { this._activeTab = tab; this.notifyChannels('activeTab'); }\n\n // ── Row Operations ─────────────────────────────────────────\n\n /** Add a row at the given index (or at the end). Returns the inserted row. */\n addRow(row: DesignRow, index?: number): DesignRow {\n const cloned = structuredClone(row);\n this.history.push(this.design);\n const rows = this.design.body.rows;\n if (index !== undefined && index >= 0 && index <= rows.length) {\n rows.splice(index, 0, cloned);\n } else {\n rows.push(cloned);\n }\n this.syncCounters();\n this.notifyChannels('design');\n this.emitUpdate('row_added', cloned);\n return cloned;\n }\n\n /** Remove a row by ID. Returns true if removed. */\n removeRow(rowId: string): boolean {\n const idx = lookup.getRowIndex(this.design, rowId);\n if (idx === -1) return false;\n this.history.push(this.design);\n this.design.body.rows.splice(idx, 1);\n if (this._selectedId === rowId) this._selectedId = null;\n this.notifyChannels('design');\n this.emitUpdate('row_removed');\n return true;\n }\n\n /** Move a row from one index to another. Returns true if moved. */\n moveRow(fromIndex: number, toIndex: number): boolean {\n const rows = this.design.body.rows;\n if (fromIndex < 0 || fromIndex >= rows.length || toIndex < 0 || toIndex >= rows.length) return false;\n if (fromIndex === toIndex) return false;\n this.history.push(this.design);\n const [row] = rows.splice(fromIndex, 1);\n rows.splice(toIndex, 0, row);\n this.notifyChannels('design');\n this.emitUpdate('row_reordered');\n return true;\n }\n\n /** Duplicate a row, assigning fresh IDs to all nested elements */\n duplicateRow(rowId: string): DesignRow | undefined {\n const row = lookup.findRow(this.design, rowId);\n if (!row) return undefined;\n this.history.push(this.design);\n const cloned = structuredClone(row);\n const rowNum = this.counterManager.next('u_row');\n cloned.id = `u_row_${rowNum}`;\n cloned.values._meta = { htmlID: cloned.id, htmlClassNames: 'u_row' };\n for (const col of cloned.columns) {\n const colNum = this.counterManager.next('u_column');\n col.id = `u_column_${colNum}`;\n col.values._meta = { htmlID: col.id, htmlClassNames: 'u_column' };\n for (const content of col.contents) {\n const cNum = this.counterManager.next(`u_content_${content.type}`);\n content.id = `u_content_${content.type}_${cNum}`;\n content.values._meta = { htmlID: content.id, htmlClassNames: `u_content_${content.type}` };\n }\n }\n const idx = lookup.getRowIndex(this.design, rowId);\n this.design.body.rows.splice(idx + 1, 0, cloned);\n this.syncCounters();\n this.notifyChannels('design');\n this.emitUpdate('row_added', cloned);\n return cloned;\n }\n\n /** Get the index of a row */\n getRowIndex(rowId: string): number {\n return lookup.getRowIndex(this.design, rowId);\n }\n\n /** Update row-level values. Returns true if updated. */\n updateRowValues(rowId: string, patch: Partial<RowValues>): boolean {\n const row = lookup.findRow(this.design, rowId);\n if (!row) return false;\n this.history.push(this.design);\n Object.assign(row.values, patch);\n this.notifyChannels('design');\n this.emitUpdate('content_updated');\n return true;\n }\n\n // ── Column Operations ──────────────────────────────────────\n\n /** Update column-level values. Returns true if updated. */\n updateColumnValues(columnId: string, patch: Partial<ColumnValues>): boolean {\n const col = lookup.findColumn(this.design, columnId);\n if (!col) return false;\n this.history.push(this.design);\n Object.assign(col.values, patch);\n this.notifyChannels('design');\n this.emitUpdate('content_updated');\n return true;\n }\n\n // ── Content Operations ─────────────────────────────────────\n\n /** Add content to a column at the given index. Returns the inserted content. */\n addContent(columnId: string, content: DesignContent, index?: number): DesignContent | undefined {\n const col = lookup.findColumn(this.design, columnId);\n if (!col) return undefined;\n const cloned = structuredClone(content);\n this.history.push(this.design);\n if (index !== undefined && index >= 0 && index <= col.contents.length) {\n col.contents.splice(index, 0, cloned);\n } else {\n col.contents.push(cloned);\n }\n this.syncCounters();\n this.notifyChannels('design');\n this.emitUpdate('content_added', cloned);\n return cloned;\n }\n\n /** Remove a content block by ID. Returns true if removed. */\n removeContent(contentId: string): boolean {\n for (const row of this.design.body.rows) {\n for (const col of row.columns) {\n const idx = col.contents.findIndex((c) => c.id === contentId);\n if (idx !== -1) {\n this.history.push(this.design);\n col.contents.splice(idx, 1);\n if (this._selectedId === contentId) this._selectedId = null;\n this.notifyChannels('design');\n this.emitUpdate('content_removed');\n return true;\n }\n }\n }\n return false;\n }\n\n /** Update content values by ID. Returns true if updated. */\n updateContentValues(contentId: string, patch: Partial<ContentValues>): boolean {\n const content = lookup.findContent(this.design, contentId);\n if (!content) return false;\n this.history.push(this.design);\n Object.assign(content.values, patch);\n this.notifyChannels('design');\n this.emitUpdate('content_updated');\n return true;\n }\n\n /** Move a content block to a different column at a given index. Returns true if moved. */\n moveContent(contentId: string, targetColumnId: string, targetIndex: number): boolean {\n const content = lookup.findContent(this.design, contentId);\n if (!content) return false;\n\n const targetCol = lookup.findColumn(this.design, targetColumnId);\n if (!targetCol) return false;\n\n this.history.push(this.design);\n\n // Remove from source — labeled break to exit both loops\n let removed: DesignContent | undefined;\n outer: for (const row of this.design.body.rows) {\n for (const col of row.columns) {\n const idx = col.contents.findIndex((c) => c.id === contentId);\n if (idx !== -1) {\n [removed] = col.contents.splice(idx, 1);\n break outer;\n }\n }\n }\n if (!removed) return false;\n\n // Clamp target index to valid range\n const clampedIndex = Math.min(targetIndex, targetCol.contents.length);\n targetCol.contents.splice(clampedIndex, 0, removed);\n this.notifyChannels('design');\n this.emitUpdate('content_reordered');\n return true;\n }\n\n /** Duplicate a content block, inserting the copy right after the original */\n duplicateContent(contentId: string): DesignContent | undefined {\n const content = lookup.findContent(this.design, contentId);\n if (!content) return undefined;\n for (const row of this.design.body.rows) {\n for (const col of row.columns) {\n const idx = col.contents.findIndex((c) => c.id === contentId);\n if (idx !== -1) {\n this.history.push(this.design);\n const cloned = structuredClone(content);\n const counter = this.counterManager.next(`u_content_${content.type}`);\n cloned.id = `u_content_${content.type}_${counter}`;\n cloned.values._meta = { htmlID: cloned.id, htmlClassNames: `u_content_${content.type}` };\n col.contents.splice(idx + 1, 0, cloned);\n this.syncCounters();\n this.notifyChannels('design');\n this.emitUpdate('content_added', cloned);\n return cloned;\n }\n }\n }\n return undefined;\n }\n\n // ── Body Values ────────────────────────────────────────────\n\n /** Update body-level values (background, fonts, etc.) */\n updateBodyValues(patch: Partial<BodyValues>): void {\n this.history.push(this.design);\n Object.assign(this.design.body.values, patch);\n this.notifyChannels('design');\n this.emitUpdate('body_updated');\n }\n\n // ── Lookups (delegate to design-lookup) ────────────────────\n\n findRow(rowId: string): DesignRow | undefined { return lookup.findRow(this.design, rowId); }\n findColumn(columnId: string): DesignColumn | undefined { return lookup.findColumn(this.design, columnId); }\n findContent(contentId: string): DesignContent | undefined { return lookup.findContent(this.design, contentId); }\n findParentColumn(contentId: string): DesignColumn | undefined { return lookup.findParentColumn(this.design, contentId); }\n findParentRow(columnId: string): DesignRow | undefined { return lookup.findParentRow(this.design, columnId); }\n\n // ── Factory Methods (delegate to design-factory) ───────────\n\n /** Create a new row with the given column layout */\n createRow(cellProportions: number[]): DesignRow {\n const row = createRow(this.counterManager, cellProportions);\n this.syncCounters();\n return row;\n }\n\n /** Create a new content block for the given tool type */\n createContent(type: string, values: Record<string, unknown> = {}): DesignContent {\n const content = createContent(this.counterManager, type, values);\n this.syncCounters();\n return content;\n }\n\n // ── Private Helpers ────────────────────────────────────────\n\n private syncCounters(): void {\n this.design.counters = this.counterManager.getCounters();\n }\n\n private emitUpdate(type: DesignUpdatedEvent['type'], item?: unknown): void {\n this.events.emit('design:updated', { type, item });\n }\n}\n","/**\n * @module ToolRegistry\n *\n * Registry for built-in and custom tools. Supports both eager and lazy\n * registration. Lazy tools are loaded on first use (drag/render) to\n * reduce the initial bundle size.\n */\n\nimport type { TemplateResult } from 'lit';\nimport type { ToolDefinition, ToolPropertyGroup, ContentValues, EditorRenderContext, ExportRenderContext } from '@emabuild/types';\n\n/** Lit-specific tool definition (narrows TEditorResult to TemplateResult) */\nexport interface LitToolDefinition extends ToolDefinition<TemplateResult> {\n renderer: {\n renderEditor(values: ContentValues, context: EditorRenderContext): TemplateResult;\n renderHtml(values: ContentValues, context: ExportRenderContext): string;\n };\n}\n\n/** Lazy loader function that returns the tool definition */\nexport type LazyToolLoader = () => Promise<LitToolDefinition>;\n\n/** Minimal metadata for displaying a lazy tool in the sidebar before it's loaded */\nexport interface LazyToolMeta {\n name: string;\n label: string;\n icon: string;\n position?: number;\n}\n\nexport class ToolRegistry {\n private tools = new Map<string, LitToolDefinition>();\n private lazyLoaders = new Map<string, LazyToolLoader>();\n private lazyMeta = new Map<string, LazyToolMeta>();\n private loadingPromises = new Map<string, Promise<LitToolDefinition | undefined>>();\n\n /** Register a tool eagerly (available immediately) */\n register(tool: LitToolDefinition): void {\n this.tools.set(tool.name, tool);\n this.lazyLoaders.delete(tool.name);\n this.lazyMeta.delete(tool.name);\n }\n\n /**\n * Register a tool lazily. The tool's code is only loaded when first needed.\n * Provide metadata (name, label, icon) so the tool can appear in the sidebar.\n *\n * @param meta - Display metadata for the sidebar palette\n * @param loader - Async function that imports and returns the tool definition\n *\n * @example\n * ```ts\n * registry.registerLazy(\n * { name: 'timer', label: 'Timer', icon: '<svg>...</svg>', position: 11 },\n * () => import('./built-in/timer-tool.js').then(m => m.timerTool),\n * );\n * ```\n */\n registerLazy(meta: LazyToolMeta, loader: LazyToolLoader): void {\n if (this.tools.has(meta.name)) return; // already eagerly registered\n this.lazyMeta.set(meta.name, meta);\n this.lazyLoaders.set(meta.name, loader);\n }\n\n /** Get a tool by name. Returns undefined if not loaded yet (use ensureLoaded for lazy tools). */\n get(name: string): LitToolDefinition | undefined {\n return this.tools.get(name);\n }\n\n /** Check if a tool is registered (eager or lazy) */\n has(name: string): boolean {\n return this.tools.has(name) || this.lazyLoaders.has(name);\n }\n\n /** Check if a tool is fully loaded and ready to render */\n isLoaded(name: string): boolean {\n return this.tools.has(name);\n }\n\n /**\n * Ensure a lazy tool is loaded. Returns the tool definition.\n * If the tool is already loaded, returns it immediately.\n * If it's being loaded, returns the in-flight promise.\n */\n async ensureLoaded(name: string): Promise<LitToolDefinition | undefined> {\n if (this.tools.has(name)) return this.tools.get(name);\n\n if (this.loadingPromises.has(name)) return this.loadingPromises.get(name);\n\n const loader = this.lazyLoaders.get(name);\n if (!loader) return undefined;\n\n const promise = loader()\n .then((tool) => {\n if (!tool?.name || !tool?.renderer) {\n throw new Error(`[ToolRegistry] Loaded tool \"${name}\" has invalid definition`);\n }\n this.tools.set(name, tool);\n this.lazyLoaders.delete(name);\n this.lazyMeta.delete(name);\n this.loadingPromises.delete(name);\n return tool;\n })\n .catch((err) => {\n this.loadingPromises.delete(name);\n console.error(`[ToolRegistry] Failed to load tool \"${name}\":`, err);\n return undefined;\n });\n\n this.loadingPromises.set(name, promise);\n return promise;\n }\n\n /**\n * Get all tools for display in the sidebar palette.\n * Returns both loaded tools and lazy tool metadata, sorted by position.\n */\n getAll(): LitToolDefinition[] {\n return Array.from(this.tools.values()).sort((a, b) => (a.position ?? 0) - (b.position ?? 0));\n }\n\n /**\n * Get all tool names and display metadata (including lazy tools not yet loaded).\n * Used by the sidebar to show all available tools.\n */\n getAllMeta(): LazyToolMeta[] {\n const metas: LazyToolMeta[] = [];\n\n for (const tool of this.tools.values()) {\n metas.push({ name: tool.name, label: tool.label, icon: tool.icon, position: tool.position });\n }\n for (const meta of this.lazyMeta.values()) {\n metas.push(meta);\n }\n\n return metas.sort((a, b) => (a.position ?? 0) - (b.position ?? 0));\n }\n\n /** Get default values for a tool. Loads lazily if needed (sync — returns empty if not loaded). */\n getDefaultValues(name: string): Record<string, unknown> {\n const tool = this.tools.get(name);\n if (!tool) return {};\n\n const defaults: Record<string, unknown> = { ...tool.defaultValues };\n for (const group of Object.values(tool.options)) {\n for (const [key, prop] of Object.entries(group.options)) {\n if (!(key in defaults)) {\n defaults[key] = prop.defaultValue;\n }\n }\n }\n return defaults;\n }\n\n /** Get property groups for a tool */\n getPropertyGroups(name: string): Record<string, ToolPropertyGroup> {\n return this.tools.get(name)?.options ?? {};\n }\n}\n","/** Shared drag state — simple module-level singleton to avoid shadow DOM event propagation issues */\n\ninterface DragState {\n /** ID of the content currently being dragged (null if not dragging content) */\n draggingContentId: string | null;\n /** ID of the row currently being dragged (null if not dragging a row) */\n draggingRowId: string | null;\n /** Reference to the element being dragged (for opacity restore on invalid drops) */\n draggingElement: HTMLElement | null;\n\n startContentDrag(contentId: string, el?: HTMLElement): void;\n startRowDrag(rowId: string, el?: HTMLElement): void;\n reset(): void;\n}\n\nexport const dragState: DragState = {\n draggingContentId: null,\n draggingRowId: null,\n draggingElement: null,\n\n startContentDrag(contentId: string, el?: HTMLElement) {\n this.draggingContentId = contentId;\n this.draggingElement = el ?? null;\n },\n\n startRowDrag(rowId: string, el?: HTMLElement) {\n this.draggingRowId = rowId;\n this.draggingElement = el ?? null;\n },\n\n reset() {\n if (this.draggingElement) {\n this.draggingElement.style.opacity = '1';\n this.draggingElement = null;\n }\n this.draggingContentId = null;\n this.draggingRowId = null;\n },\n};\n","/**\n * @module drop-indicator\n *\n * Reusable drop indicator creation and positioning.\n * Used by DragManager for both content-level (blue) and row-level (purple) indicators.\n */\n\n/**\n * Create a floating drop indicator element.\n * @param color - CSS color for the indicator line\n * @returns An absolutely-positioned HTMLElement (hidden by default)\n */\nexport function createDropIndicator(color: string): HTMLElement {\n const el = document.createElement('div');\n Object.assign(el.style, {\n position: 'absolute',\n left: '0',\n right: '0',\n height: '3px',\n background: color,\n borderRadius: '2px',\n pointerEvents: 'none',\n zIndex: '1000',\n display: 'none',\n boxShadow: `0 0 6px ${color}80`,\n });\n return el;\n}\n\n/**\n * Position an indicator at a specific Y offset within a container.\n * @param indicator - The indicator element\n * @param container - The shadow root or element to append the indicator to\n * @param items - The list of elements to position between\n * @param index - The insertion index (0 = before first, items.length = after last)\n * @param insetX - Horizontal inset from edges (e.g. \"4px\" for content, \"0\" for rows)\n */\nexport function positionIndicator(\n indicator: HTMLElement,\n container: ShadowRoot | HTMLElement,\n items: HTMLElement[],\n index: number,\n insetX = '4px',\n): void {\n if (indicator.parentNode !== container) {\n indicator.remove();\n container.appendChild(indicator);\n }\n\n const containerEl = container instanceof ShadowRoot ? container.host as HTMLElement : container;\n const containerRect = containerEl.getBoundingClientRect();\n\n let indicatorY: number;\n if (items.length === 0 || index === 0) {\n indicatorY = items.length === 0 ? 0 : items[0].getBoundingClientRect().top - containerRect.top;\n } else if (index >= items.length) {\n const lastRect = items[items.length - 1].getBoundingClientRect();\n indicatorY = lastRect.bottom - containerRect.top;\n } else {\n const elRect = items[index].getBoundingClientRect();\n indicatorY = elRect.top - containerRect.top;\n }\n\n Object.assign(indicator.style, {\n display: 'block',\n top: `${indicatorY}px`,\n left: insetX,\n right: insetX,\n width: 'auto',\n });\n}\n\n/** Hide a drop indicator */\nexport function hideIndicator(indicator: HTMLElement | null): void {\n if (indicator) indicator.style.display = 'none';\n}\n","/**\n * @module shadow-dom-utils\n *\n * Utilities for traversing nested shadow DOM trees.\n * Required because the editor uses Lit Web Components with shadow DOM,\n * and standard `querySelectorAll` doesn't cross shadow boundaries.\n */\n\n/**\n * Recursively walk all elements across shadow DOM boundaries.\n * @param root - Starting point (ShadowRoot or HTMLElement)\n * @param callback - Called for each element encountered\n */\nexport function walkShadowDom(root: ShadowRoot | HTMLElement, callback: (el: HTMLElement) => void): void {\n const children = root instanceof ShadowRoot ? root.children : root.children;\n for (const child of Array.from(children)) {\n const el = child as HTMLElement;\n callback(el);\n if (el.shadowRoot) walkShadowDom(el.shadowRoot, callback);\n if (el.children?.length) walkShadowDom(el, callback);\n }\n}\n\n/**\n * Query all elements matching a selector across shadow DOM boundaries.\n * @param root - Starting point\n * @param selector - CSS selector to match\n * @returns Array of matching elements\n */\nexport function queryShadowAll<T extends HTMLElement>(root: ShadowRoot | HTMLElement, selector: string): T[] {\n const results: T[] = [];\n walkShadowDom(root, (el) => {\n if (el.matches?.(selector)) results.push(el as T);\n });\n return results;\n}\n\n/**\n * Walk up the DOM tree (including shadow DOM boundaries) to find\n * an ancestor with a specific `data-*` attribute.\n * @param el - Starting element\n * @param dataKey - The dataset key to look for (e.g. \"contentId\" for data-content-id)\n * @returns The matching ancestor element, or null\n */\nexport function findAncestorWithData(el: HTMLElement | null, dataKey: string): HTMLElement | null {\n while (el) {\n if (el.dataset?.[dataKey]) return el;\n if (el.parentElement) {\n el = el.parentElement;\n } else if ((el.getRootNode() as ShadowRoot).host) {\n el = (el.getRootNode() as ShadowRoot).host as HTMLElement;\n } else {\n break;\n }\n }\n return null;\n}\n","/**\n * @module DragManager\n *\n * Orchestrates all drag-and-drop operations in the editor.\n * Handles three drag types:\n * - Tool drag: from sidebar palette into canvas columns\n * - Layout drag: from sidebar layout presets between canvas rows\n * - Content drag: reordering existing content blocks between columns\n *\n * Uses {@link drop-indicator} for visual feedback and\n * {@link shadow-dom-utils} for traversing nested shadow DOM.\n */\n\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry } from '../tools/tool-registry.js';\nimport { dragState } from './drag-state.js';\nimport { createDropIndicator, positionIndicator, hideIndicator } from './drop-indicator.js';\nimport { queryShadowAll } from './shadow-dom-utils.js';\n\ntype DropType = 'content' | 'row';\n\ninterface DropTarget {\n type: DropType;\n columnId?: string;\n contentIndex?: number;\n rowIndex?: number;\n y: number;\n}\n\nexport class DragManager {\n private store: EditorStore;\n private toolRegistry: ToolRegistry;\n private root: ShadowRoot;\n private currentDrop: DropTarget | null = null;\n private contentIndicator: HTMLElement | null = null;\n private rowIndicator: HTMLElement | null = null;\n\n constructor(store: EditorStore, toolRegistry: ToolRegistry, root: ShadowRoot) {\n this.store = store;\n this.toolRegistry = toolRegistry;\n this.root = root;\n }\n\n /** Attach all drag event listeners to the shadow root */\n attach(): void {\n this.root.addEventListener('dragover', this.onDragOver as unknown as EventListener);\n this.root.addEventListener('drop', this.onDrop as unknown as EventListener);\n this.root.addEventListener('dragend', this.onDragEnd as unknown as EventListener);\n this.root.addEventListener('dragleave', this.onDragLeave as unknown as EventListener);\n this.contentIndicator = createDropIndicator('#3b82f6');\n this.rowIndicator = createDropIndicator('#8b5cf6');\n }\n\n /** Remove all event listeners and clean up indicators */\n detach(): void {\n this.root.removeEventListener('dragover', this.onDragOver as unknown as EventListener);\n this.root.removeEventListener('drop', this.onDrop as unknown as EventListener);\n this.root.removeEventListener('dragend', this.onDragEnd as unknown as EventListener);\n this.root.removeEventListener('dragleave', this.onDragLeave as unknown as EventListener);\n this.contentIndicator?.remove();\n this.rowIndicator?.remove();\n }\n\n // ── Event Handlers ─────────────────────────────────────────\n\n private onDragOver = (e: DragEvent) => {\n const types = e.dataTransfer?.types || [];\n const isToolDrag = types.includes('application/maileditor-tool');\n const isLayoutDrag = types.includes('application/maileditor-layout');\n const isContentDrag = types.includes('application/maileditor-content') || !!dragState.draggingContentId;\n const isRowDrag = types.includes('application/maileditor-row') || !!dragState.draggingRowId;\n\n if (!isToolDrag && !isContentDrag && !isLayoutDrag && !isRowDrag) return;\n\n e.preventDefault();\n e.dataTransfer!.dropEffect = (isToolDrag || isLayoutDrag) ? 'copy' : 'move';\n\n if (isLayoutDrag || isRowDrag) {\n this.currentDrop = this.findRowDropTarget(e.clientY);\n hideIndicator(this.contentIndicator);\n this.showRowIndicator();\n } else {\n this.currentDrop = this.findContentDropTarget(e.clientX, e.clientY);\n hideIndicator(this.rowIndicator);\n this.showContentIndicator();\n }\n };\n\n private onDrop = async (e: DragEvent) => {\n e.preventDefault();\n this.hideAllIndicators();\n\n // Capture drop target before reset clears it\n const drop = this.currentDrop;\n\n // Row reorder drag\n const rowId = e.dataTransfer?.getData('application/maileditor-row') || dragState.draggingRowId;\n if (rowId) {\n this.handleRowDrop(rowId, drop);\n this.reset();\n return;\n }\n\n const layoutData = e.dataTransfer?.getData('application/maileditor-layout');\n if (layoutData) {\n this.handleLayoutDrop(JSON.parse(layoutData), drop);\n this.reset();\n return;\n }\n\n const toolName = e.dataTransfer?.getData('application/maileditor-tool');\n if (toolName) {\n await this.handleToolDrop(toolName, drop);\n this.reset();\n return;\n }\n\n const contentId = e.dataTransfer?.getData('application/maileditor-content') || dragState.draggingContentId;\n if (contentId) {\n this.handleContentDrop(contentId, drop);\n }\n this.reset();\n };\n\n private onDragEnd = () => {\n this.hideAllIndicators();\n this.reset();\n };\n\n private onDragLeave = (e: DragEvent) => {\n const related = e.relatedTarget as HTMLElement | null;\n if (!related || !this.root.contains(related)) {\n this.hideAllIndicators();\n this.currentDrop = null;\n }\n };\n\n // ── Drop Handlers ──────────────────────────────────────────\n\n private handleRowDrop(rowId: string, drop: DropTarget | null = this.currentDrop): void {\n if (drop?.type === 'row' && drop.rowIndex !== undefined) {\n const fromIndex = this.store.getRowIndex(rowId);\n if (fromIndex === -1) return;\n // Adjust target index if dragging downward (since removing shifts indices)\n const toIndex = drop.rowIndex > fromIndex ? drop.rowIndex - 1 : drop.rowIndex;\n if (fromIndex !== toIndex) {\n this.store.moveRow(fromIndex, toIndex);\n }\n }\n }\n\n private handleLayoutDrop(cells: number[], drop: DropTarget | null = this.currentDrop): void {\n const row = this.store.createRow(cells);\n const rowIndex = drop?.type === 'row' ? drop.rowIndex : undefined;\n this.store.addRow(row, rowIndex);\n }\n\n private async handleToolDrop(toolName: string, drop: DropTarget | null): Promise<void> {\n // Ensure lazy tool is loaded before creating content\n await this.toolRegistry.ensureLoaded(toolName);\n\n if (drop?.type === 'content' && drop.columnId) {\n const defaults = this.toolRegistry.getDefaultValues(toolName);\n const content = this.store.createContent(toolName, defaults);\n this.store.addContent(drop.columnId, content, drop.contentIndex);\n this.store.select(content.id);\n } else {\n const row = this.store.createRow([1]);\n this.store.addRow(row);\n const defaults = this.toolRegistry.getDefaultValues(toolName);\n const content = this.store.createContent(toolName, defaults);\n this.store.addContent(row.columns[0].id, content);\n this.store.select(content.id);\n }\n }\n\n private handleContentDrop(contentId: string, drop: DropTarget | null): void {\n if (drop?.type === 'content' && drop.columnId) {\n this.store.moveContent(contentId, drop.columnId, drop.contentIndex!);\n this.store.select(contentId);\n }\n }\n\n // ── Drop Target Detection ─────────────────────────────────\n\n private findRowDropTarget(clientY: number): DropTarget | null {\n const canvas = this.root.querySelector('me-editor-canvas');\n if (!canvas?.shadowRoot) return null;\n\n const rows = Array.from(canvas.shadowRoot.querySelectorAll('me-row-renderer')) as HTMLElement[];\n if (rows.length === 0) return { type: 'row', rowIndex: 0, y: 0 };\n\n let bestDist = Math.abs(clientY - rows[0].getBoundingClientRect().top);\n let bestTarget: DropTarget = { type: 'row', rowIndex: 0, y: rows[0].getBoundingClientRect().top };\n\n for (let i = 0; i < rows.length; i++) {\n const y = rows[i].getBoundingClientRect().bottom;\n const dist = Math.abs(clientY - y);\n if (dist < bestDist) {\n bestDist = dist;\n bestTarget = { type: 'row', rowIndex: i + 1, y };\n }\n }\n return bestTarget;\n }\n\n private findContentDropTarget(clientX: number, clientY: number): DropTarget | null {\n const columns = queryShadowAll<HTMLElement>(this.root, 'me-column-renderer');\n let bestTarget: DropTarget | null = null;\n let bestDist = Infinity;\n\n for (const colEl of columns) {\n const columnId = colEl.dataset.columnId;\n if (!columnId || !colEl.shadowRoot) continue;\n\n const colRect = colEl.getBoundingClientRect();\n if (clientX < colRect.left || clientX > colRect.right) continue;\n\n const contentEls = Array.from(colEl.shadowRoot.querySelectorAll('me-content-renderer')) as HTMLElement[];\n\n if (contentEls.length === 0) {\n const dist = Math.abs(clientY - (colRect.top + colRect.height / 2));\n if (dist < bestDist) {\n bestDist = dist;\n bestTarget = { type: 'content', columnId, contentIndex: 0, y: colRect.top + colRect.height / 2 };\n }\n continue;\n }\n\n // Check before first element\n const firstY = contentEls[0].getBoundingClientRect().top;\n let dist = Math.abs(clientY - firstY);\n if (dist < bestDist) {\n bestDist = dist;\n bestTarget = { type: 'content', columnId, contentIndex: 0, y: firstY };\n }\n\n // Check between and after each element\n for (let i = 0; i < contentEls.length; i++) {\n const rect = contentEls[i].getBoundingClientRect();\n const nextRect = contentEls[i + 1]?.getBoundingClientRect();\n const y = nextRect ? (rect.bottom + nextRect.top) / 2 : rect.bottom;\n dist = Math.abs(clientY - y);\n if (dist < bestDist) {\n bestDist = dist;\n bestTarget = { type: 'content', columnId, contentIndex: i + 1, y };\n }\n }\n }\n return bestTarget;\n }\n\n // ── Indicator Positioning ──────────────────────────────────\n\n private showContentIndicator(): void {\n if (!this.contentIndicator || !this.currentDrop?.columnId) {\n hideIndicator(this.contentIndicator);\n return;\n }\n\n const columns = queryShadowAll<HTMLElement>(this.root, 'me-column-renderer');\n const colEl = columns.find((c) => c.dataset.columnId === this.currentDrop!.columnId);\n if (!colEl?.shadowRoot) return;\n\n const contentEls = Array.from(colEl.shadowRoot.querySelectorAll('me-content-renderer')) as HTMLElement[];\n positionIndicator(this.contentIndicator, colEl.shadowRoot, contentEls, this.currentDrop.contentIndex ?? 0, '4px');\n }\n\n private showRowIndicator(): void {\n if (!this.rowIndicator || !this.currentDrop) {\n hideIndicator(this.rowIndicator);\n return;\n }\n\n const canvas = this.root.querySelector('me-editor-canvas');\n const canvasBody = canvas?.shadowRoot?.querySelector('.canvas-body') as HTMLElement | null;\n if (!canvasBody) return;\n\n const rows = Array.from(canvas!.shadowRoot!.querySelectorAll('me-row-renderer')) as HTMLElement[];\n positionIndicator(this.rowIndicator, canvasBody, rows, this.currentDrop.rowIndex ?? 0, '0');\n }\n\n private hideAllIndicators(): void {\n hideIndicator(this.contentIndicator);\n hideIndicator(this.rowIndicator);\n }\n\n private reset(): void {\n this.currentDrop = null;\n dragState.reset();\n }\n}\n","/**\n * @module value-extractor\n *\n * Type-safe utilities for extracting values from content value maps.\n * Replaces repetitive `(values.x as string) || 'default'` casts\n * used across all tool renderers.\n */\n\nimport type { ContentValues } from '@emabuild/types';\n\n/**\n * Extract a string value with a fallback default.\n * @param values - The content values map\n * @param key - The property key to extract\n * @param fallback - Default value if key is missing or empty\n */\nexport function str(values: ContentValues, key: string, fallback = ''): string {\n const v = values[key];\n if (typeof v === 'string' && v !== '') return v;\n if (typeof v === 'number') return String(v);\n return fallback;\n}\n\n/**\n * Extract a numeric value with a fallback default.\n * Parses strings like \"14px\" or \"100%\" to their numeric part.\n * @param values - The content values map\n * @param key - The property key to extract\n * @param fallback - Default value if key is missing or not a number\n */\nexport function num(values: ContentValues, key: string, fallback = 0): number {\n const v = values[key];\n if (typeof v === 'number') return v;\n if (typeof v === 'string') {\n const parsed = parseFloat(v);\n return isNaN(parsed) ? fallback : parsed;\n }\n return fallback;\n}\n\n/**\n * Extract an image URL from a value that can be either:\n * - A plain string URL: `\"https://example.com/img.jpg\"`\n * - An object with a `url` field: `{ url: \"https://...\", width: 600, ... }`\n *\n * The object format is used by some external editors.\n */\nexport function imageUrl(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value && typeof value === 'object' && 'url' in value) {\n return (value as Record<string, unknown>).url as string || '';\n }\n return '';\n}\n\n/**\n * Extract image metadata (width, maxWidth) from an object-format src.\n */\nexport function imageMeta(value: unknown): { width?: number; maxWidth?: string } {\n if (value && typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n return {\n width: typeof obj.width === 'number' ? obj.width : undefined,\n maxWidth: typeof obj.maxWidth === 'string' ? obj.maxWidth : undefined,\n };\n }\n return {};\n}\n\n/**\n * Extract link href and target from either:\n * - Flat format: `{ href: \"...\", target: \"_blank\" }`\n * - Action object: `{ action: { name: \"web\", values: { href: \"...\", target: \"_blank\" } } }`\n *\n * The action object format is used by some external editors.\n */\nexport function linkAction(values: ContentValues): { href: string; target: string } {\n const action = values.action;\n if (action && typeof action === 'object') {\n const actValues = (action as Record<string, unknown>).values as Record<string, unknown> | undefined;\n return {\n href: (actValues?.href as string) || '',\n target: (actValues?.target as string) || '_blank',\n };\n }\n return {\n href: str(values, 'href'),\n target: str(values, 'target', '_blank'),\n };\n}\n\n/**\n * Extract text content, supporting both plain string and Lexical JSON format.\n * Some editors store text as `textJson` (Lexical editor state) instead of a\n * plain `text` string. This helper extracts readable text from either format.\n *\n * @param values - Content values map\n * @param fallback - Default if no text is found\n */\nexport function textContent(values: ContentValues, fallback = ''): string {\n // Plain string text\n const text = values.text;\n if (typeof text === 'string' && text !== '') return text;\n\n // Lexical JSON format (textJson field)\n const textJson = values.textJson;\n if (typeof textJson === 'string') {\n try {\n const parsed = JSON.parse(textJson);\n const parts: string[] = [];\n const walk = (node: Record<string, unknown>) => {\n if (typeof node.text === 'string') parts.push(node.text);\n if (node.type === 'linebreak') parts.push('<br/>');\n const children = node.children as Record<string, unknown>[] | undefined;\n if (children) children.forEach(walk);\n };\n walk(parsed.root || parsed);\n if (parts.length > 0) return parts.join('');\n } catch { /* ignore parse errors */ }\n }\n\n return fallback;\n}\n\n/**\n * Extract font-family CSS value from content values.\n * Handles both string format and object format { label, value, url }.\n * If a Google Font URL is present, injects a stylesheet link into the document.\n */\nexport function getFontFamily(values: ContentValues, fallback = 'arial,helvetica,sans-serif'): string {\n const ff = values.fontFamily;\n if (typeof ff === 'string' && ff !== '') return ff;\n if (ff && typeof ff === 'object') {\n const obj = ff as Record<string, unknown>;\n const cssValue = (obj.value as string) || fallback;\n // Load Google Font if URL is provided\n const url = obj.url as string | undefined;\n if (url && typeof document !== 'undefined') {\n const id = `emabuild-font-${cssValue.replace(/[^a-z]/gi, '')}`;\n if (!document.getElementById(id)) {\n const link = document.createElement('link');\n link.id = id;\n link.rel = 'stylesheet';\n link.href = url;\n document.head.appendChild(link);\n }\n }\n return cssValue;\n }\n return fallback;\n}\n\n/**\n * Extract button colors from either flat values or buttonColors object.\n * Some editors store colors in a nested `buttonColors` object:\n * `{ backgroundColor: null, buttonColors: { backgroundColor: '#c40909', color: '#fff' } }`\n */\nexport function buttonColors(values: ContentValues): { bg: string; color: string } {\n const bc = values.buttonColors;\n if (bc && typeof bc === 'object') {\n const obj = bc as Record<string, unknown>;\n return {\n bg: (obj.backgroundColor as string) || str(values, 'backgroundColor', '#3b82f6'),\n color: (obj.color as string) || str(values, 'textColor', '#ffffff'),\n };\n }\n return {\n bg: str(values, 'backgroundColor', '#3b82f6'),\n color: str(values, 'textColor', '#ffffff'),\n };\n}\n\n/**\n * Safely parse a JSON string with a typed fallback.\n * Used by tools that store structured data as JSON strings\n * (social icons, menu items, table data, form fields).\n *\n * @param value - The raw value (expected to be a JSON string)\n * @param fallback - Returned if parsing fails or value is not a string\n *\n * @example\n * ```ts\n * const items = jsonParse<MenuItem[]>(values.items, defaultItems);\n * ```\n */\nexport function jsonParse<T>(value: unknown, fallback: T): T {\n if (typeof value !== 'string') return fallback;\n try {\n return JSON.parse(value) as T;\n } catch {\n return fallback;\n }\n}\n","/**\n * @module email-html\n *\n * Shared HTML generation utilities for email-safe output.\n * Provides the table-cell wrapper used by every tool's `renderHtml()`,\n * plus VML helpers for Outlook compatibility.\n */\n\n/** Options for the standard email table cell wrapper */\nexport interface TableCellOptions {\n /** CSS padding (e.g. \"10px\" or \"10px 20px\") */\n padding: string;\n /** Horizontal alignment: \"left\" | \"center\" | \"right\" */\n align?: string;\n /** Additional inline styles on the `<td>` element */\n extraTdStyle?: string;\n}\n\n/**\n * Wrap content in the standard email-safe table cell structure.\n * This is the `<table role=\"presentation\">` pattern used by every tool.\n *\n * @param content - The inner HTML content\n * @param options - Cell configuration (padding, alignment, extra styles)\n * @returns Complete table HTML string\n *\n * @example\n * ```ts\n * return emailTableCell('<p>Hello</p>', { padding: '10px', align: 'left' });\n * ```\n */\nexport function emailTableCell(content: string, options: TableCellOptions): string {\n const { padding, align = 'left', extraTdStyle = '' } = options;\n const tdStyle = `padding:${padding};font-family:arial,helvetica,sans-serif;${extraTdStyle}`;\n return `<table role=\"presentation\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" border=\"0\">\n <tbody><tr><td style=\"${tdStyle}\" align=\"${align}\">\n ${content}\n </td></tr></tbody>\n</table>`;\n}\n\n/** Options for VML rounded-rectangle button (Outlook fallback) */\nexport interface VmlButtonOptions {\n /** Background color */\n bgColor: string;\n /** Text color */\n textColor: string;\n /** Font size (e.g. \"14px\") */\n fontSize: string;\n /** Font weight (e.g. \"700\") */\n fontWeight: string;\n /** CSS border-radius (e.g. \"6px\") */\n borderRadius: string;\n}\n\n/**\n * Generate a VML roundrect button for Outlook email clients.\n * Outlook doesn't support CSS border-radius on `<a>` tags,\n * so VML is needed for rounded buttons.\n *\n * @param text - Button label\n * @param href - Button link URL\n * @param options - Visual styling options\n * @returns VML HTML wrapped in MSO conditional comments\n */\nexport function vmlRoundrectButton(text: string, href: string, options: VmlButtonOptions): string {\n const { bgColor, textColor, fontSize, fontWeight, borderRadius } = options;\n const radiusPx = parseInt(borderRadius) || 0;\n if (radiusPx <= 0) return '';\n\n const arcsize = Math.round((radiusPx / 20) * 100);\n return `<!--[if mso]>\n <v:roundrect xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:w=\"urn:schemas-microsoft-com:office:word\" href=\"${href}\" style=\"height:auto;v-text-anchor:middle;width:auto;\" arcsize=\"${arcsize}%\" stroke=\"f\" fillcolor=\"${bgColor}\">\n <w:anchorlock/>\n <center style=\"color:${textColor};font-family:arial,helvetica,sans-serif;font-size:${fontSize};font-weight:${fontWeight};\">${text}</center>\n </v:roundrect>\n <![endif]-->`;\n}\n","/**\n * @module shared-options\n *\n * Shared option groups and dropdown choices reused across multiple tools.\n * Centralizes definitions to avoid duplication and ensure consistency.\n */\n\nimport type { ToolPropertyGroup, ToolProperty } from '@emabuild/types';\n\n// ── Dropdown option arrays ──────────────────────────────────\n\nexport const LINE_HEIGHT_OPTIONS = [\n { label: '100%', value: '100%' }, { label: '120%', value: '120%' },\n { label: '140%', value: '140%' }, { label: '160%', value: '160%' },\n { label: '180%', value: '180%' }, { label: '200%', value: '200%' },\n] as const;\n\nexport const FONT_WEIGHT_OPTIONS = [\n { label: 'Normal', value: '400' }, { label: 'Medium', value: '500' },\n { label: 'Semi Bold', value: '600' }, { label: 'Bold', value: '700' },\n { label: 'Extra Bold', value: '800' },\n] as const;\n\nexport const FONT_WEIGHT_OPTIONS_SIMPLE = [\n { label: 'Normal', value: '400' }, { label: 'Bold', value: '700' },\n] as const;\n\nexport const HEADING_FONT_SIZE_OPTIONS = [\n { label: '12px', value: '12px' }, { label: '14px', value: '14px' },\n { label: '16px', value: '16px' }, { label: '18px', value: '18px' },\n { label: '20px', value: '20px' }, { label: '22px', value: '22px' },\n { label: '26px', value: '26px' }, { label: '30px', value: '30px' },\n { label: '36px', value: '36px' }, { label: '48px', value: '48px' },\n { label: '60px', value: '60px' },\n] as const;\n\nexport const BUTTON_FONT_SIZE_OPTIONS = [\n { label: '12px', value: '12px' }, { label: '13px', value: '13px' },\n { label: '14px', value: '14px' }, { label: '16px', value: '16px' },\n { label: '18px', value: '18px' }, { label: '20px', value: '20px' },\n] as const;\n\n// ── Shared option properties ────────────────────────────────\n\nexport const lineHeightProp = (defaultValue = '140%'): ToolProperty => ({\n label: 'Line Height', defaultValue, widget: 'dropdown',\n widgetParams: { options: [...LINE_HEIGHT_OPTIONS] },\n});\n\nexport const fontWeightProp = (defaultValue = '700', simple = false): ToolProperty => ({\n label: 'Font Weight', defaultValue, widget: 'dropdown',\n widgetParams: { options: [...(simple ? FONT_WEIGHT_OPTIONS_SIMPLE : FONT_WEIGHT_OPTIONS)] },\n});\n\n// ── Shared property groups ──────────────────────────────────\n\n/** Spacing group with containerPadding */\nexport const SPACING_GROUP: ToolPropertyGroup = {\n title: 'Spacing',\n options: {\n containerPadding: { label: 'Padding', defaultValue: '10px', widget: 'padding' },\n },\n};\n\n/** General group with anchor + visibility toggles */\nexport const GENERAL_GROUP: ToolPropertyGroup = {\n title: 'General',\n options: {\n anchor: { label: 'Anchor', defaultValue: '', widget: 'text' },\n hideDesktop: { label: 'Hide on Desktop', defaultValue: false, widget: 'toggle' },\n hideMobile: { label: 'Hide on Mobile', defaultValue: false, widget: 'toggle' },\n },\n};\n\n/** Minimal general group with visibility toggles only (no anchor) */\nexport const GENERAL_GROUP_MINIMAL: ToolPropertyGroup = {\n title: 'General',\n options: {\n hideDesktop: { label: 'Hide on Desktop', defaultValue: false, widget: 'toggle' },\n hideMobile: { label: 'Hide on Mobile', defaultValue: false, widget: 'toggle' },\n },\n};\n","/**\n * @module text-tool\n *\n * Rich text content block. Renders HTML text with formatting.\n *\n * Email compatibility: Uses `<div>` inside a table cell with inline styles.\n * Supports bold, italic, links, font sizes via HTML content.\n * Works across all major email clients.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport type { ContentValues, EditorRenderContext, ExportRenderContext } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str, getFontFamily } from '../helpers/value-extractor.js';\nimport { emailTableCell } from '../helpers/email-html.js';\nimport { SPACING_GROUP, GENERAL_GROUP, lineHeightProp } from './shared-options.js';\n\nexport const textTool: LitToolDefinition = {\n name: 'text',\n label: 'Text',\n icon: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 7V4h16v3\"/><path d=\"M9 20h6\"/><path d=\"M12 4v16\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 1,\n options: {\n text: {\n title: 'Text',\n options: {\n text: {\n label: 'Text Content',\n defaultValue: '<p style=\"font-size: 14px;\">This is a new text block. Change the text.</p>',\n widget: 'rich_text',\n },\n },\n },\n style: {\n title: 'Style',\n options: {\n color: { label: 'Text Color', defaultValue: '#000000', widget: 'color_picker' },\n backgroundColor: { label: 'Background Color', defaultValue: '', widget: 'color_picker' },\n textAlign: { label: 'Text Align', defaultValue: 'left', widget: 'alignment' },\n lineHeight: lineHeightProp(),\n },\n },\n spacing: SPACING_GROUP,\n general: GENERAL_GROUP,\n },\n defaultValues: {\n text: '<p style=\"font-size: 14px;\">This is a new text block. Change the text.</p>',\n color: '#000000',\n backgroundColor: '',\n lineHeight: '140%',\n containerPadding: '10px',\n textAlign: 'left',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const bgColor = str(values, 'backgroundColor', 'transparent');\n const color = str(values, 'color', 'inherit');\n const lineHeight = str(values, 'lineHeight', '140%');\n const textAlign = str(values, 'textAlign', 'left');\n const fontFamily = getFontFamily(values);\n const textContent = str(values, 'text');\n\n return html`\n <div style=\"background-color:${bgColor};color:${color};line-height:${lineHeight};text-align:${textAlign};font-family:${fontFamily};\">\n ${unsafeHTML(textContent)}\n </div>\n `;\n },\n\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const bgColor = str(values, 'backgroundColor');\n const color = str(values, 'color', '#000000');\n const lineHeight = str(values, 'lineHeight', '140%');\n const textAlign = str(values, 'textAlign', 'left');\n const textContent = str(values, 'text');\n const bgStyle = bgColor ? `background-color:${bgColor};` : '';\n\n const inner = `<div style=\"font-size:14px;color:${color};line-height:${lineHeight};text-align:${textAlign};\">${textContent}</div>`;\n return emailTableCell(inner, { padding, extraTdStyle: bgStyle });\n },\n },\n};\n","/**\n * @module heading-tool\n *\n * Heading content block (H1-H4) with full styling support:\n * font size, color, weight, alignment, line height, letter spacing,\n * font family, container padding, and responsive visibility.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport type { ContentValues } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str, textContent, getFontFamily } from '../helpers/value-extractor.js';\nimport { emailTableCell } from '../helpers/email-html.js';\nimport { SPACING_GROUP, GENERAL_GROUP, lineHeightProp, fontWeightProp, HEADING_FONT_SIZE_OPTIONS } from './shared-options.js';\n\n/** Build inline style string from heading values */\nfunction buildHeadingStyle(values: ContentValues): string {\n const parts: string[] = [];\n parts.push('font-size:' + str(values, 'fontSize', '22px'));\n parts.push('color:' + str(values, 'color', '#000000'));\n parts.push('text-align:' + str(values, 'textAlign', 'left'));\n parts.push('font-weight:' + str(values, 'fontWeight', '700'));\n parts.push('line-height:' + str(values, 'lineHeight', '140%'));\n parts.push('letter-spacing:' + str(values, 'letterSpacing', 'normal'));\n parts.push('font-family:' + getFontFamily(values));\n return parts.join(';');\n}\n\nexport const headingTool: LitToolDefinition = {\n name: 'heading',\n label: 'Heading',\n icon: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 12h12\"/><path d=\"M6 4v16\"/><path d=\"M18 4v16\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 2,\n options: {\n text: {\n title: 'Heading',\n options: {\n text: { label: 'Text', defaultValue: 'Heading', widget: 'text' },\n headingType: {\n label: 'Heading Type', defaultValue: 'h1', widget: 'dropdown',\n widgetParams: { options: [\n { label: 'H1', value: 'h1' }, { label: 'H2', value: 'h2' },\n { label: 'H3', value: 'h3' }, { label: 'H4', value: 'h4' },\n ]},\n },\n },\n },\n style: {\n title: 'Style',\n options: {\n fontSize: {\n label: 'Font Size', defaultValue: '22px', widget: 'dropdown',\n widgetParams: { options: [...HEADING_FONT_SIZE_OPTIONS] },\n },\n color: { label: 'Text Color', defaultValue: '#000000', widget: 'color_picker' },\n textAlign: { label: 'Text Align', defaultValue: 'left', widget: 'alignment' },\n fontWeight: fontWeightProp(),\n lineHeight: lineHeightProp(),\n letterSpacing: {\n label: 'Letter Spacing', defaultValue: '0px', widget: 'number_unit',\n widgetParams: { unit: 'px', min: -5, max: 50, step: 0.1 },\n },\n },\n },\n spacing: SPACING_GROUP,\n general: GENERAL_GROUP,\n },\n defaultValues: {\n text: 'Heading', headingType: 'h1', fontSize: '22px', color: '#000000',\n textAlign: 'left', fontWeight: '700', lineHeight: '140%',\n letterSpacing: '0px', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const styles = {\n padding: str(values, 'containerPadding', '10px'),\n fontSize: str(values, 'fontSize', '22px'),\n color: str(values, 'color', '#000000'),\n textAlign: str(values, 'textAlign', 'left'),\n fontWeight: str(values, 'fontWeight', '700'),\n lineHeight: str(values, 'lineHeight', '140%'),\n letterSpacing: str(values, 'letterSpacing', 'normal'),\n fontFamily: getFontFamily(values),\n };\n const text = textContent(values, 'Heading');\n return html`<div style=${styleMap(styles)}>${unsafeHTML(text)}</div>`;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const fontSize = str(values, 'fontSize', '22px');\n const color = str(values, 'color', '#000000');\n const textAlign = str(values, 'textAlign', 'left');\n const fontWeight = str(values, 'fontWeight', '700');\n const lineHeight = str(values, 'lineHeight', '140%');\n const letterSpacing = str(values, 'letterSpacing', 'normal');\n const fontFamily = getFontFamily(values);\n const tag = str(values, 'headingType', 'h1');\n const text = textContent(values, 'Heading');\n\n const inner = `<${tag} style=\"margin:0;font-size:${fontSize};color:${color};text-align:${textAlign};font-weight:${fontWeight};line-height:${lineHeight};letter-spacing:${letterSpacing};font-family:${fontFamily};\">${text}</${tag}>`;\n return emailTableCell(inner, { padding });\n },\n },\n};\n","/**\n * @module paragraph-tool\n *\n * Block paragraph with configurable line-height and letter-spacing.\n *\n * Email compatibility: Inline styles on a `<div>` inside table cell.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport type { ContentValues } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str } from '../helpers/value-extractor.js';\nimport { emailTableCell } from '../helpers/email-html.js';\nimport { SPACING_GROUP } from './shared-options.js';\n\nexport const paragraphTool: LitToolDefinition = {\n name: 'paragraph',\n label: 'Paragraph',\n icon: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"/><line x1=\"3\" y1=\"14\" x2=\"17\" y2=\"14\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 3,\n options: {\n text: {\n title: 'Paragraph',\n options: {\n text: {\n label: 'Text',\n defaultValue: '<p style=\"font-size:14px;line-height:1.6;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>',\n widget: 'rich_text',\n },\n },\n },\n style: {\n title: 'Style',\n options: {\n color: { label: 'Text Color', defaultValue: '#374151', widget: 'color_picker' },\n textAlign: { label: 'Text Align', defaultValue: 'left', widget: 'alignment' },\n lineHeight: { label: 'Line Height', defaultValue: '160%', widget: 'text' },\n letterSpacing: { label: 'Letter Spacing', defaultValue: 'normal', widget: 'text' },\n },\n },\n spacing: SPACING_GROUP,\n },\n defaultValues: {\n text: '<p style=\"font-size:14px;line-height:1.6;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>',\n color: '#374151', lineHeight: '160%', letterSpacing: 'normal',\n textAlign: 'left', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const color = str(values, 'color', '#374151');\n const lineHeight = str(values, 'lineHeight', '160%');\n const textAlign = str(values, 'textAlign', 'left');\n return html`<div style=\"color:${color};line-height:${lineHeight};text-align:${textAlign};\">${unsafeHTML(str(values, 'text'))}</div>`;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const color = str(values, 'color', '#374151');\n const lineHeight = str(values, 'lineHeight', '160%');\n const textAlign = str(values, 'textAlign', 'left');\n const letterSpacing = str(values, 'letterSpacing', 'normal');\n const inner = `<div style=\"font-size:14px;color:${color};line-height:${lineHeight};text-align:${textAlign};letter-spacing:${letterSpacing};word-wrap:break-word;\">${str(values, 'text')}</div>`;\n return emailTableCell(inner, { padding });\n },\n },\n};\n","/**\n * @module image-tool\n *\n * Responsive image block with optional link and border-radius.\n *\n * Email compatibility: Uses `<img>` with explicit width attribute,\n * max-width:100% for responsive scaling, display:block to remove\n * the bottom gap. Alt text required for accessibility.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport type { ContentValues, ExportRenderContext } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str, imageUrl, imageMeta, linkAction } from '../helpers/value-extractor.js';\nimport { emailTableCell } from '../helpers/email-html.js';\nimport { SPACING_GROUP, GENERAL_GROUP } from './shared-options.js';\n\nexport const imageTool: LitToolDefinition = {\n name: 'image',\n label: 'Image',\n icon: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 3,\n options: {\n image: {\n title: 'Image',\n options: {\n src: { label: 'Image URL', defaultValue: '', widget: 'image_upload' },\n alt: { label: 'Alt Text', defaultValue: '', widget: 'text' },\n href: { label: 'Link URL', defaultValue: '', widget: 'text' },\n target: { label: 'Link Target', defaultValue: '_blank', widget: 'text' },\n },\n },\n style: {\n title: 'Style',\n options: {\n width: {\n label: 'Width', defaultValue: '100%', widget: 'dropdown',\n widgetParams: { options: [\n { label: 'Auto', value: 'auto' }, { label: '25%', value: '25%' },\n { label: '50%', value: '50%' }, { label: '75%', value: '75%' },\n { label: '100%', value: '100%' },\n ]},\n },\n align: { label: 'Align', defaultValue: 'center', widget: 'alignment' },\n borderRadius: { label: 'Border Radius', defaultValue: '0px', widget: 'text' },\n },\n },\n spacing: SPACING_GROUP,\n general: GENERAL_GROUP,\n },\n defaultValues: {\n src: 'https://placehold.co/600x200/e2e8f0/64748b?text=Drop+Image+Here',\n alt: 'Image', href: '', target: '_blank', width: '100%',\n maxWidth: '100%', align: 'center', borderRadius: '0px', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const src = imageUrl(values.src);\n const alt = str(values, 'alt');\n const meta = imageMeta(values.src);\n const width = meta.maxWidth || str(values, 'width', '100%');\n const borderRadius = str(values, 'borderRadius', '0px');\n const align = str(values, 'textAlign', str(values, 'align', 'center'));\n\n if (!src) {\n return html`<div style=\"text-align:${align};\"><div style=\"background:#f1f5f9;border:2px dashed #cbd5e1;border-radius:8px;padding:40px 20px;text-align:center;color:#94a3b8;font-size:13px;\">No image set. Enter a URL in the property panel.</div></div>`;\n }\n return html`<div style=\"text-align:${align};\"><img src=${src} alt=${alt} style=\"display:inline-block;max-width:100%;width:${width};border-radius:${borderRadius};border:0;\" /></div>`;\n },\n renderHtml(values: ContentValues, ctx: ExportRenderContext): string {\n const padding = str(values, 'containerPadding', '10px');\n const src = imageUrl(values.src);\n const alt = str(values, 'alt');\n const link = linkAction(values);\n const meta = imageMeta(values.src);\n const width = meta.maxWidth || str(values, 'width', '100%');\n const borderRadius = str(values, 'borderRadius', '0px');\n const align = str(values, 'textAlign', str(values, 'align', 'center'));\n // Calculate pixel width: percentage of column or absolute pixels\n let widthPx: number;\n if (width.includes('%')) {\n widthPx = Math.round(ctx.columnWidth * (parseFloat(width) / 100));\n } else if (width === 'auto') {\n widthPx = meta.width || ctx.columnWidth;\n } else {\n widthPx = parseInt(width) || ctx.columnWidth;\n }\n const brStyle = borderRadius !== '0px' ? `border-radius:${borderRadius};` : '';\n\n const imgTag = `<img align=\"${align}\" border=\"0\" src=\"${src}\" alt=\"${alt}\" title=\"${alt}\" style=\"display:block;border:0;height:auto;width:100%;max-width:${widthPx}px;${brStyle}\" width=\"${widthPx}\" />`;\n const content = link.href ? `<a href=\"${link.href}\" target=\"${link.target}\" style=\"text-decoration:none;\">${imgTag}</a>` : imgTag;\n return emailTableCell(content, { padding, align });\n },\n },\n};\n","/**\n * @module button-tool\n *\n * Call-to-action button with customizable colors, border-radius, and sizing.\n *\n * Email compatibility: Uses `<a>` tag styled as button with inline styles.\n * Includes VML roundrect fallback for Outlook border-radius support.\n * Uses mso-border-alt for Outlook padding.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport type { ContentValues } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str, buttonColors } from '../helpers/value-extractor.js';\nimport { emailTableCell, vmlRoundrectButton } from '../helpers/email-html.js';\nimport { SPACING_GROUP, GENERAL_GROUP, fontWeightProp, BUTTON_FONT_SIZE_OPTIONS } from './shared-options.js';\n\nexport const buttonTool: LitToolDefinition = {\n name: 'button',\n label: 'Button',\n icon: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"7\" width=\"20\" height=\"10\" rx=\"2\"/><path d=\"M12 7v10\"/><path d=\"m8 12 4-3 4 3\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 4,\n options: {\n button: {\n title: 'Button',\n options: {\n text: { label: 'Button Text', defaultValue: 'Click Me', widget: 'text' },\n href: { label: 'Link URL', defaultValue: '#', widget: 'text' },\n target: { label: 'Target', defaultValue: '_blank', widget: 'text' },\n },\n },\n style: {\n title: 'Style',\n options: {\n backgroundColor: { label: 'Button Color', defaultValue: '#3b82f6', widget: 'color_picker' },\n textColor: { label: 'Text Color', defaultValue: '#ffffff', widget: 'color_picker' },\n fontSize: {\n label: 'Font Size', defaultValue: '14px', widget: 'dropdown',\n widgetParams: { options: [...BUTTON_FONT_SIZE_OPTIONS] },\n },\n fontWeight: fontWeightProp('700', true),\n borderRadius: { label: 'Border Radius', defaultValue: '4px', widget: 'text' },\n buttonWidth: {\n label: 'Width', defaultValue: 'auto', widget: 'dropdown',\n widgetParams: { options: [\n { label: 'Auto', value: 'auto' }, { label: '100%', value: '100%' }, { label: '50%', value: '50%' },\n ]},\n },\n textAlign: { label: 'Align', defaultValue: 'center', widget: 'alignment' },\n buttonPadding: { label: 'Button Padding', defaultValue: '10px 20px', widget: 'padding' },\n borderColor: { label: 'Border Color', defaultValue: '', widget: 'color_picker' },\n borderWidth: { label: 'Border Width', defaultValue: '0px', widget: 'text' },\n },\n },\n spacing: SPACING_GROUP,\n general: GENERAL_GROUP,\n },\n defaultValues: {\n text: 'Click Me', href: '#', target: '_blank', backgroundColor: '#3b82f6',\n textColor: '#ffffff', fontSize: '14px', fontWeight: '700', borderRadius: '4px',\n buttonWidth: 'auto', textAlign: 'center', buttonPadding: '10px 20px',\n borderColor: '', borderWidth: '0px', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n \n const { bg, color } = buttonColors(values);\n const fontSize = str(values, 'fontSize', '14px');\n const fontWeight = str(values, 'fontWeight', '700');\n const radius = str(values, 'borderRadius', '4px');\n const btnPad = str(values, 'buttonPadding', str(values, 'padding', '10px 20px'));\n const text = str(values, 'text', 'Click Me');\n const align = str(values, 'textAlign', 'center');\n const btnWidth = str(values, 'buttonWidth', 'auto');\n const bw = str(values, 'borderWidth', '0px');\n const bc = str(values, 'borderColor', bg);\n const borderStyle = bw !== '0px' ? `border:${bw} solid ${bc};` : 'border:none;';\n const widthStyle = btnWidth === 'auto' ? 'display:inline-block;' : `display:block;width:${btnWidth};`;\n\n return html`\n <div style=\"text-align:${align};\">\n <a style=\"${widthStyle}background-color:${bg};color:${color};font-size:${fontSize};font-weight:${fontWeight};border-radius:${radius};padding:${btnPad};text-decoration:none;text-align:center;${borderStyle}cursor:pointer;font-family:arial,helvetica,sans-serif;\">${text}</a>\n </div>\n `;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const { bg, color } = buttonColors(values);\n const fontSize = str(values, 'fontSize', '14px');\n const fontWeight = str(values, 'fontWeight', '700');\n const radius = str(values, 'borderRadius', '4px');\n const btnPad = str(values, 'buttonPadding', str(values, 'padding', '10px 20px'));\n const text = str(values, 'text', 'Click Me');\n const align = str(values, 'textAlign', 'center');\n const href = str(values, 'href', '#');\n const target = str(values, 'target', '_blank');\n const bw = str(values, 'borderWidth', '0px');\n const bc = str(values, 'borderColor', bg);\n const borderStyle = bw !== '0px' ? `border:${bw} solid ${bc};` : 'border:none;';\n\n const vml = vmlRoundrectButton(text, href, { bgColor: bg, textColor: color, fontSize, fontWeight, borderRadius: radius });\n const vmlOpen = vml ? `${vml}\\n <!--[if !mso]><!-->` : '<!--[if !mso]><!-->';\n const vmlClose = '<!--<![endif]-->';\n\n const inner = `<div align=\"${align}\">\n ${vmlOpen}\n <a href=\"${href}\" target=\"${target}\" style=\"display:inline-block;text-decoration:none;text-align:center;color:${color};background-color:${bg};border-radius:${radius};font-size:${fontSize};font-weight:${fontWeight};padding:${btnPad};font-family:arial,helvetica,sans-serif;${borderStyle}mso-border-alt:none;\"><span style=\"line-height:120%;\">${text}</span></a>\n ${vmlClose}\n </div>`;\n return emailTableCell(inner, { padding, align });\n },\n },\n};\n","/**\n * @module divider-tool\n *\n * Horizontal line divider with configurable style, width, and color.\n *\n * Email compatibility: Uses border-top on a nested table for consistent rendering.\n */\n\nimport { html, TemplateResult } from 'lit';\nimport type { ContentValues } from '@emabuild/types';\nimport type { LitToolDefinition } from '../tool-registry.js';\nimport { str } from '../helpers/value-extractor.js';\nimport { emailTableCell } from '../helpers/email-html.js';\nimport { SPACING_GROUP, GENERAL_GROUP_MINIMAL } from './shared-options.js';\n\nexport const dividerTool: LitToolDefinition = {\n name: 'divider',\n label: 'Divider',\n icon: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/></svg>`,\n supportedDisplayModes: ['email', 'web'],\n position: 5,\n options: {\n style: {\n title: 'Style',\n options: {\n borderTopWidth: { label: 'Width', defaultValue: '1px', widget: 'text' },\n borderTopStyle: {\n label: 'Style', defaultValue: 'solid', widget: 'dropdown',\n widgetParams: { options: [\n { label: 'Solid', value: 'solid' }, { label: 'Dashed', value: 'dashed' },\n { label: 'Dotted', value: 'dotted' }, { label: 'Double', value: 'double' },\n ]},\n },\n borderTopColor: { label: 'Color', defaultValue: '#cccccc', widget: 'color_picker' },\n width: { label: 'Line Width', defaultValue: '100%', widget: 'text' },\n },\n },\n spacing: SPACING_GROUP,\n general: GENERAL_GROUP_MINIMAL,\n },\n defaultValues: {\n borderTopWidth: '1px', borderTopStyle: 'solid', borderTopColor: '#cccccc',\n width: '100%', containerPadding: '10px',\n },\n renderer: {\n renderEditor(values: ContentValues): TemplateResult {\n const padding = str(values, 'containerPadding', '10px');\n const width = str(values, 'width', '100%');\n const border = `${str(values, 'borderTopWidth', '1px')} ${str(values, 'borderTopStyle', 'solid')} ${str(values, 'borderTopColor', '#cccccc')}`;\n return html`<div><div style=\"border-top:${border};width:${width};margin:0 auto;\"></div></div>`;\n },\n renderHtml(values: ContentValues): string {\n const padding = str(values, 'containerPadding', '10px');\n const width = str(values, 'width', '100%');\n const border = `${str(values, 'borderTopWidth', '1px')} ${str(values, 'borderTopStyle', 'solid')} ${str(values, 'borderTopColor', '#cccccc')}`;\n const inner = `<table role=\"presentation\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"${width}\" style=\"border-collapse:collapse;border-top:${border};\"><tbody><tr><td style=\"font-size:0;line-height:0;\">&nbsp;</td></tr></tbody></table>`;\n return emailTableCell(inner, { padding, align: 'center' });\n },\n },\n};\n","/**\n * @module tool-manifest\n *\n * Defines which tools are loaded eagerly (in the initial bundle)\n * and which are loaded lazily (on first use).\n *\n * Eager tools: text, heading, paragraph, image, button, divider\n * — these are the most commonly used and should be available instantly.\n *\n * Lazy tools: html, social, menu, video, timer, table, form\n * — these are loaded on-demand when first dragged into the canvas.\n */\n\nimport type { LitToolDefinition, LazyToolMeta, LazyToolLoader } from '../tool-registry.js';\n\n// ── Eager imports (included in initial bundle) ───────────────\nimport { textTool } from './text-tool.js';\nimport { headingTool } from './heading-tool.js';\nimport { paragraphTool } from './paragraph-tool.js';\nimport { imageTool } from './image-tool.js';\nimport { buttonTool } from './button-tool.js';\nimport { dividerTool } from './divider-tool.js';\n\n/** Tools loaded eagerly in the initial bundle */\nexport const eagerTools: LitToolDefinition[] = [\n textTool,\n headingTool,\n paragraphTool,\n imageTool,\n buttonTool,\n dividerTool,\n];\n\n/** Tools loaded lazily on first use — metadata for sidebar display + loader */\nexport const lazyTools: Array<{ meta: LazyToolMeta; loader: LazyToolLoader }> = [\n {\n meta: { name: 'html', label: 'HTML', icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"16 18 22 12 16 6\"/><polyline points=\"8 6 2 12 8 18\"/></svg>', position: 6 },\n loader: () => import('./html-tool.js').then((m) => m.htmlTool),\n },\n {\n meta: { name: 'social', label: 'Social', icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"18\" cy=\"5\" r=\"3\"/><circle cx=\"6\" cy=\"12\" r=\"3\"/><circle cx=\"18\" cy=\"19\" r=\"3\"/><line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\"/><line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\"/></svg>', position: 8 },\n loader: () => import('./social-tool.js').then((m) => m.socialTool),\n },\n {\n meta: { name: 'menu', label: 'Menu', icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><line x1=\"4\" y1=\"6\" x2=\"20\" y2=\"6\"/><line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>', position: 9 },\n loader: () => import('./menu-tool.js').then((m) => m.menuTool),\n },\n {\n meta: { name: 'video', label: 'Video', icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polygon points=\"5 3 19 12 5 21 5 3\"/></svg>', position: 10 },\n loader: () => import('./video-tool.js').then((m) => m.videoTool),\n },\n {\n meta: { name: 'timer', label: 'Timer', icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><polyline points=\"12 6 12 12 16 14\"/></svg>', position: 11 },\n loader: () => import('./timer-tool.js').then((m) => m.timerTool),\n },\n {\n meta: { name: 'table', label: 'Table', icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M3 15h18\"/><path d=\"M9 3v18\"/><path d=\"M15 3v18\"/></svg>', position: 12 },\n loader: () => import('./table-tool.js').then((m) => m.tableTool),\n },\n {\n meta: { name: 'form', label: 'Form', icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><path d=\"M7 7h10\"/><path d=\"M7 12h10\"/><path d=\"M7 17h6\"/></svg>', position: 13 },\n loader: () => import('./form-tool.js').then((m) => m.formTool),\n },\n];\n","function w(e, i, n) {\n const t = n.backgroundColor || \"#e7e7e7\", c = n.contentWidth || \"600px\", p = n.fontFamily?.value || \"arial,helvetica,sans-serif\", u = n.textColor || \"#000000\", o = n.preheaderText || \"\" || \"&zwnj;\", s = `<div style=\"display:none;font-size:1px;color:${t};line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;\">${o}${\"&zwnj;&nbsp;\".repeat(80)}</div>`;\n return `<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\">\n<head>\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"x-apple-disable-message-reformatting\">\n <meta name=\"format-detection\" content=\"telephone=no,address=no,email=no,date=no,url=no\">\n <meta name=\"color-scheme\" content=\"light dark\">\n <meta name=\"supported-color-schemes\" content=\"light dark\">\n <title></title>\n <!--[if mso]>\n <noscript><xml>\n <o:OfficeDocumentSettings>\n <o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch>\n </o:OfficeDocumentSettings>\n </xml></noscript>\n <style type=\"text/css\">\n table, td, th { font-family: ${p} !important; }\n </style>\n <![endif]-->\n <!--[if !mso]><!-->\n <style type=\"text/css\">\n ${i}\n </style>\n <!--<![endif]-->\n <style type=\"text/css\">\n body { margin: 0; padding: 0; word-break: normal; }\n table, tr, td { vertical-align: top; border-collapse: collapse; }\n p { margin: 0; }\n a[x-apple-data-detectors='true'] { color: inherit !important; text-decoration: none !important; }\n </style>\n</head>\n<body class=\"clean-body u_body\" style=\"margin:0;padding:0;-webkit-text-size-adjust:100%;background-color:${t};color:${u};\">\n ${s}\n <table id=\"u_body\" role=\"presentation\" style=\"border-collapse:collapse;border-spacing:0;margin:0 auto;background-color:${t};width:100%;\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <tbody>\n <tr>\n <td style=\"vertical-align:top;\">\n <!--[if (mso)|(IE)]><table width=\"${parseInt(c)}\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td><![endif]-->\n ${e}\n <!--[if (mso)|(IE)]></td></tr></table><![endif]-->\n </td>\n </tr>\n </tbody>\n </table>\n</body>\n</html>`;\n}\nfunction x(e, i, n) {\n const t = parseInt(i.contentWidth || \"600\"), c = e.values.backgroundColor || \"\", p = e.values.columnsBackgroundColor || \"\", u = e.values.padding || \"0px\", g = e.cells.reduce((h, y) => h + y, 0), o = c ? `background-color:${c};` : \"\", s = e.values.backgroundImage;\n let a = \"\";\n if (s?.url) {\n const h = s.repeat === !0 || s.repeat === \"repeat\" ? \"repeat\" : \"no-repeat\", y = s.cover === !0 ? \"cover\" : s.fullWidth === !0 ? \"100% auto\" : \"auto\", f = s.center !== !1 ? \"center top\" : \"left top\";\n a = `background-image:url('${s.url}');background-repeat:${h};background-position:${f};background-size:${y};`;\n }\n const r = e.columns.length > 1, d = e.columns.map((h, y) => {\n const f = Math.round(e.cells[y] / g * t);\n return { colHtml: k(h, f, p, i, n), colWidthPx: f };\n });\n let m;\n if (r) {\n const h = d.map(\n ({ colHtml: y, colWidthPx: f }) => `<!--[if (mso)|(IE)]><td align=\"center\" width=\"${f}\" style=\"width:${f}px;padding:0px;\" valign=\"top\"><![endif]-->${y}<!--[if (mso)|(IE)]></td><![endif]-->`\n );\n m = `<!--[if (mso)|(IE)]><table role=\"presentation\" width=\"${t}\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><![endif]-->${h.join(\"\")}<!--[if (mso)|(IE)]></tr></table><![endif]-->`;\n } else\n m = d.map(({ colHtml: h }) => h).join(\"\");\n const b = e.values.hideDesktop ? \" u_hide_desktop\" : \"\", v = e.values.hideMobile ? \" u_hide_mobile\" : \"\";\n return `<div class=\"u_row${b}${v}\" style=\"padding:${u};${o}${a}\">\n <div style=\"margin:0 auto;max-width:${t}px;${r ? \"font-size:0;\" : \"\"}text-align:center;\">${m}</div>\n</div>`;\n}\nfunction k(e, i, n, t, c) {\n const p = e.values.backgroundColor || n || \"\", u = e.values.padding || \"0px\", g = e.values.borderRadius || \"0px\", o = p ? `background-color:${p};` : \"\", s = e.contents.map((a) => {\n const r = c.get(a.type);\n if (!r) return `<!-- unknown tool: ${a.type} -->`;\n const d = {\n columnWidth: i,\n displayMode: \"email\",\n contentWidth: parseInt(t.contentWidth || \"600\"),\n bodyValues: t\n };\n let m = r(a.values, d);\n const b = !!a.values.hideDesktop, v = !!a.values.hideMobile;\n return (b || v) && (m = `<div class=\"${[b && \"u_hide_desktop\", v && \"u_hide_mobile\"].filter(Boolean).join(\" \")}\">${m}</div>`), m;\n }).join(`\n`);\n return `<div class=\"u_column\" style=\"display:inline-block;vertical-align:top;width:${i}px;max-width:${i}px;font-size:14px;text-align:left;\">\n <div style=\"width:100%;${o}${g !== \"0px\" ? `border-radius:${g};` : \"\"}\">\n <div style=\"padding:${u};\">\n ${s || \"&nbsp;\"}\n </div>\n </div>\n</div>`;\n}\nfunction $(e) {\n return `\n@media only screen and (min-width: ${e + 20}px) {\n .u_row .u_column { display: inline-block !important; }\n}\n\n@media only screen and (max-width: ${e + 20}px) {\n .u_row .u_column {\n display: block !important;\n width: 100% !important;\n max-width: 100% !important;\n }\n .u_row {\n width: 100% !important;\n }\n}\n\n@media only screen and (max-width: 620px) {\n .u_row-container {\n max-width: 100% !important;\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n /* Dark mode overrides — add per-client rules as needed */\n}\n\n/* Outlook dark mode */\n[data-ogsb] body,\n[data-ogsb] table,\n[data-ogsb] td {\n /* Preserve original colors */\n}\n\n.u_hide_desktop { display: block !important; }\n.u_hide_mobile { display: block !important; }\n\n@media only screen and (max-width: ${e + 20}px) {\n .u_hide_desktop { display: block !important; }\n .u_hide_mobile { display: none !important; }\n}\n\n@media only screen and (min-width: ${e + 21}px) {\n .u_hide_desktop { display: none !important; }\n .u_hide_mobile { display: block !important; }\n}`;\n}\nconst _ = [\n \"box-sizing\",\n \"overflow-wrap\",\n \"word-break\",\n \"word-wrap\",\n \"outline\",\n \"cursor\",\n \"transition\",\n \"animation\",\n \"transform\",\n \"z-index\",\n \"display:\\\\s*flex\",\n \"display:\\\\s*grid\",\n \"gap\"\n], C = new RegExp(\n `(?:;\\\\s*|^\\\\s*)(${_.join(\"|\")})\\\\s*:[^;]*;?`,\n \"gi\"\n), E = /var\\(--[^)]*\\)/gi;\nfunction I(e) {\n return e.replace(/style=\"([^\"]*)\"/gi, (i, n) => {\n let t = n;\n return t = t.replace(C, \"\"), t = t.replace(E, \"inherit\"), t = t.replace(/;\\s*;/g, \";\").replace(/^\\s*;\\s*/, \"\").replace(/;\\s*$/, \"\").trim(), t ? `style=\"${t}\"` : \"\";\n });\n}\nfunction M(e, i, n) {\n const t = e.body.values, c = parseInt(t.contentWidth || \"600\"), p = e.body.rows.map((d) => x(d, t, i)).join(`\n`), u = $(c), g = I(p);\n let o = w(g, u, t);\n if (n?.mergeTags)\n for (const [d, m] of Object.entries(n.mergeTags))\n o = o.replaceAll(`{{${d}}}`, m);\n const s = o.match(/<body[^>]*>([\\s\\S]*)<\\/body>/i), a = o.match(/<style[^>]*>([\\s\\S]*?)<\\/style>/gi), r = [];\n return t.fontFamily?.url && r.push(t.fontFamily.url), {\n design: structuredClone(e),\n html: o,\n chunks: {\n body: s?.[1] ?? p,\n css: a?.map((d) => d.replace(/<\\/?style[^>]*>/gi, \"\")).join(`\n`) ?? u,\n fonts: r,\n js: \"\"\n }\n };\n}\nfunction P(e) {\n const i = [], n = [];\n e.includes(\"<!DOCTYPE\") || i.push({ rule: \"doctype\", message: \"Missing <!DOCTYPE> declaration. Required for consistent rendering.\", severity: \"error\" }), (!e.includes(\"<meta\") || !e.includes(\"charset\")) && i.push({ rule: \"charset\", message: 'Missing charset meta tag. Add <meta charset=\"UTF-8\">.', severity: \"error\" }), e.includes(\"viewport\") || n.push({ rule: \"viewport\", message: \"Missing viewport meta tag. Needed for responsive rendering on mobile.\", severity: \"warning\" });\n const t = (e.match(/<table/gi) || []).length, c = (e.match(/role=\"presentation\"/gi) || []).length;\n t > 0 && c < t * 0.5 && n.push({ rule: \"table-role\", message: `Only ${c}/${t} tables have role=\"presentation\". Screen readers may interpret layout tables as data tables.`, severity: \"warning\" });\n const p = e.match(/<img[^>]*>/gi) || [];\n for (const l of p)\n l.includes(\"alt=\") || i.push({ rule: \"img-alt\", message: \"Image missing alt attribute. Required for accessibility and when images are blocked.\", severity: \"error\" }), (!l.includes(\"style=\") || !l.includes(\"display\")) && n.push({ rule: \"img-display\", message: \"Image without display:block may have a bottom gap in some email clients.\", severity: \"warning\" }), (l.includes('width=\"100%\"') || !l.includes(\"width=\") && !l.includes(\"width:\")) && n.push({ rule: \"img-width\", message: \"Image without explicit pixel width. Some email clients ignore percentage widths.\", severity: \"warning\" });\n const u = e.match(/<style[^>]*>[\\s\\S]*?<\\/style>/gi) || [], g = e.includes('style=\"');\n u.length > 0 && !e.includes(\"@media\") && n.push({ rule: \"no-media-queries\", message: \"Style block found but no @media queries. Consider adding responsive breakpoints.\", severity: \"warning\" }), !g && t > 0 && i.push({ rule: \"inline-styles\", message: \"No inline styles detected. Gmail and many clients strip <style> tags — inline styles are essential.\", severity: \"error\" });\n const o = [\"position:fixed\", \"position:absolute\", \"display:flex\", \"display:grid\", \"gap:\", \"transform:\", \"animation:\"];\n for (const l of o)\n e.includes('style=\"') && e.match(new RegExp(`style=\"[^\"]*${l.replace(\":\", \":\\\\s*\")}`, \"i\")) && n.push({ rule: \"unsupported-css\", message: `CSS property \"${l.replace(\":\", \"\")}\" not supported in most email clients.`, severity: \"warning\" });\n e.includes(\"<!--[if\") || n.push({ rule: \"mso-conditionals\", message: \"No MSO conditional comments found. Outlook may not render multi-column layouts correctly.\", severity: \"warning\" }), !e.includes(\"xmlns:v\") && !e.includes(\"xmlns:o\") && n.push({ rule: \"mso-namespace\", message: \"Missing Microsoft Office XML namespaces. May affect Outlook rendering.\", severity: \"warning\" });\n const a = (e.match(/<a[^>]*>/gi) || []).filter((l) => !l.includes(\"style=\"));\n a.length > 0 && n.push({ rule: \"link-color\", message: `${a.length} link(s) without inline styles. Email clients override unstyled link colors.`, severity: \"warning\" }), !e.includes(\"color-scheme\") && !e.includes(\"prefers-color-scheme\") && n.push({ rule: \"dark-mode\", message: \"No dark mode support detected. Consider adding color-scheme meta and prefers-color-scheme media query.\", severity: \"warning\" });\n const r = Math.round(e.length / 1024);\n r > 102 ? i.push({ rule: \"size-limit\", message: `Email HTML is ${r}KB. Gmail clips emails larger than 102KB.`, severity: \"error\" }) : r > 80 && n.push({ rule: \"size-warning\", message: `Email HTML is ${r}KB. Getting close to Gmail's 102KB clip limit.`, severity: \"warning\" }), !e.includes(\"display:none\") && !e.includes(\"max-height:0\") && n.push({ rule: \"preheader\", message: \"No preheader text detected. Preheader text improves open rates in inbox previews.\", severity: \"warning\" });\n const d = 100, m = i.length * 15, b = n.length * 5, v = Math.max(0, d - m - b);\n return {\n valid: i.length === 0,\n errors: i,\n warnings: n,\n score: v\n };\n}\nexport {\n $ as getResponsiveCss,\n M as renderDesignToHtml,\n x as renderRow,\n P as validateEmailHtml,\n w as wrapInDocumentShell\n};\n//# sourceMappingURL=index.js.map\n","/**\n * @module unlayer-adapter\n *\n * Bidirectional adapter between Unlayer and Emabuild JSON design formats.\n *\n * Usage:\n * ```ts\n * import { fromUnlayer, toUnlayer } from '@emabuild/core/compat/unlayer-adapter';\n *\n * // Load an Unlayer design into Emabuild\n * const emabuildDesign = fromUnlayer(unlayerJson);\n * editor.loadDesign(emabuildDesign);\n *\n * // Export an Emabuild design as Unlayer-compatible JSON\n * editor.saveDesign((design) => {\n * const unlayerJson = toUnlayer(design);\n * });\n * ```\n */\n\nimport type {\n EmailDesign,\n DesignRow,\n DesignColumn,\n DesignContent,\n BackgroundImage,\n} from '@emabuild/types';\n\n// ── Unlayer-specific types (not exported, internal only) ─────\n\ninterface UnlayerAction {\n name: string;\n values: { href: string; target: string };\n attrs?: Record<string, string>;\n}\n\ninterface UnlayerImageSrc {\n url: string;\n width: number;\n height: number;\n maxWidth?: number;\n autoWidth?: boolean;\n}\n\ninterface UnlayerButtonColors {\n color: string;\n backgroundColor: string;\n hoverColor?: string;\n hoverBackgroundColor?: string;\n}\n\ninterface UnlayerBackgroundImage {\n url: string;\n fullWidth: boolean;\n repeat: boolean | string;\n size?: string;\n position?: string;\n center?: boolean;\n cover?: boolean;\n}\n\ninterface UnlayerMenuItem {\n key: string;\n text: string;\n link: UnlayerAction;\n}\n\n// ── Helpers ──────────────────────────────────────────────────\n\nfunction pxToNumber(val: unknown): number {\n if (typeof val === 'number') return val;\n if (typeof val === 'string') return parseInt(val, 10) || 0;\n return 0;\n}\n\nfunction numberToPx(val: unknown): string {\n if (typeof val === 'string') return val.includes('px') ? val : val + 'px';\n if (typeof val === 'number') return val + 'px';\n return '0px';\n}\n\n// ── BackgroundImage conversion ──────────────────────────────\n\nfunction bgImageFromUnlayer(ubg: UnlayerBackgroundImage | undefined): BackgroundImage {\n if (!ubg) return { url: '', fullWidth: true, repeat: false, center: true, cover: false };\n return {\n url: ubg.url || '',\n fullWidth: ubg.fullWidth ?? true,\n repeat: ubg.repeat ?? false,\n center: ubg.position === 'center' || ubg.center === true,\n cover: ubg.size === 'cover' || ubg.cover === true,\n };\n}\n\nfunction bgImageToUnlayer(bg: BackgroundImage): UnlayerBackgroundImage {\n return {\n url: bg.url || '',\n fullWidth: bg.fullWidth,\n repeat: bg.repeat,\n size: bg.cover ? 'cover' : 'custom',\n position: bg.center ? 'center' : 'top left',\n };\n}\n\n// ── Content values conversion ───────────────────────────────\n\nfunction contentFromUnlayer(type: string, uv: Record<string, unknown>): Record<string, unknown> {\n const v: Record<string, unknown> = { ...uv };\n\n // ── Image: src object → string, action → flat href/target, altText → alt\n if (type === 'image') {\n if (v.src && typeof v.src === 'object') {\n const srcObj = v.src as UnlayerImageSrc;\n v.src = srcObj.url || '';\n if (srcObj.width) v.maxWidth = srcObj.width + 'px';\n }\n if (v.altText !== undefined && v.alt === undefined) {\n v.alt = v.altText;\n delete v.altText;\n }\n if (v.action && typeof v.action === 'object') {\n const action = v.action as UnlayerAction;\n v.href = action.values?.href || '';\n v.target = action.values?.target || '_blank';\n delete v.action;\n }\n }\n\n // ── Button: action → flat, buttonColors → flat, size → flat, padding key\n if (type === 'button') {\n if (v.href && typeof v.href === 'object') {\n const action = v.href as UnlayerAction;\n v.href = action.values?.href || '';\n v.target = action.values?.target || '_blank';\n }\n if (v.buttonColors && typeof v.buttonColors === 'object') {\n const bc = v.buttonColors as UnlayerButtonColors;\n v.backgroundColor = bc.backgroundColor || v.backgroundColor;\n v.textColor = bc.color || v.textColor;\n delete v.buttonColors;\n }\n if (v.size && typeof v.size === 'object') {\n const size = v.size as Record<string, unknown>;\n v.buttonWidth = size.autoWidth ? 'auto' : (size.width ? numberToPx(size.width) : 'auto');\n delete v.size;\n }\n if (v.padding !== undefined && v.buttonPadding === undefined) {\n v.buttonPadding = v.padding;\n }\n if (v.border && typeof v.border === 'object') {\n const b = v.border as Record<string, unknown>;\n v.borderColor = b.borderTopColor || '';\n v.borderWidth = b.borderTopWidth || '0px';\n delete v.border;\n }\n // fontWeight: number → string\n if (typeof v.fontWeight === 'number') {\n v.fontWeight = String(v.fontWeight);\n }\n }\n\n // ── Heading: fontWeight number → string\n if (type === 'heading') {\n if (typeof v.fontWeight === 'number') {\n v.fontWeight = String(v.fontWeight);\n }\n }\n\n // ── Divider: nested border → flat keys\n if (type === 'divider') {\n if (v.border && typeof v.border === 'object') {\n const b = v.border as Record<string, unknown>;\n v.borderTopWidth = b.borderTopWidth || '1px';\n v.borderTopStyle = b.borderTopStyle || 'solid';\n v.borderTopColor = b.borderTopColor || '#cccccc';\n delete v.border;\n }\n }\n\n // ── Menu: Unlayer items → JSON string\n if (type === 'menu') {\n if (v.menu && typeof v.menu === 'object') {\n const menu = v.menu as { items?: UnlayerMenuItem[] };\n if (Array.isArray(menu.items)) {\n v.items = JSON.stringify(menu.items.map((item) => ({\n text: item.text || '',\n href: item.link?.values?.href || '#',\n })));\n }\n if ((v.menu as Record<string, unknown>).separator) {\n v.separator = (v.menu as Record<string, unknown>).separator;\n }\n delete v.menu;\n }\n if (v.linkColor && !v.color) {\n v.color = v.linkColor;\n }\n }\n\n return v;\n}\n\nfunction contentToUnlayer(type: string, v: Record<string, unknown>): Record<string, unknown> {\n const uv: Record<string, unknown> = { ...v };\n\n // ── Image: string → src object, flat href → action, alt → altText\n if (type === 'image') {\n const srcUrl = typeof uv.src === 'string' ? uv.src : '';\n uv.src = {\n url: srcUrl,\n width: pxToNumber(uv.maxWidth) || null,\n height: null,\n autoWidth: true,\n };\n if (uv.alt !== undefined) {\n uv.altText = uv.alt;\n delete uv.alt;\n }\n if (uv.href !== undefined || uv.target !== undefined) {\n uv.action = {\n name: 'web',\n values: { href: (uv.href as string) || '', target: (uv.target as string) || '_blank' },\n };\n delete uv.href;\n delete uv.target;\n }\n delete uv.maxWidth;\n }\n\n // ── Button: flat → action, flat → buttonColors, flat → size\n if (type === 'button') {\n if (typeof uv.href === 'string') {\n uv.href = {\n name: 'web',\n values: { href: uv.href, target: (uv.target as string) || '_blank' },\n };\n delete uv.target;\n }\n uv.buttonColors = {\n color: (uv.textColor as string) || '#ffffff',\n backgroundColor: (uv.backgroundColor as string) || '#3b82f6',\n hoverColor: (uv.textColor as string) || '#ffffff',\n hoverBackgroundColor: (uv.backgroundColor as string) || '#3b82f6',\n };\n if (uv.buttonWidth !== undefined) {\n uv.size = {\n autoWidth: uv.buttonWidth === 'auto',\n width: uv.buttonWidth === 'auto' ? '100%' : uv.buttonWidth,\n };\n delete uv.buttonWidth;\n }\n if (uv.buttonPadding !== undefined) {\n uv.padding = uv.buttonPadding;\n delete uv.buttonPadding;\n }\n if (uv.borderColor !== undefined || uv.borderWidth !== undefined) {\n uv.border = {\n borderTopWidth: uv.borderWidth || '0px',\n borderTopStyle: 'solid',\n borderTopColor: uv.borderColor || '',\n borderRightWidth: uv.borderWidth || '0px',\n borderRightStyle: 'solid',\n borderRightColor: uv.borderColor || '',\n borderBottomWidth: uv.borderWidth || '0px',\n borderBottomStyle: 'solid',\n borderBottomColor: uv.borderColor || '',\n borderLeftWidth: uv.borderWidth || '0px',\n borderLeftStyle: 'solid',\n borderLeftColor: uv.borderColor || '',\n };\n delete uv.borderColor;\n delete uv.borderWidth;\n }\n if (typeof uv.fontWeight === 'string') {\n uv.fontWeight = parseInt(uv.fontWeight, 10) || 400;\n }\n }\n\n // ── Heading: fontWeight string → number\n if (type === 'heading') {\n if (typeof uv.fontWeight === 'string') {\n uv.fontWeight = parseInt(uv.fontWeight, 10) || 400;\n }\n }\n\n // ── Divider: flat keys → nested border\n if (type === 'divider') {\n uv.border = {\n borderTopWidth: uv.borderTopWidth || '1px',\n borderTopStyle: uv.borderTopStyle || 'solid',\n borderTopColor: uv.borderTopColor || '#cccccc',\n };\n delete uv.borderTopWidth;\n delete uv.borderTopStyle;\n delete uv.borderTopColor;\n }\n\n // ── Menu: JSON string → Unlayer items\n if (type === 'menu') {\n if (typeof uv.items === 'string') {\n try {\n const items = JSON.parse(uv.items) as Array<{ text: string; href: string }>;\n uv.menu = {\n items: items.map((item, i) => ({\n key: String(i),\n text: item.text || '',\n link: {\n name: 'web',\n values: { href: item.href || '#', target: '_blank' },\n },\n })),\n };\n } catch { /* leave as-is */ }\n delete uv.items;\n }\n if (uv.color && !uv.linkColor) {\n uv.linkColor = uv.color;\n uv.textColor = uv.color;\n }\n }\n\n // ── Paragraph → text (Unlayer has no paragraph type)\n // Handled at content level in toUnlayer()\n\n return uv;\n}\n\n// ── Row-level conversion ────────────────────────────────────\n\nfunction rowFromUnlayer(urow: Record<string, unknown>): DesignRow {\n const values = (urow.values || {}) as Record<string, unknown>;\n\n // BackgroundImage conversion\n if (values.backgroundImage && typeof values.backgroundImage === 'object') {\n values.backgroundImage = bgImageFromUnlayer(values.backgroundImage as UnlayerBackgroundImage);\n }\n\n // Ensure hideMobile exists (Unlayer sometimes omits it)\n if (values.hideMobile === undefined) values.hideMobile = false;\n\n // Strip Unlayer-only UI flags (keep them as passthrough for round-trip)\n // selectable, draggable, duplicatable, deletable, hideable — left as-is\n\n const columns = ((urow.columns || []) as Record<string, unknown>[]).map((col) => columnFromUnlayer(col));\n\n return {\n id: urow.id as string,\n cells: urow.cells as number[],\n columns,\n values: values as any,\n };\n}\n\nfunction columnFromUnlayer(ucol: Record<string, unknown>): DesignColumn {\n const contents = ((ucol.contents || []) as Record<string, unknown>[]).map((c) => {\n const type = c.type as string;\n const vals = contentFromUnlayer(type, (c.values || {}) as Record<string, unknown>);\n return { id: c.id as string, type, values: vals as any };\n });\n\n return {\n id: ucol.id as string,\n contents,\n values: (ucol.values || {}) as any,\n };\n}\n\n// ══════════════════════════════════════════════════════════════\n// PUBLIC API\n// ══════════════════════════════════════════════════════════════\n\n/**\n * Convert an Unlayer design JSON to Emabuild format.\n *\n * Handles all known structural differences:\n * - Image src object → string\n * - Button/Image action objects → flat href/target\n * - Button colors nested → flat\n * - BackgroundImage format (size/position → center/cover)\n * - Divider border nested → flat\n * - Menu items nested → JSON string\n * - contentWidth number → string with px\n * - fontWeight number → string\n *\n * Unknown properties are preserved as-is (passthrough).\n */\nexport function fromUnlayer(unlayerDesign: Record<string, unknown>): EmailDesign {\n const body = (unlayerDesign.body || {}) as Record<string, unknown>;\n const bodyValues = (body.values || {}) as Record<string, unknown>;\n\n // contentWidth: number → string\n if (typeof bodyValues.contentWidth === 'number') {\n bodyValues.contentWidth = bodyValues.contentWidth + 'px';\n }\n\n // Body backgroundImage\n if (bodyValues.backgroundImage && typeof bodyValues.backgroundImage === 'object') {\n bodyValues.backgroundImage = bgImageFromUnlayer(bodyValues.backgroundImage as UnlayerBackgroundImage);\n }\n if (bodyValues.popupBackgroundImage && typeof bodyValues.popupBackgroundImage === 'object') {\n bodyValues.popupBackgroundImage = bgImageFromUnlayer(bodyValues.popupBackgroundImage as UnlayerBackgroundImage);\n }\n\n // LinkStyle: add defaults if missing\n if (bodyValues.linkStyle && typeof bodyValues.linkStyle === 'object') {\n const ls = bodyValues.linkStyle as Record<string, unknown>;\n delete ls.inherit; // Unlayer-only field\n }\n\n // Ensure body.id\n if (!body.id) body.id = 'u_body';\n\n const rows = ((body.rows || []) as Record<string, unknown>[]).map(rowFromUnlayer);\n const headers = ((body.headers || []) as Record<string, unknown>[]).map(rowFromUnlayer);\n const footers = ((body.footers || []) as Record<string, unknown>[]).map(rowFromUnlayer);\n\n // Recalculate counters from actual IDs in the design\n const counters = recalcCounters(rows, headers, footers);\n\n return {\n counters,\n body: {\n id: (body.id as string) || 'u_body',\n rows,\n headers,\n footers,\n values: bodyValues as any,\n },\n schemaVersion: 16,\n };\n}\n\n/**\n * Convert an Emabuild design JSON to Unlayer-compatible format.\n *\n * Handles all known structural differences (reverse of fromUnlayer):\n * - Image string → src object\n * - Flat href/target → action objects\n * - Flat button colors → nested buttonColors\n * - BackgroundImage center/cover → size/position\n * - Flat divider keys → nested border\n * - JSON string menu → nested items\n * - contentWidth string → number\n * - paragraph type → text type\n * - fontWeight string → number\n */\nexport function toUnlayer(design: EmailDesign): Record<string, unknown> {\n const bodyValues = { ...design.body.values } as Record<string, unknown>;\n\n // contentWidth: string → number\n if (typeof bodyValues.contentWidth === 'string') {\n bodyValues.contentWidth = parseInt(bodyValues.contentWidth, 10) || 600;\n }\n\n // Body backgroundImage\n if (bodyValues.backgroundImage && typeof bodyValues.backgroundImage === 'object') {\n bodyValues.backgroundImage = bgImageToUnlayer(bodyValues.backgroundImage as BackgroundImage);\n }\n if (bodyValues.popupBackgroundImage && typeof bodyValues.popupBackgroundImage === 'object') {\n bodyValues.popupBackgroundImage = bgImageToUnlayer(bodyValues.popupBackgroundImage as BackgroundImage);\n }\n\n const convertRow = (row: DesignRow): Record<string, unknown> => {\n const rv = { ...row.values } as Record<string, unknown>;\n if (rv.backgroundImage && typeof rv.backgroundImage === 'object') {\n rv.backgroundImage = bgImageToUnlayer(rv.backgroundImage as BackgroundImage);\n }\n // Add Unlayer UI flags if missing\n if (rv.selectable === undefined) rv.selectable = true;\n if (rv.draggable === undefined) rv.draggable = true;\n if (rv.duplicatable === undefined) rv.duplicatable = true;\n if (rv.deletable === undefined) rv.deletable = true;\n\n return {\n id: row.id,\n cells: row.cells,\n columns: row.columns.map((col) => ({\n id: col.id,\n contents: col.contents.map((content) => {\n // paragraph → text for Unlayer\n const type = content.type === 'paragraph' ? 'text' : content.type;\n const vals = contentToUnlayer(type, { ...content.values } as Record<string, unknown>);\n // Add Unlayer UI flags\n if (vals.selectable === undefined) vals.selectable = true;\n if (vals.draggable === undefined) vals.draggable = true;\n if (vals.duplicatable === undefined) vals.duplicatable = true;\n if (vals.deletable === undefined) vals.deletable = true;\n return { id: content.id, type, values: vals };\n }),\n values: col.values,\n })),\n values: rv,\n };\n };\n\n return {\n counters: design.counters,\n body: {\n id: design.body.id,\n rows: design.body.rows.map(convertRow),\n headers: design.body.headers.map(convertRow),\n footers: design.body.footers.map(convertRow),\n values: bodyValues,\n },\n schemaVersion: 12, // Unlayer uses version 12\n };\n}\n\n// ── Counter recalculation ───────────────────────────────────\n\nfunction recalcCounters(...rowGroups: DesignRow[][]): Record<string, number> {\n const counters: Record<string, number> = {};\n\n const bumpId = (id: string) => {\n // Extract prefix and number: \"u_row_3\" → prefix=\"u_row\", num=3\n const match = id.match(/^(.+?)(\\d+)$/);\n if (match) {\n const prefix = match[1].replace(/_$/, ''); // \"u_row_\" → \"u_row\"\n const num = parseInt(match[2], 10);\n counters[prefix] = Math.max(counters[prefix] || 0, num);\n }\n };\n\n for (const rows of rowGroups) {\n for (const row of rows) {\n bumpId(row.id);\n for (const col of row.columns) {\n bumpId(col.id);\n for (const content of col.contents) {\n bumpId(content.id);\n }\n }\n }\n }\n\n return counters;\n}\n","/**\n * @module InlineToolbar\n *\n * Floating formatting toolbar for inline text editing.\n * Appears above the selected text when a content block is in edit mode.\n * Uses document.execCommand for formatting (widely supported in contenteditable).\n */\n\nimport { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport type { MergeTagGroup } from '@emabuild/types';\n\n@customElement('me-inline-toolbar')\nexport class InlineToolbar extends LitElement {\n static styles = css`\n :host {\n position: fixed;\n z-index: 10000;\n display: none;\n }\n :host(.visible) {\n display: block;\n animation: fadeIn 0.15s ease;\n }\n @keyframes fadeIn {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .toolbar {\n display: flex;\n align-items: center;\n gap: 2px;\n padding: 4px 6px;\n background: #1e293b;\n border-radius: 10px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.2);\n }\n .btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n color: var(--me-grey-300);\n cursor: pointer;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 600;\n transition: all 0.1s ease;\n padding: 0;\n }\n .btn:hover { background: rgba(255,255,255,0.08); color: white; }\n .btn.active { background: rgba(93,118,139,0.4); color: white; }\n .separator {\n width: 1px;\n height: 20px;\n background: #334155;\n margin: 0 2px;\n }\n .btn svg {\n width: 16px;\n height: 16px;\n stroke: currentColor;\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n /* Merge tag dropdown */\n .merge-wrap { position: relative; }\n .merge-dropdown {\n position: absolute;\n top: calc(100% + 6px);\n left: 50%;\n transform: translateX(-50%);\n background: white;\n border: 1px solid var(--me-grey-200);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0,0,0,0.15);\n min-width: 200px;\n max-height: 260px;\n overflow-y: auto;\n z-index: 10;\n padding: 4px 0;\n }\n .merge-group-name {\n padding: 6px 12px 2px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--me-grey-500);\n font-family: sans-serif;\n }\n .merge-item {\n display: block;\n width: 100%;\n padding: 6px 12px;\n background: none;\n border: none;\n color: var(--me-grey-600);\n font-size: 13px;\n text-align: left;\n cursor: pointer;\n white-space: nowrap;\n }\n .merge-item:hover {\n background: var(--me-blue-50);\n color: var(--me-grey-900);\n }\n `;\n\n @property({ type: Boolean }) visible = false;\n @property({ attribute: false }) mergeTags: MergeTagGroup[] = [];\n @state() private mergeDropdownOpen = false;\n\n private _outsideClickHandler = (e: MouseEvent) => {\n if (!this.mergeDropdownOpen) return;\n const path = e.composedPath();\n if (!path.includes(this)) {\n this.mergeDropdownOpen = false;\n }\n };\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener('mousedown', this._outsideClickHandler, true);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('mousedown', this._outsideClickHandler, true);\n }\n\n private exec(command: string, value?: string) {\n document.execCommand(command, false, value);\n this.requestUpdate();\n }\n\n private isActive(command: string): boolean {\n try { return document.queryCommandState(command); } catch { return false; }\n }\n\n /** Position the toolbar above a given element */\n positionAbove(el: HTMLElement) {\n const rect = el.getBoundingClientRect();\n this.style.left = `${rect.left + rect.width / 2}px`;\n this.style.top = `${rect.top - 8}px`;\n this.style.transform = 'translate(-50%, -100%)';\n this.classList.add('visible');\n }\n\n hide() {\n this.classList.remove('visible');\n this.mergeDropdownOpen = false;\n }\n\n private insertMergeTag(value: string) {\n document.execCommand('insertHTML', false, value);\n this.mergeDropdownOpen = false;\n this.requestUpdate();\n }\n\n private toggleMergeDropdown(e: Event) {\n e.preventDefault();\n this.mergeDropdownOpen = !this.mergeDropdownOpen;\n }\n\n private handleLink() {\n if (this.isActive('createLink')) {\n this.exec('unlink');\n } else {\n const url = prompt('Enter URL:');\n if (url) this.exec('createLink', url);\n }\n }\n\n render() {\n return html`\n <div class=\"toolbar\" @mousedown=${(e: Event) => e.preventDefault()}>\n <button class=\"btn ${this.isActive('bold') ? 'active' : ''}\"\n @click=${() => this.exec('bold')} title=\"Bold (Ctrl+B)\">\n <strong>B</strong>\n </button>\n <button class=\"btn ${this.isActive('italic') ? 'active' : ''}\"\n @click=${() => this.exec('italic')} title=\"Italic (Ctrl+I)\">\n <em>I</em>\n </button>\n <button class=\"btn ${this.isActive('underline') ? 'active' : ''}\"\n @click=${() => this.exec('underline')} title=\"Underline (Ctrl+U)\">\n <u>U</u>\n </button>\n <button class=\"btn ${this.isActive('strikeThrough') ? 'active' : ''}\"\n @click=${() => this.exec('strikeThrough')} title=\"Strikethrough\">\n <s>S</s>\n </button>\n <div class=\"separator\"></div>\n <button class=\"btn ${this.isActive('createLink') ? 'active' : ''}\"\n @click=${this.handleLink} title=\"Link\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/></svg>\n </button>\n <div class=\"separator\"></div>\n <button class=\"btn\" @click=${() => this.exec('justifyLeft')} title=\"Align Left\">\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\"/><line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\"/></svg>\n </button>\n <button class=\"btn\" @click=${() => this.exec('justifyCenter')} title=\"Align Center\">\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\"/><line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\"/></svg>\n </button>\n <button class=\"btn\" @click=${() => this.exec('justifyRight')} title=\"Align Right\">\n <svg viewBox=\"0 0 24 24\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"/><line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\"/><line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\"/></svg>\n </button>\n ${this.mergeTags.length > 0 ? html`\n <div class=\"separator\"></div>\n <div class=\"merge-wrap\">\n <button class=\"btn ${this.mergeDropdownOpen ? 'active' : ''}\"\n @click=${this.toggleMergeDropdown} title=\"Insert Merge Tag\">\n <span style=\"font-size:13px;font-weight:700;letter-spacing:-0.5px;\">{x}</span>\n </button>\n ${this.mergeDropdownOpen ? html`\n <div class=\"merge-dropdown\" @mousedown=${(e: Event) => e.preventDefault()}>\n ${this.mergeTags.map(group => html`\n <div class=\"merge-group-name\">${group.name}</div>\n ${Object.entries(group.mergeTags).map(([_key, tag]) => html`\n <button class=\"merge-item\" @click=${() => this.insertMergeTag(tag.value)}>\n ${tag.name}\n </button>\n `)}\n `)}\n </div>\n ` : nothing}\n </div>\n ` : nothing}\n </div>\n `;\n }\n}\n","/**\n * @module ContentRenderer\n * Renders a single content block with selection/hover UI, drag support,\n * and inline WYSIWYG editing for text-based tools (text, heading, paragraph).\n *\n * Subscribes to: design, selection, hover, viewMode\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport type { DesignContent } from '@emabuild/types';\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry } from '../tools/tool-registry.js';\nimport { StoreController } from '../utils/store-controller.js';\nimport { dragState } from '../dnd/drag-state.js';\nimport './inline-toolbar.js';\nimport type { InlineToolbar } from './inline-toolbar.js';\n\n/** Tool types that support inline text editing */\nconst INLINE_EDITABLE_TYPES = new Set(['text', 'heading', 'paragraph']);\n\n/** Map tool type to the values key that holds the text content */\nfunction getTextKey(type: string): string {\n return type === 'html' ? 'html' : 'text';\n}\n\n@customElement('me-content-renderer')\nexport class ContentRenderer extends LitElement {\n static styles = css`\n :host {\n display: block; position: relative;\n transition: outline 0.15s ease, transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s ease;\n }\n :host(.selected) { outline: 2px solid var(--me-primary); outline-offset: -1px; box-shadow: 0 0 0 4px var(--me-primary-10); }\n :host(.hovered:not(.selected)) { outline: 2px dashed var(--me-primary-30); outline-offset: -1px; box-shadow: 0 0 0 4px var(--me-primary-5); }\n :host(.hovered.a11y-issue) {\n outline: 2px solid var(--me-danger) !important; outline-offset: -1px;\n animation: a11yPulse 1s ease-in-out infinite;\n }\n @keyframes a11yPulse {\n 0%, 100% { box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.15); }\n 50% { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.25); }\n }\n :host(.editing) { outline: 2px solid #32769B; outline-offset: -1px; }\n :host(.just-dropped) {\n animation: dropIn 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n :host(.just-duplicated) {\n animation: duplicateFlash 0.5s ease-out;\n }\n @keyframes duplicateFlash {\n 0% { background: var(--me-primary-10, rgba(93,118,139,0.1)); transform: scale(1.01); }\n 100% { background: transparent; transform: scale(1); }\n }\n :host(.removing) {\n animation: fadeRemove 0.25s ease-out forwards;\n pointer-events: none;\n }\n @keyframes fadeRemove {\n to { opacity: 0; transform: scale(0.96) translateY(-4px); height: 0; margin: 0; padding: 0; overflow: hidden; }\n }\n :host(.hidden-in-view) { opacity: 0.3; position: relative; }\n .hidden-badge {\n position: absolute; top: 4px; right: 4px; z-index: 5;\n background: #f59e0b; color: white; font-size: 10px; font-weight: 600;\n padding: 2px 6px; border-radius: 3px; font-family: sans-serif;\n pointer-events: none;\n }\n @keyframes dropIn {\n 0% { opacity: 0; transform: scale(0.92) translateY(-8px); }\n 100% { opacity: 1; transform: scale(1) translateY(0); }\n }\n /* Drag handle — straddles the right border, vertically centered */\n .drag-handle {\n display: none;\n position: absolute;\n top: 50%;\n right: -12px;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n background: var(--me-primary);\n color: white;\n border: 2px solid white;\n border-radius: 50%;\n cursor: grab;\n z-index: 20;\n align-items: center;\n justify-content: center;\n padding: 0;\n box-shadow: 0 1px 4px rgba(0,0,0,0.2);\n transition: background 0.15s ease, transform 0.15s ease;\n }\n .drag-handle:hover {\n background: var(--me-primary-dark);\n transform: translateY(-50%) scale(1.15);\n }\n .drag-handle:active { cursor: grabbing; }\n .drag-handle svg {\n width: 12px; height: 12px; fill: currentColor; stroke: none;\n }\n :host(.selected) .drag-handle,\n :host(.hovered) .drag-handle { display: flex; }\n :host(.editing) .drag-handle { display: none; }\n /* Action bar */\n .action-bar {\n display: none; position: absolute; top: -28px; right: 4px;\n background: var(--me-primary); border-radius: 6px; padding: 2px; gap: 2px; z-index: 10;\n align-items: center;\n }\n :host(.selected:not(.editing)) .action-bar { display: flex; }\n .action-bar-label {\n font-size: 10px; color: rgba(255,255,255,0.6); font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.03em;\n padding: 0 4px;\n }\n .action-btn {\n background: none; border: none; color: white; cursor: pointer;\n padding: 2px 6px; font-size: 12px; line-height: 1; border-radius: 2px;\n }\n .action-btn:hover { background: rgba(255,255,255,0.15); }\n .content-wrapper { position: relative; cursor: default; box-sizing: border-box; }\n /* Reset paragraph margins in user content to match email rendering.\n Override inline margin from external editors (e.g. margin: 1.25em 0px). */\n .content-wrapper p { margin: 0 !important; }\n .inline-editable {\n outline: none; cursor: text; min-height: 1em;\n }\n .inline-editable:focus { outline: none; }\n `;\n\n private storeCtrl = new StoreController(this, ['design', 'selection', 'viewMode']);\n\n @property({ attribute: false }) content!: DesignContent;\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n @property({ attribute: false }) toolRegistry!: ToolRegistry;\n\n @state() private editing = false;\n\n private toolbar: InlineToolbar | null = null;\n private editableEl: HTMLElement | null = null;\n\n // ── Event handlers ───────────────────────────────────────\n\n private handleClick(e: Event) {\n e.stopPropagation();\n if (!this.editing) {\n this.store.select(this.content.id);\n }\n }\n\n private handleDblClick(e: Event) {\n e.stopPropagation();\n if (INLINE_EDITABLE_TYPES.has(this.content.type)) {\n this.startEditing();\n }\n }\n\n private handleMouseEnter() {\n this.classList.add('hovered');\n this.store.hover(this.content.id);\n }\n private handleMouseLeave() {\n this.classList.remove('hovered');\n this.store.hover(null);\n }\n private handleDelete(e: Event) {\n e.stopPropagation();\n this.classList.add('removing');\n const id = this.content.id;\n this.addEventListener('animationend', () => this.store.removeContent(id), { once: true });\n }\n private handleDuplicate(e: Event) {\n e.stopPropagation();\n const cloned = this.store.duplicateContent(this.content.id);\n if (cloned) {\n // Flash the new element after render\n requestAnimationFrame(() => {\n const parent = this.parentElement;\n if (parent?.shadowRoot) {\n const el = parent.shadowRoot.querySelector(`[data-content-id=\"${cloned.id}\"]`) as HTMLElement;\n el?.classList.add('just-duplicated');\n setTimeout(() => el?.classList.remove('just-duplicated'), 600);\n }\n });\n }\n }\n\n /** Called from the drag handle only (not the whole block) */\n private handleDragStart(e: DragEvent) {\n e.stopPropagation();\n e.dataTransfer!.setData('application/maileditor-content', this.content.id);\n e.dataTransfer!.effectAllowed = 'move';\n this.style.opacity = '0.4';\n this.style.transform = 'scale(0.97)';\n dragState.startContentDrag(this.content.id, this);\n }\n\n private handleDragEnd() {\n this.style.transform = '';\n dragState.reset();\n }\n\n // ── Inline editing ───────────────────────────────────────\n\n private startEditing() {\n this.editing = true;\n this.classList.add('editing');\n this.storeCtrl.hostDisconnected();\n\n // Create a contenteditable overlay in the LIGHT DOM (document.body).\n // contenteditable inside Shadow DOM has cursor/selection bugs across browsers.\n // The overlay is positioned exactly over this element.\n const rect = this.getBoundingClientRect();\n const styles = this.getInlineStyles(this.content.values);\n const textKey = getTextKey(this.content.type);\n const textHtml = (this.content.values[textKey] as string) || '';\n\n const overlay = document.createElement('div');\n overlay.contentEditable = 'true';\n overlay.innerHTML = textHtml;\n Object.assign(overlay.style, {\n position: 'fixed',\n left: rect.left + 'px',\n top: rect.top + 'px',\n width: rect.width + 'px',\n minHeight: rect.height + 'px',\n zIndex: '9999',\n background: 'white',\n boxShadow: '0 0 0 2px #8b5cf6, 0 4px 16px rgba(0,0,0,0.15)',\n borderRadius: '2px',\n outline: 'none',\n boxSizing: 'border-box',\n });\n // Apply tool styles\n styles.split(';').forEach(s => {\n const [prop, val] = s.split(':').map(x => x?.trim());\n if (prop && val) {\n overlay.style.setProperty(prop, val);\n }\n });\n\n overlay.addEventListener('keydown', this.handleInlineKeydown);\n overlay.addEventListener('blur', this.handleOverlayBlur);\n\n document.body.appendChild(overlay);\n this.editableEl = overlay;\n overlay.focus();\n\n // Place cursor at end\n const sel = window.getSelection();\n const range = document.createRange();\n range.selectNodeContents(overlay);\n range.collapse(false);\n sel?.removeAllRanges();\n sel?.addRange(range);\n\n this.showToolbar();\n }\n\n private stopEditing() {\n if (!this.editing) return;\n\n // Save content from the overlay\n this.saveInlineContent();\n\n // Remove the overlay from the document\n if (this.editableEl) {\n this.editableEl.removeEventListener('keydown', this.handleInlineKeydown);\n this.editableEl.removeEventListener('blur', this.handleOverlayBlur);\n this.editableEl.remove();\n }\n\n this.editing = false;\n this.classList.remove('editing');\n this.editableEl = null;\n\n // Reconnect to store updates and re-render with saved content\n this.storeCtrl.hostConnected();\n this.requestUpdate();\n\n this.toolbar?.hide();\n }\n\n private saveInlineContent() {\n if (!this.editableEl) return;\n const newHtml = this.editableEl.innerHTML;\n const key = getTextKey(this.content.type);\n const currentVal = this.content.values[key];\n\n if (newHtml !== currentVal) {\n this.store.updateContentValues(this.content.id, { [key]: newHtml } as any);\n }\n }\n\n private handleInlineInput = () => {\n // Don't save to store while typing — that causes re-renders\n // which reset the cursor. Save only on blur (stopEditing).\n // Just reposition the toolbar.\n this.showToolbar();\n };\n\n private handleInlineBlur = (e: FocusEvent) => {\n const related = e.relatedTarget as HTMLElement | null;\n if (related && (related.closest('me-inline-toolbar') || this.toolbar?.contains(related))) {\n return;\n }\n setTimeout(() => {\n if (document.activeElement !== this.editableEl && !this.toolbar?.matches(':hover')) {\n this.stopEditing();\n }\n }, 150);\n };\n\n /** Blur handler for the light-DOM overlay */\n private handleOverlayBlur = (e: FocusEvent) => {\n const related = e.relatedTarget as HTMLElement | null;\n if (related && (related.closest('me-inline-toolbar') || this.toolbar?.contains(related))) {\n return;\n }\n setTimeout(() => {\n if (document.activeElement !== this.editableEl && !this.toolbar?.matches(':hover')) {\n this.stopEditing();\n }\n }, 200);\n };\n\n private handleInlineKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n this.stopEditing();\n }\n };\n\n private showToolbar() {\n if (!this.toolbar) {\n this.toolbar = document.createElement('me-inline-toolbar') as InlineToolbar;\n document.body.appendChild(this.toolbar);\n }\n this.toolbar.mergeTags = this.store.mergeTags;\n if (this.editableEl) {\n this.toolbar.positionAbove(this.editableEl);\n }\n }\n\n // ── Lightweight hover subscription (no re-render, class toggle only) ──\n private hoverUnsub: (() => void) | null = null;\n\n // ── Lifecycle ────────────────────────────────────────────\n\n connectedCallback() {\n super.connectedCallback();\n // Entrance animation on first mount\n this.classList.add('just-dropped');\n setTimeout(() => this.classList.remove('just-dropped'), 400);\n // Subscribe to hover channel for a11y-panel-triggered hovers (class toggle only, no re-render)\n if (this.store) {\n this.hoverUnsub = this.store.subscribeChannels(['hover'], () => {\n const isHoveredViaStore = this.store.hoveredId === this.content?.id;\n if (isHoveredViaStore) this.classList.add('hovered');\n else if (!this.matches(':hover')) this.classList.remove('hovered');\n });\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n if (this.editing) this.stopEditing();\n this.hoverUnsub?.();\n this.toolbar?.remove();\n this.toolbar = null;\n }\n\n // ── Render ───────────────────────────────────────────────\n\n render() {\n if (!this.store) return html``;\n const isSelected = this.store.selectedId === this.content.id;\n const viewMode = this.store.viewMode;\n const hideDesktop = !!this.content.values.hideDesktop;\n const hideMobile = !!this.content.values.hideMobile;\n const hiddenInView = (viewMode === 'desktop' && hideDesktop) || (viewMode === 'mobile' && hideMobile);\n\n const hasA11yIssue = this.store.a11yIssueIds.has(this.content.id);\n this.classList.toggle('selected', isSelected && !this.editing);\n this.classList.toggle('a11y-issue', hasA11yIssue);\n this.classList.toggle('hidden-in-view', hiddenInView);\n this.removeAttribute('draggable'); // drag only via handle\n this.dataset.contentId = this.content.id;\n\n // If another element got selected, stop editing\n if (this.editing && !isSelected) {\n this.stopEditing();\n }\n\n const tool = this.toolRegistry.get(this.content.type);\n\n // Lazy tool not loaded yet\n if (!tool && this.toolRegistry.has(this.content.type)) {\n this.toolRegistry.ensureLoaded(this.content.type).then(() => this.requestUpdate());\n return html`<div style=\"padding:16px;text-align:center;color:#9ca3af;font-size:13px;\">Loading ${this.content.type}...</div>`;\n }\n\n const hiddenLabel = hideDesktop ? 'Hidden on desktop' : hideMobile ? 'Hidden on mobile' : '';\n const isInlineEditable = INLINE_EDITABLE_TYPES.has(this.content.type);\n\n // ── Drag handle (shared between both modes) ──\n const dragHandle = html`\n <button class=\"drag-handle\" draggable=\"true\" title=\"Drag to move\"\n @dragstart=${(e: DragEvent) => this.handleDragStart(e)}\n @dragend=${() => this.handleDragEnd()}\n @mousedown=${(e: Event) => e.stopPropagation()}>\n <svg viewBox=\"0 0 16 16\"><circle cx=\"5\" cy=\"3\" r=\"1.5\"/><circle cx=\"11\" cy=\"3\" r=\"1.5\"/><circle cx=\"5\" cy=\"8\" r=\"1.5\"/><circle cx=\"11\" cy=\"8\" r=\"1.5\"/><circle cx=\"5\" cy=\"13\" r=\"1.5\"/><circle cx=\"11\" cy=\"13\" r=\"1.5\"/></svg>\n </button>\n `;\n\n // ── Render tool content ──\n const rendered = tool?.renderer.renderEditor(this.content.values, {\n isSelected, isHovered: this.classList.contains('hovered'), columnWidth: 600, displayMode: 'email',\n });\n\n // ── Inline editing mode ──\n if (this.editing && isInlineEditable) {\n return html`${dragHandle}<div class=\"content-wrapper\" style=\"visibility:hidden;\">${rendered}</div>`;\n }\n\n // Apply containerPadding at the wrapper level (with box-sizing: border-box)\n // so the padding doesn't shrink the content area\n const containerPadding = (this.content.values.containerPadding as string) || '0px';\n\n return html`\n ${hiddenInView ? html`<div class=\"hidden-badge\">${hiddenLabel}</div>` : ''}\n ${dragHandle}\n <div class=\"action-bar\">\n <span class=\"action-bar-label\">${this.content.type}</span>\n <button class=\"action-btn\" @click=${this.handleDuplicate} title=\"Duplicate\">&#10697;</button>\n <button class=\"action-btn\" @click=${this.handleDelete} title=\"Delete\">&#10005;</button>\n </div>\n <div class=\"content-wrapper\" style=\"padding:${containerPadding};\"\n @click=${this.handleClick}\n @dblclick=${this.handleDblClick}\n @mouseenter=${this.handleMouseEnter}\n @mouseleave=${this.handleMouseLeave}>\n ${rendered ?? html`<div style=\"padding:10px;color:#999;font-style:italic;\">Unknown tool: ${this.content.type}</div>`}\n </div>\n `;\n }\n\n /** Build inline CSS for the contenteditable area based on content values */\n private getInlineStyles(values: Record<string, unknown>): string {\n const parts: string[] = [];\n const s = (key: string, fallback = '') => {\n const v = values[key];\n return typeof v === 'string' ? v : typeof v === 'number' ? String(v) : fallback;\n };\n\n parts.push(`padding:${s('containerPadding', '10px')}`);\n\n const bgColor = s('backgroundColor');\n if (bgColor) parts.push(`background-color:${bgColor}`);\n\n const color = s('color');\n if (color) parts.push(`color:${color}`);\n\n const fontSize = s('fontSize');\n if (fontSize) parts.push(`font-size:${fontSize}`);\n\n const fontWeight = s('fontWeight');\n if (fontWeight) parts.push(`font-weight:${fontWeight}`);\n\n const lineHeight = s('lineHeight', '140%');\n parts.push(`line-height:${lineHeight}`);\n\n const textAlign = s('textAlign');\n if (textAlign) parts.push(`text-align:${textAlign}`);\n\n const letterSpacing = s('letterSpacing');\n if (letterSpacing && letterSpacing !== 'normal') parts.push(`letter-spacing:${letterSpacing}`);\n\n // Font family (handle object format)\n const ff = values.fontFamily;\n if (typeof ff === 'string') {\n parts.push(`font-family:${ff}`);\n } else if (ff && typeof ff === 'object') {\n parts.push(`font-family:${(ff as Record<string, unknown>).value || 'inherit'}`);\n }\n\n parts.push('word-break:break-word', 'outline:none', 'min-height:1em');\n\n return parts.join(';');\n }\n}\n","/** @module ColumnRenderer — Subscribes to: design */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { DesignColumn } from '@emabuild/types';\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry } from '../tools/tool-registry.js';\nimport { StoreController } from '../utils/store-controller.js';\nimport './content-renderer.js';\n\n@customElement('me-column-renderer')\nexport class ColumnRenderer extends LitElement {\n static styles = css`\n :host {\n display: block;\n min-height: 40px;\n position: relative;\n }\n .empty-column {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 60px;\n border: 2px dashed var(--me-grey-300, #d1d5db);\n border-radius: 8px;\n color: var(--me-grey-400, #9ca3af);\n font-size: 12px;\n font-family: sans-serif;\n margin: 4px;\n animation: emptyBreath 3s ease-in-out infinite;\n }\n @keyframes emptyBreath {\n 0%, 100% { border-color: var(--me-grey-300, #d1d5db); opacity: 0.6; }\n 50% { border-color: var(--me-primary, #5d768b); opacity: 1; }\n }\n .drop-indicator {\n height: 3px;\n background: #3b82f6;\n border-radius: 2px;\n margin: 0 4px;\n opacity: 0;\n transition: opacity 0.15s ease;\n }\n .drop-indicator.active {\n opacity: 1;\n }\n `;\n\n private storeCtrl = new StoreController(this, ['design']);\n\n @property({ attribute: false }) column!: DesignColumn;\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n @property({ attribute: false }) toolRegistry!: ToolRegistry;\n @property({ type: Number }) widthPercent = 100;\n\n render() {\n const padding = this.column.values.padding || '0px';\n const bgColor = this.column.values.backgroundColor || 'transparent';\n const contents = this.column.contents;\n\n this.dataset.columnId = this.column.id;\n this.style.width = `${this.widthPercent}%`;\n this.style.padding = padding;\n this.style.backgroundColor = bgColor;\n this.style.verticalAlign = 'top';\n this.style.boxSizing = 'border-box';\n\n if (contents.length === 0) {\n return html`\n <div class=\"empty-column\" data-column-id=${this.column.id}>\n Drag content here\n </div>\n `;\n }\n\n return html`\n ${repeat(contents, (c) => c.id, (content) => html`\n <me-content-renderer\n .content=${content}\n .store=${this.store}\n .toolRegistry=${this.toolRegistry}\n ></me-content-renderer>\n `)}\n `;\n }\n}\n","/** @module RowRenderer — Subscribes to: design */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { DesignRow } from '@emabuild/types';\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry } from '../tools/tool-registry.js';\nimport { StoreController } from '../utils/store-controller.js';\nimport { dragState } from '../dnd/drag-state.js';\nimport './column-renderer.js';\n\n@customElement('me-row-renderer')\nexport class RowRenderer extends LitElement {\n static styles = css`\n :host {\n display: block;\n position: relative;\n transition: opacity 0.2s ease, transform 0.25s ease;\n }\n :host(.hidden-in-view) { opacity: 0.3; }\n :host(.removing) {\n animation: rowRemove 0.25s ease-out forwards;\n pointer-events: none;\n }\n @keyframes rowRemove {\n to { opacity: 0; transform: scaleY(0.8); height: 0; margin: 0; overflow: hidden; }\n }\n .row-hidden-badge {\n position: absolute; top: 4px; left: 4px; z-index: 5;\n background: #f59e0b; color: white; font-size: 10px; font-weight: 600;\n padding: 2px 6px; border-radius: 3px; font-family: sans-serif;\n pointer-events: none;\n }\n .row-wrapper {\n display: flex;\n flex-wrap: nowrap;\n position: relative;\n min-height: 30px;\n transition: box-shadow 0.15s ease;\n }\n :host(:hover) .row-wrapper {\n box-shadow: inset 0 0 0 2px var(--me-primary-30);\n }\n\n /* Drop-in animation for newly added rows */\n :host(.just-added) {\n animation: rowSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n }\n @keyframes rowSlideIn {\n 0% { opacity: 0; transform: translateY(-10px) scaleY(0.95); }\n 100% { opacity: 1; transform: translateY(0) scaleY(1); }\n }\n\n /* ── Drag handle — right side, vertically centered ── */\n .drag-handle {\n display: none;\n position: absolute;\n right: -12px;\n top: 50%;\n transform: translateY(-50%);\n width: 24px;\n height: 24px;\n background: var(--me-primary);\n color: white;\n border: 2px solid white;\n border-radius: 50%;\n cursor: grab;\n z-index: 20;\n align-items: center;\n justify-content: center;\n padding: 0;\n box-shadow: 0 1px 4px rgba(0,0,0,0.2);\n transition: background 0.15s ease, transform 0.15s ease;\n }\n .drag-handle:hover {\n background: var(--me-primary-dark);\n transform: translateY(-50%) scale(1.15);\n }\n .drag-handle:active { cursor: grabbing; }\n .drag-handle svg {\n width: 12px; height: 12px; fill: currentColor; stroke: none;\n }\n :host(:hover) .drag-handle { display: flex; }\n\n /* ── Action bar — top-right ── */\n .action-bar {\n display: none;\n position: absolute;\n top: -28px;\n right: 4px;\n background: var(--me-primary);\n border-radius: 6px;\n padding: 2px;\n gap: 2px;\n z-index: 10;\n align-items: center;\n }\n :host(:hover) .action-bar { display: flex; }\n .action-bar-label {\n font-size: 10px; color: rgba(255,255,255,0.6); font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.03em;\n padding: 0 4px;\n }\n .action-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 2px 6px;\n font-size: 12px;\n line-height: 1;\n border-radius: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .action-btn:hover { background: rgba(255,255,255,0.15); }\n .action-btn.danger:hover { background: rgba(239,68,68,0.5); }\n .action-btn svg {\n width: 14px;\n height: 14px;\n stroke: currentColor;\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n .action-separator {\n width: 1px;\n background: rgba(255,255,255,0.3);\n margin: 2px 1px;\n }\n `;\n\n private storeCtrl = new StoreController(this, ['design', 'viewMode']);\n\n @property({ attribute: false }) row!: DesignRow;\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n @property({ attribute: false }) toolRegistry!: ToolRegistry;\n\n private handleDragStart = (e: DragEvent) => {\n e.stopPropagation();\n e.dataTransfer!.setData('application/maileditor-row', this.row.id);\n e.dataTransfer!.effectAllowed = 'move';\n this.style.opacity = '0.4';\n this.style.transform = 'scale(0.98)';\n dragState.startRowDrag(this.row.id, this);\n };\n\n private handleDragEnd = () => {\n this.style.transform = '';\n dragState.reset();\n };\n\n private handleMoveUp(e: Event) {\n e.stopPropagation();\n const idx = this.store.getRowIndex(this.row.id);\n if (idx > 0) this.store.moveRow(idx, idx - 1);\n }\n\n private handleMoveDown(e: Event) {\n e.stopPropagation();\n const idx = this.store.getRowIndex(this.row.id);\n const total = this.store.getRows().length;\n if (idx < total - 1) this.store.moveRow(idx, idx + 1);\n }\n\n private handleDuplicate(e: Event) {\n e.stopPropagation();\n this.store.duplicateRow(this.row.id);\n }\n\n private handleDelete(e: Event) {\n e.stopPropagation();\n this.classList.add('removing');\n const id = this.row.id;\n this.addEventListener('animationend', () => this.store.removeRow(id), { once: true });\n }\n\n render() {\n if (!this.store) return html``;\n const { row, store, toolRegistry } = this;\n const bgColor = row.values.backgroundColor || 'transparent';\n const colsBgColor = row.values.columnsBackgroundColor || 'transparent';\n const padding = row.values.padding || '0px';\n const totalCells = row.cells.reduce((a, b) => a + b, 0);\n\n // Background image support — same logic as email export (fluid-hybrid.ts)\n const bgImg = row.values.backgroundImage;\n const bgUrl = typeof bgImg === 'object' && bgImg?.url ? bgImg.url : '';\n let bgImageStyle = '';\n if (bgUrl) {\n const repeat = bgImg!.repeat === true || bgImg!.repeat === 'repeat' ? 'repeat' : 'no-repeat';\n const size = bgImg!.cover === true ? 'cover' : bgImg!.fullWidth === true ? '100% auto' : 'auto';\n const position = bgImg!.center !== false ? 'center' : 'top left';\n bgImageStyle = `background-image:url('${bgUrl}');background-size:${size};background-position:${position};background-repeat:${repeat};`;\n }\n\n const viewMode = store.viewMode;\n const hideDesktop = !!row.values.hideDesktop;\n const hideMobile = !!row.values.hideMobile;\n const hiddenInView = (viewMode === 'desktop' && hideDesktop) || (viewMode === 'mobile' && hideMobile);\n const hiddenLabel = hideDesktop ? 'Hidden on desktop' : hideMobile ? 'Hidden on mobile' : '';\n\n this.classList.toggle('hidden-in-view', hiddenInView);\n this.removeAttribute('draggable'); // drag only via handle\n this.dataset.rowId = row.id;\n\n const idx = store.getRowIndex(row.id);\n const total = store.getRows().length;\n\n return html`\n ${hiddenInView ? html`<div class=\"row-hidden-badge\">${hiddenLabel}</div>` : ''}\n <button class=\"drag-handle\" draggable=\"true\" title=\"Drag to reorder\"\n @dragstart=${this.handleDragStart}\n @dragend=${this.handleDragEnd}\n @mousedown=${(e: Event) => e.stopPropagation()}>\n <svg viewBox=\"0 0 16 16\"><circle cx=\"5\" cy=\"3\" r=\"1.5\"/><circle cx=\"11\" cy=\"3\" r=\"1.5\"/><circle cx=\"5\" cy=\"8\" r=\"1.5\"/><circle cx=\"11\" cy=\"8\" r=\"1.5\"/><circle cx=\"5\" cy=\"13\" r=\"1.5\"/><circle cx=\"11\" cy=\"13\" r=\"1.5\"/></svg>\n </button>\n <div class=\"action-bar\">\n <span class=\"action-bar-label\">Row</span>\n ${idx > 0 ? html`\n <button class=\"action-btn\" @click=${this.handleMoveUp} title=\"Move Up\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M12 19V5\"/><path d=\"m5 12 7-7 7 7\"/></svg>\n </button>\n ` : ''}\n ${idx < total - 1 ? html`\n <button class=\"action-btn\" @click=${this.handleMoveDown} title=\"Move Down\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M12 5v14\"/><path d=\"m19 12-7 7-7-7\"/></svg>\n </button>\n ` : ''}\n <div class=\"action-separator\"></div>\n <button class=\"action-btn danger\" @click=${this.handleDelete} title=\"Delete Row\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M3 6h18\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"/><path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>\n </button>\n </div>\n <div\n class=\"row-wrapper\"\n style=\"background-color:${bgColor};padding:${padding};${bgImageStyle}\"\n >\n ${repeat(row.columns, (col) => col.id, (col, i) => {\n const widthPercent = (row.cells[i] / totalCells) * 100;\n return html`\n <me-column-renderer\n .column=${col}\n .store=${store}\n .toolRegistry=${toolRegistry}\n .widthPercent=${widthPercent}\n style=\"background-color:${colsBgColor};\"\n ></me-column-renderer>\n `;\n })}\n </div>\n `;\n }\n}\n","/**\n * @module EditorCanvas\n * Central canvas area that renders the email design rows.\n * Subscribes to: design, viewMode\n */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry } from '../tools/tool-registry.js';\nimport { StoreController } from '../utils/store-controller.js';\nimport './row-renderer.js';\n\n@customElement('me-editor-canvas')\nexport class EditorCanvas extends LitElement {\n static styles = css`\n :host {\n display: block;\n flex: 1;\n overflow-y: auto;\n background: var(--me-grey-100);\n }\n /* Full-width body background — mirrors the email <body> */\n .canvas-bg {\n min-height: 100%;\n padding: 0 20px 20px;\n }\n .canvas-body {\n margin: 0 auto;\n background: #ffffff;\n min-height: 200px;\n position: relative;\n transition: max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n .canvas-body.undo-flash {\n animation: undoFlash 0.3s ease-out;\n }\n @keyframes undoFlash {\n 0% { box-shadow: inset 0 0 0 2px var(--me-primary-30, rgba(93,118,139,0.3)); }\n 100% { box-shadow: none; }\n }\n .empty-canvas {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n min-height: 300px; color: var(--me-grey-400); font-family: sans-serif; gap: 12px;\n padding: 40px 20px; text-align: center;\n }\n .empty-icon {\n width: 56px; height: 56px; border-radius: 50%;\n background: var(--me-primary-5, rgba(93,118,139,0.05));\n display: flex; align-items: center; justify-content: center;\n animation: emptyPulse 3s ease-in-out infinite;\n }\n .empty-icon svg { width: 24px; height: 24px; stroke: var(--me-primary); fill: none; stroke-width: 1.5; }\n @keyframes emptyPulse {\n 0%, 100% { opacity: 0.6; transform: scale(0.95); }\n 50% { opacity: 1; transform: scale(1); }\n }\n .empty-title { font-size: 14px; font-weight: 600; color: var(--me-grey-600); }\n .empty-sub { font-size: 12px; color: var(--me-grey-400); max-width: 240px; line-height: 1.5; }\n .empty-actions { display: flex; gap: 8px; margin-top: 8px; }\n .empty-action {\n padding: 6px 14px; border-radius: var(--me-radius, 8px); border: 1px solid var(--me-grey-200);\n background: white; color: var(--me-grey-600); font-size: 11px; font-weight: 600;\n cursor: pointer; transition: all var(--me-transition, 150ms ease); font-family: sans-serif;\n }\n .empty-action:hover { border-color: var(--me-primary); color: var(--me-primary); background: var(--me-primary-5); }\n .empty-action.primary { background: var(--me-primary); color: white; border-color: var(--me-primary); }\n .empty-action.primary:hover { background: var(--me-primary-dark, #4a6070); }\n .empty-shortcut {\n font-size: 10px; color: var(--me-grey-300); margin-top: 12px; font-family: sans-serif;\n }\n .empty-shortcut kbd {\n background: var(--me-grey-100); border: 1px solid var(--me-grey-200);\n border-radius: 3px; padding: 1px 4px; font-size: 10px; font-family: monospace;\n }\n .view-toggle {\n display: flex;\n justify-content: center;\n margin: 8px 0 12px;\n gap: 4px;\n }\n .view-btn {\n padding: 6px 16px;\n border: 1px solid var(--me-grey-200);\n background: white;\n cursor: pointer;\n font-size: 11px;\n font-weight: 600;\n font-family: sans-serif;\n color: var(--me-grey-700);\n transition: all 0.15s ease;\n }\n .view-btn:hover { background: var(--me-grey-50); }\n .view-btn:first-child { border-radius: 8px 0 0 8px; }\n .view-btn:last-child { border-radius: 0 8px 8px 0; }\n .view-btn.active {\n background: var(--me-primary);\n border-color: var(--me-primary);\n color: white;\n }\n\n /* ── Quick-add row gaps ─────────────────────────── */\n .row-gap {\n height: 20px;\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 2;\n }\n .row-gap .add-btn {\n opacity: 0;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n border: none;\n background: var(--me-primary);\n color: white;\n font-size: 16px;\n line-height: 1;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity 0.15s, transform 0.15s;\n padding: 0;\n font-family: sans-serif;\n }\n .row-gap:hover .add-btn {\n opacity: 1;\n }\n .row-gap .add-btn:hover {\n transform: scale(1.1);\n }\n .row-gap::before {\n content: '';\n position: absolute;\n left: 5%;\n right: 5%;\n top: 50%;\n height: 2px;\n background: transparent;\n border-radius: 1px;\n transition: background 0.2s ease;\n }\n .row-gap:hover::before {\n background: rgba(93, 118, 139, 0.2);\n }\n\n /* ── Quick-add floating menu ───────────────────── */\n .quick-add-menu {\n background: white;\n border: 1px solid var(--me-grey-200);\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0,0,0,0.12);\n padding: 8px;\n z-index: 100;\n animation: qaFadeIn 0.12s ease-out;\n font-family: sans-serif;\n }\n @keyframes qaFadeIn {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n }\n .quick-tools {\n display: flex;\n gap: 4px;\n }\n .quick-tools button {\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 8px;\n background: var(--me-grey-50);\n cursor: pointer;\n font-size: 14px;\n font-family: sans-serif;\n color: var(--me-grey-700);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.12s, color 0.12s;\n }\n .quick-tools button:hover {\n background: var(--me-primary);\n color: white;\n }\n .quick-separator {\n height: 1px;\n background: var(--me-grey-200);\n margin: 6px 0;\n }\n .quick-layouts {\n display: flex;\n gap: 4px;\n }\n .quick-layouts button {\n flex: 1;\n height: 28px;\n border: 1px solid var(--me-grey-200);\n border-radius: 6px;\n background: white;\n cursor: pointer;\n padding: 3px 4px;\n display: flex;\n gap: 2px;\n align-items: stretch;\n transition: border-color 0.12s;\n }\n .quick-layouts button:hover {\n border-color: var(--me-primary);\n }\n .quick-layouts button .ql-col {\n background: var(--me-grey-300);\n border-radius: 2px;\n flex-grow: var(--col-flex, 1);\n transition: background 0.12s;\n }\n .quick-layouts button:hover .ql-col {\n background: var(--me-primary);\n }\n `;\n\n private storeCtrl = new StoreController(this, ['design', 'viewMode']);\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n @property({ attribute: false }) toolRegistry!: ToolRegistry;\n\n @state() private quickAddIndex: number | null = null;\n @state() private quickAddPos = { x: 0, y: 0 };\n\n private boundCloseQuickAdd = this.closeQuickAdd.bind(this);\n\n override connectedCallback() {\n super.connectedCallback();\n document.addEventListener('click', this.boundCloseQuickAdd);\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('click', this.boundCloseQuickAdd);\n }\n\n private handleCanvasClick() {\n this.store.select(null);\n }\n\n /** Flash the canvas border to confirm undo/redo */\n flashUndo() {\n const body = this.shadowRoot?.querySelector('.canvas-body');\n if (body) {\n body.classList.add('undo-flash');\n body.addEventListener('animationend', () => body.classList.remove('undo-flash'), { once: true });\n }\n }\n\n private setViewMode(mode: 'desktop' | 'mobile') {\n this.store.setViewMode(mode);\n }\n\n // ── Quick-add methods ──────────────────────────────────────\n\n private openQuickAdd(e: Event, index: number) {\n e.stopPropagation();\n const btn = e.currentTarget as HTMLElement;\n const rect = btn.getBoundingClientRect();\n this.quickAddPos = {\n x: rect.left + rect.width / 2,\n y: rect.bottom + 6,\n };\n this.quickAddIndex = index;\n }\n\n private closeQuickAdd() {\n if (this.quickAddIndex !== null) {\n this.quickAddIndex = null;\n }\n }\n\n private async quickAddTool(type: string, index: number) {\n await this.toolRegistry.ensureLoaded(type);\n const defaults = this.toolRegistry.getDefaultValues(type);\n const row = this.store.createRow([1]);\n const addedRow = this.store.addRow(row, index);\n const colId = addedRow.columns[0].id;\n const content = this.store.createContent(type, defaults);\n this.store.addContent(colId, content);\n this.quickAddIndex = null;\n }\n\n private quickAddLayout(cells: number[], index: number) {\n const row = this.store.createRow(cells);\n this.store.addRow(row, index);\n this.quickAddIndex = null;\n }\n\n private renderRowGap(index: number) {\n return html`\n <div class=\"row-gap\">\n <button\n class=\"add-btn\"\n @click=${(e: Event) => this.openQuickAdd(e, index)}\n title=\"Add row\"\n >+</button>\n </div>\n `;\n }\n\n private renderQuickAddMenu() {\n if (this.quickAddIndex === null) return '';\n const idx = this.quickAddIndex;\n const x = this.quickAddPos.x;\n const y = this.quickAddPos.y;\n\n const layoutPresets: { cells: number[]; label: string }[] = [\n { cells: [1], label: '100%' },\n { cells: [1, 1], label: '50/50' },\n { cells: [1, 1, 1], label: '33/33/33' },\n { cells: [2, 1], label: '66/33' },\n { cells: [1, 2], label: '33/66' },\n { cells: [1, 1, 1, 1], label: '25x4' },\n ];\n\n return html`\n <div\n class=\"quick-add-menu\"\n style=\"position:fixed;left:${x}px;top:${y}px;transform:translateX(-50%)\"\n @click=${(e: Event) => e.stopPropagation()}\n >\n <div class=\"quick-tools\">\n <button @click=${() => this.quickAddTool('text', idx)} title=\"Text\">T</button>\n <button @click=${() => this.quickAddTool('heading', idx)} title=\"Heading\">H</button>\n <button @click=${() => this.quickAddTool('image', idx)} title=\"Image\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/><polyline points=\"21 15 16 10 5 21\"/></svg>\n </button>\n <button @click=${() => this.quickAddTool('button', idx)} title=\"Button\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"7\" width=\"20\" height=\"10\" rx=\"3\"/></svg>\n </button>\n <button @click=${() => this.quickAddTool('divider', idx)} title=\"Divider\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"/></svg>\n </button>\n </div>\n <div class=\"quick-separator\"></div>\n <div class=\"quick-layouts\">\n ${layoutPresets.map(\n (lp) => {\n const total = lp.cells.reduce((a, b) => a + b, 0);\n return html`\n <button\n @click=${() => this.quickAddLayout(lp.cells, idx)}\n title=${lp.label}\n >\n ${lp.cells.map((c) => html`<div class=\"ql-col\" style=\"--col-flex:${c / total}\"></div>`)}\n </button>\n `;\n },\n )}\n </div>\n </div>\n `;\n }\n\n render() {\n const rows = this.store.getRows();\n const bodyValues = this.store.getBodyValues();\n const contentWidth = bodyValues.contentWidth || '600px';\n const bgColor = bodyValues.backgroundColor || '#e7e7e7';\n const viewMode = this.store.viewMode;\n const canvasWidth = viewMode === 'mobile' ? '375px' : contentWidth;\n\n return html`\n <div class=\"view-toggle\">\n <button\n class=\"view-btn ${viewMode === 'desktop' ? 'active' : ''}\"\n @click=${() => this.setViewMode('desktop')}\n >Desktop</button>\n <button\n class=\"view-btn ${viewMode === 'mobile' ? 'active' : ''}\"\n @click=${() => this.setViewMode('mobile')}\n >Mobile</button>\n </div>\n\n <div class=\"canvas-bg\" style=\"background-color:${bgColor};\" @click=${this.handleCanvasClick}>\n <div\n class=\"canvas-body\"\n style=\"max-width:${canvasWidth};\"\n >\n ${rows.length === 0\n ? html`\n <div class=\"empty-canvas\">\n <div class=\"empty-icon\">\n <svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"/><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"/></svg>\n </div>\n <div class=\"empty-title\">Start building your email</div>\n <div class=\"empty-sub\">Drag elements from the sidebar, use the + button, or start with a template</div>\n <div class=\"empty-actions\">\n <button class=\"empty-action primary\" @click=${() => this.quickAddTool('heading', 0)}>Add Heading</button>\n <button class=\"empty-action\" @click=${() => this.quickAddTool('text', 0)}>Add Text</button>\n <button class=\"empty-action\" @click=${() => this.quickAddLayout([1, 1], 0)}>2 Columns</button>\n </div>\n <div class=\"empty-shortcut\">\n <kbd>Ctrl</kbd>+<kbd>Z</kbd> undo · <kbd>Ctrl</kbd>+<kbd>D</kbd> duplicate · <kbd>Del</kbd> remove\n </div>\n </div>\n ${this.renderRowGap(0)}\n `\n : html`\n ${this.renderRowGap(0)}\n ${repeat(rows, (row) => row.id, (row, i) => html`\n <me-row-renderer\n .row=${row}\n .store=${this.store}\n .toolRegistry=${this.toolRegistry}\n ></me-row-renderer>\n ${this.renderRowGap(i + 1)}\n `)}\n `}\n </div>\n </div>\n ${this.renderQuickAddMenu()}\n `;\n }\n}\n","/**\n * @module BodySettings\n *\n * Component for editing global body-level settings:\n * background color, content width, font family, text/link colors,\n * and preheader text. Rendered inside the sidebar \"Body\" tab.\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { EditorStore } from '../state/editor-store.js';\nimport { StoreController } from '../utils/store-controller.js';\n\n/** Font options — email-safe system fonts + popular Google Fonts */\nconst EMAIL_SAFE_FONTS = [\n // System / email-safe fonts\n { label: 'Arial', value: 'arial,helvetica,sans-serif', url: '' },\n { label: 'Helvetica', value: 'helvetica,sans-serif', url: '' },\n { label: 'Georgia', value: 'georgia,serif', url: '' },\n { label: 'Times New Roman', value: \"'times new roman',times,serif\", url: '' },\n { label: 'Trebuchet MS', value: 'trebuchet ms,helvetica,sans-serif', url: '' },\n { label: 'Verdana', value: 'verdana,geneva,sans-serif', url: '' },\n { label: 'Courier New', value: \"'courier new',courier,monospace\", url: '' },\n // Google Fonts\n { label: 'Lato', value: \"'Lato',sans-serif\", url: 'https://fonts.googleapis.com/css?family=Lato:400,700' },\n { label: 'Montserrat', value: \"'Montserrat',sans-serif\", url: 'https://fonts.googleapis.com/css?family=Montserrat:400,700' },\n { label: 'Old Standard TT', value: \"'Old Standard TT',serif\", url: 'https://fonts.googleapis.com/css?family=Old+Standard+TT:400,700' },\n { label: 'Open Sans', value: \"'Open Sans',sans-serif\", url: 'https://fonts.googleapis.com/css?family=Open+Sans:400,700' },\n { label: 'Pacifico', value: \"'Pacifico',cursive\", url: 'https://fonts.googleapis.com/css?family=Pacifico:400' },\n { label: 'Playfair Display', value: \"'Playfair Display',serif\", url: 'https://fonts.googleapis.com/css?family=Playfair+Display:400,700' },\n { label: 'Raleway', value: \"'Raleway',sans-serif\", url: 'https://fonts.googleapis.com/css?family=Raleway:400,700' },\n { label: 'Roboto', value: \"'Roboto',sans-serif\", url: 'https://fonts.googleapis.com/css?family=Roboto:400,700' },\n { label: 'Rubik', value: \"'Rubik',sans-serif\", url: 'https://fonts.googleapis.com/css?family=Rubik:400,700' },\n { label: 'Source Sans Pro', value: \"'Source Sans Pro',sans-serif\", url: 'https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700' },\n] as const;\n\n@customElement('me-body-settings')\nexport class BodySettings extends LitElement {\n static styles = css`\n :host { display: block; }\n .section-title {\n font-size: 11px; font-weight: 600; text-transform: uppercase;\n color: #9ca3af; letter-spacing: 0.05em; margin: 0 0 8px 0;\n }\n .field { margin-bottom: 12px; }\n .field-label { display: block; font-size: 12px; color: #6b7280; margin-bottom: 4px; }\n .input {\n width: 100%; padding: 5px 8px; border: 1px solid #d1d5db; border-radius: 4px;\n font-size: 12px; box-sizing: border-box;\n }\n .input:focus { outline: none; border-color: #3b82f6; }\n .color-row { display: flex; gap: 6px; align-items: center; }\n .color-swatch {\n width: 32px; height: 32px; border: 1px solid #d1d5db; border-radius: 4px;\n padding: 0; cursor: pointer;\n }\n .align-group { display: flex; gap: 2px; }\n .align-btn {\n flex: 1; padding: 5px; border: 1px solid #d1d5db; background: white;\n border-radius: 4px; cursor: pointer; font-size: 11px; color: #6b7280;\n }\n .align-btn.active { border-color: #3b82f6; background: #eff6ff; color: #3b82f6; }\n .field.highlight textarea {\n animation: preheaderPulse 0.6s ease-in-out 4;\n border-color: #dc2626;\n }\n @keyframes preheaderPulse {\n 0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0); }\n 50% { box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.2); }\n }\n `;\n\n private storeCtrl = new StoreController(this, ['design']);\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n /** Scroll to preheader field, focus it, and pulse highlight */\n highlightPreheader() {\n const field = this.shadowRoot?.getElementById('preheader-field');\n const input = this.shadowRoot?.getElementById('preheader-input') as HTMLTextAreaElement | null;\n if (field) {\n field.scrollIntoView({ behavior: 'smooth', block: 'center' });\n field.classList.add('highlight');\n input?.focus();\n setTimeout(() => field.classList.remove('highlight'), 5000);\n }\n }\n\n private update_(key: string, value: unknown) {\n this.store.updateBodyValues({ [key]: value } as any);\n }\n\n private updateLinkStyle(key: string, value: unknown) {\n const current = this.store.getBodyValues().linkStyle;\n this.store.updateBodyValues({ linkStyle: { ...current, [key]: value } } as any);\n }\n\n private updateFontFamily(value: string) {\n const font = EMAIL_SAFE_FONTS.find((f) => f.value === value);\n const update: Record<string, unknown> = { label: font?.label || value, value };\n if (font?.url) {\n update.url = font.url;\n // Load the font immediately\n const id = `emabuild-font-${value.replace(/[^a-z]/gi, '')}`;\n if (!document.getElementById(id)) {\n const link = document.createElement('link');\n link.id = id;\n link.rel = 'stylesheet';\n link.href = font.url;\n document.head.appendChild(link);\n }\n }\n this.store.updateBodyValues({ fontFamily: update } as any);\n }\n\n render() {\n const v = this.store.getBodyValues();\n\n return html`\n ${this.renderColorField('Background Color', v.backgroundColor || '#e7e7e7', (c) => this.update_('backgroundColor', c))}\n\n <p class=\"section-title\" style=\"margin-top:16px;\">Content</p>\n <div class=\"field\">\n <label class=\"field-label\">Content Width (px)</label>\n <input class=\"input\" type=\"number\" .value=${parseInt(v.contentWidth || '600')} min=\"320\" max=\"960\" step=\"10\"\n @change=${(e: Event) => this.update_('contentWidth', (e.target as HTMLInputElement).value + 'px')} />\n </div>\n <div class=\"field\">\n <label class=\"field-label\">Content Align</label>\n <div class=\"align-group\">\n ${['left', 'center', 'right'].map((a) => html`\n <button class=\"align-btn ${v.contentAlign === a ? 'active' : ''}\"\n @click=${() => this.update_('contentAlign', a)}>${a}</button>\n `)}\n </div>\n </div>\n\n <p class=\"section-title\" style=\"margin-top:16px;\">Typography</p>\n <div class=\"field\">\n <label class=\"field-label\">Font Family</label>\n <select class=\"input\" @change=${(e: Event) => this.updateFontFamily((e.target as HTMLSelectElement).value)}>\n <optgroup label=\"System Fonts\">\n ${EMAIL_SAFE_FONTS.filter((f) => !f.url).map((f) => html`<option value=${f.value} ?selected=${v.fontFamily?.value === f.value}>${f.label}</option>`)}\n </optgroup>\n <optgroup label=\"Google Fonts\">\n ${EMAIL_SAFE_FONTS.filter((f) => !!f.url).map((f) => html`<option value=${f.value} ?selected=${v.fontFamily?.value === f.value}>${f.label}</option>`)}\n </optgroup>\n </select>\n </div>\n ${this.renderColorField('Text Color', v.textColor || '#000000', (c) => this.update_('textColor', c))}\n\n <p class=\"section-title\" style=\"margin-top:16px;\">Links</p>\n ${this.renderColorField('Link Color', v.linkStyle?.linkColor || '#0000ee', (c) => this.updateLinkStyle('linkColor', c))}\n <div class=\"field\">\n <label style=\"display:flex;align-items:center;gap:8px;font-size:12px;color:#6b7280;cursor:pointer;\">\n <input type=\"checkbox\" .checked=${v.linkStyle?.linkUnderline ?? true}\n @change=${(e: Event) => this.updateLinkStyle('linkUnderline', (e.target as HTMLInputElement).checked)} />\n Underline Links\n </label>\n </div>\n\n <p class=\"section-title\" style=\"margin-top:16px;\">Email</p>\n <div class=\"field\" id=\"preheader-field\">\n <label class=\"field-label\">Preheader Text</label>\n <textarea class=\"input\" id=\"preheader-input\" .value=${v.preheaderText || ''} placeholder=\"Preview text shown in inbox...\"\n style=\"min-height:60px;resize:vertical;font-family:inherit;\"\n @change=${(e: Event) => this.update_('preheaderText', (e.target as HTMLTextAreaElement).value)}></textarea>\n </div>\n `;\n }\n\n /** Reusable color field (swatch + hex input) */\n private renderColorField(label: string, value: string, onChange: (v: string) => void) {\n return html`\n <div class=\"field\">\n <label class=\"field-label\">${label}</label>\n <div class=\"color-row\">\n <input class=\"color-swatch\" type=\"color\" .value=${value} @input=${(e: Event) => onChange((e.target as HTMLInputElement).value)} />\n <input class=\"input\" type=\"text\" .value=${value} style=\"flex:1;\" @change=${(e: Event) => onChange((e.target as HTMLInputElement).value)} />\n </div>\n </div>\n `;\n }\n}\n","/**\n * @module EditorSidebar\n *\n * Left-side panel with two tabs:\n * - Elements: categorized tools + layout presets + search\n * - Body: global email settings\n */\n\nimport { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry, LazyToolMeta } from '../tools/tool-registry.js';\nimport { StoreController } from '../utils/store-controller.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport './body-settings.js';\nimport { checkA11y } from './a11y-checker.js';\n\n/** Tool categories for grouping in the sidebar */\nconst TOOL_CATEGORIES: Record<string, { label: string; tools: string[] }> = {\n text: { label: 'Text', tools: ['text', 'heading', 'paragraph'] },\n media: { label: 'Media', tools: ['image', 'video'] },\n actions: { label: 'Actions', tools: ['button', 'social', 'menu'] },\n structure: { label: 'Structure', tools: ['divider', 'html', 'timer', 'table', 'form'] },\n};\n\n@customElement('me-editor-sidebar')\nexport class EditorSidebar extends LitElement {\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n width: 280px;\n min-width: 280px;\n background: #ffffff;\n border-right: 1px solid var(--me-grey-100);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n overflow-y: auto;\n transition: width 200ms ease, min-width 200ms ease;\n position: relative;\n }\n :host(.collapsed) {\n width: 0; min-width: 0; overflow: hidden; border-right: none;\n }\n\n /* ── Tabs ── */\n .tabs {\n display: flex;\n border-bottom: 1px solid var(--me-grey-200);\n background: #ffffff;\n flex-shrink: 0;\n }\n .tab {\n flex: 1; padding: 10px 8px; border: none; background: none;\n cursor: pointer; font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.05em;\n color: var(--me-grey-500); text-align: center;\n transition: all 150ms ease; border-bottom: 2px solid transparent;\n }\n .tab:hover { color: var(--me-grey-700); background: var(--me-grey-100); }\n .tab.active { color: var(--me-primary); border-bottom-color: var(--me-primary); }\n\n /* ── Search ── */\n .search-wrap {\n padding: 10px 12px 6px;\n flex-shrink: 0;\n }\n .search-input {\n width: 100%;\n border: 1px solid var(--me-grey-200);\n border-radius: 8px;\n padding: 6px 10px 6px 30px;\n font-size: 12px;\n color: var(--me-grey-700);\n background: var(--me-grey-50) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E\") 10px center no-repeat;\n outline: none;\n transition: all 150ms ease;\n box-sizing: border-box;\n }\n .search-input::placeholder { color: var(--me-grey-400); }\n .search-input:focus {\n border-color: var(--me-primary);\n background-color: #fff;\n box-shadow: 0 0 0 2px rgba(93,118,139,0.15);\n }\n\n /* ── Scrollable content ── */\n .tab-content {\n padding: 0 12px 16px;\n flex: 1;\n overflow-y: auto;\n animation: tabFadeIn 0.2s ease-out;\n }\n @keyframes tabFadeIn {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n /* ── Category groups ── */\n .category {\n margin-top: 12px;\n }\n .category-title {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n color: var(--me-blue-600);\n letter-spacing: 0.06em;\n margin: 0 0 6px 2px;\n padding: 4px 0;\n border-bottom: 1px solid var(--me-blue-50);\n }\n\n /* ── Tool grid (2 columns) ── */\n .tool-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 4px;\n }\n .tool-item {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 6px;\n padding: 6px 8px;\n border: 1px solid transparent;\n border-radius: 8px;\n cursor: grab;\n background: transparent;\n transition: all 150ms ease;\n font-size: 11px;\n color: var(--me-grey-600);\n }\n .tool-item:hover {\n border-color: var(--me-grey-200);\n background: var(--me-grey-50);\n }\n .tool-item:hover .tool-icon { color: var(--me-primary); }\n .tool-item:active { cursor: grabbing; background: var(--me-primary-5); }\n .tool-icon {\n width: 18px; height: 18px;\n display: flex; align-items: center; justify-content: center;\n color: var(--me-grey-400);\n transition: color 150ms ease;\n flex-shrink: 0;\n }\n .tool-icon svg { width: 18px; height: 18px; }\n\n /* ── Layout presets ── */\n .layout-section { margin-top: 14px; }\n .layout-grid {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n gap: 6px;\n }\n .layout-item {\n display: flex; align-items: center; justify-content: center;\n gap: 2px; padding: 8px 4px;\n border: 1px solid var(--me-grey-200); border-radius: 8px;\n cursor: pointer; background: white;\n transition: all 150ms ease;\n }\n .layout-item:hover { border-color: var(--me-primary); background: var(--me-primary-5); }\n .layout-item:hover .layout-col { background: var(--me-primary); }\n .layout-item:active { background: var(--me-primary-10); }\n .layout-col {\n height: 18px; background: var(--me-grey-300); border-radius: 2px;\n transition: background 150ms ease;\n }\n\n /* ── A11y tab badge ── */\n .tab-badge {\n display: inline-flex;\n gap: 3px;\n margin-left: 4px;\n vertical-align: middle;\n }\n .tab-dot {\n width: 6px; height: 6px; border-radius: 50%;\n }\n .tab-dot.error { background: var(--me-danger); }\n .tab-dot.warning { background: var(--me-warning); }\n .tab-dot.info { background: var(--me-blue-600); }\n\n /* ── No results ── */\n .no-results {\n text-align: center; color: var(--me-grey-400); font-size: 12px;\n padding: 24px 0;\n }\n `;\n\n private storeCtrl = new StoreController(this, ['activeTab', 'design']);\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n @property({ attribute: false }) toolRegistry!: ToolRegistry;\n\n @state() private searchQuery = '';\n\n private getA11ySeverities(): { errors: boolean; warnings: boolean; infos: boolean } {\n const issues = checkA11y(this.store);\n return {\n errors: issues.some((i) => i.severity === 'error'),\n warnings: issues.some((i) => i.severity === 'warning'),\n infos: issues.some((i) => i.severity === 'info'),\n };\n }\n\n private handleDragStart(e: DragEvent, toolName: string) {\n e.dataTransfer!.setData('application/maileditor-tool', toolName);\n e.dataTransfer!.effectAllowed = 'copy';\n }\n\n private handleLayoutDragStart(e: DragEvent, cells: number[]) {\n e.dataTransfer!.setData('application/maileditor-layout', JSON.stringify(cells));\n e.dataTransfer!.effectAllowed = 'copy';\n }\n\n private addRowWithLayout(cells: number[]) {\n const row = this.store.createRow(cells);\n this.store.addRow(row);\n }\n\n render() {\n const activeTab = this.store.activeTab;\n\n return html`\n <div class=\"tabs\">\n <button class=\"tab ${activeTab === 'content' ? 'active' : ''}\"\n @click=${() => this.store.setActiveTab('content')}>Elements</button>\n <button class=\"tab ${activeTab === 'body' ? 'active' : ''}\"\n @click=${() => this.store.setActiveTab('body')}>Body</button>\n <button class=\"tab ${activeTab === 'a11y' ? 'active' : ''}\"\n @click=${() => this.store.setActiveTab('a11y')}>A11y${this.renderA11yBadge()}</button>\n </div>\n\n ${activeTab === 'content' ? this.renderElementsTab() : ''}\n ${activeTab === 'body' ? html`<div class=\"tab-content\" style=\"padding-top:12px;\">${this.renderBodyTab()}</div>` : ''}\n ${activeTab === 'a11y' ? html`<div class=\"tab-content\" style=\"padding-top:12px;\"><me-a11y-checker .store=${this.store} .toolRegistry=${this.toolRegistry}></me-a11y-checker></div>` : ''}\n `;\n }\n\n private renderElementsTab() {\n const allTools = this.toolRegistry.getAllMeta();\n const q = this.searchQuery.toLowerCase().trim();\n\n // Build categorized tool list\n const toolMap = new Map<string, LazyToolMeta>();\n for (const t of allTools) toolMap.set(t.name, t);\n\n // Filter by search\n const matchesSearch = (t: LazyToolMeta) =>\n !q || t.label.toLowerCase().includes(q) || t.name.toLowerCase().includes(q);\n\n let hasResults = false;\n\n const categories = Object.entries(TOOL_CATEGORIES).map(([, cat]) => {\n const tools = cat.tools\n .map((name) => toolMap.get(name))\n .filter((t): t is LazyToolMeta => !!t && matchesSearch(t));\n if (tools.length > 0) hasResults = true;\n return { label: cat.label, tools };\n });\n\n // Check for uncategorized tools (custom tools)\n const categorizedNames = new Set(Object.values(TOOL_CATEGORIES).flatMap((c) => c.tools));\n const uncategorized = allTools.filter((t) => !categorizedNames.has(t.name) && matchesSearch(t));\n if (uncategorized.length > 0) hasResults = true;\n\n // Check if layouts match search\n const showLayouts = !q || 'layout'.includes(q) || 'row'.includes(q) || 'column'.includes(q);\n\n return html`\n <div class=\"search-wrap\">\n <input class=\"search-input\"\n type=\"text\"\n placeholder=\"Search elements...\"\n .value=${this.searchQuery}\n @input=${(e: Event) => { this.searchQuery = (e.target as HTMLInputElement).value; }}\n />\n </div>\n <div class=\"tab-content\">\n ${categories.map((cat) =>\n cat.tools.length === 0 ? nothing : html`\n <div class=\"category\">\n <div class=\"category-title\">${cat.label}</div>\n <div class=\"tool-grid\">\n ${cat.tools.map((tool) => this.renderToolItem(tool))}\n </div>\n </div>\n `\n )}\n ${uncategorized.length > 0 ? html`\n <div class=\"category\">\n <div class=\"category-title\">Custom</div>\n <div class=\"tool-grid\">\n ${uncategorized.map((tool) => this.renderToolItem(tool))}\n </div>\n </div>\n ` : ''}\n ${showLayouts ? html`\n <div class=\"layout-section\">\n <div class=\"category-title\">Rows</div>\n <div class=\"layout-grid\">\n ${this.renderLayoutOption([1], '100%')}\n ${this.renderLayoutOption([1, 1], '50/50')}\n ${this.renderLayoutOption([1, 1, 1], '33/33/33')}\n ${this.renderLayoutOption([2, 1], '66/33')}\n ${this.renderLayoutOption([1, 2], '33/66')}\n ${this.renderLayoutOption([1, 1, 1, 1], '25x4')}\n </div>\n </div>\n ` : ''}\n ${!hasResults && !showLayouts ? html`\n <div class=\"no-results\">No elements match \"${this.searchQuery}\"</div>\n ` : ''}\n </div>\n `;\n }\n\n private renderA11yBadge() {\n const { errors, warnings, infos } = this.getA11ySeverities();\n if (!errors && !warnings && !infos) return nothing;\n return html`<span class=\"tab-badge\">${errors ? html`<span class=\"tab-dot error\"></span>` : nothing}${warnings ? html`<span class=\"tab-dot warning\"></span>` : nothing}${infos ? html`<span class=\"tab-dot info\"></span>` : nothing}</span>`;\n }\n\n private renderToolItem(tool: LazyToolMeta) {\n return html`\n <div class=\"tool-item\"\n draggable=\"true\"\n @dragstart=${(e: DragEvent) => this.handleDragStart(e, tool.name)}>\n <div class=\"tool-icon\">${unsafeHTML(tool.icon)}</div>\n <span>${tool.label}</span>\n </div>\n `;\n }\n\n private renderLayoutOption(cells: number[], label: string) {\n const total = cells.reduce((a, b) => a + b, 0);\n return html`\n <div class=\"layout-item\" draggable=\"true\"\n @click=${() => this.addRowWithLayout(cells)}\n @dragstart=${(e: DragEvent) => this.handleLayoutDragStart(e, cells)}\n title=${label}>\n ${cells.map((c) => html`<div class=\"layout-col\" style=\"width:${(c / total) * 100}%;\"></div>`)}\n </div>\n `;\n }\n\n private renderBodyTab() {\n return html`<me-body-settings .store=${this.store}></me-body-settings>`;\n }\n}\n","/**\n * @module color-picker-widget\n * Color swatch + hex text input widget for property editing.\n */\nimport { html, TemplateResult } from 'lit';\n\n/** Render a color picker with swatch and hex input */\nexport function renderColorPicker(value: string, onChange: (v: string) => void, label: string): TemplateResult {\n const safeValue = value && /^#[0-9a-fA-F]{3,8}$/.test(value) ? value : '#000000';\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n <div class=\"prop-color\">\n <input class=\"color-swatch\" type=\"color\" .value=${safeValue}\n @input=${(e: Event) => onChange((e.target as HTMLInputElement).value)} />\n <input class=\"prop-input\" type=\"text\" .value=${value ?? ''} style=\"flex:1;\"\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).value)} />\n </div>\n </div>\n `;\n}\n","/**\n * @module dropdown-widget\n * Native `<select>` dropdown for predefined option lists.\n */\nimport { html, TemplateResult } from 'lit';\n\ninterface DropdownOption { label: string; value: string; }\n\n/** Render a dropdown select widget */\nexport function renderDropdown(value: string, onChange: (v: string) => void, label: string, params?: Record<string, unknown>): TemplateResult {\n const options = (params?.options as DropdownOption[]) || [];\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n <select class=\"prop-input\" @change=${(e: Event) => onChange((e.target as HTMLSelectElement).value)}>\n ${options.map((opt) => html`<option value=${opt.value} ?selected=${value === opt.value}>${opt.label}</option>`)}\n </select>\n </div>\n `;\n}\n","/**\n * @module alignment-widget\n * Visual left/center/right alignment picker.\n */\nimport { html, TemplateResult } from 'lit';\n\n/** Render an alignment picker with 3 buttons */\nexport function renderAlignment(value: string, onChange: (v: string) => void, label: string): TemplateResult {\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n <div style=\"display:flex;gap:2px;\">\n ${['left', 'center', 'right'].map((opt) => html`\n <button\n style=\"flex:1;padding:6px;border:1px solid ${value === opt ? '#3b82f6' : '#d1d5db'};background:${value === opt ? '#eff6ff' : 'white'};border-radius:4px;cursor:pointer;font-size:11px;text-transform:capitalize;color:${value === opt ? '#3b82f6' : '#6b7280'};\"\n @click=${() => onChange(opt)}\n >${opt}</button>\n `)}\n </div>\n </div>\n `;\n}\n","/**\n * @module padding-widget\n * 4-side padding editor (top/right/bottom/left) with CSS shorthand support.\n *\n * Parses CSS shorthand formats:\n * - \"10px\" → all sides 10\n * - \"10px 20px\" → top/bottom 10, left/right 20\n * - \"10px 20px 30px 40px\" → top 10, right 20, bottom 30, left 40\n */\nimport { html, TemplateResult } from 'lit';\n\n/** Parse CSS padding shorthand into [top, right, bottom, left] */\nfunction parsePadding(value: string): [number, number, number, number] {\n const parts = (value || '0px').split(/\\s+/).map((p) => parseInt(p) || 0);\n const top = parts[0];\n const right = parts[1] ?? top;\n const bottom = parts[2] ?? top;\n const left = parts[3] ?? right;\n return [top, right, bottom, left];\n}\n\n/** Convert 4 values back to shortest CSS shorthand */\nfunction toPaddingShorthand(t: number, r: number, b: number, l: number): string {\n if (t === r && r === b && b === l) return `${t}px`;\n if (t === b && r === l) return `${t}px ${r}px`;\n return `${t}px ${r}px ${b}px ${l}px`;\n}\n\n/** Render a 4-side padding editor (T/R/B/L grid) */\nexport function renderPadding(value: string, onChange: (v: string) => void, label: string): TemplateResult {\n const [top, right, bottom, left] = parsePadding(value);\n\n const update = (t: number, r: number, b: number, l: number) => onChange(toPaddingShorthand(t, r, b, l));\n\n const sides = [\n { label: 'T', val: top, change: (v: number) => update(v, right, bottom, left) },\n { label: 'R', val: right, change: (v: number) => update(top, v, bottom, left) },\n { label: 'B', val: bottom, change: (v: number) => update(top, right, v, left) },\n { label: 'L', val: left, change: (v: number) => update(top, right, bottom, v) },\n ];\n\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:4px;\">\n ${sides.map((s) => html`\n <div style=\"display:flex;align-items:center;gap:4px;\">\n <span style=\"font-size:10px;color:#9ca3af;width:12px;\">${s.label}</span>\n <input type=\"number\" .value=${s.val} min=\"0\"\n @change=${(e: Event) => s.change(parseInt((e.target as HTMLInputElement).value) || 0)}\n style=\"flex:1;padding:4px 6px;border:1px solid #d1d5db;border-radius:3px;font-size:12px;width:50px;\" />\n </div>\n `)}\n </div>\n </div>\n `;\n}\n","/**\n * @module toggle-widget\n * Boolean toggle (checkbox with label).\n */\nimport { html, TemplateResult } from 'lit';\n\n/** Render a toggle checkbox */\nexport function renderToggle(value: boolean, onChange: (v: boolean) => void, label: string): TemplateResult {\n return html`\n <div class=\"prop-row\">\n <div class=\"prop-toggle\">\n <input type=\"checkbox\" .checked=${!!value}\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).checked)} />\n <label class=\"prop-label\" style=\"margin:0;\">${label}</label>\n </div>\n </div>\n `;\n}\n","/**\n * @module text-input-widget\n * Single-line text input for string values.\n */\nimport { html, TemplateResult } from 'lit';\n\n/** Render a text input */\nexport function renderTextInput(value: string, onChange: (v: string) => void, label: string): TemplateResult {\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n <input class=\"prop-input\" type=\"text\" .value=${value ?? ''}\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).value)} />\n </div>\n `;\n}\n","/**\n * @module textarea-widget\n * Multi-line text area for HTML/rich text content editing.\n */\nimport { html, TemplateResult } from 'lit';\n\n/** Render a textarea with monospace font for HTML editing */\nexport function renderTextArea(value: string, onChange: (v: string) => void, label: string): TemplateResult {\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n <textarea class=\"prop-input\"\n style=\"min-height:100px;font-family:'SF Mono',Menlo,monospace;font-size:12px;\"\n .value=${value ?? ''}\n @change=${(e: Event) => onChange((e.target as HTMLTextAreaElement).value)}\n ></textarea>\n </div>\n `;\n}\n","/**\n * @module number-unit-widget\n * Numeric input with unit suffix (px, %, em) and arrow key support.\n * Propagates changes on every input event (not just change) for\n * real-time preview while using arrow keys or mouse wheel.\n */\nimport { html, TemplateResult } from 'lit';\n\n/**\n * Render a numeric input with unit suffix.\n * @param value - Current value as string with unit (e.g. \"10px\")\n * @param onChange - Called on every input change with the full value string\n * @param label - Field label\n * @param params - Optional: { unit, min, max, step }\n */\nexport function renderNumberUnit(\n value: string,\n onChange: (v: string) => void,\n label: string,\n params?: Record<string, unknown>,\n): TemplateResult {\n const unit = (params?.unit as string) || 'px';\n const min = (params?.min as number) ?? 0;\n const max = (params?.max as number) ?? 100;\n const step = (params?.step as number) ?? 0.1;\n\n // Parse numeric part from value string (e.g. \"10px\" → 10)\n const numValue = parseFloat(value) || 0;\n\n const handleInput = (e: Event) => {\n const num = parseFloat((e.target as HTMLInputElement).value) || 0;\n onChange(`${num}${unit}`);\n };\n\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n <div style=\"display:flex;align-items:center;gap:4px;\">\n <input\n type=\"number\"\n .value=${String(numValue)}\n min=${min}\n max=${max}\n step=${step}\n @input=${handleInput}\n style=\"flex:1;padding:6px 8px;border:1px solid #d1d5db;border-radius:4px;font-size:13px;color:#111827;\"\n />\n <span style=\"font-size:12px;color:#9ca3af;min-width:20px;\">${unit}</span>\n </div>\n </div>\n `;\n}\n","/**\n * @module image-upload-widget\n * Image URL input with optional upload button.\n * When an image upload callback is registered via `registerCallback('image', fn)`,\n * shows an upload button alongside the URL input.\n */\nimport { html, TemplateResult, nothing } from 'lit';\n\n/** Render an image URL input with optional upload button */\nexport function renderImageUpload(\n value: string,\n onChange: (v: string) => void,\n label: string,\n uploadCallback?: Function,\n): TemplateResult {\n const handleUpload = () => {\n if (!uploadCallback) return;\n uploadCallback({\n done: (data: { url: string }) => {\n if (data?.url) onChange(data.url);\n },\n });\n };\n\n return html`\n <div class=\"prop-row\">\n <label class=\"prop-label\">${label}</label>\n ${value ? html`\n <div style=\"margin-bottom:6px;border-radius:6px;overflow:hidden;border:1px solid var(--me-grey-200,#e5e7eb);background:var(--me-grey-50,#f9fafb);\">\n <img src=${value} alt=\"Preview\" style=\"display:block;width:100%;max-height:120px;object-fit:cover;\" />\n </div>\n ` : nothing}\n <div style=\"display:flex;gap:4px;\">\n <input class=\"prop-input\" type=\"text\" .value=${value ?? ''} placeholder=\"https://...\"\n style=\"flex:1;${uploadCallback ? 'border-radius:8px 0 0 8px;' : ''}\"\n @change=${(e: Event) => onChange((e.target as HTMLInputElement).value)} />\n ${uploadCallback ? html`\n <button @click=${handleUpload}\n style=\"padding:0 10px;border:1px solid var(--me-grey-200,#e5e7eb);border-left:none;border-radius:0 8px 8px 0;background:var(--me-grey-50,#f9fafb);cursor:pointer;color:var(--me-grey-600,#4b5563);font-size:11px;font-weight:600;transition:all 150ms ease;white-space:nowrap;\"\n title=\"Upload image\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"vertical-align:middle;\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/></svg>\n </button>\n ` : nothing}\n </div>\n </div>\n `;\n}\n","/**\n * @module PropertyPanel\n *\n * Right-side panel that renders editable properties for the selected\n * content block. Dynamically generates widgets based on the tool's\n * property definitions (options → groups → properties → widgets).\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { DesignContent, ToolPropertyGroup, ToolProperty } from '@emabuild/types';\nimport type { EditorStore } from '../state/editor-store.js';\nimport type { ToolRegistry } from '../tools/tool-registry.js';\nimport { StoreController } from '../utils/store-controller.js';\nimport {\n renderColorPicker, renderDropdown, renderAlignment,\n renderPadding, renderToggle, renderTextInput, renderTextArea,\n renderNumberUnit, renderImageUpload,\n} from './widgets/index.js';\n\n@customElement('me-property-panel')\nexport class PropertyPanel extends LitElement {\n static styles = css`\n :host {\n display: flex; flex-direction: column; width: 280px; min-width: 280px;\n background: #fff; border-left: 1px solid var(--me-grey-100);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n overflow-y: auto;\n transition: width 200ms ease, min-width 200ms ease, opacity 200ms ease;\n }\n :host(.hidden) {\n width: 0; min-width: 0; opacity: 0; overflow: hidden; border-left: none;\n }\n\n /* ── Panel header ── */\n .header {\n padding: 10px 12px; border-bottom: 1px solid var(--me-grey-100); background: #fff;\n flex-shrink: 0;\n }\n .header-title {\n font-size: 12px; font-weight: 700; color: var(--me-grey-900); margin: 0;\n }\n .header-type {\n font-size: 10px; color: var(--me-grey-400); text-transform: uppercase;\n letter-spacing: 0.03em; margin: 2px 0 0 0;\n }\n\n /* ── Empty state ── */\n .no-selection {\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n flex: 1; color: var(--me-grey-400); font-size: 12px; gap: 8px; padding: 40px 16px; text-align: center;\n }\n\n /* ── Property groups ── */\n .group { padding: 0 12px 4px; }\n .group-title {\n padding: 8px 0 4px; font-size: 10px; font-weight: 700; color: var(--me-blue-600);\n cursor: default; user-select: none;\n display: flex; align-items: center; justify-content: space-between;\n text-transform: uppercase; letter-spacing: 0.06em;\n border-bottom: 1px solid var(--me-blue-50);\n margin-bottom: 8px;\n }\n .group-body { display: flex; flex-direction: column; gap: 8px; padding-bottom: 4px; }\n\n /* ── Property rows ── */\n .prop-row { margin-bottom: 0; display: flex; flex-direction: column; gap: 4px; }\n .prop-label {\n display: block; font-size: 11px; font-weight: 500; color: var(--me-grey-600);\n letter-spacing: 0.01em;\n }\n\n /* ── Inputs & selects ── */\n .prop-input {\n width: 100%; padding: 6px 10px; border: 1px solid var(--me-grey-200); border-radius: 8px;\n font-size: 12px; color: var(--me-grey-700); background: #fff; box-sizing: border-box;\n transition: border-color 150ms ease, box-shadow 150ms ease;\n }\n .prop-input:focus {\n outline: none; border-color: var(--me-primary);\n box-shadow: 0 0 0 2px var(--me-primary-30);\n }\n select.prop-input {\n appearance: none; padding-right: 28px;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 8px center;\n }\n textarea.prop-input { min-height: 80px; resize: vertical; font-family: monospace; }\n\n /* ── Toggle ── */\n .prop-toggle { display: flex; align-items: center; gap: 8px; }\n\n /* ── Color picker ── */\n .prop-color { display: flex; align-items: center; gap: 8px; }\n .color-swatch {\n width: 28px; height: 28px; border-radius: 6px; border: 1px solid var(--me-grey-200);\n cursor: pointer; padding: 0; transition: border-color 150ms ease;\n }\n .color-swatch:hover { border-color: var(--me-primary); }\n `;\n\n private storeCtrl = new StoreController(this, ['design', 'selection']);\n\n @property({ attribute: false })\n set store(s: EditorStore) { this.storeCtrl.setStore(s); }\n get store(): EditorStore { return this.storeCtrl.store!; }\n\n @property({ attribute: false }) toolRegistry!: ToolRegistry;\n\n /** Create a change handler bound to a specific content ID and property key */\n private onChange(contentId: string, key: string) {\n return (value: unknown) => {\n this.store.updateContentValues(contentId, { [key]: value } as any);\n };\n }\n\n render() {\n const selectedId = this.store.selectedId;\n const content = selectedId ? this.store.findContent(selectedId) : undefined;\n this.classList.toggle('hidden', !content);\n\n if (!content) {\n return html``;\n }\n\n const tool = this.toolRegistry.get(content.type);\n if (!tool) {\n return html`<div class=\"no-selection\">Unknown tool: ${content.type}</div>`;\n }\n\n return html`\n <div class=\"header\">\n <p class=\"header-title\">${tool.label}</p>\n <p class=\"header-type\">${content.type}</p>\n </div>\n ${Object.entries(tool.options).map(([, group]) => this.renderGroup(content, group))}\n `;\n }\n\n private renderGroup(content: DesignContent, group: ToolPropertyGroup) {\n return html`\n <div class=\"group\">\n <div class=\"group-title\">${group.title}</div>\n <div class=\"group-body\">\n ${Object.entries(group.options).map(([key, prop]) =>\n this.renderWidget(content, key, prop),\n )}\n </div>\n </div>\n `;\n }\n\n /** Delegate to the correct widget function based on the property's widget type */\n private renderWidget(content: DesignContent, key: string, prop: ToolProperty) {\n const value = content.values[key] ?? prop.defaultValue;\n const change = this.onChange(content.id, key);\n\n switch (prop.widget) {\n case 'color_picker': return renderColorPicker(value as string, change as (v: string) => void, prop.label);\n case 'toggle': return renderToggle(value as boolean, change as (v: boolean) => void, prop.label);\n case 'rich_text': return renderTextArea(value as string, change as (v: string) => void, prop.label);\n case 'dropdown': return renderDropdown(value as string, change as (v: string) => void, prop.label, prop.widgetParams);\n case 'alignment': return renderAlignment(value as string, change as (v: string) => void, prop.label);\n case 'padding': return renderPadding(value as string, change as (v: string) => void, prop.label);\n case 'number_unit': return renderNumberUnit(value as string, change as (v: string) => void, prop.label, prop.widgetParams);\n case 'image_upload': return renderImageUpload(value as string, change as (v: string) => void, prop.label, this.store.getCallback('image'));\n case 'text':\n default: return renderTextInput(value as string, change as (v: string) => void, prop.label);\n }\n }\n}\n","import { LitElement, html, css, nothing } from 'lit';\nimport { checkA11y } from './sidebar/a11y-checker.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport type {\n EmailDesign,\n MailEditorConfig,\n MergeTagGroup,\n MergeTagDefinition,\n ExportResult,\n ExportOptions,\n ToolDefinition,\n PropertyEditorDefinition,\n CustomTabDefinition,\n CallbackType,\n ImageUploadCallback,\n DisplayConditionCallback,\n} from '@emabuild/types';\nimport { EditorStore } from './state/editor-store.js';\nimport { ToolRegistry, type LitToolDefinition } from './tools/tool-registry.js';\nimport { DragManager } from './dnd/drag-manager.js';\nimport { eagerTools, lazyTools } from './tools/built-in/tool-manifest.js';\nimport { renderDesignToHtml } from '@emabuild/email-renderer';\nimport { fromUnlayer, toUnlayer } from './compat/unlayer-adapter.js';\n\n// Import sub-components\nimport './canvas/editor-canvas.js';\nimport './sidebar/editor-sidebar.js';\nimport './properties/property-panel.js';\n\n@customElement('mail-editor')\nexport class MailEditorElement extends LitElement {\n static styles = css`\n :host {\n /* ── Design tokens ── */\n --me-primary: #5d768b;\n --me-primary-dark: #4a6070;\n --me-primary-5: rgba(93,118,139,0.05);\n --me-primary-10: rgba(93,118,139,0.1);\n --me-primary-30: rgba(93,118,139,0.3);\n\n --me-grey-900: #111827;\n --me-grey-700: #374151;\n --me-grey-600: #4b5563;\n --me-grey-500: #6b7280;\n --me-grey-400: #9ca3af;\n --me-grey-300: #d1d5db;\n --me-grey-200: #e5e7eb;\n --me-grey-100: #f3f4f6;\n --me-grey-50: #f9fafb;\n\n --me-blue-50: #EDF5FF;\n --me-blue-600: #245A7F;\n\n --me-danger: #dc2626;\n --me-warning: #d97706;\n --me-success: #16a34a;\n\n --me-radius-sm: 6px;\n --me-radius: 8px;\n --me-radius-lg: 10px;\n\n --me-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --me-transition: 150ms ease;\n\n /* ── Layout ── */\n display: flex;\n width: 100%;\n height: 100%;\n flex: 1;\n min-height: 500px;\n font-family: var(--me-font);\n color: var(--me-grey-900);\n box-sizing: border-box;\n overflow: hidden;\n position: relative;\n }\n * { box-sizing: border-box; }\n .sidebar-toggle {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n left: 10px;\n width: 28px;\n height: 28px;\n border-radius: var(--me-radius);\n border: 1px solid var(--me-grey-200);\n background: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 40;\n box-shadow: 0 1px 4px rgba(0,0,0,0.08);\n transition: all var(--me-transition);\n padding: 0;\n color: var(--me-grey-500);\n }\n .sidebar-toggle:hover {\n background: var(--me-grey-50);\n color: var(--me-primary);\n box-shadow: 0 2px 8px rgba(0,0,0,0.12);\n }\n .sidebar-toggle svg {\n width: 14px;\n height: 14px;\n stroke: currentColor;\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n transition: transform 200ms ease;\n }\n .sidebar-toggle.collapsed {\n width: 20px;\n height: 20px;\n border: none;\n background: transparent;\n box-shadow: none;\n color: var(--me-primary);\n animation: pulse-hint 2s ease-in-out infinite;\n }\n .sidebar-toggle.collapsed:hover {\n background: transparent;\n color: var(--me-primary-dark);\n animation: none;\n transform: translateY(-50%) scale(1.2);\n }\n .sidebar-toggle.collapsed svg {\n width: 22px;\n height: 22px;\n transform: rotate(180deg);\n }\n @keyframes pulse-hint {\n 0%, 100% { opacity: 0.5; }\n 50% { opacity: 1; }\n }\n\n /* ── A11y dots when sidebar collapsed ── */\n .a11y-dots {\n position: absolute;\n left: 14px;\n top: calc(50% + 18px);\n display: flex;\n flex-direction: column;\n gap: 6px;\n z-index: 40;\n }\n .a11y-dot {\n width: 8px; height: 8px; border-radius: 50%;\n }\n .a11y-dot.error { background: #dc2626; animation: pulse-e 1.8s ease-in-out infinite; }\n .a11y-dot.warning { background: #d97706; animation: pulse-w 2.3s ease-in-out infinite; }\n .a11y-dot.info { background: #5d768b; animation: pulse-i 2.7s ease-in-out infinite; }\n @keyframes pulse-e {\n 0%, 100% { opacity: 0.4; transform: scale(0.85); }\n 50% { opacity: 1; transform: scale(1.1); }\n }\n @keyframes pulse-w {\n 0%, 100% { opacity: 0.35; transform: scale(0.9); }\n 60% { opacity: 1; transform: scale(1.15); }\n }\n @keyframes pulse-i {\n 0%, 100% { opacity: 0.3; transform: scale(0.9); }\n 40% { opacity: 0.9; transform: scale(1.05); }\n }\n `;\n\n @property({ type: Object }) options: MailEditorConfig = {};\n\n private store = new EditorStore();\n private toolRegistry = new ToolRegistry();\n private dragManager: DragManager | null = null;\n private callbacks = new Map<string, Function>();\n private unsubscribe: (() => void) | null = null;\n @state() private sidebarCollapsed = false;\n @state() private a11yHasErrors = false;\n @state() private a11yHasWarnings = false;\n @state() private a11yHasInfos = false;\n\n private a11yDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n\n private updateA11yState() {\n if (this.a11yDebounceTimer) clearTimeout(this.a11yDebounceTimer);\n this.a11yDebounceTimer = setTimeout(() => {\n const issues = checkA11y(this.store);\n this.a11yHasErrors = issues.some((i) => i.severity === 'error');\n this.a11yHasWarnings = issues.some((i) => i.severity === 'warning');\n this.a11yHasInfos = issues.some((i) => i.severity === 'info');\n const ids = new Set<string>();\n for (const i of issues) { if (i.elementId && (i.severity === 'error' || i.severity === 'warning')) ids.add(i.elementId); }\n this.store.setA11yIssueIds(ids);\n }, 300);\n }\n\n private toggleSidebar() {\n this.sidebarCollapsed = !this.sidebarCollapsed;\n const sidebar = this.shadowRoot?.querySelector('me-editor-sidebar');\n sidebar?.classList.toggle('collapsed', this.sidebarCollapsed);\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.registerBuiltInTools();\n this.applyOptions();\n this.setAttribute('tabindex', '0');\n this.addEventListener('keydown', this._handleKeydown);\n }\n\n firstUpdated() {\n // Attach DnD to shadow root\n this.dragManager = new DragManager(this.store, this.toolRegistry, this.shadowRoot!);\n this.dragManager.attach();\n\n // Forward events\n this.store.events.on('design:loaded', (detail) => {\n this.dispatchEvent(new CustomEvent('design:loaded', { detail, bubbles: true, composed: true }));\n });\n this.store.events.on('design:updated', (detail) => {\n this.dispatchEvent(new CustomEvent('design:updated', { detail, bubbles: true, composed: true }));\n });\n\n // Track a11y state for collapsed sidebar dots\n this.unsubscribe = this.store.subscribeChannels(['design'], () => this.updateA11yState());\n this.updateA11yState();\n\n // Fire ready event\n this.dispatchEvent(new CustomEvent('editor:ready', { bubbles: true, composed: true }));\n\n // Preload lazy tools during browser idle time\n this.preloadLazyTools();\n }\n\n private _handleKeydown = (e: KeyboardEvent) => {\n const mod = e.metaKey || e.ctrlKey;\n\n // Don't capture if user is typing in an input/textarea/select.\n // Use composedPath() to see through shadow DOM boundaries —\n // e.target may point to a shadow host, not the actual <input>.\n const path = e.composedPath();\n const isEditing = path.some((el) => {\n const htmlEl = el as HTMLElement;\n const tag = htmlEl?.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;\n if (htmlEl?.isContentEditable) return true;\n return false;\n });\n\n if (isEditing && !mod) return;\n\n const canvas = this.shadowRoot?.querySelector('me-editor-canvas') as any;\n\n if (mod && e.key === 'z' && !e.shiftKey) {\n e.preventDefault();\n this.store.undo();\n canvas?.flashUndo?.();\n } else if (mod && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) {\n e.preventDefault();\n this.store.redo();\n canvas?.flashUndo?.();\n } else if (mod && e.key === 'd' && !e.shiftKey && this.store.selectedId && !isEditing) {\n e.preventDefault();\n this.store.duplicateContent(this.store.selectedId);\n } else if ((e.key === 'Delete' || e.key === 'Backspace') && this.store.selectedId && !isEditing) {\n e.preventDefault();\n this.store.removeContent(this.store.selectedId);\n } else if (e.key === 'Escape') {\n this.store.select(null);\n }\n };\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.dragManager?.detach();\n this.unsubscribe?.();\n this.store.events.removeAllListeners();\n this.removeEventListener('keydown', this._handleKeydown);\n }\n\n // ----------------------------------------------------------\n // Public API — public API\n // ----------------------------------------------------------\n\n loadDesign(design: EmailDesign): void {\n this.store.loadDesign(design);\n }\n\n /** Load an Unlayer design JSON, converting it to Emabuild format */\n loadUnlayerDesign(unlayerJson: Record<string, unknown>): void {\n this.store.loadDesign(fromUnlayer(unlayerJson));\n }\n\n saveDesign(callback: (design: EmailDesign) => void): void {\n callback(structuredClone(this.store.getDesign()));\n }\n\n /** Save the design as Unlayer-compatible JSON */\n saveUnlayerDesign(callback: (design: Record<string, unknown>) => void): void {\n callback(toUnlayer(this.store.getDesign()));\n }\n\n exportHtml(callback: (result: ExportResult) => void, options?: ExportOptions): void {\n // Ensure all lazy tools used in the design are loaded before export\n const design = this.store.getDesign();\n const usedTypes = new Set<string>();\n for (const row of design.body.rows) {\n for (const col of row.columns) {\n for (const content of col.contents) {\n usedTypes.add(content.type);\n }\n }\n }\n\n const loadPromises = Array.from(usedTypes)\n .filter((type) => !this.toolRegistry.isLoaded(type))\n .map((type) => this.toolRegistry.ensureLoaded(type));\n\n if (loadPromises.length > 0) {\n Promise.all(loadPromises).then(() => this.doExport(design, callback, options));\n } else {\n this.doExport(design, callback, options);\n }\n }\n\n private doExport(design: EmailDesign, callback: (result: ExportResult) => void, options?: ExportOptions): void {\n const toolRenderers = new Map<string, (values: Record<string, unknown>, ctx: any) => string>();\n for (const tool of this.toolRegistry.getAll()) {\n toolRenderers.set(tool.name, (values, ctx) => tool.renderer.renderHtml(values as any, ctx));\n }\n callback(renderDesignToHtml(design, toolRenderers, options));\n }\n\n async exportHtmlAsync(options?: ExportOptions): Promise<ExportResult> {\n return new Promise((resolve) => this.exportHtml(resolve, options));\n }\n\n registerTool(definition: LitToolDefinition): void {\n this.toolRegistry.register(definition);\n this.requestUpdate();\n }\n\n registerPropertyEditor(_name: string, _editor: PropertyEditorDefinition): void {\n // TODO: implement custom property editor registry\n }\n\n registerTab(_tab: CustomTabDefinition): void {\n // TODO: implement custom tab registry\n }\n\n registerCallback(type: string, callback: Function): void {\n this.callbacks.set(type, callback);\n this.store.setCallback(type, callback);\n }\n\n setMergeTags(tags: MergeTagGroup[]): void {\n this.store.setMergeTags(tags);\n }\n\n undo(): void {\n this.store.undo();\n }\n\n redo(): void {\n this.store.redo();\n }\n\n setBodyValues(values: Record<string, unknown>): void {\n this.store.updateBodyValues(values as any);\n }\n\n // ----------------------------------------------------------\n // Internal\n // ----------------------------------------------------------\n\n /**\n * Preload lazy tools during browser idle time.\n * Uses requestIdleCallback to avoid blocking the main thread.\n * Falls back to setTimeout(1000) for browsers without idle callback support.\n */\n private preloadLazyTools() {\n const idle = window.requestIdleCallback ?? ((cb: () => void) => setTimeout(cb, 1000));\n for (const { meta } of lazyTools) {\n idle(() => {\n this.toolRegistry.ensureLoaded(meta.name);\n });\n }\n }\n\n private registerBuiltInTools() {\n // Eager tools — loaded immediately (most commonly used)\n for (const tool of eagerTools) {\n this.toolRegistry.register(tool);\n }\n // Lazy tools — loaded on first use to reduce initial bundle\n for (const { meta, loader } of lazyTools) {\n this.toolRegistry.registerLazy(meta, loader);\n }\n }\n\n private applyOptions() {\n if (this.options.design) {\n this.store.loadDesign(this.options.design);\n }\n if (this.options.mergeTags) {\n const raw = this.options.mergeTags;\n const groups: MergeTagGroup[] = Array.isArray(raw)\n ? raw as MergeTagGroup[]\n : Object.values(raw as Record<string, MergeTagGroup>);\n this.store.setMergeTags(groups);\n }\n }\n\n render() {\n return html`\n <me-editor-sidebar\n .store=${this.store}\n .toolRegistry=${this.toolRegistry}\n ></me-editor-sidebar>\n <button class=\"sidebar-toggle ${this.sidebarCollapsed ? 'collapsed' : ''}\"\n @click=${this.toggleSidebar}\n title=\"${this.sidebarCollapsed ? 'Show tools' : 'Hide tools'}\"\n style=\"left:${this.sidebarCollapsed ? '10px' : '290px'}\">\n ${this.sidebarCollapsed\n ? html`<svg viewBox=\"0 0 24 24\"><path d=\"M13 18l-6-6 6-6\"/><path d=\"M19 18l-6-6 6-6\"/></svg>`\n : html`<svg viewBox=\"0 0 24 24\"><path d=\"M15 18l-6-6 6-6\"/></svg>`}\n </button>\n ${this.sidebarCollapsed && (this.a11yHasErrors || this.a11yHasWarnings || this.a11yHasInfos) ? html`\n <div class=\"a11y-dots\">\n ${this.a11yHasErrors ? html`<div class=\"a11y-dot error\"></div>` : nothing}\n ${this.a11yHasWarnings ? html`<div class=\"a11y-dot warning\"></div>` : nothing}\n ${this.a11yHasInfos ? html`<div class=\"a11y-dot info\"></div>` : nothing}\n </div>\n ` : nothing}\n <me-editor-canvas\n .store=${this.store}\n .toolRegistry=${this.toolRegistry}\n ></me-editor-canvas>\n <me-property-panel\n .store=${this.store}\n .toolRegistry=${this.toolRegistry}\n ></me-property-panel>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mail-editor': MailEditorElement;\n }\n}\n","/**\n * Explicitly registers all custom elements.\n * Uses a self-invoking pattern that bundlers cannot tree-shake.\n */\n\nimport { MailEditorElement } from './mail-editor.js';\nimport { EditorCanvas } from './canvas/editor-canvas.js';\nimport { RowRenderer } from './canvas/row-renderer.js';\nimport { ColumnRenderer } from './canvas/column-renderer.js';\nimport { ContentRenderer } from './canvas/content-renderer.js';\nimport { EditorSidebar } from './sidebar/editor-sidebar.js';\nimport { BodySettings } from './sidebar/body-settings.js';\nimport { PropertyPanel } from './properties/property-panel.js';\nimport { InlineToolbar } from './canvas/inline-toolbar.js';\nimport { A11yChecker } from './sidebar/a11y-checker.js';\n\nfunction register(name: string, ctor: CustomElementConstructor): void {\n if (!customElements.get(name)) {\n customElements.define(name, ctor);\n }\n}\n\nregister('mail-editor', MailEditorElement);\nregister('me-editor-canvas', EditorCanvas);\nregister('me-row-renderer', RowRenderer);\nregister('me-column-renderer', ColumnRenderer);\nregister('me-content-renderer', ContentRenderer);\nregister('me-editor-sidebar', EditorSidebar);\nregister('me-body-settings', BodySettings);\nregister('me-property-panel', PropertyPanel);\nregister('me-inline-toolbar', InlineToolbar);\nregister('me-a11y-checker', A11yChecker);\n\n// Force bundlers to keep this module as a side-effect\n// by exporting a value that depends on the registrations\nexport const EMABUILD_REGISTERED = customElements.get('mail-editor') !== undefined;\n"],"names":["StoreController","host","channels","store","parseColor","color","s","named","h","m","luminance","r","g","b","rs","gs","bs","c","v","contrastRatio","fg","bg","c1","c2","l1","l2","isRealColor","resolveBackground","colors","parsePx","value","fallback","parseLineHeight","n","A11yChecker","LitElement","checkA11y","elementId","row","colId","defaults","content","issues","errors","warnings","infos","html","nothing","issue","css","__decorateClass","property","customElement","design","bodyValues","bodyBg","bodyTextColor","hasHeading","headingTypes","rowBg","colsBg","col","effectiveBg","type","label","alt","textColor","ratio","fontSize","isBold","min","fs","lh","btnBg","btnText","btnRowRatio","padParts","estH","txt","empty","generic","totalContent","a","lvls","i","bodyRatio","linkColor","lr","lvt","createCounterManager","counters","key","prefix","current","EventEmitter","event","listener","payload","fn","e","HistoryManager","maxHistory","currentDesign","prev","next","createEmptyDesign","createRow","cm","cellProportions","rowNum","columns","colNum","createContent","values","counter","id","findRow","rowId","findColumn","columnId","findContent","contentId","findParentColumn","findParentRow","getRowIndex","EditorStore","ids","ch","subs","ALL_CHANNELS","toNotify","tags","mode","tab","index","cloned","rows","idx","lookup.getRowIndex","fromIndex","toIndex","lookup.findRow","cNum","patch","lookup.findColumn","lookup.findContent","targetColumnId","targetIndex","targetCol","removed","outer","clampedIndex","lookup.findParentColumn","lookup.findParentRow","item","ToolRegistry","tool","meta","loader","name","promise","err","metas","group","prop","dragState","el","createDropIndicator","positionIndicator","indicator","container","items","insetX","containerRect","indicatorY","hideIndicator","walkShadowDom","root","callback","children","child","queryShadowAll","selector","results","DragManager","toolRegistry","types","isToolDrag","isLayoutDrag","isContentDrag","isRowDrag","drop","layoutData","toolName","related","cells","rowIndex","clientY","canvas","bestDist","bestTarget","y","dist","clientX","colEl","colRect","contentEls","firstY","rect","nextRect","canvasBody","str","imageUrl","imageMeta","obj","linkAction","action","actValues","textContent","text","textJson","parsed","parts","walk","node","getFontFamily","ff","cssValue","url","link","buttonColors","bc","jsonParse","emailTableCell","options","padding","align","extraTdStyle","vmlRoundrectButton","href","bgColor","fontWeight","borderRadius","radiusPx","arcsize","LINE_HEIGHT_OPTIONS","FONT_WEIGHT_OPTIONS","FONT_WEIGHT_OPTIONS_SIMPLE","HEADING_FONT_SIZE_OPTIONS","BUTTON_FONT_SIZE_OPTIONS","lineHeightProp","defaultValue","fontWeightProp","simple","SPACING_GROUP","GENERAL_GROUP","GENERAL_GROUP_MINIMAL","textTool","lineHeight","textAlign","fontFamily","unsafeHTML","bgStyle","inner","headingTool","styles","styleMap","letterSpacing","tag","paragraphTool","imageTool","src","width","ctx","widthPx","brStyle","imgTag","buttonTool","radius","btnPad","btnWidth","bw","borderStyle","widthStyle","target","vml","vmlOpen","dividerTool","border","eagerTools","lazyTools","w","t","p","u","o","x","f","d","k","$","_","C","E","I","M","pxToNumber","val","numberToPx","bgImageFromUnlayer","ubg","bgImageToUnlayer","contentFromUnlayer","uv","srcObj","size","menu","contentToUnlayer","srcUrl","rowFromUnlayer","urow","columnFromUnlayer","ucol","contents","vals","fromUnlayer","unlayerDesign","body","ls","headers","footers","recalcCounters","toUnlayer","convertRow","rv","rowGroups","bumpId","match","num","InlineToolbar","command","_key","state","INLINE_EDITABLE_TYPES","getTextKey","ContentRenderer","parent","textKey","textHtml","overlay","sel","range","newHtml","currentVal","isSelected","viewMode","hideDesktop","hideMobile","hiddenInView","hasA11yIssue","hiddenLabel","isInlineEditable","dragHandle","rendered","containerPadding","ColumnRenderer","repeat","RowRenderer","total","colsBgColor","totalCells","bgImg","bgUrl","bgImageStyle","position","widthPercent","EditorCanvas","lp","contentWidth","canvasWidth","EMAIL_SAFE_FONTS","BodySettings","field","input","font","update","onChange","TOOL_CATEGORIES","EditorSidebar","activeTab","allTools","q","toolMap","matchesSearch","hasResults","categories","cat","tools","categorizedNames","uncategorized","showLayouts","renderColorPicker","safeValue","renderDropdown","params","opt","renderAlignment","parsePadding","top","right","bottom","left","toPaddingShorthand","l","renderPadding","renderToggle","renderTextInput","renderTextArea","renderNumberUnit","unit","max","step","numValue","handleInput","renderImageUpload","uploadCallback","handleUpload","data","PropertyPanel","selectedId","change","MailEditorElement","mod","isEditing","htmlEl","detail","unlayerJson","usedTypes","loadPromises","toolRenderers","renderDesignToHtml","resolve","definition","_name","_editor","_tab","idle","cb","raw","groups","register","ctor","EMABUILD_REGISTERED"],"mappings":"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"}