Код IT Загрузка примера кода…

HTML main.html
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>No-Code Constructor</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
            background: #f0f2f5;
            overflow: hidden;
        }

        /* Панель инструментов */
        .toolbar {
            position: fixed;
            top: 20px;
            left: 20px;
            right: 20px;
            background: white;
            border-radius: 12px;
            padding: 12px 20px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            display: flex;
            gap: 15px;
            z-index: 1000;
            flex-wrap: wrap;
        }

        .btn {
            padding: 8px 16px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.2s;
        }

        .btn-primary {
            background: #3b82f6;
            color: white;
        }

        .btn-primary:hover {
            background: #2563eb;
        }

        .btn-secondary {
            background: #ef4444;
            color: white;
        }

        .btn-secondary:hover {
            background: #dc2626;
        }

        .btn-outline {
            background: white;
            border: 1px solid #d1d5db;
            color: #374151;
        }

        .btn-outline:hover {
            background: #f9fafb;
        }

        .element-btn {
            background: #f3f4f6;
            border: 1px solid #e5e7eb;
            padding: 6px 12px;
            font-size: 13px;
        }

        .element-btn:hover {
            background: #e5e7eb;
        }

        /* Холст */
        .canvas-container {
            margin-top: 90px;
            margin-left: 20px;
            margin-right: 20px;
            margin-bottom: 20px;
            height: calc(100vh - 110px);
            overflow-y: auto;
            background: #e5e7eb;
            border-radius: 12px;
            padding: 20px;
        }

        #canvas {
            min-height: 500px;
            background: white;
            border-radius: 8px;
            padding: 40px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            position: relative;
        }

        /* Редактируемые элементы */
        .editable-element {
            position: relative;
            margin: 8px 0;
            padding: 12px;
            border: 2px solid transparent;
            transition: all 0.2s;
            cursor: move;
        }

        .editable-element:hover {
            border-color: #3b82f6;
            background: #eff6ff;
        }

        .editable-element.selected {
            border-color: #3b82f6;
            background: #dbeafe;
            box-shadow: 0 0 0 3px rgba(59,130,246,0.2);
        }

        /* Кнопки управления элементом */
        .element-controls {
            position: absolute;
            top: -30px;
            right: 0;
            display: none;
            gap: 5px;
            background: white;
            padding: 4px;
            border-radius: 6px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            z-index: 10;
        }

        .editable-element:hover .element-controls {
            display: flex;
        }

        .control-btn {
            padding: 4px 8px;
            font-size: 12px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        .edit-btn {
            background: #3b82f6;
            color: white;
        }

        .delete-btn {
            background: #ef4444;
            color: white;
        }

        /* Модальное окно редактирования */
        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 2000;
            align-items: center;
            justify-content: center;
        }

        .modal.active {
            display: flex;
        }

        .modal-content {
            background: white;
            border-radius: 12px;
            padding: 24px;
            width: 400px;
            max-width: 90%;
        }

        .modal-content h3 {
            margin-bottom: 16px;
        }

        .modal-content input,
        .modal-content textarea,
        .modal-content select {
            width: 100%;
            padding: 8px;
            margin: 8px 0;
            border: 1px solid #d1d5db;
            border-radius: 6px;
            font-size: 14px;
        }

        .modal-content textarea {
            min-height: 80px;
        }

        .modal-buttons {
            display: flex;
            gap: 10px;
            margin-top: 16px;
        }

        /* Drag and drop placeholder */
        .drag-over {
            border: 2px dashed #3b82f6;
            background: #eff6ff;
        }
    </style>
