;(function (window, document) {
    'use strict';

    const DEFAULT_CONFIG = {
        activation_required: true,
        activation_status: false,
        api_key_last4: '',
        agent_mode: true,
        cdn_js: 'https://unpkg.com/grapesjs@0.21.10/dist/grapes.min.js',
        cdn_css: 'https://unpkg.com/grapesjs@0.21.10/dist/css/grapes.min.css',
        debug: false
    };

    const internal = {
        config: { ...DEFAULT_CONFIG },
        loading: false,
        ready: false,
        preloadPromise: null,
        editor: null,
        mountId: 'vmo-grapes-shadow-mount',
        lastSignature: '',
        lastResult: null,
        lastRunAt: 0,
        lastError: null,
        mediaCounter: 0
    };

    function readConfig() {
        const runtime = (window.vmoGrapesConfig && typeof window.vmoGrapesConfig === 'object')
            ? window.vmoGrapesConfig
            : {};
        internal.config = { ...DEFAULT_CONFIG, ...runtime };
    }

    function isActivated() {
        return internal.config.activation_required ? !!internal.config.activation_status : true;
    }

    function log() {
        if (!internal.config.debug) return;
        try {
            console.log('[VMO Grapes]', ...arguments);
        } catch (_) {}
    }

    function warn() {
        try {
            console.warn('[VMO Grapes]', ...arguments);
        } catch (_) {}
    }

    function escapeHtml(value) {
        return String(value || '')
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;');
    }

    function stripHtmlComments(html) {
        const input = String(html || '');
        if (!input) return '';

        if (typeof window.vmoSanitizeGeneratedHtml === 'function') {
            return window.vmoSanitizeGeneratedHtml(input);
        }

        return input.replace(/<!--[\s\S]*?-->/g, '');
    }

    function safeJsonForScript(value) {
        try {
            return JSON.stringify(value)
                .replace(/</g, '\\u003c')
                .replace(/>/g, '\\u003e')
                .replace(/&/g, '\\u0026')
                .replace(/\u2028/g, '\\u2028')
                .replace(/\u2029/g, '\\u2029');
        } catch (_) {
            return '{}';
        }
    }

    function slugify(value) {
        return String(value || 'section')
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/^-+|-+$/g, '') || 'section';
    }

    function nextMediaId() {
        internal.mediaCounter += 1;
        return `grapes-media-${Date.now()}-${internal.mediaCounter}`;
    }

    function ensureCss(url) {
        if (!url) return;
        if (document.querySelector(`link[data-vmo-grapes="css"][href="${url}"]`)) return;
        const link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = url;
        link.dataset.vmoGrapes = 'css';
        document.head.appendChild(link);
    }

    function ensureScript(url) {
        if (!url) {
            return Promise.reject(new Error('Missing GrapesJS script URL'));
        }

        if (window.grapesjs) {
            return Promise.resolve(window.grapesjs);
        }

        const existing = document.querySelector(`script[data-vmo-grapes="js"][src="${url}"]`);
        if (existing) {
            return new Promise((resolve, reject) => {
                if (window.grapesjs) {
                    resolve(window.grapesjs);
                    return;
                }
                existing.addEventListener('load', () => resolve(window.grapesjs), { once: true });
                existing.addEventListener('error', () => reject(new Error('Failed loading GrapesJS')), { once: true });
            });
        }

        return new Promise((resolve, reject) => {
            const script = document.createElement('script');
            script.src = url;
            script.async = true;
            script.dataset.vmoGrapes = 'js';
            script.addEventListener('load', () => resolve(window.grapesjs), { once: true });
            script.addEventListener('error', () => reject(new Error('Failed loading GrapesJS')), { once: true });
            document.head.appendChild(script);
        });
    }

    function ensureMount() {
        let mount = document.getElementById(internal.mountId);
        if (mount) return mount;

        mount = document.createElement('div');
        mount.id = internal.mountId;
        mount.style.cssText = [
            'position:fixed',
            'width:1px',
            'height:1px',
            'opacity:0',
            'pointer-events:none',
            'overflow:hidden',
            'left:-99999px',
            'top:-99999px',
            'z-index:-1'
        ].join(';');
        document.body.appendChild(mount);
        return mount;
    }

    function initEditor() {
        if (internal.editor) return internal.editor;
        if (!window.grapesjs || typeof window.grapesjs.init !== 'function') {
            throw new Error('GrapesJS runtime unavailable');
        }

        const mount = ensureMount();
        internal.editor = window.grapesjs.init({
            container: `#${internal.mountId}`,
            fromElement: false,
            height: '1px',
            width: '1px',
            storageManager: false,
            panels: { defaults: [] },
            selectorManager: { componentFirst: true }
        });

        mount.setAttribute('data-vmo-grapes-ready', '1');
        return internal.editor;
    }

    function preload() {
        readConfig();
        if (!isActivated()) {
            return Promise.resolve(false);
        }

        if (internal.ready && internal.editor) {
            return Promise.resolve(true);
        }
        if (internal.preloadPromise) {
            return internal.preloadPromise;
        }

        internal.loading = true;
        ensureCss(internal.config.cdn_css);
        internal.preloadPromise = ensureScript(internal.config.cdn_js)
            .then(() => {
                initEditor();
                internal.ready = true;
                internal.loading = false;
                log('GrapesJS adapter ready');
                return true;
            })
            .catch((err) => {
                internal.ready = false;
                internal.loading = false;
                internal.lastError = err;
                warn('GrapesJS preload failed.', err?.message || err);
                return false;
            })
            .finally(() => {
                internal.preloadPromise = null;
            });

        return internal.preloadPromise;
    }

    function cloneBlocks(blocks) {
        if (!Array.isArray(blocks)) return [];
        return blocks.map((block) => ({ ...block }));
    }

    function signatureForBlocks(blocks) {
        if (!Array.isArray(blocks) || !blocks.length) return 'empty';
        return blocks.map((block) => `${block?.id || ''}:${(block?.html || '').length}`).join('|');
    }

    function validatePass(blocks) {
        const editor = internal.editor;
        if (!editor) {
            return { ok: false, reason: 'editor_unavailable' };
        }

        try {
            const combined = blocks.map((block) => block?.html || '').join('\n');
            editor.setComponents(combined || '<div></div>');
            editor.getHtml();
            return { ok: true };
        } catch (err) {
            internal.lastError = err;
            return { ok: false, reason: err?.message || 'parse_failed' };
        }
    }

    function normalizePlan(plan) {
        if (!plan || typeof plan !== 'object') return {};
        const safe = { ...plan };
        if (!Array.isArray(safe.sections)) safe.sections = [];
        if (!safe.integrations || typeof safe.integrations !== 'object') safe.integrations = {};
        if (!safe.site || typeof safe.site !== 'object') safe.site = {};
        if (!safe.brand || typeof safe.brand !== 'object') safe.brand = {};
        if (!safe.tech_stack || typeof safe.tech_stack !== 'object') safe.tech_stack = {};
        if (!Array.isArray(safe.tech_stack.selected)) safe.tech_stack.selected = [];
        return safe;
    }

    /* ═══════════════════════════════════════════════════════════════════ *
     * PREMIUM COMPOSITION ENGINE v2                                     *
     * Tailwind CSS + GSAP/ScrollTrigger + Lenis + Swiper + React 18    *
     * ═══════════════════════════════════════════════════════════════════ */

    const CDN_URLS = {
        font: 'https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Cormorant+Garamond:wght@600;700&display=swap',
        tailwind: 'https://cdn.tailwindcss.com',
        react: 'https://unpkg.com/react@18/umd/react.production.min.js',
        react_dom: 'https://unpkg.com/react-dom@18/umd/react-dom.production.min.js',
        gsap: 'https://unpkg.com/gsap@3.12.5/dist/gsap.min.js',
        scrolltrigger: 'https://unpkg.com/gsap@3.12.5/dist/ScrollTrigger.min.js',
        lenis: 'https://unpkg.com/lenis@1.1.13/dist/lenis.min.js',
        swiper_css: 'https://unpkg.com/swiper@11/swiper-bundle.min.css',
        swiper_js: 'https://unpkg.com/swiper@11/swiper-bundle.min.js'
    };

    function extractNarrativePoints(section) {
        if (!section || typeof section !== 'object' || !Array.isArray(section.bullets)) {
            return [];
        }

        return section.bullets
            .map((item) => String(item || '').trim())
            .filter(Boolean)
            .slice(0, 6);
    }

    function buildMediaNarrative(sectionType, mediaType, section, variantLabel) {
        const headline = String(section?.headline || '').trim();
        const subheadline = String(section?.subheadline || '').trim();
        const body = String(section?.body || '').trim().slice(0, 220);
        const bullets = extractNarrativePoints(section).slice(0, 4).join(', ');
        const label = String(variantLabel || sectionType || 'section').trim();
        const context = [headline, subheadline, body, bullets].filter(Boolean).join('. ');

        if (mediaType === 'video') {
            return `Cinematic ${label} loop for a premium ${headline || sectionType} website section. ${context ? `Story context: ${context}. ` : ''}Editorial camera motion, layered depth, atmospheric lighting, polished premium surfaces, no text, no logos, seamless website-safe loop.`;
        }

        return `Premium ${label} image for a ${headline || sectionType} website section. ${context ? `Story context: ${context}. ` : ''}Editorial composition, dimensional lighting, premium materials, refined color harmony, no text overlay, polished commercial art direction.`;
    }

    function buildMarquee(items) {
        const values = Array.isArray(items) ? items.filter(Boolean).slice(0, 6) : [];
        if (!values.length) return '';

        const chips = values.concat(values).map(function (item) {
            return '<span class="vmo-marquee-chip">' + escapeHtml(item) + '</span>';
        }).join('');

        return '<div class="vmo-marquee"><div class="vmo-marquee-track">' + chips + '</div></div>';
    }

    function buildSectionId(type, index) {
        const safeType = slugify(type || ('section-' + (index + 1)));
        return safeType === 'default' ? ('section-' + (index + 1)) : ('section-' + (index + 1) + '-' + safeType);
    }

    function buildSectionAnchors(sections) {
        const labelMap = {
            hero: 'Home',
            proof: 'Proof',
            stats: 'Proof',
            logos: 'Proof',
            metrics: 'Proof',
            services: 'Services',
            features: 'Services',
            showcase: 'Showcase',
            story: 'Showcase',
            experience: 'Showcase',
            gallery: 'Gallery',
            portfolio: 'Portfolio',
            products: 'Products',
            shop: 'Products',
            ecommerce: 'Products',
            about: 'About',
            testimonials: 'Reviews',
            reviews: 'Reviews',
            pricing: 'Pricing',
            faq: 'FAQ',
            contact: 'Contact'
        };

        const anchors = [];
        const seen = new Set();
        (Array.isArray(sections) ? sections : []).forEach(function (section, index) {
            const type = slugify((section && section.type) || '');
            const label = labelMap[type];
            if (!label || seen.has(label)) return;
            anchors.push({ href: '#' + buildSectionId(type, index), label: label });
            seen.add(label);
        });

        if (!anchors.some(function (item) { return item.label === 'Home'; })) {
            anchors.unshift({ href: '#section-1-hero', label: 'Home' });
        }

        return anchors.slice(0, 5);
    }

    function buildQuickActionChips(integrations, className) {
        const chipClass = className || 'vmo-action-chip';
        const chips = [];

        if (integrations.phone_enabled && integrations.phone_number) {
            const phone = String(integrations.phone_number);
            chips.push('<a href="tel:' + escapeHtml(phone.replace(/[^+\d]/g, '')) + '" class="' + chipClass + '">&#x260E; ' + escapeHtml(phone) + '</a>');
        }

        if (integrations.email_enabled && integrations.email_address) {
            const email = String(integrations.email_address);
            chips.push('<a href="mailto:' + escapeHtml(email) + '" class="' + chipClass + '">&#x2709; ' + escapeHtml(email) + '</a>');
        }

        return chips.join('');
    }

    function composePremiumMedia(sectionType, mediaType, section, variantLabel, shellClass) {
        const id = nextMediaId();
        const btn = '<button class="vmo-replace-btn absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/40 opacity-0 group-hover:opacity-100 transition-all duration-300 rounded-2xl cursor-pointer" data-replace-media="' + escapeHtml(id) + '"><span class="px-4 py-2 bg-white/90 backdrop-blur-sm text-gray-900 text-sm font-semibold rounded-lg shadow-lg">&#x1F504; Replace</span></button>';
        const prompt = buildMediaNarrative(sectionType, mediaType, section, variantLabel);
        const classes = shellClass || 'min-h-[320px] rounded-[30px]';
        const shellStart = '<div class="relative group"><div class="vmo-media-shell ' + classes + '" data-vmo-parallax="slow"><div class="vmo-media-aura"></div><div class="vmo-media-grid"></div>';
        const shellEnd = '</div>' + btn + '</div>';

        if (mediaType === 'video') {
            return shellStart
                + '<div class="vmo-media-placeholder vmo-media-placeholder-video flex h-full min-h-[320px] w-full items-end justify-start" data-media-id="' + id + '" data-type="video" data-vmo-sora="true" data-vmo-sora-prompt="' + escapeHtml(prompt) + '">'
                + '</div>'
                + shellEnd;
        }

        return shellStart
            + '<div class="vmo-media-placeholder vmo-media-placeholder-image flex h-full min-h-[320px] w-full items-end justify-start" data-media-id="' + id + '" data-type="image" data-vmo-generate="true" data-vmo-prompt="' + escapeHtml(prompt) + '">'
            + '</div>'
            + shellEnd;
    }

    function composeHeroSection(s, i, integrations, site) {
        const hl = escapeHtml(s.headline || 'Welcome');
        const heroMediaType = s.media === 'image' || s.media === 'video' ? s.media : 'video';
        const media = composePremiumMedia('hero', heroMediaType, s, 'cinematic hero backdrop', 'min-h-[74vh] rounded-[36px]');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.38em] text-slate-500">' + escapeHtml(s.subheadline) + '</p>' : '';
        const body = s.body ? '<p class="mt-6 max-w-2xl text-lg leading-relaxed text-slate-600 lg:text-xl">' + escapeHtml(s.body) + '</p>' : '';
        const cta1 = s.cta_primary ? '<a href="#" class="vmo-premium-btn">' + escapeHtml(s.cta_primary) + '</a>' : '';
        const cta2 = s.cta_secondary ? '<a href="#" class="vmo-premium-btn vmo-premium-btn-secondary">' + escapeHtml(s.cta_secondary) + '</a>' : '';
        const bullets = extractNarrativePoints(s);
        const proofLabels = ['Narrative', 'Offer', 'Confidence'];
        const heroCards = bullets.slice(0, 3).map(function (item, idx) {
            return '<article class="vmo-proof-card" data-vmo-float="' + idx + '"><p class="vmo-proof-card-kicker">' + proofLabels[idx] + '</p><p class="mt-3 text-base font-semibold leading-snug text-slate-900">' + escapeHtml(item) + '</p></article>';
        }).join('');
        const heroMarquee = buildMarquee(bullets.length ? bullets : [s.headline, s.cta_primary, s.cta_secondary]);
        const quickActions = buildQuickActionChips(integrations, 'vmo-action-chip');
        const directionChip = (s.design_direction || s.interaction_style)
            ? '<span class="vmo-action-chip vmo-action-chip-muted">' + escapeHtml([s.design_direction, s.interaction_style].filter(Boolean).join(' · ')) + '</span>'
            : '';
        const floatingIntro = escapeHtml(site && site.business_name ? site.business_name : (s.headline || 'Opening Sequence'));
        const floatingCopy = escapeHtml(s.design_direction || (site && site.goal) || 'Layered opening composition with premium media and guided motion.');
        const floatingList = bullets.slice(0, 3).map(function (item, idx) {
            return '<div class="vmo-hero-list-item"><span class="vmo-hero-list-index">0' + (idx + 1) + '</span><p>' + escapeHtml(item) + '</p></div>';
        }).join('');

        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="' + buildSectionId('hero', i) + '" class="vmo-hero-stage relative flex min-h-[100vh] items-center overflow-hidden pb-20 pt-28 lg:pb-24 lg:pt-36" data-vmo-section-type="hero" data-vmo-animate>'
            + '<div class="vmo-overlay-container" data-vmo-overlay-slot="hero"></div>'
            + '<div class="pointer-events-none absolute -left-20 top-16 h-64 w-64 rounded-full bg-white/55 blur-3xl"></div>'
            + '<div class="pointer-events-none absolute right-0 top-0 h-72 w-72 rounded-full bg-[color:var(--vmo-accent-soft)] blur-3xl"></div>'
            + '<div class="pointer-events-none absolute bottom-0 left-1/4 h-44 w-44 rounded-full bg-white/35 blur-3xl"></div>'
            + '<div class="relative z-10 mx-auto grid max-w-7xl grid-cols-1 gap-10 px-6 lg:grid-cols-[1.03fr_.97fr] lg:items-center lg:gap-16">'
            + '<div>'
            + ((quickActions || directionChip) ? '<div class="mb-6 flex flex-wrap items-center gap-3">' + directionChip + quickActions + '</div>' : '')
            + sub
            + '<h2 class="vmo-display mt-5 max-w-4xl text-[clamp(3.35rem,7vw,6.4rem)] font-semibold leading-[0.9] tracking-[-0.04em] text-slate-950">' + hl + '</h2>'
            + body
            + '<div class="mt-10 flex flex-wrap gap-4">' + cta1 + cta2 + '</div>'
            + (heroCards ? '<div class="vmo-proof-grid mt-10">' + heroCards + '</div>' : '')
            + (heroMarquee ? '<div class="mt-8">' + heroMarquee + '</div>' : '')
            + '<div class="vmo-scroll-cue mt-8"><span class="vmo-scroll-cue-line"></span><span>Scroll to explore</span></div>'
            + '</div>'
            + '<div class="relative lg:pl-6">'
            + '<div class="absolute -left-6 top-10 hidden h-[70%] w-[70%] rounded-full border border-white/40 lg:block"></div>'
            + '<div class="vmo-hero-media-stage">'
            + media
            + '<div class="vmo-hero-floating-panel vmo-hero-floating-panel-top">'
            + '<p class="vmo-floating-panel-kicker">Opening Mode</p>'
            + '<h3 class="mt-2 text-lg font-semibold text-slate-950">' + floatingIntro + '</h3>'
            + '<p class="mt-2 text-sm leading-6 text-slate-600">' + floatingCopy + '</p>'
            + '</div>'
            + (floatingList ? '<div class="vmo-hero-floating-panel vmo-hero-floating-panel-bottom"><p class="vmo-floating-panel-kicker">Key Moments</p><div class="vmo-hero-list mt-4">' + floatingList + '</div></div>' : '')
            + '</div>'
            + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeServicesSection(s, i) {
        const hl = escapeHtml(s.headline || 'Our Services');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-white/55">' + escapeHtml(s.subheadline) + '</p>' : '';
        const body = s.body ? '<p class="mt-5 max-w-2xl text-lg leading-relaxed text-white/72">' + escapeHtml(s.body) + '</p>' : '';
        const icons = ['&#x1F680;', '&#x2B50;', '&#x1F4A1;', '&#x1F3AF;', '&#x26A1;', '&#x1F527;'];
        const bullets = extractNarrativePoints(s);
        const cards = bullets.filter(Boolean).map(function (item, bi) {
            return '<article class="vmo-service-card vmo-glass-card min-w-[280px] max-w-[340px] p-7 lg:min-w-[340px]" data-vmo-float="' + bi + '">'
                + '<div class="mb-5 flex h-14 w-14 items-center justify-center rounded-2xl bg-white/14 text-2xl text-white ring-1 ring-white/20">' + icons[bi % icons.length] + '</div>'
                + '<p class="text-sm font-semibold uppercase tracking-[0.26em] text-white/45">Service ' + String(bi + 1).padStart(2, '0') + '</p>'
                + '<h3 class="mt-4 text-2xl font-semibold tracking-tight text-white">' + escapeHtml(item) + '</h3>'
                + '<p class="mt-4 text-sm leading-7 text-white/68">Purpose-built experiences, richer motion choreography, and media-led storytelling anchored to this offer.</p>'
                + '</article>';
        }).join('');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-services" class="relative overflow-hidden bg-slate-950 py-24 text-white lg:py-32" data-vmo-section-type="services" data-vmo-animate>'
            + '<div class="pointer-events-none absolute left-0 top-0 h-full w-full bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.18),transparent_34%),radial-gradient(circle_at_bottom_right,rgba(255,255,255,0.08),transparent_28%)]"></div>'
            + '<div class="relative mx-auto max-w-7xl px-6"><div class="max-w-3xl">' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold tracking-[-0.035em] text-white md:text-6xl">' + hl + '</h2>' + body + '</div>'
            + '<div class="vmo-horizontal-rail mt-14"><div class="vmo-horizontal-track">' + cards + '</div></div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeAboutSection(s, i) {
        const hl = escapeHtml(s.headline || 'About Us');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-slate-500">' + escapeHtml(s.subheadline) + '</p>' : '';
        const body = s.body ? '<p class="mt-6 text-lg leading-relaxed text-slate-600">' + escapeHtml(s.body) + '</p>' : '';
        const media = composePremiumMedia('about', s.media || 'image', s, 'editorial feature image', 'min-h-[540px] rounded-[34px]');
        const order = (i % 2 === 1) ? ' md:order-last' : '';
        const bullets = extractNarrativePoints(s);
        const bulletList = bullets.length
            ? '<div class="mt-8 grid gap-3">' + bullets.slice(0, 3).map(function (item) {
                return '<div class="vmo-glass-card flex items-start gap-4 px-5 py-4"><span class="mt-1 text-sm font-semibold uppercase tracking-[0.26em] text-slate-500">01</span><p class="text-base font-medium leading-relaxed text-slate-800">' + escapeHtml(item) + '</p></div>';
            }).join('') + '</div>'
            : '';
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-about" class="bg-[#f7f2ea] py-24 lg:py-32" data-vmo-section-type="about" data-vmo-animate>'
            + '<div class="mx-auto grid max-w-7xl grid-cols-1 items-center gap-12 px-6 md:grid-cols-2 lg:gap-20">'
            + '<div class="' + order + '">' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold leading-[0.92] tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2>' + body + bulletList + '</div>'
            + '<div class="relative">'
            + '<div class="absolute -right-6 top-12 hidden h-[60%] w-[55%] rounded-[32px] border border-white/50 lg:block"></div>'
            + media + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeProofSection(s, i) {
        const hl = escapeHtml(s.headline || 'Proof That Moves Decisions');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-slate-500">' + escapeHtml(s.subheadline) + '</p>' : '';
        const body = s.body ? '<p class="mt-5 max-w-2xl text-lg leading-relaxed text-slate-600">' + escapeHtml(s.body) + '</p>' : '';
        const bullets = extractNarrativePoints(s);
        const cards = (bullets.length ? bullets : [s.headline, s.body, s.cta_primary]).filter(Boolean).slice(0, 4).map(function (item, idx) {
            return '<article class="vmo-proof-card"><p class="vmo-proof-card-kicker">Proof 0' + (idx + 1) + '</p><p class="mt-3 text-lg font-semibold leading-snug text-slate-950">' + escapeHtml(item) + '</p></article>';
        }).join('');
        const marquee = buildMarquee(bullets);

        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="' + buildSectionId('proof', i) + '" class="bg-[#f3ede4] py-20 lg:py-24" data-vmo-section-type="proof" data-vmo-animate>'
            + '<div class="mx-auto max-w-7xl px-6">'
            + '<div class="grid gap-10 lg:grid-cols-[0.82fr_1.18fr] lg:items-end">'
            + '<div>' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold leading-[0.95] tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2>'
            + body + '</div>'
            + '<div class="vmo-proof-grid">' + cards + '</div>'
            + '</div>'
            + (marquee ? '<div class="mt-10">' + marquee + '</div>' : '')
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeShowcaseSection(s, i) {
        const hl = escapeHtml(s.headline || 'Featured Experience');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-white/52">' + escapeHtml(s.subheadline) + '</p>' : '';
        const body = s.body ? '<p class="mt-6 max-w-2xl text-lg leading-relaxed text-white/72">' + escapeHtml(s.body) + '</p>' : '';
        const mediaType = s.media === 'video' ? 'video' : 'image';
        const media = composePremiumMedia('showcase', mediaType, s, mediaType === 'video' ? 'scroll-led showcase motion' : 'editorial showcase image', 'min-h-[620px] rounded-[34px]');
        const cta1 = s.cta_primary ? '<a href="#" class="vmo-premium-btn">' + escapeHtml(s.cta_primary) + '</a>' : '';
        const cta2 = s.cta_secondary ? '<a href="#" class="vmo-premium-btn vmo-premium-btn-secondary">' + escapeHtml(s.cta_secondary) + '</a>' : '';
        const bullets = extractNarrativePoints(s);
        const notes = bullets.slice(0, 3).map(function (item, idx) {
            return '<article class="vmo-showcase-note"><span class="vmo-showcase-note-index">0' + (idx + 1) + '</span><div><p class="vmo-proof-card-kicker">Feature Layer</p><p class="mt-2 text-base leading-7 text-white/82">' + escapeHtml(item) + '</p></div></article>';
        }).join('');
        const detailBadge = (s.design_direction || s.interaction_style)
            ? '<div class="vmo-hero-floating-panel vmo-showcase-panel"><p class="vmo-floating-panel-kicker">Motion Direction</p><p class="mt-2 text-sm leading-6 text-slate-600">' + escapeHtml([s.design_direction, s.interaction_style].filter(Boolean).join(' · ')) + '</p></div>'
            : '';

        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="' + buildSectionId('showcase', i) + '" class="relative overflow-hidden bg-slate-950 py-24 text-white lg:py-32" data-vmo-section-type="showcase" data-vmo-animate>'
            + '<div class="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.15),transparent_28%),radial-gradient(circle_at_bottom_right,rgba(255,255,255,0.08),transparent_26%)]"></div>'
            + '<div class="relative mx-auto grid max-w-7xl grid-cols-1 items-center gap-12 px-6 lg:grid-cols-[1.04fr_.96fr] lg:gap-20">'
            + '<div class="relative order-last lg:order-first">'
            + '<div class="vmo-hero-media-stage">' + media + detailBadge + '</div>'
            + '</div>'
            + '<div>' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold leading-[0.94] tracking-[-0.035em] text-white md:text-6xl">' + hl + '</h2>'
            + body
            + '<div class="mt-10 flex flex-wrap gap-4">' + cta1 + cta2 + '</div>'
            + (notes ? '<div class="mt-10 space-y-4">' + notes + '</div>' : '')
            + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeTestimonialsSection(s, i) {
        const hl = escapeHtml(s.headline || 'What Our Clients Say');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-slate-500">' + escapeHtml(s.subheadline) + '</p>' : '';
        const bullets = Array.isArray(s.bullets) ? s.bullets : ['Great service and results!', 'Absolutely transformed our business.', 'Highly recommend to anyone.'];
        const slides = bullets.filter(Boolean).map(function (quote, bi) {
            return '<div class="swiper-slide"><div class="vmo-glass-card h-full p-8">'
                + '<p class="text-xs font-semibold uppercase tracking-[0.3em] text-slate-500">Client Perspective</p>'
                + '<p class="mt-5 text-xl leading-relaxed text-slate-900">&ldquo;' + escapeHtml(quote) + '&rdquo;</p>'
                + '<p class="mt-8 text-sm font-semibold text-slate-700">Client ' + (bi + 1) + '</p></div></div>';
        }).join('');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-testimonials" class="bg-white py-24 lg:py-32" data-vmo-section-type="testimonials" data-vmo-animate>'
            + '<div class="mx-auto max-w-7xl px-6"><div class="mx-auto mb-16 max-w-3xl text-center">' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2></div>'
            + '<div class="swiper vmo-testimonial-swiper"><div class="swiper-wrapper">' + slides + '</div>'
            + '<div class="swiper-pagination mt-8"></div></div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeProductsSection(s, i) {
        const hl = escapeHtml(s.headline || 'Our Products');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-slate-500">' + escapeHtml(s.subheadline) + '</p>' : '';
        const bullets = Array.isArray(s.bullets) ? s.bullets : ['Product A', 'Product B', 'Product C'];
        const cards = bullets.filter(Boolean).map(function (product, pi) {
            const isLead = pi === 0;
            const media = composePremiumMedia('product', 'image', { headline: product, subheadline: s.headline, body: s.body }, 'product showcase', (isLead ? 'aspect-[16/10]' : 'aspect-[4/3]') + ' rounded-[26px]');
            return '<div class="' + (isLead ? 'sm:col-span-2 lg:col-span-2 ' : '') + 'vmo-glass-card overflow-hidden p-4 transition-transform duration-300 hover:-translate-y-1">'
                + media
                + '<div class="px-3 pb-3 pt-6"><h3 class="text-xl font-semibold text-slate-950">' + escapeHtml(product) + '</h3>'
                + '<p class="mt-2 text-sm leading-6 text-slate-600">Premium product storytelling with elevated motion, media-first presentation, and conversion-focused framing.</p>'
                + '<div class="mt-5 flex items-center justify-between"><span class="text-2xl font-semibold text-slate-950">$99</span>'
                + '<button class="vmo-pay-btn vmo-premium-btn vmo-premium-btn-secondary px-5 py-3 text-sm" data-vmo-product="' + escapeHtml(product) + '">Buy Now</button>'
                + '</div></div></div>';
        }).join('');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-products" class="bg-white py-24 lg:py-32" data-vmo-section-type="products" data-vmo-animate>'
            + '<div class="mx-auto max-w-7xl px-6"><div class="mx-auto mb-16 max-w-3xl text-center">' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2></div>'
            + '<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">' + cards + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composePricingSection(s, i) {
        const hl = escapeHtml(s.headline || 'Pricing');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-slate-500">' + escapeHtml(s.subheadline) + '</p>' : '';
        const bullets = Array.isArray(s.bullets) ? s.bullets : ['Starter — $29/mo', 'Pro — $79/mo', 'Enterprise — $199/mo'];
        const featured = Math.floor(bullets.length / 2);
        const cards = bullets.filter(Boolean).map(function (plan, pi) {
            const ring = (pi === featured) ? ' ring-2 ring-accent scale-105' : '';
            const badge = (pi === featured) ? '<span class="absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-[color:var(--vmo-accent)] px-4 py-1 text-xs font-bold text-white">Popular</span>' : '';
            return '<div class="vmo-glass-card relative p-8' + ring + '">'
                + badge + '<h3 class="text-xl font-bold text-gray-900">' + escapeHtml(plan) + '</h3>'
                + '<p class="mt-4 text-sm leading-7 text-slate-600">Premium surfaces, consistent typography, and sharper conversion framing built into every plan tier.</p>'
                + '<a href="#" class="vmo-premium-btn mt-6 inline-flex w-full justify-center">Get Started</a></div>';
        }).join('');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-pricing" class="bg-[#f2eee8] py-24 lg:py-32" data-vmo-section-type="pricing" data-vmo-animate>'
            + '<div class="mx-auto max-w-7xl px-6"><div class="mx-auto mb-16 max-w-3xl text-center">' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2></div>'
            + '<div class="grid grid-cols-1 md:grid-cols-3 gap-8 items-start">' + cards + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeContactSection(s, i, integrations) {
        const hl = escapeHtml(s.headline || 'Get In Touch');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-white/55">' + escapeHtml(s.subheadline) + '</p>' : '';
        const body = s.body ? '<p class="mt-5 text-lg leading-relaxed text-white/72">' + escapeHtml(s.body) + '</p>' : '';
        var chips = '';
        if (integrations.phone_enabled && integrations.phone_number) {
            var ph = String(integrations.phone_number);
            chips += '<a href="tel:' + escapeHtml(ph.replace(/[^+\d]/g, '')) + '" class="vmo-glass-card flex items-center gap-3 px-5 py-3 text-sm font-semibold text-white">&#x1F4DE; ' + escapeHtml(ph) + '</a>';
        }
        if (integrations.email_enabled && integrations.email_address) {
            var em = String(integrations.email_address);
            chips += '<a href="mailto:' + escapeHtml(em) + '" class="vmo-glass-card flex items-center gap-3 px-5 py-3 text-sm font-semibold text-white">&#x2709; ' + escapeHtml(em) + '</a>';
        }
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="' + buildSectionId('contact', i) + '" class="relative overflow-hidden bg-slate-950 py-24 text-white lg:py-32" data-vmo-section-type="contact" data-vmo-animate>'
            + '<div class="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.18),transparent_30%),linear-gradient(140deg,rgba(255,255,255,0.04),transparent_58%)]"></div>'
            + '<div class="relative mx-auto grid max-w-7xl grid-cols-1 gap-16 px-6 md:grid-cols-2"><div>' + sub
            + '<h2 class="vmo-display mt-4 text-4xl font-semibold tracking-[-0.035em] text-white md:text-6xl">' + hl + '</h2>' + body
            + (chips ? '<div class="mt-8 flex flex-col sm:flex-row gap-4">' + chips + '</div>' : '')
            + '</div><form class="vmo-glass-card space-y-5 p-7" data-vmo-form="lead" onsubmit="event.preventDefault();">'
            + '<input type="text" name="name" placeholder="Your name" required class="w-full rounded-2xl border border-white/15 bg-white/8 px-5 py-4 text-white outline-none transition placeholder:text-white/40 focus:border-white/35">'
            + '<input type="email" name="email" placeholder="Your email" required class="w-full rounded-2xl border border-white/15 bg-white/8 px-5 py-4 text-white outline-none transition placeholder:text-white/40 focus:border-white/35">'
            + '<textarea name="message" rows="4" placeholder="How can we help?" class="w-full resize-none rounded-2xl border border-white/15 bg-white/8 px-5 py-4 text-white outline-none transition placeholder:text-white/40 focus:border-white/35"></textarea>'
            + '<button type="submit" class="vmo-premium-btn w-full justify-center">Send Message</button>'
            + '</form></div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeGallerySection(s, i) {
        const hl = escapeHtml(s.headline || 'Gallery');
        const bullets = Array.isArray(s.bullets) ? s.bullets : ['Project A', 'Project B', 'Project C', 'Project D'];
        const items = bullets.filter(Boolean).map(function (item, gi) {
            const isLead = gi === 0;
            const isTall = gi === 3;
            const mediaShape = isLead ? 'aspect-[16/10]' : (isTall ? 'aspect-[4/5]' : 'aspect-square');
            const shellClasses = (isLead ? 'sm:col-span-2 xl:col-span-2 ' : '') + (isTall ? 'xl:row-span-2 ' : '');
            return '<div class="' + shellClasses + 'relative group overflow-hidden rounded-2xl">'
                + composePremiumMedia('gallery', 'image', { headline: item, subheadline: s.headline, body: s.body }, 'gallery showcase', mediaShape + ' rounded-[24px]')
                + '<div class="pointer-events-none absolute inset-x-4 bottom-4 rounded-2xl bg-slate-950/58 px-4 py-3 opacity-0 backdrop-blur-xl transition-opacity duration-300 group-hover:opacity-100"><p class="text-sm font-semibold text-white">' + escapeHtml(item) + '</p></div></div>';
        }).join('');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-gallery" class="bg-[#f7f2ea] py-24 lg:py-32" data-vmo-section-type="gallery" data-vmo-animate>'
            + '<div class="mx-auto max-w-7xl px-6">'
            + '<h2 class="vmo-display mb-16 text-center text-4xl font-semibold tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2>'
            + '<div class="grid grid-cols-1 gap-5 sm:grid-cols-2 xl:grid-cols-4">' + items + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeTeamSection(s, i) {
        const hl = escapeHtml(s.headline || 'Meet the Team');
        const bullets = Array.isArray(s.bullets) ? s.bullets : ['Team Member A', 'Team Member B', 'Team Member C'];
        const cards = bullets.filter(Boolean).map(function (member, ti) {
            return '<div class="text-center">'
                + composePremiumMedia('team', 'image', { headline: member, subheadline: s.headline }, 'team portrait', 'mx-auto aspect-[4/5] max-w-[280px] rounded-[32px]')
                + '<h3 class="mt-5 text-lg font-bold text-gray-900">' + escapeHtml(member) + '</h3>'
                + '<p class="mt-1 text-sm text-gray-500">Team Member</p></div>';
        }).join('');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-team" class="py-24 lg:py-32 bg-white" data-vmo-section-type="team" data-vmo-animate>'
            + '<div class="max-w-7xl mx-auto px-6">'
            + '<h2 class="vmo-display mb-16 text-center text-4xl font-semibold tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2>'
            + '<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-10">' + cards + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeFaqSection(s, i) {
        const hl = escapeHtml(s.headline || 'Frequently Asked Questions');
        const bullets = Array.isArray(s.bullets) ? s.bullets : ['How does this work?', 'What is the pricing?', 'Do you offer support?'];
        const items = bullets.filter(Boolean).map(function (q, fi) {
            return '<details class="group vmo-glass-card overflow-hidden"' + (fi === 0 ? ' open' : '') + '>'
                + '<summary class="flex cursor-pointer items-center justify-between px-6 py-5 font-semibold text-slate-900 transition hover:bg-white/45">'
                + escapeHtml(q) + '<span class="ml-4 text-gray-400 group-open:rotate-45 transition-transform duration-200 text-xl">+</span></summary>'
                + '<div class="px-6 pb-5 leading-relaxed text-slate-600">Our team is here to help. Contact us for detailed information.</div></details>';
        }).join('');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-faq" class="bg-[#f2eee8] py-24 lg:py-32" data-vmo-section-type="faq" data-vmo-animate>'
            + '<div class="mx-auto max-w-3xl px-6">'
            + '<h2 class="vmo-display mb-16 text-center text-4xl font-semibold tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2>'
            + '<div class="space-y-3">' + items + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeCtaSection(s, i) {
        const hl = escapeHtml(s.headline || 'Ready to Get Started?');
        const sub = s.subheadline ? '<p class="mt-5 text-xl text-white/70">' + escapeHtml(s.subheadline) + '</p>' : '';
        const cta = escapeHtml(s.cta_primary || 'Get Started');
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '-cta" class="relative overflow-hidden bg-slate-950 py-24 text-white lg:py-32" data-vmo-section-type="cta" data-vmo-animate>'
            + '<div class="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.12),transparent_35%),radial-gradient(circle_at_bottom_right,rgba(255,255,255,0.08),transparent_26%)]"></div>'
            + '<div class="relative mx-auto max-w-4xl px-6 text-center">'
            + '<h2 class="vmo-display text-4xl font-semibold tracking-[-0.035em] text-white md:text-6xl">' + hl + '</h2>' + sub
            + '<a href="#" class="vmo-premium-btn mt-10 inline-flex text-lg">' + cta + '</a>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composeDefaultSection(s, i, integrations) {
        const hl = escapeHtml(s.headline || 'Section');
        const sub = s.subheadline ? '<p class="text-xs font-semibold uppercase tracking-[0.34em] text-slate-500">' + escapeHtml(s.subheadline) + '</p>' : '';
        const body = s.body ? '<p class="mt-5 text-lg leading-relaxed text-slate-600">' + escapeHtml(s.body) + '</p>' : '';
        const media = composePremiumMedia('section', s.media || 'image', s, 'feature section media', 'min-h-[420px] rounded-[30px]');
        const order = (i % 2 === 1) ? ' md:order-last' : '';
        const bg = (i % 2 === 0) ? 'bg-white' : 'bg-gray-50/50';
        const showForm = (s.type === 'contact') || (integrations.contact_form && !integrations._contactRendered);
        if (showForm) integrations._contactRendered = true;
        const form = showForm ? '<form class="vmo-glass-card mt-8 space-y-4 p-5" data-vmo-form="lead" onsubmit="event.preventDefault();"><input type="text" name="name" placeholder="Your name" required class="w-full rounded-2xl border border-slate-200 bg-white/70 px-5 py-3.5 outline-none"><input type="email" name="email" placeholder="Your email" required class="w-full rounded-2xl border border-slate-200 bg-white/70 px-5 py-3.5 outline-none"><textarea name="message" rows="3" placeholder="Message" class="w-full resize-none rounded-2xl border border-slate-200 bg-white/70 px-5 py-3.5 outline-none"></textarea><button type="submit" class="vmo-premium-btn">Send</button></form>' : '';
        return '<!-- SECTION ' + (i + 1) + ' -->'
            + '<section id="section-' + (i + 1) + '" class="py-24 lg:py-32 ' + bg + '" data-vmo-section-type="default" data-vmo-animate>'
            + '<div class="max-w-7xl mx-auto px-6 grid grid-cols-1 md:grid-cols-2 gap-12 lg:gap-20 items-center">'
            + '<div class="' + order + '">' + sub
            + '<h2 class="vmo-display text-4xl font-semibold tracking-[-0.035em] text-slate-950 md:text-6xl">' + hl + '</h2>' + body + form + '</div>'
            + '<div>' + media + '</div>'
            + '</div></section><!-- END SECTION ' + (i + 1) + ' -->\n';
    }

    function composePremiumSection(section, index, integrations) {
        if (!section || typeof section !== 'object') section = {};
        const type = slugify(section.type || ('section-' + (index + 1)));
        switch (type) {
            case 'hero': return composeHeroSection(section, index, integrations, integrations._site || {});
            case 'proof': case 'stats': case 'logos': case 'metrics': return composeProofSection(section, index);
            case 'services': case 'features': return composeServicesSection(section, index);
            case 'about': return composeAboutSection(section, index);
            case 'showcase': case 'story': case 'experience': return composeShowcaseSection(section, index);
            case 'testimonials': case 'reviews': return composeTestimonialsSection(section, index);
            case 'products': case 'shop': case 'ecommerce': return composeProductsSection(section, index);
            case 'pricing': return composePricingSection(section, index);
            case 'contact': return composeContactSection(section, index, integrations);
            case 'gallery': case 'portfolio': return composeGallerySection(section, index);
            case 'team': return composeTeamSection(section, index);
            case 'faq': return composeFaqSection(section, index);
            case 'cta': return composeCtaSection(section, index);
            default: return composeDefaultSection(section, index, integrations);
        }
    }

    function buildPremiumCss(primary, accent) {
        return `
:root{
    --vmo-primary:${primary};
    --vmo-accent:${accent};
    --vmo-accent-soft:color-mix(in srgb, ${accent} 22%, white);
    --vmo-text:#0f1723;
    --vmo-muted:#5b6879;
    --vmo-surface:rgba(255,255,255,0.62);
    --vmo-line:rgba(255,255,255,0.42);
    --vmo-shadow:0 28px 80px rgba(15,23,35,0.12);
}
[id^="section-"]{scroll-margin-top:8rem;}
html{scroll-behavior:smooth;background:#f7f2ea;}
body{
    margin:0;
    font-family:"Manrope",system-ui,sans-serif;
    color:var(--vmo-text);
    background:
        radial-gradient(circle at top left, rgba(255,255,255,0.84), transparent 30%),
        radial-gradient(circle at bottom right, rgba(255,255,255,0.42), transparent 28%),
        linear-gradient(180deg, #faf7f1 0%, #f3ede4 52%, #f8f4ee 100%);
    -webkit-font-smoothing:antialiased;
}
body::before{
    content:"";
    position:fixed;
    inset:0;
    pointer-events:none;
    background-image:linear-gradient(rgba(15,23,35,0.035) 1px, transparent 1px),linear-gradient(90deg, rgba(15,23,35,0.03) 1px, transparent 1px);
    background-size:42px 42px;
    mask-image:radial-gradient(circle at center, black 28%, transparent 82%);
    opacity:.24;
}
.vmo-site-header{
    position:fixed;
    inset:0 0 auto 0;
    z-index:60;
    padding:1rem 1rem 0;
    pointer-events:none;
}
.vmo-site-header-shell{
    pointer-events:auto;
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:1rem;
    max-width:84rem;
    margin:0 auto;
    padding:.9rem 1.05rem;
    border:1px solid rgba(255,255,255,0.62);
    border-radius:999px;
    background:linear-gradient(180deg, rgba(255,255,255,0.8), rgba(255,255,255,0.62));
    box-shadow:0 20px 46px rgba(15,23,35,0.12);
    backdrop-filter:blur(26px);
}
.vmo-brand-lockup{display:grid;gap:.15rem;text-decoration:none;color:inherit;min-width:0;}
.vmo-brand-kicker{font-size:.68rem;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:var(--vmo-muted);}
.vmo-brand-name{font-size:1rem;font-weight:800;letter-spacing:-0.03em;color:var(--vmo-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:16rem;}
.vmo-brand-tagline{font-size:.8rem;color:var(--vmo-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:20rem;}
.vmo-site-nav{display:flex;align-items:center;gap:.3rem;}
.vmo-site-nav a{
    display:inline-flex;
    align-items:center;
    min-height:42px;
    padding:0 .95rem;
    border-radius:999px;
    color:rgba(15,23,35,0.72);
    font-size:.86rem;
    font-weight:700;
    text-decoration:none;
    transition:background .24s ease,color .24s ease;
}
.vmo-site-nav a:hover{background:rgba(15,23,35,0.06);color:var(--vmo-text);}
[data-vmo-animate]{opacity:0;transform:translateY(40px);transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1);}
[data-vmo-animate].vmo-visible{opacity:1;transform:translateY(0);}
[data-vmo-parallax]{will-change:transform;}
.vmo-display{font-family:"Cormorant Garamond",serif;}
.vmo-glass-card{
    background:linear-gradient(180deg, rgba(255,255,255,0.76), rgba(255,255,255,0.52));
    border:1px solid rgba(255,255,255,0.62);
    box-shadow:var(--vmo-shadow);
    backdrop-filter:blur(24px);
    border-radius:28px;
}
.vmo-premium-btn{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    gap:.65rem;
    min-height:56px;
    padding:0 1.65rem;
    border-radius:999px;
    border:1px solid rgba(255,255,255,0.24);
    background:linear-gradient(135deg, color-mix(in srgb, var(--vmo-primary) 76%, white), color-mix(in srgb, var(--vmo-accent) 82%, white));
    color:#fff;
    font-weight:700;
    text-decoration:none;
    box-shadow:0 18px 46px color-mix(in srgb, var(--vmo-accent) 24%, transparent);
    transition:transform .28s ease, box-shadow .28s ease, background .28s ease;
}
.vmo-premium-btn:hover{transform:translateY(-2px);box-shadow:0 24px 58px color-mix(in srgb, var(--vmo-accent) 28%, transparent);}
.vmo-premium-btn-secondary{
    background:rgba(255,255,255,0.14);
    color:inherit;
    backdrop-filter:blur(22px);
    border-color:rgba(255,255,255,0.28);
    box-shadow:none;
}
.vmo-hero-stage .vmo-premium-btn-secondary{color:var(--vmo-text);border-color:rgba(15,23,35,0.12);background:rgba(255,255,255,0.55);}
.vmo-action-chip{
    display:inline-flex;
    align-items:center;
    gap:.55rem;
    min-height:42px;
    padding:0 .95rem;
    border-radius:999px;
    border:1px solid rgba(255,255,255,0.62);
    background:rgba(255,255,255,0.7);
    color:var(--vmo-text);
    text-decoration:none;
    font-size:.8rem;
    font-weight:700;
    letter-spacing:.02em;
    box-shadow:0 16px 38px rgba(15,23,35,0.08);
    backdrop-filter:blur(20px);
}
.vmo-action-chip-muted{color:var(--vmo-muted);}
.vmo-media-shell{
    position:relative;
    overflow:hidden;
    border:1px solid rgba(255,255,255,0.48);
    background:linear-gradient(155deg, rgba(255,255,255,0.56), rgba(255,255,255,0.14));
    box-shadow:0 28px 90px rgba(15,23,35,0.16);
}
.vmo-media-placeholder{
    position:relative;
    overflow:hidden;
    width:100%;
    height:100%;
    min-height:inherit;
    padding:1.5rem;
    color:#fff;
    font-size:0;
    line-height:0;
}
.vmo-media-placeholder-image{background:linear-gradient(135deg, rgba(8,17,32,0.92), color-mix(in srgb, var(--vmo-accent) 55%, #081120), rgba(8,17,32,0.88));}
.vmo-media-placeholder-video{background:linear-gradient(135deg, rgba(8,17,32,0.96), color-mix(in srgb, var(--vmo-primary) 45%, #081120), rgba(8,17,32,0.86));}
.vmo-media-placeholder::before{
    content:"";
    position:absolute;
    inset:-18%;
    background:radial-gradient(circle at 20% 20%, rgba(255,255,255,0.32), transparent 22%),radial-gradient(circle at 80% 70%, rgba(255,255,255,0.18), transparent 24%);
    animation:vmoPulseGlow 10s ease-in-out infinite alternate;
}
.vmo-media-badge{
    position:absolute;
    left:1rem;
    top:1rem;
    z-index:2;
    border-radius:999px;
    border:1px solid rgba(255,255,255,0.24);
    background:rgba(255,255,255,0.12);
    padding:.5rem .8rem;
    font-size:.72rem;
    font-weight:700;
    letter-spacing:.18em;
    text-transform:uppercase;
}
.vmo-media-copy{
    position:relative;
    z-index:2;
    display:grid;
    gap:.35rem;
    max-width:18rem;
}
.vmo-media-copy strong{font-size:1.35rem;font-weight:700;line-height:1;}
.vmo-media-copy span{font-size:.9rem;line-height:1.55;color:rgba(255,255,255,0.78);}
.vmo-media-aura,
.vmo-media-grid{position:absolute;inset:0;pointer-events:none;}
.vmo-media-aura{background:radial-gradient(circle at top right, rgba(255,255,255,0.28), transparent 28%),radial-gradient(circle at bottom left, rgba(255,255,255,0.16), transparent 26%);mix-blend-mode:screen;}
.vmo-media-grid{background-image:linear-gradient(rgba(255,255,255,0.08) 1px, transparent 1px),linear-gradient(90deg, rgba(255,255,255,0.08) 1px, transparent 1px);background-size:28px 28px;mask-image:linear-gradient(180deg, transparent, black 18%, black 82%, transparent);opacity:.28;}
.vmo-marquee{overflow:hidden;padding:.3rem 0;}
.vmo-marquee-track{display:flex;gap:.85rem;width:max-content;animation:vmoMarquee 20s linear infinite;}
.vmo-marquee-chip{
    display:inline-flex;
    align-items:center;
    min-height:40px;
    padding:0 1rem;
    border-radius:999px;
    background:rgba(255,255,255,0.66);
    border:1px solid rgba(255,255,255,0.62);
    color:var(--vmo-text);
    font-size:.84rem;
    font-weight:700;
    letter-spacing:.03em;
    backdrop-filter:blur(18px);
}
.vmo-horizontal-rail{overflow:hidden;padding-bottom:.5rem;}
.vmo-horizontal-track{display:flex;gap:1.25rem;width:max-content;align-items:stretch;}
.vmo-proof-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));}
.vmo-proof-card{
    background:linear-gradient(180deg, rgba(255,255,255,0.8), rgba(255,255,255,0.58));
    border:1px solid rgba(255,255,255,0.64);
    box-shadow:0 22px 54px rgba(15,23,35,0.1);
    backdrop-filter:blur(20px);
    border-radius:28px;
    padding:1.15rem 1.2rem;
}
.vmo-proof-card-kicker{font-size:.7rem;font-weight:800;letter-spacing:.22em;text-transform:uppercase;color:var(--vmo-muted);}
.vmo-hero-media-stage{position:relative;}
.vmo-hero-floating-panel{
    position:absolute;
    z-index:4;
    max-width:16rem;
    padding:1rem 1.05rem;
    border-radius:24px;
    border:1px solid rgba(255,255,255,0.72);
    background:linear-gradient(180deg, rgba(255,255,255,0.84), rgba(255,255,255,0.66));
    box-shadow:0 24px 60px rgba(15,23,35,0.14);
    backdrop-filter:blur(22px);
}
.vmo-hero-floating-panel-top{left:-1.65rem;top:1.15rem;}
.vmo-hero-floating-panel-bottom{right:-1.15rem;bottom:1.4rem;max-width:20rem;}
.vmo-showcase-panel{right:1rem;top:1rem;left:auto;bottom:auto;}
.vmo-floating-panel-kicker{font-size:.68rem;font-weight:800;letter-spacing:.22em;text-transform:uppercase;color:var(--vmo-muted);}
.vmo-hero-list{display:grid;gap:.85rem;}
.vmo-hero-list-item{display:grid;grid-template-columns:auto 1fr;gap:.8rem;align-items:start;}
.vmo-hero-list-item p{margin:0;font-size:.92rem;line-height:1.6;color:var(--vmo-text);}
.vmo-hero-list-index{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-width:2.1rem;
    height:2.1rem;
    border-radius:999px;
    background:rgba(15,23,35,0.07);
    color:var(--vmo-text);
    font-size:.76rem;
    font-weight:800;
    letter-spacing:.08em;
}
.vmo-scroll-cue{display:inline-flex;align-items:center;gap:.9rem;font-size:.68rem;font-weight:800;letter-spacing:.26em;text-transform:uppercase;color:var(--vmo-muted);}
.vmo-scroll-cue-line{display:inline-block;width:3.2rem;height:1px;background:rgba(15,23,35,0.26);}
.vmo-showcase-note{
    display:grid;
    grid-template-columns:auto 1fr;
    gap:1rem;
    align-items:start;
    padding:1.05rem 1.1rem;
    border-radius:24px;
    border:1px solid rgba(255,255,255,0.12);
    background:rgba(255,255,255,0.05);
    backdrop-filter:blur(16px);
}
.vmo-showcase-note-index{
    display:inline-flex;
    align-items:center;
    justify-content:center;
    min-width:2.25rem;
    height:2.25rem;
    border-radius:999px;
    background:rgba(255,255,255,0.12);
    color:#fff;
    font-size:.8rem;
    font-weight:800;
    letter-spacing:.08em;
}
.vmo-service-card{color:#fff;}
.swiper-pagination-bullet{background:rgba(15,23,35,0.16)!important;opacity:1!important;}
.swiper-pagination-bullet-active{background:var(--vmo-accent)!important;}
.vmo-overlay-container{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:1;}
@keyframes vmoMarquee{0%{transform:translate3d(0,0,0)}100%{transform:translate3d(-50%,0,0)}}
@keyframes vmoPulseGlow{0%{transform:translate3d(0,0,0) scale(1)}100%{transform:translate3d(0,-12px,0) scale(1.08)}}
@media (max-width: 1024px){
    .vmo-site-header-shell{padding:.8rem .9rem;}
    .vmo-brand-tagline{display:none;}
    .vmo-horizontal-rail{overflow-x:auto;scrollbar-width:none;}
    .vmo-horizontal-rail::-webkit-scrollbar{display:none;}
    .vmo-horizontal-track{width:auto;min-width:100%;}
    .vmo-hero-floating-panel-top,
    .vmo-hero-floating-panel-bottom,
    .vmo-showcase-panel{position:relative;left:auto;right:auto;top:auto;bottom:auto;max-width:none;margin-top:1rem;}
}
@media (max-width: 767px){
    .vmo-site-header{padding:.8rem .8rem 0;}
    .vmo-site-header-shell{border-radius:28px;align-items:flex-start;}
    .vmo-brand-name{max-width:11.5rem;}
}
`;
    }

    function buildCdnHead(primary, accent) {
        return '<link rel="preconnect" href="https://fonts.googleapis.com">'
            + '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>'
            + '<link rel="stylesheet" href="' + CDN_URLS.font + '">'
            + '<script src="' + CDN_URLS.tailwind + '"><\/script>'
            + '<script>tailwind.config={theme:{extend:{colors:{primary:"' + primary + '",accent:"' + accent + '"},fontFamily:{sans:["Manrope","system-ui","sans-serif"],display:["Cormorant Garamond","serif"]}}}}<\/script>'
            + '<link rel="stylesheet" href="' + CDN_URLS.swiper_css + '">';
    }

    const VMO_INIT_JS = `(function(){
        "use strict";
        var isMobile = window.innerWidth < 768;
        var prefersReduced = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;

        if (window.Lenis && !isMobile) {
            var lenis = new Lenis({
                duration: 1.18,
                easing: function(t){ return Math.min(1, 1.001 - Math.pow(2, -10 * t)); },
                smoothWheel: true,
                wheelMultiplier: 0.95
            });

            function raf(time){
                lenis.raf(time);
                requestAnimationFrame(raf);
            }
            requestAnimationFrame(raf);

            if (window.gsap && window.ScrollTrigger) {
                lenis.on("scroll", function(){ window.ScrollTrigger.update(); });
                window.gsap.ticker.add(function(time){ lenis.raf(time * 1000); });
                window.gsap.ticker.lagSmoothing(0);
            }
        }

        if (window.gsap && window.ScrollTrigger && !prefersReduced) {
            window.gsap.registerPlugin(window.ScrollTrigger);

            document.querySelectorAll("[data-vmo-animate]").forEach(function(el){
                window.gsap.fromTo(el, { opacity: 0, y: isMobile ? 26 : 48 }, {
                    opacity: 1,
                    y: 0,
                    duration: isMobile ? 0.58 : 0.88,
                    ease: "power3.out",
                    scrollTrigger: { trigger: el, start: "top 86%", once: true }
                });
            });

            document.querySelectorAll("[data-vmo-parallax]").forEach(function(el){
                var yShift = el.getAttribute("data-vmo-parallax") === "slow" ? -12 : -18;
                window.gsap.to(el, {
                    yPercent: yShift,
                    ease: "none",
                    scrollTrigger: {
                        trigger: el.closest("section") || el,
                        start: "top bottom",
                        end: "bottom top",
                        scrub: true
                    }
                });
            });

            document.querySelectorAll("[data-vmo-float]").forEach(function(el, index){
                window.gsap.to(el, {
                    y: index % 2 === 0 ? -10 : 10,
                    duration: 3 + (index * 0.18),
                    repeat: -1,
                    yoyo: true,
                    ease: "sine.inOut"
                });
            });

            document.querySelectorAll(".vmo-horizontal-track").forEach(function(track){
                if (isMobile) return;
                var rail = track.parentElement;
                if (!rail) return;
                var travel = Math.max(0, track.scrollWidth - rail.clientWidth);
                if (!travel) return;
                window.gsap.to(track, {
                    x: -travel,
                    ease: "none",
                    scrollTrigger: {
                        trigger: rail,
                        start: "top 78%",
                        end: "+=" + Math.max(rail.offsetWidth, travel),
                        scrub: true
                    }
                });
            });
        } else if (!prefersReduced) {
            var observer = new IntersectionObserver(function(entries){
                entries.forEach(function(entry){
                    if (entry.isIntersecting) {
                        entry.target.classList.add("vmo-visible");
                        observer.unobserve(entry.target);
                    }
                });
            }, { threshold: 0.12 });

            document.querySelectorAll("[data-vmo-animate]").forEach(function(el){ observer.observe(el); });
        }

        if (window.Swiper) {
            document.querySelectorAll(".vmo-testimonial-swiper").forEach(function(el){
                new Swiper(el, {
                    slidesPerView: 1,
                    spaceBetween: 24,
                    pagination: { el: el.querySelector(".swiper-pagination"), clickable: true },
                    breakpoints: { 768: { slidesPerView: 2 }, 1100: { slidesPerView: 3 } }
                });
            });
        }

        document.querySelectorAll(".vmo-replace-btn").forEach(function(btn){
            btn.addEventListener("click", function(ev){
                ev.preventDefault();
                ev.stopPropagation();
                var mid = btn.getAttribute("data-replace-media");
                if (window.vmoOpenMediaPicker) window.vmoOpenMediaPicker(mid);
                else if (window.parent && window.parent.vmoOpenMediaPicker) window.parent.vmoOpenMediaPicker(mid);
            });
        });

        document.querySelectorAll(".vmo-pay-btn").forEach(function(btn){
            btn.addEventListener("click", function(ev){
                ev.preventDefault();
                var prod = btn.getAttribute("data-vmo-product") || "Product";
                if (window.vmoPayCheckout) window.vmoPayCheckout(prod);
                else alert("VMO Pay checkout for: " + prod);
            });
        });
    })();`;

    function buildInitScripts() {
        return '<script src="' + CDN_URLS.react + '"><\/script>'
            + '<script src="' + CDN_URLS.react_dom + '"><\/script>'
            + '<script src="' + CDN_URLS.gsap + '"><\/script>'
            + '<script src="' + CDN_URLS.scrolltrigger + '"><\/script>'
            + '<script src="' + CDN_URLS.lenis + '"><\/script>'
            + '<script src="' + CDN_URLS.swiper_js + '"><\/script>'
            + '<script>' + VMO_INIT_JS + '<\/script>';
    }

    function composeWebsitePremium(plan, context) {
        context = context || {};
        readConfig();
        if (!isActivated()) return { ok: false, reason: 'activation_required' };
        if (!internal.ready || !internal.editor) return { ok: false, reason: 'adapter_not_ready' };

        const normalized = normalizePlan(plan);
        const site = normalized.site || {};
        const brand = normalized.brand || {};
        const integrations = { ...(normalized.integrations || {}) };
        if (!integrations.phone_number && context.phoneNumber) integrations.phone_number = String(context.phoneNumber);
        if (!integrations.email_address && context.emailAddress) integrations.email_address = String(context.emailAddress);
        integrations.phone_enabled = !!integrations.phone_enabled;
        integrations.email_enabled = !!integrations.email_enabled;

        const selectedTech = Array.isArray(normalized.tech_stack && normalized.tech_stack.selected) && normalized.tech_stack.selected.length
            ? normalized.tech_stack.selected.slice()
            : ['React 18', 'Tailwind CSS', 'GSAP'];
        if (!selectedTech.includes('React 18')) selectedTech.unshift('React 18');

        const primary = String(brand.primary_color || '#0f172a');
        const accent = String(brand.accent_color || '#0ea5e9');
        const bizName = escapeHtml(site.business_name || 'Business Website');
        const tagline = escapeHtml(site.tagline || '');
        const goal = escapeHtml(site.goal || '');
        integrations._site = site;

        /* Build header */
        const sectionAnchors = buildSectionAnchors(normalized.sections || []);
        const headerNav = sectionAnchors.map(function (item) {
            return '<a href="' + item.href + '">' + escapeHtml(item.label) + '</a>';
        }).join('');
        const heroSection = (normalized.sections || []).find(function (section) {
            return slugify((section && section.type) || '') === 'hero';
        }) || {};
        const contactAnchor = sectionAnchors.find(function (item) { return item.label === 'Contact'; });
        const headerCtaHref = contactAnchor ? contactAnchor.href : '#section-footer';
        const headerCtaLabel = escapeHtml(heroSection.cta_primary || 'Start Project');
        const headerChips = buildQuickActionChips(integrations, 'vmo-action-chip');
        const headerHtml = '<header class="vmo-site-header"><div class="vmo-site-header-shell"><a href="#section-1-hero" class="vmo-brand-lockup"><span class="vmo-brand-kicker">Curated Web Experience</span><span class="vmo-brand-name">' + bizName + '</span>' + (tagline ? '<span class="vmo-brand-tagline">' + tagline + '</span>' : '') + '</a><nav class="vmo-site-nav hidden lg:flex">' + headerNav + '</nav><div class="flex items-center gap-3">' + (headerChips ? '<div class="hidden xl:flex items-center gap-2">' + headerChips + '</div>' : '') + '<a href="' + headerCtaHref + '" class="vmo-premium-btn">' + headerCtaLabel + '</a></div></div></header>';

        /* Build sections */
        const sectionsHtml = (normalized.sections || []).map(function (s, idx) {
            return composePremiumSection(s, idx, integrations);
        }).join('\n');

        /* Build footer */
        const year = new Date().getFullYear();
        const footerHtml = '<footer id="section-footer" class="bg-gray-950 text-gray-400 py-16"><div class="max-w-7xl mx-auto px-6 flex flex-col md:flex-row justify-between gap-8"><div><p class="text-white font-semibold text-lg">' + bizName + '</p><p class="mt-2 text-sm max-w-md">' + (goal || 'Built to convert and scale.') + '</p></div><div class="text-sm"><p>&copy; ' + year + ' ' + bizName + '. All rights reserved.</p><p class="mt-1">Powered by VMO AI</p></div></div></footer>';

        /* Full page */
        const pageHtml = '<div id="vmo-gjs-page" class="vmo-premium-page font-sans" data-vmo-generated="grapesjs-premium">' + headerHtml + sectionsHtml + footerHtml + '</div>';

        const cdnHead = buildCdnHead(primary, accent);
        const initScripts = buildInitScripts();

        try {
            const editor = internal.editor;
            editor.setComponents(pageHtml);
            editor.setStyle(buildPremiumCss(primary, accent));
            const shellHtml = editor.getHtml();
            const finalCss = editor.getCss();
            const sanitizedShellHtml = stripHtmlComments(shellHtml);
            return {
                ok: true,
                html: cdnHead + '\n<style>' + finalCss + '</style>\n' + sanitizedShellHtml + '\n' + initScripts,
                metadata: {
                    sections: (normalized.sections || []).length,
                    tech_stack: selectedTech,
                    render_engine: 'tailwind_gsap_lenis_react18',
                    source: normalized.source || 'openai_strategy_to_grapes'
                }
            };
        } catch (err) {
            internal.lastError = err;
            return { ok: false, reason: err && err.message ? err.message : 'compose_failed' };
        }
    }

    /* ═══════════════════════════════════════════════════════════════════ *
     * LEGACY COMPOSITION HELPERS (preserved for backward compatibility) *
     * ═══════════════════════════════════════════════════════════════════ */

    function composeMedia(sectionType, mediaType, section) {
        return composePremiumMedia(
            sectionType,
            mediaType,
            section || {},
            mediaType === 'video' ? 'cinematic section backdrop' : 'premium section image',
            'min-h-[320px] rounded-[24px]'
        );
    }

    function composeBullets(items) {
        if (!Array.isArray(items) || !items.length) return '';
        const listItems = items
            .filter(Boolean)
            .map((item) => `<li>${escapeHtml(item)}</li>`)
            .join('');
        return listItems ? `<ul class="vmo-gjs-bullets">${listItems}</ul>` : '';
    }

    function composeContactExtras(integrations) {
        const actions = [];
        if (integrations.phone_enabled && integrations.phone_number) {
            const phone = String(integrations.phone_number);
            const phoneHref = `tel:${phone.replace(/[^+\d]/g, '')}`;
            actions.push(`<a class="vmo-gjs-contact-chip" href="${escapeHtml(phoneHref)}">Call: ${escapeHtml(phone)}</a>`);
        }
        if (integrations.email_enabled && integrations.email_address) {
            const email = String(integrations.email_address);
            actions.push(`<a class="vmo-gjs-contact-chip" href="mailto:${escapeHtml(email)}">Email: ${escapeHtml(email)}</a>`);
        }
        return actions.length ? `<div class="vmo-gjs-contact-grid">${actions.join('')}</div>` : '';
    }

    function composeSection(section, index, integrations) {
        const type = slugify(section.type || `section-${index + 1}`);
        const sectionId = `section-${index + 1}-${type}`;
        const headline = section.headline || 'Section headline';
        const subheadline = section.subheadline || '';
        const body = section.body || '';
        const ctaPrimary = section.cta_primary || '';
        const ctaSecondary = section.cta_secondary || '';
        const mediaType = section.media === 'video' ? 'video' : 'image';
        const bullets = composeBullets(section.bullets || []);

        const showContactForm = type === 'contact' || (!!integrations.contact_form && index === (integrations._lastIndex || 0));
        const contactExtras = type === 'contact' ? composeContactExtras(integrations) : '';

        const mediaColumn = `<div class="vmo-gjs-media">${composeMedia(type, mediaType, section)}</div>`;
        const textColumn = `
            <div class="vmo-gjs-content">
                <h2>${escapeHtml(headline)}</h2>
                ${subheadline ? `<p class="vmo-gjs-subheadline">${escapeHtml(subheadline)}</p>` : ''}
                ${body ? `<p class="vmo-gjs-body">${escapeHtml(body)}</p>` : ''}
                ${bullets}
                <div class="vmo-gjs-actions">
                    ${ctaPrimary ? `<a class="vmo-gjs-btn vmo-gjs-btn-primary" href="#">${escapeHtml(ctaPrimary)}</a>` : ''}
                    ${ctaSecondary ? `<a class="vmo-gjs-btn vmo-gjs-btn-secondary" href="#">${escapeHtml(ctaSecondary)}</a>` : ''}
                </div>
                ${contactExtras}
                ${showContactForm ? `
                    <form class="vmo-gjs-form" data-vmo-form="lead">
                        <input type="text" name="name" placeholder="Your name" required>
                        <input type="email" name="email" placeholder="Your email" required>
                        <textarea name="message" rows="4" placeholder="How can we help?"></textarea>
                        <button type="submit" class="vmo-gjs-btn vmo-gjs-btn-primary">Send Request</button>
                    </form>
                ` : ''}
            </div>
        `;

        const swapLayout = index % 2 === 1;
        const layout = swapLayout ? `${mediaColumn}${textColumn}` : `${textColumn}${mediaColumn}`;

        return `
<!-- SECTION ${index + 1} -->
<section id="${sectionId}" class="vmo-gjs-section" data-vmo-section-type="${type}">
    <div class="vmo-gjs-shell">
        ${layout}
    </div>
</section>
<!-- END SECTION ${index + 1} -->
`;
    }

    function buildTemplateCss(plan) {
        const primary = String(plan.brand.primary_color || '#0f172a');
        const accent = String(plan.brand.accent_color || '#0ea5e9');
        return `
:root{--vmo-gjs-primary:${primary};--vmo-gjs-accent:${accent};--vmo-gjs-bg:#ffffff;--vmo-gjs-text:#0f172a;--vmo-gjs-muted:#475569;}
*{box-sizing:border-box;}
body{margin:0;font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:var(--vmo-gjs-bg);color:var(--vmo-gjs-text);line-height:1.5;}
.vmo-gjs-header{padding:28px 20px;border-bottom:1px solid rgba(15,23,42,.08);position:sticky;top:0;background:rgba(255,255,255,.95);backdrop-filter:blur(8px);z-index:9;}
.vmo-gjs-header-inner{max-width:1180px;margin:0 auto;display:flex;justify-content:space-between;gap:18px;align-items:center;}
.vmo-gjs-brand h1{margin:0;font-size:24px;line-height:1.2;}
.vmo-gjs-brand p{margin:6px 0 0;color:var(--vmo-gjs-muted);}
.vmo-gjs-tech{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;}
.vmo-gjs-chip{padding:6px 10px;border-radius:999px;background:#eef2ff;border:1px solid #dbeafe;color:#1e3a8a;font-size:12px;font-weight:600;}
.vmo-gjs-section{padding:56px 20px;}
.vmo-gjs-shell{max-width:1180px;margin:0 auto;display:grid;grid-template-columns:1fr 1fr;gap:28px;align-items:center;}
.vmo-gjs-content h2{margin:0 0 10px;font-size:34px;line-height:1.1;}
.vmo-gjs-subheadline{margin:0 0 12px;color:var(--vmo-gjs-accent);font-weight:600;}
.vmo-gjs-body{margin:0 0 14px;color:var(--vmo-gjs-muted);}
.vmo-gjs-bullets{margin:0 0 16px;padding-left:20px;color:var(--vmo-gjs-muted);}
.vmo-gjs-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:10px;}
.vmo-gjs-btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:10px 16px;border-radius:10px;text-decoration:none;font-weight:600;}
.vmo-gjs-btn-primary{background:var(--vmo-gjs-primary);color:#fff;}
.vmo-gjs-btn-secondary{background:#f1f5f9;color:#0f172a;}
.vmo-gjs-media{min-height:260px;}
.vmo-gjs-form{margin-top:14px;display:grid;gap:10px;}
.vmo-gjs-form input,.vmo-gjs-form textarea{width:100%;padding:12px;border:1px solid #cbd5e1;border-radius:8px;font:inherit;}
.vmo-gjs-contact-grid{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px;}
.vmo-gjs-contact-chip{padding:8px 12px;border-radius:999px;background:#ecfeff;color:#0f766e;text-decoration:none;border:1px solid #99f6e4;font-weight:600;}
.vmo-gjs-footer{padding:26px 20px;border-top:1px solid rgba(15,23,42,.08);color:var(--vmo-gjs-muted);}
.vmo-gjs-footer-inner{max-width:1180px;margin:0 auto;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;}
@media (max-width: 960px){
  .vmo-gjs-shell{grid-template-columns:1fr;}
  .vmo-gjs-content h2{font-size:28px;}
  .vmo-gjs-header-inner{flex-direction:column;align-items:flex-start;}
}
`;
    }

    function composeWebsite(plan, context = {}) {
        readConfig();
        if (!isActivated()) {
            return { ok: false, reason: 'activation_required' };
        }
        if (!internal.ready || !internal.editor) {
            return { ok: false, reason: 'adapter_not_ready' };
        }

        const normalized = normalizePlan(plan);
        const site = normalized.site || {};
        const integrations = { ...(normalized.integrations || {}) };
        if (!integrations.phone_number && context.phoneNumber) integrations.phone_number = String(context.phoneNumber);
        if (!integrations.email_address && context.emailAddress) integrations.email_address = String(context.emailAddress);
        integrations.phone_enabled = !!integrations.phone_enabled;
        integrations.email_enabled = !!integrations.email_enabled;
        integrations._lastIndex = Math.max((normalized.sections || []).length - 1, 0);

                const selectedTech = Array.isArray(normalized.tech_stack?.selected) && normalized.tech_stack.selected.length
                        ? normalized.tech_stack.selected.slice()
                        : ['React 18', 'HTML5', 'CSS3', 'JavaScript (ES6+)'];
                if (!selectedTech.includes('React 18')) {
                        selectedTech.unshift('React 18');
                }
                if (!selectedTech.includes('JavaScript (ES6+)')) {
                        selectedTech.push('JavaScript (ES6+)');
                }

                const runtimePlan = {
                        site: normalized.site || {},
                        brand: normalized.brand || {},
                        integrations,
                        sections: Array.isArray(normalized.sections) ? normalized.sections : [],
                        selectedTech: selectedTech.slice(0, 6)
                };

                const runtimePlanJson = safeJsonForScript(runtimePlan);
                const reactRuntime = `
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script>
(function(){
    const payload = ${runtimePlanJson};
    const site = payload.site || {};
    const integrations = payload.integrations || {};
    const sections = Array.isArray(payload.sections) ? payload.sections : [];
    const selectedTech = Array.isArray(payload.selectedTech) ? payload.selectedTech : [];
    const rootEl = document.getElementById('vmo-react-root');

    if (!rootEl || !window.React || !window.ReactDOM || typeof window.ReactDOM.createRoot !== 'function') {
        return;
    }

    const e = window.React.createElement;

    const slugifyLocal = (value) => String(value || 'section').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'section';
    const toText = (value, fallback = '') => {
        if (value === undefined || value === null) return fallback;
        return String(value);
    };
    const mediaIdFor = (sectionType, index) => 'react-media-' + slugifyLocal(sectionType) + '-' + (index + 1) + '-' + Date.now() + '-' + Math.floor(Math.random() * 100000);

    const mediaNode = (sectionType, mediaType, index) => {
        const mediaId = mediaIdFor(sectionType, index);
        const label = toText(sectionType, 'section');
        if (mediaType === 'video') {
            return e('div', {
                className: 'vmo-media-placeholder',
                'data-media-id': mediaId,
                'data-type': 'video',
                'data-vmo-sora': 'true',
                'data-vmo-sora-prompt': 'Cinematic ' + label + ' website loop with layered depth, elegant motion, premium lighting, and no text.',
                style: {
                    width: '100%',
                    height: '100%',
                    minHeight: '260px',
                    borderRadius: '14px',
                    display: 'flex',
                    alignItems: 'flex-end',
                    padding: '18px',
                    color: 'transparent',
                    fontSize: '0',
                    lineHeight: '0',
                    background: 'linear-gradient(135deg, #081120, #1e3a5f, #081120)'
                }
            });
        }

        return e('div', {
            className: 'vmo-media-placeholder',
            'data-media-id': mediaId,
            'data-type': 'image',
            'data-vmo-generate': 'true',
            'data-vmo-prompt': 'Premium ' + label + ' image for a cinematic website section with editorial composition and no text overlay.',
            style: {
                width: '100%',
                height: '100%',
                minHeight: '260px',
                borderRadius: '14px',
                display: 'flex',
                alignItems: 'flex-end',
                padding: '18px',
                color: 'transparent',
                fontSize: '0',
                lineHeight: '0',
                background: 'linear-gradient(135deg, #0f172a, #1d4ed8, #0f172a)'
            }
        });
    };

    const sectionNode = (section, index, total) => {
        const type = slugifyLocal((section && section.type) || ('section-' + (index + 1)));
        const sectionId = 'section-' + (index + 1) + '-' + type;
        const headline = toText(section?.headline, 'Section headline');
        const subheadline = toText(section?.subheadline, '');
        const body = toText(section?.body, '');
        const ctaPrimary = toText(section?.cta_primary, '');
        const ctaSecondary = toText(section?.cta_secondary, '');
        const mediaType = section?.media === 'video' ? 'video' : 'image';
        const bullets = Array.isArray(section?.bullets) ? section.bullets.map((b) => toText(b)).filter(Boolean) : [];

        const textChildren = [e('h2', { key: 'h2' }, headline)];
        if (subheadline) textChildren.push(e('p', { className: 'vmo-gjs-subheadline', key: 'sub' }, subheadline));
        if (body) textChildren.push(e('p', { className: 'vmo-gjs-body', key: 'body' }, body));
        if (bullets.length) {
            textChildren.push(
                e('ul', { className: 'vmo-gjs-bullets', key: 'bullets' },
                    bullets.map((item, itemIndex) => e('li', { key: 'b-' + itemIndex }, item))
                )
            );
        }

        const actionButtons = [];
        if (ctaPrimary) actionButtons.push(e('a', { className: 'vmo-gjs-btn vmo-gjs-btn-primary', href: '#', key: 'cta1' }, ctaPrimary));
        if (ctaSecondary) actionButtons.push(e('a', { className: 'vmo-gjs-btn vmo-gjs-btn-secondary', href: '#', key: 'cta2' }, ctaSecondary));
        if (actionButtons.length) textChildren.push(e('div', { className: 'vmo-gjs-actions', key: 'actions' }, actionButtons));

        if (type === 'contact') {
            const chips = [];
            if (integrations.phone_enabled && integrations.phone_number) {
                const phone = toText(integrations.phone_number);
                chips.push(e('a', { className: 'vmo-gjs-contact-chip', href: 'tel:' + phone.replace(/[^+\\d]/g, ''), key: 'phone' }, 'Call: ' + phone));
            }
            if (integrations.email_enabled && integrations.email_address) {
                const email = toText(integrations.email_address);
                chips.push(e('a', { className: 'vmo-gjs-contact-chip', href: 'mailto:' + email, key: 'email' }, 'Email: ' + email));
            }
            if (chips.length) textChildren.push(e('div', { className: 'vmo-gjs-contact-grid', key: 'chips' }, chips));
        }

        const showContactForm = type === 'contact' || (!!integrations.contact_form && index === (total - 1));
        if (showContactForm) {
            textChildren.push(
                e('form', { className: 'vmo-gjs-form', 'data-vmo-form': 'lead', key: 'form', onSubmit: function (event) { event.preventDefault(); } }, [
                    e('input', { key: 'name', type: 'text', name: 'name', placeholder: 'Your name', required: true }),
                    e('input', { key: 'email', type: 'email', name: 'email', placeholder: 'Your email', required: true }),
                    e('textarea', { key: 'message', name: 'message', rows: 4, placeholder: 'How can we help?' }),
                    e('button', { key: 'submit', type: 'submit', className: 'vmo-gjs-btn vmo-gjs-btn-primary' }, 'Send Request')
                ])
            );
        }

        const textCol = e('div', { className: 'vmo-gjs-content', key: 'text' }, textChildren);
        const mediaCol = e('div', { className: 'vmo-gjs-media', key: 'media' }, mediaNode(type, mediaType, index));
        const layout = index % 2 === 1 ? [mediaCol, textCol] : [textCol, mediaCol];

        return e('section', {
            id: sectionId,
            className: 'vmo-gjs-section',
            'data-vmo-section-type': type,
            'data-vmo-section-index': String(index + 1),
            key: 'section-' + index
        }, e('div', { className: 'vmo-gjs-shell' }, layout));
    };

    const header = e('header', { className: 'vmo-gjs-header', key: 'header' },
        e('div', { className: 'vmo-gjs-header-inner' }, [
            e('div', { className: 'vmo-gjs-brand', key: 'brand' }, [
                e('h1', { key: 'name' }, toText(site.business_name, 'Business Website')),
                e('p', { key: 'tagline' }, toText(site.tagline, 'Built from consultation intelligence'))
            ]),
            e('div', { className: 'vmo-gjs-tech', key: 'tech' },
                selectedTech.slice(0, 6).map((tech, techIndex) => e('span', { className: 'vmo-gjs-chip', key: 'tech-' + techIndex }, toText(tech)))
            )
        ])
    );

    const sectionNodes = sections.map((section, index) => sectionNode(section, index, sections.length));
    const footer = e('footer', { className: 'vmo-gjs-footer', id: 'section-footer', key: 'footer' },
        e('div', { className: 'vmo-gjs-footer-inner' }, [
            e('span', { key: 'left' }, toText(site.business_name, 'Business Website')),
            e('span', { key: 'right' }, toText(site.goal, 'Built to convert and scale'))
        ])
    );

    const app = e('main', { className: 'vmo-gjs-page', 'data-vmo-generated': 'grapesjs-react' }, [header, ...sectionNodes, footer]);
    window.ReactDOM.createRoot(rootEl).render(app);
})();
</script>`;

        try {
            const editor = internal.editor;
                        editor.setComponents('<div id="vmo-react-root" data-vmo-react-root="1"><div class="vmo-gjs-loading">Building React frontend...</div></div>');
                        editor.setStyle(buildTemplateCss(normalized) + '\n.vmo-gjs-loading{padding:28px;border:1px dashed #94a3b8;border-radius:12px;color:#334155;font-weight:600;text-align:center;}');

                        const shellHtml = editor.getHtml();
            const finalCss = editor.getCss();
            const sanitizedShellHtml = stripHtmlComments(shellHtml);
            return {
                ok: true,
                                html: `<style>${finalCss}</style>\n${sanitizedShellHtml}\n${reactRuntime}`,
                metadata: {
                    sections: (normalized.sections || []).length,
                    tech_stack: selectedTech,
                                        render_engine: 'react18',
                    source: normalized.source || 'openai_strategy_to_grapes'
                }
            };
        } catch (err) {
            internal.lastError = err;
            return { ok: false, reason: err?.message || 'compose_failed' };
        }
    }

    function runPipeline(blocks, options = {}) {
        readConfig();
        const cloned = cloneBlocks(blocks);

        if (!isActivated()) {
            return { applied: false, mode: 'activation_required', blocks: cloned };
        }

        if (!internal.ready || !internal.editor) {
            preload();
            return { applied: false, mode: 'warming', blocks: cloned };
        }

        const now = Date.now();
        const signature = signatureForBlocks(cloned);
        const minIntervalMs = Number.isFinite(Number(options.minIntervalMs)) ? Number(options.minIntervalMs) : 250;
        if (internal.lastResult && internal.lastSignature === signature && (now - internal.lastRunAt) < minIntervalMs) {
            return internal.lastResult;
        }

        const validation = validatePass(cloned);

        /* ── Enhanced structural checks ── */
        var structuralWarnings = [];
        var combinedHtml = cloned.map(function (b) { return b && b.html ? b.html : ''; }).join('');
        if (combinedHtml.length < 200) structuralWarnings.push('content_too_short');
        if (combinedHtml.indexOf('data-vmo-section-type') === -1 && combinedHtml.indexOf('data-vmo-animate') === -1) {
            structuralWarnings.push('missing_section_markers');
        }
        if (combinedHtml.indexOf('<h') === -1) structuralWarnings.push('no_headings');
        if (combinedHtml.indexOf('vmo-media-placeholder') === -1 && combinedHtml.indexOf('<img') === -1) {
            structuralWarnings.push('no_media_elements');
        }

        const result = {
            applied: validation.ok,
            mode: 'background_validation',
            blocks: cloned,
            validation,
            structural: {
                warnings: structuralWarnings,
                contentLength: combinedHtml.length,
                hasTailwind: combinedHtml.indexOf('tailwind') !== -1 || combinedHtml.indexOf('class="') !== -1,
                hasGsapMarkers: combinedHtml.indexOf('data-vmo-animate') !== -1,
                hasMediaPlaceholders: combinedHtml.indexOf('vmo-media-placeholder') !== -1
            }
        };

        internal.lastRunAt = now;
        internal.lastSignature = signature;
        internal.lastResult = result;
        window.vmoGrapesLastRun = {
            applied: result.applied,
            mode: result.mode,
            at: new Date().toISOString(),
            validation: validation
        };

        if (!validation.ok) {
            warn('GrapesJS validation failed:', validation.reason || 'unknown');
        }

        return result;
    }

    window.vmoGrapesAdapter = {
        preload,
        isActivated,
        isReady: () => !!internal.ready,
        runPipeline,
        composeWebsite: composeWebsitePremium,
        getState: () => ({
            activated: isActivated(),
            ready: internal.ready,
            loading: internal.loading,
            keyHint: internal.config.api_key_last4 ? `***${internal.config.api_key_last4}` : null,
            lastError: internal.lastError ? (internal.lastError.message || String(internal.lastError)) : null,
            lastRun: window.vmoGrapesLastRun || null
        })
    };

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            preload();
        });
    } else {
        preload();
    }
})(window, document);
