{"id":3448,"date":"2025-08-27T12:55:36","date_gmt":"2025-08-27T10:55:36","guid":{"rendered":"https:\/\/moodul.es\/?page_id=3448"},"modified":"2025-08-27T14:18:47","modified_gmt":"2025-08-27T12:18:47","slug":"faq","status":"publish","type":"page","link":"https:\/\/moodul.es\/fr\/faq\/","title":{"rendered":"faq"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"3448\" class=\"elementor elementor-3448\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f6b3783 e-flex e-con-boxed wcf-starter-animations-none e-con e-parent\" data-id=\"f6b3783\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1196662 elementor-widget elementor-widget-shortcode\" data-id=\"1196662\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">        \n        <!-- FAQ Widget Container 1 -->\n        <style>\n        \/* Estilos del FAQ Widget *\/\n        .faq-widget-1 {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n            margin: 20px 0;\n        }\n        \n        .faq-widget-1 .faq-main-title {\n            text-align: center;\n            font-size: 28px;\n            font-weight: 700;\n            color: #333;\n            margin-bottom: 30px;\n            padding-bottom: 15px;\n            border-bottom: 3px solid #333;\n        }\n        \n        .faq-widget-1 .faq-item {\n            border: 1px solid #e9ecef;\n            border-radius: 8px;\n            margin-bottom: 15px;\n            overflow: hidden;\n            transition: all 0.3s ease;\n            background: white;\n        }\n        \n        .faq-widget-1 .faq-item:hover {\n            box-shadow: 0 4px 12px rgba(0,0,0,0.08);\n        }\n        \n        .faq-widget-1 .faq-question {\n            padding: 20px;\n            background: #f8f9fa;\n            cursor: pointer;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            user-select: none;\n            transition: all 0.3s ease;\n        }\n        \n        .faq-widget-1 .faq-question:hover {\n            background: #e9ecef;\n        }\n        \n        .faq-widget-1 .faq-question h2 {\n            margin: 0;\n            font-size: 16px;\n            font-weight: 600;\n            color: #333;\n            flex: 1;\n            line-height: 1.4;\n            padding-right: 20px;\n        }\n        \n        .faq-widget-1 .faq-toggle {\n            width: 20px;\n            height: 20px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            transition: transform 0.3s ease;\n            flex-shrink: 0;\n        }\n        \n        .faq-widget-1 .faq-toggle::after {\n            content: \"\u25bc\";\n            font-size: 12px;\n            color: #666;\n        }\n        \n        .faq-widget-1 .faq-item.active .faq-question {\n            background: #333;\n        }\n        \n        .faq-widget-1 .faq-item.active .faq-question h2 {\n            color: white;\n        }\n        \n        .faq-widget-1 .faq-item.active .faq-toggle::after {\n            color: white;\n        }\n        \n        .faq-widget-1 .faq-item.active .faq-toggle {\n            transform: rotate(180deg);\n        }\n        \n        .faq-widget-1 .faq-answer {\n            display: none;\n            padding: 20px;\n            background: white;\n            border-top: 1px solid #e9ecef;\n        }\n        \n        .faq-widget-1 .faq-answer.show {\n            display: block;\n        }\n        \n        .faq-widget-1 .faq-answer p {\n            margin: 0 0 15px 0;\n            color: #555;\n            line-height: 1.6;\n            font-size: 15px;\n        }\n        \n        .faq-widget-1 .faq-answer p:last-child {\n            margin-bottom: 0;\n        }\n        \n        .faq-widget-1 .faq-image {\n            margin: 20px 0;\n            text-align: center;\n        }\n        \n        .faq-widget-1 .faq-image img {\n            max-width: 100%;\n            height: auto;\n            border-radius: 8px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n        }\n        \n        .faq-widget-1 .loading {\n            text-align: center;\n            padding: 40px;\n            color: #666;\n        }\n        \n        .faq-widget-1 .error {\n            padding: 20px;\n            background: #f8d7da;\n            color: #721c24;\n            border: 1px solid #f5c6cb;\n            border-radius: 4px;\n        }\n        \n        @media (max-width: 768px) {\n            .faq-widget-1 .faq-question h2 {\n                font-size: 14px;\n            }\n        }\n        <\/style>\n        \n        <div id=\"faq-widget-1\" \n             class=\"faq-widget-1\"\n             data-sheet-id=\"\"\n             data-sheet-name=\"Hoja1\"\n             data-published-key=\"2PACX-1vT4E_KhRRy8XxoDwZrj5CuBq4IC8fR0sbj3aLBFhvE1NQkBmwNlmkecJY9-g70DuMocBgCCOnltbmWN\"\n             data-gid=\"2135149465\"\n             data-title=\"\"\n             data-mode=\"expanded\"\n             data-schema=\"yes\"\n             data-microdata=\"yes\"\n             data-show-images=\"yes\">\n            <div class=\"loading\">Chargement des FAQ...<\/div>\n        <\/div>\n        \n        <script>\n        (function() {\n            const container = document.getElementById('faq-widget-1');\n            const sheetId = container.dataset.sheetId;\n            const sheetName = container.dataset.sheetName;\n            const publishedKey = container.dataset.publishedKey;\n            const gid = container.dataset.gid;\n            const title = container.dataset.title;\n            const mode = container.dataset.mode;\n            const generateSchema = container.dataset.schema === 'yes';\n            const generateMicrodata = container.dataset.microdata === 'yes';\n            const showImages = container.dataset.showImages === 'yes';\n            \n            let faqData = [];\n            \n            console.log('FAQ Widget iniciando:', {sheetId, sheetName, publishedKey, gid});\n            \n            async function loadFAQ() {\n                try {\n                    let url;\n                    \n                    \/\/ Prioridad 1: URL publicada con clave y GID\n                    if (publishedKey && gid) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/e\/${publishedKey}\/pub?output=csv&gid=${gid}`;\n                        console.log('Usando URL publicada con GID:', url);\n                    }\n                    \/\/ Prioridad 2: URL publicada sin GID\n                    else if (publishedKey) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/e\/${publishedKey}\/pub?output=csv`;\n                        console.log('Usando URL publicada:', url);\n                    }\n                    \/\/ Prioridad 3: Intentar con gviz\n                    else if (sheetId && sheetName) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/${sheetId}\/gviz\/tq?tqx=out:csv&sheet=${encodeURIComponent(sheetName)}`;\n                        console.log('Usando gviz con pesta\u00f1a:', url);\n                    }\n                    \/\/ Prioridad 4: Gviz sin pesta\u00f1a\n                    else if (sheetId) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/${sheetId}\/gviz\/tq?tqx=out:csv`;\n                        console.log('Usando gviz b\u00e1sico:', url);\n                    }\n                    \n                    const response = await fetch(url);\n                    \n                    if (!response.ok) {\n                        throw new Error(`Error HTTP: ${response.status}`);\n                    }\n                    \n                    const text = await response.text();\n                    console.log('CSV recibido, longitud:', text.length);\n                    \n                    if (text.includes('<!DOCTYPE') || text.includes('<html')) {\n                        throw new Error('El documento no est\u00e1 compartido correctamente');\n                    }\n                    \n                    faqData = parseCSV(text);\n                    renderFAQ(faqData);\n                    \n                    if (generateSchema) {\n                        generateSchemaJSON(faqData);\n                    }\n                    \n                } catch (error) {\n                    console.error('Error:', error);\n                    container.innerHTML = `\n                        <div class=\"error\">\n                            <strong>Error al cargar las preguntas:<\/strong><br>\n                            ${error.message}<br>\n                            <small>Verifica la configuraci\u00f3n del shortcode.<\/small>\n                        <\/div>\n                    `;\n                }\n            }\n            \n            function parseCSV(csv) {\n                \/\/ Normaliza saltos de l\u00ednea y elimina BOM\n                if (!csv || typeof csv !== 'string') return [];\n                let text = csv.replace(\/\\r\\n\/g, '\\n').replace(\/\\r\/g, '\\n');\n                if (text.charCodeAt(0) === 0xFEFF) {\n                    text = text.slice(1);\n                }\n                const rows = parseCSVRows(text);\n                if (!rows || rows.length === 0) return [];\n\n                \/\/ Detectar fila de cabecera de forma flexible (soporta acentos y may\u00fasculas)\n                const isHeader = (cols) => {\n                    const norm = cols.map(normalizeHeader);\n                    return (\n                        norm.some(c => c.includes('pregunta') || c.includes('question')) ||\n                        norm.some(c => c.includes('respuesta') || c.includes('answer') || c.includes('contenido')) ||\n                        norm.some(c => c.includes('categoria'))\n                    );\n                };\n\n                let startIndex = 0;\n                let header = rows[0];\n                if (isHeader(header)) {\n                    startIndex = 1;\n                } else {\n                    \/\/ Buscar cabecera en las primeras 5 filas por si hay l\u00edneas en blanco al inicio\n                    for (let i = 1; i < Math.min(5, rows.length); i++) {\n                        if (isHeader(rows[i])) {\n                            header = rows[i];\n                            startIndex = i + 1;\n                            break;\n                        }\n                    }\n                }\n\n                \/\/ \u00cdndices de columnas\n                const headerNorm = (header || []).map(normalizeHeader);\n                const catIndex = headerNorm.findIndex(h => h.includes('categoria'));\n                let qIndex = headerNorm.findIndex(h => h.includes('pregunta') || h.includes('question'));\n                let aIndex = headerNorm.findIndex(h => h.includes('respuesta') || h.includes('answer') || h.includes('contenido'));\n                let imgIndex = headerNorm.findIndex(h => h.includes('imagen') || h.includes('image'));\n\n                \/\/ Fallback robusto si no hay cabeceras claras\n                if (qIndex === -1 && aIndex === -1) {\n                    \/\/ Evaluar n\u00famero de columnas t\u00edpico en las primeras filas\n                    const sampleCount = Math.min(10, rows.length);\n                    const counts = {};\n                    for (let i = 0; i < sampleCount; i++) {\n                        const len = (rows[i] || []).length;\n                        if (!len) continue;\n                        counts[len] = (counts[len] || 0) + 1;\n                    }\n                    let typicalCols = 0, maxFreq = -1;\n                    Object.keys(counts).forEach(k => {\n                        const n = parseInt(k, 10);\n                        if (counts[k] > maxFreq) { maxFreq = counts[k]; typicalCols = n; }\n                    });\n\n                    if (typicalCols >= 3) {\n                        \/\/ Asumimos formato: CATEGOR\u00cdA | PREGUNTA | RESPUESTA\n                        qIndex = 1;\n                        aIndex = 2;\n                    } else {\n                        \/\/ Asumimos formato: PREGUNTA | RESPUESTA\n                        qIndex = 0;\n                        aIndex = 1;\n                    }\n                    \/\/ No asumir imagen por defecto para evitar confundir RESPUESTA con IMAGEN\n                    imgIndex = -1;\n                    startIndex = 0; \/\/ asume que no hay cabecera\n                } else {\n                    \/\/ Ajustes cuando existe columna de categor\u00eda en cabecera\n                    if (catIndex !== -1 && headerNorm.length >= 3) {\n                        if (qIndex === -1) qIndex = 1; \/\/ despu\u00e9s de categor\u00eda\n                        if (aIndex === -1) aIndex = 2; \/\/ respuesta en tercera columna\n                    } else {\n                        if (qIndex === -1) qIndex = 0;\n                        if (aIndex === -1) aIndex = qIndex === 0 ? 1 : 0;\n                    }\n                }\n\n                const result = [];\n                for (let i = startIndex; i < rows.length; i++) {\n                    const row = rows[i];\n                    if (!row || row.length === 0) continue;\n\n                    \/\/ Unir columnas sobrantes dentro de la respuesta en caso de separadores accidentales\n                    let question = (row[qIndex] || '').trim();\n                    let answer = '';\n                    if (row.length > Math.max(aIndex, qIndex)) {\n                        \/\/ La respuesta puede abarcar m\u00faltiples columnas si hay comas sueltas; las unimos\n                        const answerParts = row.slice(aIndex);\n                        answer = (answerParts.join(',') || '').trim();\n                    } else {\n                        answer = (row[aIndex] || '').trim();\n                    }\n                    const image = imgIndex !== -1 ? (row[imgIndex] || '').trim() : '';\n\n                    if (!question && !answer) continue;\n                    if (question && answer) {\n                        result.push({\n                            question: question,\n                            answer: formatAnswer(answer),\n                            image: image\n                        });\n                    }\n                }\n\n                console.log('Preguntas parseadas:', result.length);\n                return result;\n            }\n\n            \/\/ Parser robusto de CSV (soporta comillas y saltos de l\u00ednea dentro de campos)\n            function parseCSVRows(text) {\n                const rows = [];\n                let row = [];\n                let field = '';\n                let inQuotes = false;\n\n                for (let i = 0; i < text.length; i++) {\n                    const char = text[i];\n\n                    if (char === '\"') {\n                        if (inQuotes) {\n                            \/\/ Escapar comillas dobles dentro de un campo entrecomillado\n                            if (text[i + 1] === '\"') {\n                                field += '\"';\n                                i++; \/\/ saltar la segunda comilla\n                            } else {\n                                inQuotes = false;\n                            }\n                        } else {\n                            inQuotes = true;\n                        }\n                    } else if (char === ',' && !inQuotes) {\n                        row.push(field);\n                        field = '';\n                    } else if (char === '\\n' && !inQuotes) {\n                        row.push(field);\n                        \/\/ Limpia comillas envolventes y espacios\n                        rows.push(row.map(s => (s || '').replace(\/^\"|\"$\/g, '').trim()));\n                        row = [];\n                        field = '';\n                    } else {\n                        field += char;\n                    }\n                }\n\n                \/\/ \u00daltimo campo\/fila si no termina con salto de l\u00ednea\n                if (field.length > 0 || row.length > 0) {\n                    row.push(field);\n                    rows.push(row.map(s => (s || '').replace(\/^\"|\"$\/g, '').trim()));\n                }\n\n                return rows;\n            }\n\n            function normalizeHeader(str) {\n                return (str || '')\n                    .toString()\n                    .trim()\n                    .toLowerCase()\n                    .normalize('NFD')\n                    .replace(\/[\\u0300-\\u036f]\/g, ''); \/\/ elimina acentos\n            }\n\n\n\n            function formatAnswer(text) {\n                if (!text) return '';\n                \n                text = text.replace(\/\\\\n\/g, '<br>');\n                text = text.replace(\/\\n\/g, '<br>');\n                text = text.replace(\/\\*\\*(.*?)\\*\\*\/g, '<strong>$1<\/strong>');\n                text = text.replace(\/\\*(.*?)\\*\/g, '<em>$1<\/em>');\n                \n                return text;\n            }\n            \n            function processGoogleDriveImage(url) {\n                if (!url || !showImages) return '';\n                \n                let imageUrl = '';\n                \n                \/\/ Si ya es una URL de thumbnail\n                if (url.includes('drive.google.com\/thumbnail?')) {\n                    imageUrl = url;\n                }\n                \/\/ Detectar si es un enlace de Google Drive\n                else if (url.includes('drive.google.com')) {\n                    \/\/ Extraer el ID del archivo\n                    const match = url.match(\/\\\/file\\\/d\\\/([a-zA-Z0-9-_]+)\/);\n                    if (match) {\n                        const fileId = match[1];\n                        imageUrl = `https:\/\/drive.google.com\/thumbnail?id=${fileId}&sz=w1000`;\n                    }\n                }\n                \/\/ Si es una URL directa\n                else if (url.match(\/\\.(jpg|jpeg|png|gif|webp)$\/i) || url.includes('http')) {\n                    imageUrl = url;\n                }\n                \n                if (imageUrl) {\n                    return `\n                        <div class=\"faq-image\">\n                            <img decoding=\"async\" src=\"${imageUrl}\" alt=\"Imagen relacionada\" loading=\"lazy\">\n                        <\/div>\n                    `;\n                }\n                \n                return '';\n            }\n            \n            function renderFAQ(data) {\n                if (data.length === 0) {\n                    container.innerHTML = '<p>No se encontraron preguntas.<\/p>';\n                    return;\n                }\n                \n                let html = '';\n                \n                if (title) {\n                    html += `<h1 class=\"faq-main-title\">${title}<\/h1>`;\n                }\n                \n                html += '<div class=\"faq-content\">';\n                \n                data.forEach((item, index) => {\n                    const itemId = `faq-${Date.now()}-${index}`;\n                    \n                    if (generateMicrodata) {\n                        html += `\n                            <article class=\"faq-item\" data-id=\"${itemId}\" \n                                     itemscope itemprop=\"mainEntity\" \n                                     itemtype=\"https:\/\/schema.org\/Question\">\n                                <div class=\"faq-question\">\n                                    <h2 itemprop=\"name\">${item.question}<\/h2>\n                                    <span class=\"faq-toggle\"><\/span>\n                                <\/div>\n                                <div class=\"faq-answer\" itemscope itemprop=\"acceptedAnswer\" \n                                     itemtype=\"https:\/\/schema.org\/Answer\">\n                                    <div itemprop=\"text\">\n                                        <p>${item.answer}<\/p>\n                                        ${processGoogleDriveImage(item.image)}\n                                    <\/div>\n                                <\/div>\n                            <\/article>\n                        `;\n                    } else {\n                        html += `\n                            <article class=\"faq-item\" data-id=\"${itemId}\">\n                                <div class=\"faq-question\">\n                                    <h2>${item.question}<\/h2>\n                                    <span class=\"faq-toggle\"><\/span>\n                                <\/div>\n                                <div class=\"faq-answer\">\n                                    <p>${item.answer}<\/p>\n                                    ${processGoogleDriveImage(item.image)}\n                                <\/div>\n                            <\/article>\n                        `;\n                    }\n                });\n                \n                html += '<\/div>';\n                \n                container.innerHTML = html;\n                \n                \/\/ Setup accordion\n                setupAccordion();\n            }\n            \n            function setupAccordion() {\n                container.querySelectorAll('.faq-question').forEach(q => {\n                    q.addEventListener('click', function() {\n                        const item = this.closest('.faq-item');\n                        const answer = item.querySelector('.faq-answer');\n                        const wasActive = item.classList.contains('active');\n                        \n                        \/\/ Modo accordion: cerrar otros\n                        if (mode === 'accordion') {\n                            container.querySelectorAll('.faq-item.active').forEach(activeItem => {\n                                if (activeItem !== item) {\n                                    activeItem.classList.remove('active');\n                                    activeItem.querySelector('.faq-answer').classList.remove('show');\n                                }\n                            });\n                        }\n                        \n                        \/\/ Toggle actual\n                        if (wasActive) {\n                            item.classList.remove('active');\n                            answer.classList.remove('show');\n                        } else {\n                            item.classList.add('active');\n                            answer.classList.add('show');\n                        }\n                    });\n                });\n            }\n            \n            function generateSchemaJSON(data) {\n                const faqItems = data.map(item => ({\n                    \"@type\": \"Question\",\n                    \"name\": item.question,\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": item.answer.replace(\/<[^>]*>\/g, '')\n                    }\n                }));\n                \n                const schema = {\n                    \"@context\": \"https:\/\/schema.org\",\n                    \"@type\": \"FAQPage\",\n                    \"mainEntity\": faqItems\n                };\n                \n                const script = document.createElement('script');\n                script.type = 'application\/ld+json';\n                script.textContent = JSON.stringify(schema);\n                document.head.appendChild(script);\n                \n                console.log('Schema JSON-LD generado con', faqItems.length, 'preguntas');\n            }\n            \n            \/\/ Iniciar\n            loadFAQ();\n        })();\n        <\/script>\n        \n        <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-a01a75f e-flex e-con-boxed wcf-starter-animations-none e-con e-parent\" data-id=\"a01a75f\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-31b23c4 elementor-widget elementor-widget-shortcode\" data-id=\"31b23c4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">        \n        <!-- FAQ Widget Container 2 -->\n        <style>\n        \/* Estilos del FAQ Widget *\/\n        .faq-widget-2 {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n            margin: 20px 0;\n        }\n        \n        .faq-widget-2 .faq-main-title {\n            text-align: center;\n            font-size: 28px;\n            font-weight: 700;\n            color: #333;\n            margin-bottom: 30px;\n            padding-bottom: 15px;\n            border-bottom: 3px solid #333;\n        }\n        \n        .faq-widget-2 .faq-item {\n            border: 1px solid #e9ecef;\n            border-radius: 8px;\n            margin-bottom: 15px;\n            overflow: hidden;\n            transition: all 0.3s ease;\n            background: white;\n        }\n        \n        .faq-widget-2 .faq-item:hover {\n            box-shadow: 0 4px 12px rgba(0,0,0,0.08);\n        }\n        \n        .faq-widget-2 .faq-question {\n            padding: 20px;\n            background: #f8f9fa;\n            cursor: pointer;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            user-select: none;\n            transition: all 0.3s ease;\n        }\n        \n        .faq-widget-2 .faq-question:hover {\n            background: #e9ecef;\n        }\n        \n        .faq-widget-2 .faq-question h2 {\n            margin: 0;\n            font-size: 16px;\n            font-weight: 600;\n            color: #333;\n            flex: 1;\n            line-height: 1.4;\n            padding-right: 20px;\n        }\n        \n        .faq-widget-2 .faq-toggle {\n            width: 20px;\n            height: 20px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            transition: transform 0.3s ease;\n            flex-shrink: 0;\n        }\n        \n        .faq-widget-2 .faq-toggle::after {\n            content: \"\u25bc\";\n            font-size: 12px;\n            color: #666;\n        }\n        \n        .faq-widget-2 .faq-item.active .faq-question {\n            background: #333;\n        }\n        \n        .faq-widget-2 .faq-item.active .faq-question h2 {\n            color: white;\n        }\n        \n        .faq-widget-2 .faq-item.active .faq-toggle::after {\n            color: white;\n        }\n        \n        .faq-widget-2 .faq-item.active .faq-toggle {\n            transform: rotate(180deg);\n        }\n        \n        .faq-widget-2 .faq-answer {\n            display: none;\n            padding: 20px;\n            background: white;\n            border-top: 1px solid #e9ecef;\n        }\n        \n        .faq-widget-2 .faq-answer.show {\n            display: block;\n        }\n        \n        .faq-widget-2 .faq-answer p {\n            margin: 0 0 15px 0;\n            color: #555;\n            line-height: 1.6;\n            font-size: 15px;\n        }\n        \n        .faq-widget-2 .faq-answer p:last-child {\n            margin-bottom: 0;\n        }\n        \n        .faq-widget-2 .faq-image {\n            margin: 20px 0;\n            text-align: center;\n        }\n        \n        .faq-widget-2 .faq-image img {\n            max-width: 100%;\n            height: auto;\n            border-radius: 8px;\n            box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n        }\n        \n        .faq-widget-2 .loading {\n            text-align: center;\n            padding: 40px;\n            color: #666;\n        }\n        \n        .faq-widget-2 .error {\n            padding: 20px;\n            background: #f8d7da;\n            color: #721c24;\n            border: 1px solid #f5c6cb;\n            border-radius: 4px;\n        }\n        \n        @media (max-width: 768px) {\n            .faq-widget-2 .faq-question h2 {\n                font-size: 14px;\n            }\n        }\n        <\/style>\n        \n        <div id=\"faq-widget-2\" \n             class=\"faq-widget-2\"\n             data-sheet-id=\"1AgNSXjMeVeX1eFOqr32gxqvuf-kr-jV8vm9RaEjwXAI\"\n             data-sheet-name=\"buen mal uso\"\n             data-published-key=\"\"\n             data-gid=\"\"\n             data-title=\"\"\n             data-mode=\"accordion\"\n             data-schema=\"yes\"\n             data-microdata=\"no\"\n             data-show-images=\"yes\">\n            <div class=\"loading\">Chargement des FAQ...<\/div>\n        <\/div>\n        \n        <script>\n        (function() {\n            const container = document.getElementById('faq-widget-2');\n            const sheetId = container.dataset.sheetId;\n            const sheetName = container.dataset.sheetName;\n            const publishedKey = container.dataset.publishedKey;\n            const gid = container.dataset.gid;\n            const title = container.dataset.title;\n            const mode = container.dataset.mode;\n            const generateSchema = container.dataset.schema === 'yes';\n            const generateMicrodata = container.dataset.microdata === 'yes';\n            const showImages = container.dataset.showImages === 'yes';\n            \n            let faqData = [];\n            \n            console.log('FAQ Widget iniciando:', {sheetId, sheetName, publishedKey, gid});\n            \n            async function loadFAQ() {\n                try {\n                    let url;\n                    \n                    \/\/ Prioridad 1: URL publicada con clave y GID\n                    if (publishedKey && gid) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/e\/${publishedKey}\/pub?output=csv&gid=${gid}`;\n                        console.log('Usando URL publicada con GID:', url);\n                    }\n                    \/\/ Prioridad 2: URL publicada sin GID\n                    else if (publishedKey) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/e\/${publishedKey}\/pub?output=csv`;\n                        console.log('Usando URL publicada:', url);\n                    }\n                    \/\/ Prioridad 3: Intentar con gviz\n                    else if (sheetId && sheetName) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/${sheetId}\/gviz\/tq?tqx=out:csv&sheet=${encodeURIComponent(sheetName)}`;\n                        console.log('Usando gviz con pesta\u00f1a:', url);\n                    }\n                    \/\/ Prioridad 4: Gviz sin pesta\u00f1a\n                    else if (sheetId) {\n                        url = `https:\/\/docs.google.com\/spreadsheets\/d\/${sheetId}\/gviz\/tq?tqx=out:csv`;\n                        console.log('Usando gviz b\u00e1sico:', url);\n                    }\n                    \n                    const response = await fetch(url);\n                    \n                    if (!response.ok) {\n                        throw new Error(`Error HTTP: ${response.status}`);\n                    }\n                    \n                    const text = await response.text();\n                    console.log('CSV recibido, longitud:', text.length);\n                    \n                    if (text.includes('<!DOCTYPE') || text.includes('<html')) {\n                        throw new Error('El documento no est\u00e1 compartido correctamente');\n                    }\n                    \n                    faqData = parseCSV(text);\n                    renderFAQ(faqData);\n                    \n                    if (generateSchema) {\n                        generateSchemaJSON(faqData);\n                    }\n                    \n                } catch (error) {\n                    console.error('Error:', error);\n                    container.innerHTML = `\n                        <div class=\"error\">\n                            <strong>Error al cargar las preguntas:<\/strong><br>\n                            ${error.message}<br>\n                            <small>Verifica la configuraci\u00f3n del shortcode.<\/small>\n                        <\/div>\n                    `;\n                }\n            }\n            \n            function parseCSV(csv) {\n                \/\/ Normaliza saltos de l\u00ednea y elimina BOM\n                if (!csv || typeof csv !== 'string') return [];\n                let text = csv.replace(\/\\r\\n\/g, '\\n').replace(\/\\r\/g, '\\n');\n                if (text.charCodeAt(0) === 0xFEFF) {\n                    text = text.slice(1);\n                }\n                const rows = parseCSVRows(text);\n                if (!rows || rows.length === 0) return [];\n\n                \/\/ Detectar fila de cabecera de forma flexible (soporta acentos y may\u00fasculas)\n                const isHeader = (cols) => {\n                    const norm = cols.map(normalizeHeader);\n                    return (\n                        norm.some(c => c.includes('pregunta') || c.includes('question')) ||\n                        norm.some(c => c.includes('respuesta') || c.includes('answer') || c.includes('contenido')) ||\n                        norm.some(c => c.includes('categoria'))\n                    );\n                };\n\n                let startIndex = 0;\n                let header = rows[0];\n                if (isHeader(header)) {\n                    startIndex = 1;\n                } else {\n                    \/\/ Buscar cabecera en las primeras 5 filas por si hay l\u00edneas en blanco al inicio\n                    for (let i = 1; i < Math.min(5, rows.length); i++) {\n                        if (isHeader(rows[i])) {\n                            header = rows[i];\n                            startIndex = i + 1;\n                            break;\n                        }\n                    }\n                }\n\n                \/\/ \u00cdndices de columnas\n                const headerNorm = (header || []).map(normalizeHeader);\n                const catIndex = headerNorm.findIndex(h => h.includes('categoria'));\n                let qIndex = headerNorm.findIndex(h => h.includes('pregunta') || h.includes('question'));\n                let aIndex = headerNorm.findIndex(h => h.includes('respuesta') || h.includes('answer') || h.includes('contenido'));\n                let imgIndex = headerNorm.findIndex(h => h.includes('imagen') || h.includes('image'));\n\n                \/\/ Fallback robusto si no hay cabeceras claras\n                if (qIndex === -1 && aIndex === -1) {\n                    \/\/ Evaluar n\u00famero de columnas t\u00edpico en las primeras filas\n                    const sampleCount = Math.min(10, rows.length);\n                    const counts = {};\n                    for (let i = 0; i < sampleCount; i++) {\n                        const len = (rows[i] || []).length;\n                        if (!len) continue;\n                        counts[len] = (counts[len] || 0) + 1;\n                    }\n                    let typicalCols = 0, maxFreq = -1;\n                    Object.keys(counts).forEach(k => {\n                        const n = parseInt(k, 10);\n                        if (counts[k] > maxFreq) { maxFreq = counts[k]; typicalCols = n; }\n                    });\n\n                    if (typicalCols >= 3) {\n                        \/\/ Asumimos formato: CATEGOR\u00cdA | PREGUNTA | RESPUESTA\n                        qIndex = 1;\n                        aIndex = 2;\n                    } else {\n                        \/\/ Asumimos formato: PREGUNTA | RESPUESTA\n                        qIndex = 0;\n                        aIndex = 1;\n                    }\n                    \/\/ No asumir imagen por defecto para evitar confundir RESPUESTA con IMAGEN\n                    imgIndex = -1;\n                    startIndex = 0; \/\/ asume que no hay cabecera\n                } else {\n                    \/\/ Ajustes cuando existe columna de categor\u00eda en cabecera\n                    if (catIndex !== -1 && headerNorm.length >= 3) {\n                        if (qIndex === -1) qIndex = 1; \/\/ despu\u00e9s de categor\u00eda\n                        if (aIndex === -1) aIndex = 2; \/\/ respuesta en tercera columna\n                    } else {\n                        if (qIndex === -1) qIndex = 0;\n                        if (aIndex === -1) aIndex = qIndex === 0 ? 1 : 0;\n                    }\n                }\n\n                const result = [];\n                for (let i = startIndex; i < rows.length; i++) {\n                    const row = rows[i];\n                    if (!row || row.length === 0) continue;\n\n                    \/\/ Unir columnas sobrantes dentro de la respuesta en caso de separadores accidentales\n                    let question = (row[qIndex] || '').trim();\n                    let answer = '';\n                    if (row.length > Math.max(aIndex, qIndex)) {\n                        \/\/ La respuesta puede abarcar m\u00faltiples columnas si hay comas sueltas; las unimos\n                        const answerParts = row.slice(aIndex);\n                        answer = (answerParts.join(',') || '').trim();\n                    } else {\n                        answer = (row[aIndex] || '').trim();\n                    }\n                    const image = imgIndex !== -1 ? (row[imgIndex] || '').trim() : '';\n\n                    if (!question && !answer) continue;\n                    if (question && answer) {\n                        result.push({\n                            question: question,\n                            answer: formatAnswer(answer),\n                            image: image\n                        });\n                    }\n                }\n\n                console.log('Preguntas parseadas:', result.length);\n                return result;\n            }\n\n            \/\/ Parser robusto de CSV (soporta comillas y saltos de l\u00ednea dentro de campos)\n            function parseCSVRows(text) {\n                const rows = [];\n                let row = [];\n                let field = '';\n                let inQuotes = false;\n\n                for (let i = 0; i < text.length; i++) {\n                    const char = text[i];\n\n                    if (char === '\"') {\n                        if (inQuotes) {\n                            \/\/ Escapar comillas dobles dentro de un campo entrecomillado\n                            if (text[i + 1] === '\"') {\n                                field += '\"';\n                                i++; \/\/ saltar la segunda comilla\n                            } else {\n                                inQuotes = false;\n                            }\n                        } else {\n                            inQuotes = true;\n                        }\n                    } else if (char === ',' && !inQuotes) {\n                        row.push(field);\n                        field = '';\n                    } else if (char === '\\n' && !inQuotes) {\n                        row.push(field);\n                        \/\/ Limpia comillas envolventes y espacios\n                        rows.push(row.map(s => (s || '').replace(\/^\"|\"$\/g, '').trim()));\n                        row = [];\n                        field = '';\n                    } else {\n                        field += char;\n                    }\n                }\n\n                \/\/ \u00daltimo campo\/fila si no termina con salto de l\u00ednea\n                if (field.length > 0 || row.length > 0) {\n                    row.push(field);\n                    rows.push(row.map(s => (s || '').replace(\/^\"|\"$\/g, '').trim()));\n                }\n\n                return rows;\n            }\n\n            function normalizeHeader(str) {\n                return (str || '')\n                    .toString()\n                    .trim()\n                    .toLowerCase()\n                    .normalize('NFD')\n                    .replace(\/[\\u0300-\\u036f]\/g, ''); \/\/ elimina acentos\n            }\n\n\n\n            function formatAnswer(text) {\n                if (!text) return '';\n                \n                text = text.replace(\/\\\\n\/g, '<br>');\n                text = text.replace(\/\\n\/g, '<br>');\n                text = text.replace(\/\\*\\*(.*?)\\*\\*\/g, '<strong>$1<\/strong>');\n                text = text.replace(\/\\*(.*?)\\*\/g, '<em>$1<\/em>');\n                \n                return text;\n            }\n            \n            function processGoogleDriveImage(url) {\n                if (!url || !showImages) return '';\n                \n                let imageUrl = '';\n                \n                \/\/ Si ya es una URL de thumbnail\n                if (url.includes('drive.google.com\/thumbnail?')) {\n                    imageUrl = url;\n                }\n                \/\/ Detectar si es un enlace de Google Drive\n                else if (url.includes('drive.google.com')) {\n                    \/\/ Extraer el ID del archivo\n                    const match = url.match(\/\\\/file\\\/d\\\/([a-zA-Z0-9-_]+)\/);\n                    if (match) {\n                        const fileId = match[1];\n                        imageUrl = `https:\/\/drive.google.com\/thumbnail?id=${fileId}&sz=w1000`;\n                    }\n                }\n                \/\/ Si es una URL directa\n                else if (url.match(\/\\.(jpg|jpeg|png|gif|webp)$\/i) || url.includes('http')) {\n                    imageUrl = url;\n                }\n                \n                if (imageUrl) {\n                    return `\n                        <div class=\"faq-image\">\n                            <img decoding=\"async\" src=\"${imageUrl}\" alt=\"Imagen relacionada\" loading=\"lazy\">\n                        <\/div>\n                    `;\n                }\n                \n                return '';\n            }\n            \n            function renderFAQ(data) {\n                if (data.length === 0) {\n                    container.innerHTML = '<p>No se encontraron preguntas.<\/p>';\n                    return;\n                }\n                \n                let html = '';\n                \n                if (title) {\n                    html += `<h1 class=\"faq-main-title\">${title}<\/h1>`;\n                }\n                \n                html += '<div class=\"faq-content\">';\n                \n                data.forEach((item, index) => {\n                    const itemId = `faq-${Date.now()}-${index}`;\n                    \n                    if (generateMicrodata) {\n                        html += `\n                            <article class=\"faq-item\" data-id=\"${itemId}\" \n                                     itemscope itemprop=\"mainEntity\" \n                                     itemtype=\"https:\/\/schema.org\/Question\">\n                                <div class=\"faq-question\">\n                                    <h2 itemprop=\"name\">${item.question}<\/h2>\n                                    <span class=\"faq-toggle\"><\/span>\n                                <\/div>\n                                <div class=\"faq-answer\" itemscope itemprop=\"acceptedAnswer\" \n                                     itemtype=\"https:\/\/schema.org\/Answer\">\n                                    <div itemprop=\"text\">\n                                        <p>${item.answer}<\/p>\n                                        ${processGoogleDriveImage(item.image)}\n                                    <\/div>\n                                <\/div>\n                            <\/article>\n                        `;\n                    } else {\n                        html += `\n                            <article class=\"faq-item\" data-id=\"${itemId}\">\n                                <div class=\"faq-question\">\n                                    <h2>${item.question}<\/h2>\n                                    <span class=\"faq-toggle\"><\/span>\n                                <\/div>\n                                <div class=\"faq-answer\">\n                                    <p>${item.answer}<\/p>\n                                    ${processGoogleDriveImage(item.image)}\n                                <\/div>\n                            <\/article>\n                        `;\n                    }\n                });\n                \n                html += '<\/div>';\n                \n                container.innerHTML = html;\n                \n                \/\/ Setup accordion\n                setupAccordion();\n            }\n            \n            function setupAccordion() {\n                container.querySelectorAll('.faq-question').forEach(q => {\n                    q.addEventListener('click', function() {\n                        const item = this.closest('.faq-item');\n                        const answer = item.querySelector('.faq-answer');\n                        const wasActive = item.classList.contains('active');\n                        \n                        \/\/ Modo accordion: cerrar otros\n                        if (mode === 'accordion') {\n                            container.querySelectorAll('.faq-item.active').forEach(activeItem => {\n                                if (activeItem !== item) {\n                                    activeItem.classList.remove('active');\n                                    activeItem.querySelector('.faq-answer').classList.remove('show');\n                                }\n                            });\n                        }\n                        \n                        \/\/ Toggle actual\n                        if (wasActive) {\n                            item.classList.remove('active');\n                            answer.classList.remove('show');\n                        } else {\n                            item.classList.add('active');\n                            answer.classList.add('show');\n                        }\n                    });\n                });\n            }\n            \n            function generateSchemaJSON(data) {\n                const faqItems = data.map(item => ({\n                    \"@type\": \"Question\",\n                    \"name\": item.question,\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": item.answer.replace(\/<[^>]*>\/g, '')\n                    }\n                }));\n                \n                const schema = {\n                    \"@context\": \"https:\/\/schema.org\",\n                    \"@type\": \"FAQPage\",\n                    \"mainEntity\": faqItems\n                };\n                \n                const script = document.createElement('script');\n                script.type = 'application\/ld+json';\n                script.textContent = JSON.stringify(schema);\n                document.head.appendChild(script);\n                \n                console.log('Schema JSON-LD generado con', faqItems.length, 'preguntas');\n            }\n            \n            \/\/ Iniciar\n            loadFAQ();\n        })();\n        <\/script>\n        \n        <\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-7a49f97 e-flex e-con-boxed wcf-starter-animations-none e-con e-parent\" data-id=\"7a49f97\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-80df7d0 elementor-widget elementor-widget-html\" data-id=\"80df7d0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"test-moodul-faq\"><\/div>\n<script>\n(async function() {\n    const container = document.getElementById('test-moodul-faq');\n    \n    \/\/ ID CORRECTO\n    const SHEET_ID = '1J9GlMU9eMqMG4IbTDcCnPytzTji4NWO3SujQLUKSk84';\n    const SHEET_NAME = 'faq_proceso_moodul';\n    \n    try {\n        const url = `https:\/\/docs.google.com\/spreadsheets\/d\/${SHEET_ID}\/gviz\/tq?tqx=out:csv&sheet=${encodeURIComponent(SHEET_NAME)}`;\n        console.log('Cargando desde:', url);\n        \n        const response = await fetch(url);\n        const text = await response.text();\n        \n        \/\/ Mostrar primeras l\u00edneas para verificar\n        const lines = text.split('\\n').slice(0, 5);\n        container.innerHTML = `\n            <h3>\u2705 Datos cargados correctamente<\/h3>\n            <p><strong>Sheet ID:<\/strong> ${SHEET_ID}<\/p>\n            <p><strong>Pesta\u00f1a:<\/strong> ${SHEET_NAME}<\/p>\n            <p><strong>Primeras l\u00edneas:<\/strong><\/p>\n            <pre style=\"background: #f5f5f5; padding: 10px; overflow-x: auto;\">\n${lines.join('\\n')}\n            <\/pre>\n            <p><strong>Total caracteres:<\/strong> ${text.length}<\/p>\n        `;\n    } catch(error) {\n        container.innerHTML = `\n            <h3>\u274c Error<\/h3>\n            <p>${error.message}<\/p>\n        `;\n    }\n})();\n<\/script>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-2ce8491 e-flex e-con-boxed wcf-starter-animations-none e-con e-parent\" data-id=\"2ce8491\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d699cd1 elementor-widget elementor-widget-html\" data-id=\"d699cd1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"faq-moodul-widget\" class=\"faq-moodul-container\"><\/div>\n\n<style>\n.faq-moodul-container {\n    max-width: 100%;\n    margin: 20px 0;\n    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n.faq-moodul-category {\n    margin-bottom: 30px;\n}\n\n.faq-moodul-category-title {\n    font-size: 22px;\n    font-weight: 700;\n    color: #333;\n    margin-bottom: 20px;\n    padding-bottom: 10px;\n    border-bottom: 2px solid #e9ecef;\n}\n\n.faq-moodul-item {\n    border: 1px solid #e9ecef;\n    border-radius: 8px;\n    margin-bottom: 15px;\n    background: white;\n    overflow: hidden;\n    transition: all 0.3s ease;\n}\n\n.faq-moodul-item:hover {\n    box-shadow: 0 4px 12px rgba(0,0,0,0.08);\n}\n\n.faq-moodul-question {\n    padding: 20px;\n    background: #f8f9fa;\n    cursor: pointer;\n    user-select: none;\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n}\n\n.faq-moodul-question:hover {\n    background: #e9ecef;\n}\n\n.faq-moodul-question h2 {\n    margin: 0;\n    font-size: 16px;\n    font-weight: 600;\n    color: #333;\n    flex: 1;\n    padding-right: 20px;\n    line-height: 1.4;\n}\n\n.faq-moodul-item.active .faq-moodul-question {\n    background: #333;\n}\n\n.faq-moodul-item.active .faq-moodul-question h2 {\n    color: white;\n}\n\n.faq-moodul-answer {\n    display: none;\n    padding: 20px;\n    background: white;\n    border-top: 1px solid #e9ecef;\n}\n\n.faq-moodul-answer.show {\n    display: block;\n}\n\n.faq-moodul-answer p {\n    color: #555;\n    line-height: 1.6;\n    font-size: 15px;\n    margin: 0;\n    padding: 0;\n}\n\n.faq-moodul-toggle {\n    width: 20px;\n    height: 20px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    transition: transform 0.3s ease;\n}\n\n.faq-moodul-item.active .faq-moodul-toggle {\n    transform: rotate(180deg);\n}\n\n.faq-moodul-toggle::after {\n    content: \"\u25bc\";\n    font-size: 12px;\n    color: #666;\n}\n\n.faq-moodul-item.active .faq-moodul-toggle::after {\n    color: white;\n}\n\n.loading-moodul {\n    text-align: center;\n    padding: 40px;\n    color: #666;\n}\n\n.tab-selector {\n    display: flex;\n    gap: 10px;\n    margin-bottom: 20px;\n    flex-wrap: wrap;\n}\n\n.tab-button {\n    padding: 10px 20px;\n    background: #f8f9fa;\n    border: 2px solid #e9ecef;\n    border-radius: 25px;\n    cursor: pointer;\n    font-weight: 500;\n    transition: all 0.3s ease;\n}\n\n.tab-button:hover {\n    background: #e9ecef;\n}\n\n.tab-button.active {\n    background: #333;\n    color: white;\n    border-color: #333;\n}\n<\/style>\n\n<script>\n(function() {\n    'use strict';\n    \n    const container = document.getElementById('faq-moodul-widget');\n    \n    \/\/ Configuraci\u00f3n de pesta\u00f1as disponibles\n    const SHEETS = {\n        'faq_ampliaciones_modificaciones': 0,\n        'faq_ventajas_casas_modulares': 1,\n        'faq_sistema_constructivo_mstsk': 2,\n        'faq_eficiencia_energetica_soste': 3,\n        'faq_diseno_personalizacion': 4\n    };\n    \n    \/\/ GID de cada pesta\u00f1a (se obtiene de la URL cuando navegas a cada pesta\u00f1a)\n    const SHEET_GIDS = {\n        'faq_ampliaciones_modificaciones': '2135149465',\n        'faq_ventajas_casas_modulares': '0', \/\/ Ajusta estos valores\n        'faq_sistema_constructivo_mstsk': '1', \/\/ seg\u00fan tu sheet\n        'faq_eficiencia_energetica_soste': '2',\n        'faq_diseno_personalizacion': '3'\n    };\n    \n    let currentData = {};\n    \n    container.innerHTML = '<div class=\"loading-moodul\">Cargando preguntas frecuentes...<\/div>';\n    \n    function parseCSV(csv) {\n        const lines = csv.split('\\n');\n        const result = {};\n        \n        for (let i = 1; i < lines.length; i++) {\n            const line = lines[i].trim();\n            if (!line) continue;\n            \n            \/\/ Parse mejorado\n            let parts = [];\n            let current = '';\n            let inQuotes = false;\n            \n            for (let j = 0; j < line.length; j++) {\n                const char = line[j];\n                \n                if (char === '\"') {\n                    inQuotes = !inQuotes;\n                } else if (char === ',' && !inQuotes) {\n                    parts.push(current.trim());\n                    current = '';\n                } else {\n                    current += char;\n                }\n            }\n            parts.push(current.trim());\n            \n            if (parts.length >= 3) {\n                let category = parts[0].replace(\/^\"|\"$\/g, '').trim();\n                let question = parts[1].replace(\/^\"|\"$\/g, '').trim();\n                let answer = parts[2].replace(\/^\"|\"$\/g, '').trim();\n                \n                \/\/ Formatear respuesta\n                answer = answer.replace(\/\\\\n\/g, '<br>');\n                answer = answer.replace(\/\\n\/g, '<br>');\n                \n                if (category && question) {\n                    if (!result[category]) {\n                        result[category] = [];\n                    }\n                    \n                    result[category].push({\n                        question: question,\n                        answer: answer || 'Informaci\u00f3n disponible pr\u00f3ximamente.'\n                    });\n                }\n            }\n        }\n        \n        return result;\n    }\n    \n    function renderFAQ(data) {\n        let html = '';\n        \n        if (Object.keys(data).length === 0) {\n            html = '<p>No se encontraron preguntas en esta secci\u00f3n.<\/p>';\n        } else {\n            Object.keys(data).forEach(category => {\n                html += `<div class=\"faq-moodul-category\">`;\n                html += `<div class=\"faq-moodul-category-title\">${category}<\/div>`;\n                \n                data[category].forEach((item, index) => {\n                    html += `\n                        <div class=\"faq-moodul-item\" data-index=\"${index}\">\n                            <div class=\"faq-moodul-question\">\n                                <h2>${item.question}<\/h2>\n                                <span class=\"faq-moodul-toggle\"><\/span>\n                            <\/div>\n                            <div class=\"faq-moodul-answer\">\n                                <p>${item.answer}<\/p>\n                            <\/div>\n                        <\/div>\n                    `;\n                });\n                \n                html += `<\/div>`;\n            });\n        }\n        \n        \/\/ Actualizar solo el contenido FAQ, no los tabs\n        const faqContent = container.querySelector('#faq-content');\n        if (faqContent) {\n            faqContent.innerHTML = html;\n        } else {\n            container.innerHTML = '<div id=\"faq-content\">' + html + '<\/div>';\n        }\n        \n        setupAccordion();\n    }\n    \n    function setupAccordion() {\n        container.querySelectorAll('.faq-moodul-question').forEach(question => {\n            \/\/ Remover listeners anteriores\n            const newQuestion = question.cloneNode(true);\n            question.parentNode.replaceChild(newQuestion, question);\n            \n            newQuestion.addEventListener('click', function() {\n                const item = this.closest('.faq-moodul-item');\n                const answer = item.querySelector('.faq-moodul-answer');\n                \n                if (item.classList.contains('active')) {\n                    item.classList.remove('active');\n                    answer.classList.remove('show');\n                } else {\n                    \/\/ Cerrar otros\n                    container.querySelectorAll('.faq-moodul-item.active').forEach(activeItem => {\n                        activeItem.classList.remove('active');\n                        activeItem.querySelector('.faq-moodul-answer').classList.remove('show');\n                    });\n                    \n                    item.classList.add('active');\n                    answer.classList.add('show');\n                }\n            });\n        });\n    }\n    \n    function loadSheet(sheetName) {\n        const gid = SHEET_GIDS[sheetName] || '0';\n        \n        \/\/ URL para acceder a una pesta\u00f1a espec\u00edfica\n        const url = `https:\/\/docs.google.com\/spreadsheets\/d\/e\/2PACX-1vT4E_KhRRy8XxoDwZrj5CuBq4IC8fR0sbj3aLBFhvE1NQkBmwNlmkecJY9-g70DuMocBgCCOnltbmWN\/pub?output=csv&gid=${gid}`;\n        \n        console.log('Cargando pesta\u00f1a:', sheetName, 'GID:', gid);\n        \n        fetch(url)\n            .then(response => {\n                if (!response.ok) throw new Error('Error HTTP: ' + response.status);\n                return response.text();\n            })\n            .then(csvText => {\n                console.log('CSV cargado para', sheetName, '- Longitud:', csvText.length);\n                const data = parseCSV(csvText);\n                console.log('Datos parseados:', Object.keys(data).length, 'categor\u00edas');\n                currentData = data;\n                renderFAQ(data);\n            })\n            .catch(error => {\n                console.error('Error:', error);\n                const faqContent = container.querySelector('#faq-content') || container;\n                faqContent.innerHTML = `<div style=\"color: red;\">Error al cargar: ${error.message}<\/div>`;\n            });\n    }\n    \n    \/\/ Crear tabs para cambiar entre pesta\u00f1as\n    function createTabs() {\n        let tabsHtml = '<div class=\"tab-selector\">';\n        \n        const tabNames = {\n            'faq_ampliaciones_modificaciones': '\ud83c\udfd7\ufe0f Ampliaciones',\n            'faq_ventajas_casas_modulares': '\ud83c\udfe0 Ventajas',\n            'faq_sistema_constructivo_mstsk': '\ud83d\udd27 Sistema Constructivo',\n            'faq_eficiencia_energetica_soste': '\ud83c\udf31 Eficiencia',\n            'faq_diseno_personalizacion': '\ud83c\udfa8 Dise\u00f1o'\n        };\n        \n        Object.keys(SHEETS).forEach((sheet, index) => {\n            const isActive = index === 0 ? 'active' : '';\n            tabsHtml += `<button class=\"tab-button ${isActive}\" data-sheet=\"${sheet}\">${tabNames[sheet] || sheet}<\/button>`;\n        });\n        \n        tabsHtml += '<\/div><div id=\"faq-content\"><\/div>';\n        \n        container.innerHTML = tabsHtml;\n        \n        \/\/ Event listeners para tabs\n        container.querySelectorAll('.tab-button').forEach(button => {\n            button.addEventListener('click', function() {\n                \/\/ Actualizar active\n                container.querySelectorAll('.tab-button').forEach(b => b.classList.remove('active'));\n                this.classList.add('active');\n                \n                \/\/ Cargar nueva pesta\u00f1a\n                const sheetName = this.dataset.sheet;\n                loadSheet(sheetName);\n            });\n        });\n    }\n    \n    \/\/ Inicializar\n    createTabs();\n    \n    \/\/ Cargar primera pesta\u00f1a por defecto\n    loadSheet('faq_ampliaciones_modificaciones');\n    \n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-3448","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/pages\/3448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/comments?post=3448"}],"version-history":[{"count":13,"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/pages\/3448\/revisions"}],"predecessor-version":[{"id":3464,"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/pages\/3448\/revisions\/3464"}],"wp:attachment":[{"href":"https:\/\/moodul.es\/fr\/wp-json\/wp\/v2\/media?parent=3448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}