</head>
<body>
    <div class="toolbar">
        <div style="display: flex; gap: 8px;">
            <button class="btn btn-outline element-btn" data-type="header">📝 Заголовок</button>
            <button class="btn btn-outline element-btn" data-type="text">📄 Текст</button>
            <button class="btn btn-outline element-btn" data-type="image">🖼️ Изображение</button>
            <button class="btn btn-outline element-btn" data-type="button">🔘 Кнопка</button>
            <button class="btn btn-outline element-btn" data-type="divider">➖ Разделитель</button>
        </div>
        <div style="flex:1"></div>
        <button class="btn btn-outline" id="previewBtn">👁️ Предпросмотр</button>
        <button class="btn btn-primary" id="exportBtn">💾 Экспорт HTML</button>
        <button class="btn btn-secondary" id="clearBtn">🗑️ Очистить</button>
    </div>

    <div class="canvas-container">
        <div id="canvas"></div>
    </div>

    <!-- Модальное окно редактирования -->
    <div id="editModal" class="modal">
        <div class="modal-content">
            <h3>Редактировать элемент</h3>
            <div id="editFields"></div>
            <div class="modal-buttons">
                <button class="btn btn-primary" id="saveEditBtn">Сохранить</button>
                <button class="btn btn-outline" id="closeModalBtn">Отмена</button>
            </div>
        </div>
    </div>

    <script>
        class PageBuilder {
            constructor() {
                this.elements = [];
                this.nextId = 1;
                this.selectedElement = null;
                this.currentEditElement = null;
                
                this.canvas = document.getElementById('canvas');
                this.init();
                this.loadFromLocalStorage();
                this.render();
            }

            init() {
                // Добавление элементов через кнопки
                document.querySelectorAll('.element-btn').forEach(btn => {
                    btn.addEventListener('click', () => {
                        const type = btn.dataset.type;
                        this.addElement(type);
                    });
                });

                // Экспорт
                document.getElementById('exportBtn').addEventListener('click', () => this.exportHTML());
                
                // Очистка
                document.getElementById('clearBtn').addEventListener('click', () => {
                    if(confirm('Очистить все?')) {
                        this.elements = [];
                        this.saveToLocalStorage();
                        this.render();
                    }
                });
                
                // Предпросмотр
                document.getElementById('previewBtn').addEventListener('click', () => this.preview());
                
                // Модальное окно
                document.getElementById('saveEditBtn').addEventListener('click', () => this.saveEdit());
                document.getElementById('closeModalBtn').addEventListener('click', () => this.closeModal());
                
                // Drag and drop для перетаскивания
                this.setupDragAndDrop();
            }
            
            addElement(type, content = null) {
                const element = {
                    id: this.nextId++,
                    type: type,
                    content: content || this.getDefaultContent(type)
                };
                this.elements.push(element);
                this.saveToLocalStorage();
                this.render();
                return element;
            }
            
            getDefaultContent(type) {
                switch(type) {
                    case 'header':
                        return { text: 'Новый заголовок', level: 'h2', align: 'left' };
                    case 'text':
                        return { text: 'Текст для вашей страницы. Дважды кликните для редактирования.', align: 'left' };
                    case 'image':
                        return { src: 'https://via.placeholder.com/400x200?text=Image', alt: 'Image', width: '100%' };
                    case 'button':
                        return { text: 'Нажми меня', url: '#', style: 'primary' };
                    case 'divider':
                        return { style: 'solid', color: '#d1d5db' };
                    default:
                        return {};
                }
            }
            
            render() {
                if (!this.canvas) return;
                
                this.canvas.innerHTML = '';
                
                this.elements.forEach((element, index) => {
                    const elementDiv = document.createElement('div');
                    elementDiv.className = 'editable-element';
                    if (this.selectedElement === element.id) {
                        elementDiv.classList.add('selected');
                    }
                    elementDiv.setAttribute('data-id', element.id);
                    elementDiv.setAttribute('draggable', 'true');
                    
                    // Содержимое элемента
                    const contentDiv = document.createElement('div');
                    contentDiv.className = 'element-content';
                    contentDiv.innerHTML = this.renderElementContent(element);
                    elementDiv.appendChild(contentDiv);
                    
                    // Кнопки управления
                    const controls = document.createElement('div');
                    controls.className = 'element-controls';
                    controls.innerHTML = `
                        <button class="control-btn edit-btn" data-id="${element.id}">✏️</button>
                        <button class="control-btn delete-btn" data-id="${element.id}">🗑️</button>
`;
                    elementDiv.appendChild(controls);
                    
                    // Обработчики
                    controls.querySelector('.edit-btn').addEventListener('click', (e) => {
                        e.stopPropagation();
                        this.openEditModal(element.id);
                    });
                    
                    controls.querySelector('.delete-btn').addEventListener('click', (e) => {
                        e.stopPropagation();
                        this.deleteElement(element.id);
                    });
                    
                    elementDiv.addEventListener('click', (e) => {
                        e.stopPropagation();
                        this.selectElement(element.id);
                    });
                    
                    // Drag and drop для переупорядочивания
                    elementDiv.addEventListener('dragstart', (e) => {
                        e.dataTransfer.setData('text/plain', element.id);
                        e.dataTransfer.effectAllowed = 'move';
                    });
                    
                    elementDiv.addEventListener('dragover', (e) => {
                        e.preventDefault();
                        e.dataTransfer.dropEffect = 'move';
                    });
                    
                    elementDiv.addEventListener('drop', (e) => {
                        e.preventDefault();
                        const draggedId = parseInt(e.dataTransfer.getData('text/plain'));
                        const targetId = element.id;
                        if (draggedId !== targetId) {
                            this.moveElement(draggedId, targetId);
                        }
                    });
                    
                    this.canvas.appendChild(elementDiv);
                });
                
                if (this.elements.length === 0) {
                    this.canvas.innerHTML = '<div style="text-align: center; padding: 60px; color: #9ca3af;">Добавьте элементы на страницу, нажимая кнопки выше</div>';
                }
            }
            
            renderElementContent(element) {
                switch(element.type) {
                    case 'header':
                        const HeaderTag = element.content.level || 'h2';
                        return `<${HeaderTag} style="text-align: ${element.content.align || 'left'}; margin: 0;">${this.escapeHtml(element.content.text)}</${HeaderTag}>`;
                    
                    case 'text':
                        return `<p style="text-align: ${element.content.align || 'left'}; margin: 0;">${this.escapeHtml(element.content.text)}</p>`;
                    
                    case 'image':
                        return `<img src="${element.content.src}" alt="${this.escapeHtml(element.content.alt)}" style="max-width: 100%; height: auto; width: ${element.content.width || 'auto'}; display: block;">`;
                    
                    case 'button':
                        const btnStyle = element.content.style === 'primary' 
                            ? 'background: #3b82f6; color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer;' 
                            : 'background: white; color: #374151; border: 1px solid #d1d5db; padding: 10px 20px; border-radius: 6px; cursor: pointer;';
                        return `<a href="${element.content.url}" style="${btnStyle} text-decoration: none; display: inline-block;">${this.escapeHtml(element.content.text)}</a>`;
                    
                    case 'divider':
                        return `<hr style="border: none; height: 1px; background: ${element.content.color || '#d1d5db'}; margin: 10px 0;">`;
                    
                    default:
                        return '';
                }
            }
            
            openEditModal(elementId) {
                const element = this.elements.find(el => el.id === elementId);
                if (!element) return;
                
                this.currentEditElement = element;
                const editFields = document.getElementById('editFields');
                
                switch(element.type) {
                    case 'header':
                        editFields.innerHTML = `
                            <label>Текст:</label>
                            <input type="text" id="edit-text" value="${this.escapeHtml(element.content.text)}">
                            <label>Уровень:</label>
                            <select id="edit-level">
                                <option value="h1" ${element.content.level === 'h1' ? 'selected' : ''}>H1</option>
                                <option value="h2" ${element.content.level === 'h2' ? 'selected' : ''}>H2</option>
                                <option value="h3" ${element.content.level === 'h3' ? 'selected' : ''}>H3</option>
                            </select>
                            <label>Выравнивание:</label>
                            <select id="edit-align">
                                <option value="left" ${element.content.align === 'left' ? 'selected' : ''}>По левому краю</option>
                                <option value="center" ${element.content.align === 'center' ? 'selected' : ''}>По центру</option>
                                <option value="right" ${element.content.align === 'right' ? 'selected' : ''}>По правому краю</option>
                            </select>
`;
                        break;
                    
                    case 'text':
                        editFields.innerHTML = `
                            <label>Текст:</label>
                            <textarea id="edit-text">${this.escapeHtml(element.content.text)}</textarea>
                            <label>Выравнивание:</label>
                            <select id="edit-align">
                                <option value="left" ${element.content.align === 'left' ? 'selected' : ''}>По левому краю</option>
                                <option value="center" ${element.content.align === 'center' ? 'selected' : ''}>По центру</option>
                                <option value="right" ${element.content.align === 'right' ? 'selected' : ''}>По правому краю</option>
                            </select>
`;
                        break;
                    
                    case 'image':
                        editFields.innerHTML = `
                            <label>URL изображения:</label>
                            <input type="text" id="edit-src" value="${this.escapeHtml(element.content.src)}">
                            <label>Alt текст:</label>
                            <input type="text" id="edit-alt" value="${this.escapeHtml(element.content.alt)}">
                            <label>Ширина:</label>
                            <input type="text" id="edit-width" value="${element.content.width || 'auto'}" placeholder="auto, 100%, 300px">
`;
                        break;
                    
                    case 'button':
                        editFields.innerHTML = `
                            <label>Текст:</label>
                            <input type="text" id="edit-text" value="${this.escapeHtml(element.content.text)}">
                            <label>Ссылка:</label>
                            <input type="text" id="edit-url" value="${element.content.url}">
                            <label>Стиль:</label>
                            <select id="edit-style">
                                <option value="primary" ${element.content.style === 'primary' ? 'selected' : ''}>Синий</option>
                                <option value="secondary" ${element.content.style === 'secondary' ? 'selected' : ''}>Белый</option>
                            </select>
`;
                        break;
                    
                    case 'divider':
                        editFields.innerHTML = `
                            <label>Цвет:</label>
                            <input type="color" id="edit-color" value="${element.content.color || '#d1d5db'}">
`;
                        break;
                }
                
                document.getElementById('editModal').classList.add('active');
            }
            
            saveEdit() {
                if (!this.currentEditElement) return;
                
                const element = this.currentEditElement;
                
                switch(element.type) {
                    case 'header':
                        element.content.text = document.getElementById('edit-text').value;
                        element.content.level = document.getElementById('edit-level').value;
                        element.content.align = document.getElementById('edit-align').value;
                        break;
                    
                    case 'text':
                        element.content.text = document.getElementById('edit-text').value;
                        element.content.align = document.getElementById('edit-align').value;
                        break;
                    
                    case 'image':
                        element.content.src = document.getElementById('edit-src').value;
                        element.content.alt = document.getElementById('edit-alt').value;
                        element.content.width = document.getElementById('edit-width').value;
                        break;
                    
                    case 'button':
                        element.content.text = document.getElementById('edit-text').value;
                        element.content.url = document.getElementById('edit-url').value;
                        element.content.style = document.getElementById('edit-style').value;
                        break;
                    
                    case 'divider':
                        element.content.color = document.getElementById('edit-color').value;
                        break;
                }
                
                this.saveToLocalStorage();
                this.render();
                this.closeModal();
            }
            
            deleteElement(id) {
                this.elements = this.elements.filter(el => el.id !== id);
                if (this.selectedElement === id) this.selectedElement = null;
                this.saveToLocalStorage();
                this.render();
            }
            
            moveElement(draggedId, targetId) {
                const draggedIndex = this.elements.findIndex(el => el.id === draggedId);
                const targetIndex = this.elements.findIndex(el => el.id === targetId);
                
                if (draggedIndex === -1 || targetIndex === -1) return;
                
                const [draggedElement] = this.elements.splice(draggedIndex, 1);
                this.elements.splice(targetIndex, 0, draggedElement);
                
                this.saveToLocalStorage();
                this.render();
            }
            
            selectElement(id) {
                this.selectedElement = id;
                this.render();
            }
            
            exportHTML() {
                let htmlContent = `<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Сгенерированная страница</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 40px;
            background: #f0f2f5;
        }
        .page-content {
            background: white;
            padding: 40px;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
        }
        img {
            max-width: 100%;
            height: auto;
        }
        a {
            text-decoration: none;
        }
    </style>
</head>
<body>
    <div class="page-content">`;
                
                this.elements.forEach(element => {
                    htmlContent += this.renderElementContent(element);
                });
                
                htmlContent += `
    </div>
</body>
</html>`;
                
                const blob = new Blob([htmlContent], { type: 'text/html' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = 'landing-page.html';
                a.click();
                URL.revokeObjectURL(url);
            }
            
            preview() {
                const previewWindow = window.open();
                previewWindow.document.write(`
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <title>Предпросмотр</title>
                        <style>
                            body {
                                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
                                max-width: 1200px;
                                margin: 0 auto;
                                padding: 40px;
                                background: #f0f2f5;
                            }
                            .preview-content {
                                background: white;
                                padding: 40px;
                                border-radius: 8px;
                                box-shadow: 0 4px 12px rgba(0,0,0,0.1);
                            }
                            img { max-width: 100%; height: auto; }
                            a { text-decoration: none; }
                        </style>
                    </head>
                    <body>
                        <div class="preview-content">
                            ${this.elements.map(el => this.renderElementContent(el)).join('')}
                        </div>
                    </body>
                    </html>
`);
                previewWindow.document.close();
            }
            
            setupDragAndDrop() {
                this.canvas.addEventListener('dragover', (e) => {
                    e.preventDefault();
                });
                
                this.canvas.addEventListener('drop', (e) => {
                    e.preventDefault();
                });
            }
            
            saveToLocalStorage() {
                localStorage.setItem('pageBuilderElements', JSON.stringify(this.elements));
                localStorage.setItem('pageBuilderNextId', this.nextId);
            }
            
            loadFromLocalStorage() {
                const saved = localStorage.getItem('pageBuilderElements');
                if (saved) {
                    this.elements = JSON.parse(saved);
                    const savedId = localStorage.getItem('pageBuilderNextId');
                    if (savedId) this.nextId = parseInt(savedId);
                }
            }
            
            closeModal() {
                document.getElementById('editModal').classList.remove('active');
                this.currentEditElement = null;
            }
            
            escapeHtml(str) {
                if (!str) return '';
                return str
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#39;');
            }
        }
        
        // Запуск
        const builder = new PageBuilder();
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>No-Code Constructor</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
            background: #f0f2f5;
            overflow: hidden;
        }

        /* Панель инструментов */
        .toolbar {
            position: fixed;
            top: 20px;
            left: 20px;
            right: 20px;
            background: white;
            border-radius: 12px;
            padding: 12px 20px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            display: flex;
            gap: 15px;
            z-index: 1000;
            flex-wrap: wrap;
        }

        .btn {
            padding: 8px 16px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.2s;
        }

        .btn-primary {
            background: #3b82f6;
            color: white;
        }

        .btn-primary:hover {
            background: #2563eb;
        }

        .btn-secondary {
            background: #ef4444;
            color: white;
        }

        .btn-secondary:hover {
            background: #dc2626;
        }

        .btn-outline {
            background: white;
            border: 1px solid #d1d5db;
            color: #374151;
        }

        .btn-outline:hover {
            background: #f9fafb;
        }

        .element-btn {
            background: #f3f4f6;
            border: 1px solid #e5e7eb;
            padding: 6px 12px;
            font-size: 13px;
        }

        .element-btn:hover {
            background: #e5e7eb;
        }

        /* Холст */
        .canvas-container {
            margin-top: 90px;
            margin-left: 20px;
            margin-right: 20px;
            margin-bottom: 20px;
            height: calc(100vh - 110px);
            overflow-y: auto;
            background: #e5e7eb;
            border-radius: 12px;
            padding: 20px;
        }

        #canvas {
            min-height: 500px;
            background: white;
            border-radius: 8px;
            padding: 40px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            position: relative;
        }

        /* Редактируемые элементы */
        .editable-element {
            position: relative;
            margin: 8px 0;
            padding: 12px;
            border: 2px solid transparent;
            transition: all 0.2s;
            cursor: move;
        }

        .editable-element:hover {
            border-color: #3b82f6;
            background: #eff6ff;
        }

        .editable-element.selected {
            border-color: #3b82f6;
            background: #dbeafe;
            box-shadow: 0 0 0 3px rgba(59,130,246,0.2);
        }

        /* Кнопки управления элементом */
        .element-controls {
            position: absolute;
            top: -30px;
            right: 0;
            display: none;
            gap: 5px;
            background: white;
            padding: 4px;
            border-radius: 6px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            z-index: 10;
        }

        .editable-element:hover .element-controls {
            display: flex;
        }

        .control-btn {
            padding: 4px 8px;
            font-size: 12px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        .edit-btn {
            background: #3b82f6;
            color: white;
        }

        .delete-btn {
            background: #ef4444;
            color: white;
        }

        /* Модальное окно редактирования */
        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 2000;
            align-items: center;
            justify-content: center;
        }

        .modal.active {
            display: flex;
        }

        .modal-content {
            background: white;
            border-radius: 12px;
            padding: 24px;
            width: 400px;
            max-width: 90%;
        }

        .modal-content h3 {
            margin-bottom: 16px;
        }

        .modal-content input,
        .modal-content textarea,
        .modal-content select {
            width: 100%;
            padding: 8px;
            margin: 8px 0;
            border: 1px solid #d1d5db;
            border-radius: 6px;
            font-size: 14px;
        }

        .modal-content textarea {
            min-height: 80px;
        }

        .modal-buttons {
            display: flex;
            gap: 10px;
            margin-top: 16px;
        }

        /* Drag and drop placeholder */
        .drag-over {
            border: 2px dashed #3b82f6;
            background: #eff6ff;
        }
    </style>
</head>
<body>
    <div class="toolbar">
        <div style="display: flex; gap: 8px;">
            <button class="btn btn-outline element-btn" data-type="header">📝 Заголовок</button>
            <button class="btn btn-outline element-btn" data-type="text">📄 Текст</button>
            <button class="btn btn-outline element-btn" data-type="image">🖼️ Изображение</button>
            <button class="btn btn-outline element-btn" data-type="button">🔘 Кнопка</button>
            <button class="btn btn-outline element-btn" data-type="divider">➖ Разделитель</button>
        </div>
        <div style="flex:1"></div>
        <button class="btn btn-outline" id="previewBtn">👁️ Предпросмотр</button>
        <button class="btn btn-primary" id="exportBtn">💾 Экспорт HTML</button>
        <button class="btn btn-secondary" id="clearBtn">🗑️ Очистить</button>
    </div>

    <div class="canvas-container">
        <div id="canvas"></div>
    </div>

    <!-- Модальное окно редактирования -->
    <div id="editModal" class="modal">
        <div class="modal-content">
            <h3>Редактировать элемент</h3>
            <div id="editFields"></div>
            <div class="modal-buttons">
                <button class="btn btn-primary" id="saveEditBtn">Сохранить</button>
                <button class="btn btn-outline" id="closeModalBtn">Отмена</button>
            </div>
        </div>
    </div>

    <script>
        class PageBuilder {
            constructor() {
                this.elements = [];
                this.nextId = 1;
                this.selectedElement = null;
                this.currentEditElement = null;
                
                this.canvas = document.getElementById('canvas');
                this.init();
                this.loadFromLocalStorage();
                this.render();
            }

            init() {
                // Добавление элементов через кнопки
                document.querySelectorAll('.element-btn').forEach(btn => {
                    btn.addEventListener('click', () => {
                        const type = btn.dataset.type;
                        this.addElement(type);
                    });
                });

                // Экспорт
                document.getElementById('exportBtn').addEventListener('click', () => this.exportHTML());
                
                // Очистка
                document.getElementById('clearBtn').addEventListener('click', () => {
                    if(confirm('Очистить все?')) {
                        this.elements = [];
                        this.saveToLocalStorage();
                        this.render();
                    }
                });
                
                // Предпросмотр
                document.getElementById('previewBtn').addEventListener('click', () => this.preview());
                
                // Модальное окно
                document.getElementById('saveEditBtn').addEventListener('click', () => this.saveEdit());
                document.getElementById('closeModalBtn').addEventListener('click', () => this.closeModal());
                
                // Drag and drop для перетаскивания
                this.setupDragAndDrop();
            }
            
            addElement(type, content = null) {
                const element = {
                    id: this.nextId++,
                    type: type,
                    content: content || this.getDefaultContent(type)
                };
                this.elements.push(element);
                this.saveToLocalStorage();
                this.render();
                return element;
            }
            
            getDefaultContent(type) {
                switch(type) {
                    case 'header':
                        return { text: 'Новый заголовок', level: 'h2', align: 'left' };
                    case 'text':
                        return { text: 'Текст для вашей страницы. Дважды кликните для редактирования.', align: 'left' };
                    case 'image':
                        return { src: 'https://via.placeholder.com/400x200?text=Image', alt: 'Image', width: '100%' };
                    case 'button':
                        return { text: 'Нажми меня', url: '#', style: 'primary' };
                    case 'divider':
                        return { style: 'solid', color: '#d1d5db' };
                    default:
                        return {};
                }
            }
            
            render() {
                if (!this.canvas) return;
                
                this.canvas.innerHTML = '';
                
                this.elements.forEach((element, index) => {
                    const elementDiv = document.createElement('div');
                    elementDiv.className = 'editable-element';
                    if (this.selectedElement === element.id) {
                        elementDiv.classList.add('selected');
                    }
                    elementDiv.setAttribute('data-id', element.id);
                    elementDiv.setAttribute('draggable', 'true');
                    
                    // Содержимое элемента
                    const contentDiv = document.createElement('div');
                    contentDiv.className = 'element-content';
                    contentDiv.innerHTML = this.renderElementContent(element);
                    elementDiv.appendChild(contentDiv);
                    
                    // Кнопки управления
                    const controls = document.createElement('div');
                    controls.className = 'element-controls';
                    controls.innerHTML = `
                        <button class="control-btn edit-btn" data-id="${element.id}">✏️</button>
                        <button class="control-btn delete-btn" data-id="${element.id}">🗑️</button>
`;
                    elementDiv.appendChild(controls);
                    
                    // Обработчики
                    controls.querySelector('.edit-btn').addEventListener('click', (e) => {
                        e.stopPropagation();
                        this.openEditModal(element.id);
                    });
                    
                    controls.querySelector('.delete-btn').addEventListener('click', (e) => {
                        e.stopPropagation();
                        this.deleteElement(element.id);
                    });
                    
                    elementDiv.addEventListener('click', (e) => {
                        e.stopPropagation();
                        this.selectElement(element.id);
                    });
                    
                    // Drag and drop для переупорядочивания
                    elementDiv.addEventListener('dragstart', (e) => {
                        e.dataTransfer.setData('text/plain', element.id);
                        e.dataTransfer.effectAllowed = 'move';
                    });
                    
                    elementDiv.addEventListener('dragover', (e) => {
                        e.preventDefault();
                        e.dataTransfer.dropEffect = 'move';
                    });
                    
                    elementDiv.addEventListener('drop', (e) => {
                        e.preventDefault();
                        const draggedId = parseInt(e.dataTransfer.getData('text/plain'));
                        const targetId = element.id;
                        if (draggedId !== targetId) {
                            this.moveElement(draggedId, targetId);
                        }
                    });
                    
                    this.canvas.appendChild(elementDiv);
                });
                
                if (this.elements.length === 0) {
                    this.canvas.innerHTML = '<div style="text-align: center; padding: 60px; color: #9ca3af;">Добавьте элементы на страницу, нажимая кнопки выше</div>';
                }
            }
            
            renderElementContent(element) {
                switch(element.type) {
                    case 'header':
                        const HeaderTag = element.content.level || 'h2';
                        return `<${HeaderTag} style="text-align: ${element.content.align || 'left'}; margin: 0;">${this.escapeHtml(element.content.text)}</${HeaderTag}>`;
                    
                    case 'text':
                        return `<p style="text-align: ${element.content.align || 'left'}; margin: 0;">${this.escapeHtml(element.content.text)}</p>`;
                    
                    case 'image':
                        return `<img src="${element.content.src}" alt="${this.escapeHtml(element.content.alt)}" style="max-width: 100%; height: auto; width: ${element.content.width || 'auto'}; display: block;">`;
                    
                    case 'button':
                        const btnStyle = element.content.style === 'primary' 
                            ? 'background: #3b82f6; color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer;' 
                            : 'background: white; color: #374151; border: 1px solid #d1d5db; padding: 10px 20px; border-radius: 6px; cursor: pointer;';
                        return `<a href="${element.content.url}" style="${btnStyle} text-decoration: none; display: inline-block;">${this.escapeHtml(element.content.text)}</a>`;
                    
                    case 'divider':
                        return `<hr style="border: none; height: 1px; background: ${element.content.color || '#d1d5db'}; margin: 10px 0;">`;
                    
                    default:
                        return '';
                }
            }
            
            openEditModal(elementId) {
                const element = this.elements.find(el => el.id === elementId);
                if (!element) return;
                
                this.currentEditElement = element;
                const editFields = document.getElementById('editFields');
                
                switch(element.type) {
                    case 'header':
                        editFields.innerHTML = `
                            <label>Текст:</label>
                            <input type="text" id="edit-text" value="${this.escapeHtml(element.content.text)}">
                            <label>Уровень:</label>
                            <select id="edit-level">
                                <option value="h1" ${element.content.level === 'h1' ? 'selected' : ''}>H1</option>
                                <option value="h2" ${element.content.level === 'h2' ? 'selected' : ''}>H2</option>
                                <option value="h3" ${element.content.level === 'h3' ? 'selected' : ''}>H3</option>
                            </select>
                            <label>Выравнивание:</label>
                            <select id="edit-align">
                                <option value="left" ${element.content.align === 'left' ? 'selected' : ''}>По левому краю</option>
                                <option value="center" ${element.content.align === 'center' ? 'selected' : ''}>По центру</option>
                                <option value="right" ${element.content.align === 'right' ? 'selected' : ''}>По правому краю</option>
                            </select>
`;
                        break;
                    
                    case 'text':
                        editFields.innerHTML = `
                            <label>Текст:</label>
                            <textarea id="edit-text">${this.escapeHtml(element.content.text)}</textarea>
                            <label>Выравнивание:</label>
                            <select id="edit-align">
                                <option value="left" ${element.content.align === 'left' ? 'selected' : ''}>По левому краю</option>
                                <option value="center" ${element.content.align === 'center' ? 'selected' : ''}>По центру</option>
                                <option value="right" ${element.content.align === 'right' ? 'selected' : ''}>По правому краю</option>
                            </select>
`;
                        break;
                    
                    case 'image':
                        editFields.innerHTML = `
                            <label>URL изображения:</label>
                            <input type="text" id="edit-src" value="${this.escapeHtml(element.content.src)}">
                            <label>Alt текст:</label>
                            <input type="text" id="edit-alt" value="${this.escapeHtml(element.content.alt)}">
                            <label>Ширина:</label>
                            <input type="text" id="edit-width" value="${element.content.width || 'auto'}" placeholder="auto, 100%, 300px">
`;
                        break;
                    
                    case 'button':
                        editFields.innerHTML = `
                            <label>Текст:</label>
                            <input type="text" id="edit-text" value="${this.escapeHtml(element.content.text)}">
                            <label>Ссылка:</label>
                            <input type="text" id="edit-url" value="${element.content.url}">
                            <label>Стиль:</label>
                            <select id="edit-style">
                                <option value="primary" ${element.content.style === 'primary' ? 'selected' : ''}>Синий</option>
                                <option value="secondary" ${element.content.style === 'secondary' ? 'selected' : ''}>Белый</option>
                            </select>
`;
                        break;
                    
                    case 'divider':
                        editFields.innerHTML = `
                            <label>Цвет:</label>
                            <input type="color" id="edit-color" value="${element.content.color || '#d1d5db'}">
`;
                        break;
                }
                
                document.getElementById('editModal').classList.add('active');
            }
            
            saveEdit() {
                if (!this.currentEditElement) return;
                
                const element = this.currentEditElement;
                
                switch(element.type) {
                    case 'header':
                        element.content.text = document.getElementById('edit-text').value;
                        element.content.level = document.getElementById('edit-level').value;
                        element.content.align = document.getElementById('edit-align').value;
                        break;
                    
                    case 'text':
                        element.content.text = document.getElementById('edit-text').value;
                        element.content.align = document.getElementById('edit-align').value;
                        break;
                    
                    case 'image':
                        element.content.src = document.getElementById('edit-src').value;
                        element.content.alt = document.getElementById('edit-alt').value;
                        element.content.width = document.getElementById('edit-width').value;
                        break;
                    
                    case 'button':
                        element.content.text = document.getElementById('edit-text').value;
                        element.content.url = document.getElementById('edit-url').value;
                        element.content.style = document.getElementById('edit-style').value;
                        break;
                    
                    case 'divider':
                        element.content.color = document.getElementById('edit-color').value;
                        break;
                }
                
                this.saveToLocalStorage();
                this.render();
                this.closeModal();
            }
            
            deleteElement(id) {
                this.elements = this.elements.filter(el => el.id !== id);
                if (this.selectedElement === id) this.selectedElement = null;
                this.saveToLocalStorage();
                this.render();
            }
            
            moveElement(draggedId, targetId) {
                const draggedIndex = this.elements.findIndex(el => el.id === draggedId);
                const targetIndex = this.elements.findIndex(el => el.id === targetId);
                
                if (draggedIndex === -1 || targetIndex === -1) return;
                
                const [draggedElement] = this.elements.splice(draggedIndex, 1);
                this.elements.splice(targetIndex, 0, draggedElement);
                
                this.saveToLocalStorage();
                this.render();
            }
            
            selectElement(id) {
                this.selectedElement = id;
                this.render();
            }
            
            exportHTML() {
                let htmlContent = `<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Сгенерированная страница</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 40px;
            background: #f0f2f5;
        }
        .page-content {
            background: white;
            padding: 40px;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
        }
        img {
            max-width: 100%;
            height: auto;
        }
        a {
            text-decoration: none;
        }
    </style>
</head>
<body>
    <div class="page-content">`;
                
                this.elements.forEach(element => {
                    htmlContent += this.renderElementContent(element);
                });
                
                htmlContent += `
    </div>
</body>
</html>`;
                
                const blob = new Blob([htmlContent], { type: 'text/html' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = 'landing-page.html';
                a.click();
                URL.revokeObjectURL(url);
            }
            
            preview() {
                const previewWindow = window.open();
                previewWindow.document.write(`
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <title>Предпросмотр</title>
                        <style>
                            body {
                                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
                                max-width: 1200px;
                                margin: 0 auto;
                                padding: 40px;
                                background: #f0f2f5;
                            }
                            .preview-content {
                                background: white;
                                padding: 40px;
                                border-radius: 8px;
                                box-shadow: 0 4px 12px rgba(0,0,0,0.1);
                            }
                            img { max-width: 100%; height: auto; }
                            a { text-decoration: none; }
                        </style>
                    </head>
                    <body>
                        <div class="preview-content">
                            ${this.elements.map(el => this.renderElementContent(el)).join('')}
                        </div>
                    </body>
                    </html>
`);
                previewWindow.document.close();
            }
            
            setupDragAndDrop() {
                this.canvas.addEventListener('dragover', (e) => {
                    e.preventDefault();
                });
                
                this.canvas.addEventListener('drop', (e) => {
                    e.preventDefault();
                });
            }
            
            saveToLocalStorage() {
                localStorage.setItem('pageBuilderElements', JSON.stringify(this.elements));
                localStorage.setItem('pageBuilderNextId', this.nextId);
            }
            
            loadFromLocalStorage() {
                const saved = localStorage.getItem('pageBuilderElements');
                if (saved) {
                    this.elements = JSON.parse(saved);
                    const savedId = localStorage.getItem('pageBuilderNextId');
                    if (savedId) this.nextId = parseInt(savedId);
                }
            }
            
            closeModal() {
                document.getElementById('editModal').classList.remove('active');
                this.currentEditElement = null;
            }
            
            escapeHtml(str) {
                if (!str) return '';
                return str
                    .replace(/&/g, '&amp;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#39;');
            }
        }
        
        // Запуск
        const builder = new PageBuilder();
    </script>
</body>
</html>