/* ============================================ CARGA DE INCLUDES (menu y footer) ============================================ */ async function loadInclude(selector, url) { try { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP ${response.status}`); const html = await response.text(); const container = document.querySelector(selector); if (container) container.innerHTML = html; } catch (error) { console.error(`Error cargando ${url}:`, error); } } /* ============================================ SWITCH DE TEMA (claro por defecto) ============================================ */ function initTheme() { const savedTheme = localStorage.getItem('theme') || 'light'; document.documentElement.setAttribute('data-theme', savedTheme); } function toggleTheme() { const current = document.documentElement.getAttribute('data-theme') || 'light'; const next = current === 'dark' ? 'light' : 'dark'; document.documentElement.setAttribute('data-theme', next); localStorage.setItem('theme', next); } // Ejecutar al cargar la página document.addEventListener('DOMContentLoaded', () => { initTheme(); const themeBtn = document.querySelector('.theme-toggle'); if (themeBtn) { themeBtn.addEventListener('click', toggleTheme); } }); /* ============================================ CALCULAR ANCHO DEL SCROLLBAR ============================================ */ function getScrollbarWidth() { return window.innerWidth - document.documentElement.clientWidth; } function applyScrollbarCompensation() { const scrollbarWidth = getScrollbarWidth(); document.documentElement.style.setProperty('--scrollbar-width', `${scrollbarWidth}px`); } /* ============================================ MENÚ FULLSCREEN ============================================ */ function openMenu() { const menu = document.getElementById('fullscreen-menu'); const overlay = document.getElementById('menu-overlay'); const menuToggle = document.querySelector('.menu-toggle'); if (menu && overlay) { applyScrollbarCompensation(); menu.classList.add('is-open'); overlay.classList.add('is-open'); document.body.classList.add('menu-open'); menuToggle.setAttribute('aria-expanded', 'true'); } } function closeMenu() { const menu = document.getElementById('fullscreen-menu'); const overlay = document.getElementById('menu-overlay'); const menuToggle = document.querySelector('.menu-toggle'); if (menu && overlay) { menu.classList.remove('is-open'); overlay.classList.remove('is-open'); document.body.classList.remove('menu-open'); menuToggle.setAttribute('aria-expanded', 'false'); } } /* ============================================ ACORDEÓN DE SERVICIOS ============================================ */ function initServiciosAccordion() { const accordion = document.getElementById('servicios-accordion'); if (!accordion) { console.log('Acordeón no encontrado'); return; } const items = accordion.querySelectorAll('.servicio-item'); console.log('Items encontrados:', items.length); // Función para activar un item function activateItem(item) { if (item.classList.contains('is-active')) return; accordion.classList.add('has-active'); items.forEach(i => i.classList.remove('is-active')); item.classList.add('is-active'); } // Función para cerrar (volver al estado inicial) function closeAll() { accordion.classList.remove('has-active'); items.forEach(i => i.classList.remove('is-active')); } // Click en cada item para expandirlo items.forEach((item, index) => { console.log(`Agregando listener al item ${index}`); item.addEventListener('click', (e) => { console.log('Click en item:', index); // Si el click fue en el botón cerrar o en un botón CTA, no activar if (e.target.closest('.servicio-close')) { console.log('Click en cerrar'); return; } if (e.target.closest('.btn')) { console.log('Click en botón CTA'); return; } activateItem(item); }); }); // Click en los botones de cerrar const closeButtons = accordion.querySelectorAll('.servicio-close'); closeButtons.forEach((btn, index) => { console.log(`Agregando listener al botón cerrar ${index}`); btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); console.log('Botón cerrar clicked'); closeAll(); }); }); } /* ============================================ INICIALIZACIÓN ============================================ */ document.addEventListener('DOMContentLoaded', async () => { // Cargar menú y footer await Promise.all([ loadInclude('#menu-container', 'includes/menu.html'), loadInclude('#footer-container', 'includes/footer.html') ]); // Inicializar tema initTheme(); // Eventos del tema const themeBtn = document.querySelector('.theme-toggle'); if (themeBtn) themeBtn.addEventListener('click', toggleTheme); // Eventos del menú const menuToggle = document.querySelector('.menu-toggle'); const menuClose = document.querySelector('.menu-close'); const menuOverlay = document.getElementById('menu-overlay'); const menuLinks = document.querySelectorAll('.fullscreen-menu a'); if (menuToggle) menuToggle.addEventListener('click', openMenu); if (menuClose) menuClose.addEventListener('click', closeMenu); if (menuOverlay) menuOverlay.addEventListener('click', closeMenu); // Cerrar menú al hacer clic en un enlace menuLinks.forEach(link => { link.addEventListener('click', closeMenu); }); // Cerrar menú con tecla Escape document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeMenu(); }); // Año dinámico en el footer const yearEl = document.getElementById('current-year'); if (yearEl) yearEl.textContent = new Date().getFullYear(); initServiciosAccordion(); }); /* ============================================ LÓGICA DEL CUESTIONARIO DE DIAGNÓSTICO ============================================ */ // Datos del cuestionario const preguntas = [ { id: 1, titulo: "¿En qué etapa se encuentra hoy tu negocio o proyecto?", opciones: [ { letra: "A", texto: "Creando el proyecto desde cero o formalizando una idea reciente." }, { letra: "B", texto: "Negocio o local activo, pero con una imagen visual que no refleja la calidad de lo que vendo." }, { letra: "C", texto: "En pleno movimiento comercial, pero desbordados para contestar consultas a tiempo." }, { letra: "D", texto: "Establecido y con ventas, pero con un techo de crecimiento que necesitamos romper con publicidad." }, { letra: "E", texto: "Empresa consolidada que busca liderazgo de mercado y delegar todo su marketing de punta a punta." }, { letra: "F", texto: "Emprendimiento personal que gestiono por mi cuenta y donde necesito resolver piezas puntuales." } ] }, { id: 2, titulo: "¿Cuál es tu cuello de botella más urgente hoy?", opciones: [ { letra: "A", texto: "No tengo logo profesional ni página web; me falta confianza frente a la competencia." }, { letra: "B", texto: "No tengo tiempo ni equipo para sacar fotos o grabar videos de buena calidad de mis productos/servicios." }, { letra: "C", texto: "Perdemos clientes potenciales porque tardamos horas en responder WhatsApp o mensajes de redes." }, { letra: "D", texto: "Dependemos del boca a boca o de publicar en redes sin conseguir ventas constantes ni predecibles." }, { letra: "E", texto: "Tenemos acciones aisladas sin una dirección estratégica clara ni medición profesional de métricas." }, { letra: "F", texto: "Me faltan herramientas gráficas o plantillas para diseñar mis propias publicaciones sin perder horas." } ] }, { id: 3, titulo: "¿Con qué infraestructura digital cuentas actualmente?", opciones: [ { letra: "A", texto: "Prácticamente nada formal (solo una idea, perfil personal o logo provisional)." }, { letra: "B", texto: "Perfil comercial en redes sociales, pero con fotos caseras tomadas con el celular." }, { letra: "C", texto: "Redes y/o tienda activa con alto volumen de mensajes directos diarios sin automatizar." }, { letra: "D", texto: "Redes y web en marcha, pero sin campañas activas de publicidad paga (Meta Ads / Google Ads)." }, { letra: "E", texto: "Ecosistema activo (redes, web, pauta), pero disperso entre distintos proveedores sin sinergia." }, { letra: "F", texto: "Manejo mis propios canales y solo requiero recursos gráficos específicos para seguir operando." } ] }, { id: 4, titulo: "¿Qué tipo de solución buscas contratar en Amor y Roma?", opciones: [ { letra: "A", texto: "Proyecto inicial integral: crear mi identidad de marca y mi sitio web para salir al mercado." }, { letra: "B", texto: "Acompañamiento mensual con sesiones presenciales de fotos/video para no preocuparme del contenido." }, { letra: "C", texto: "Implementación tecnológica: automatizaciones inteligentes y asistentes para WhatsApp y redes." }, { letra: "D", texto: "Gestión de campañas de publicidad digital y páginas de venta enfocadas 100% en conversión." }, { letra: "E", texto: "Gestión integral 360°: estrategia de marca completa, pauta multicanal, redes y dirección creativa." }, { letra: "F", texto: "Un entregable puntual (diseño de plantilla, digitalización de logo o sesión única de fotos)." } ] } ]; // Perfiles de resultado const perfiles = { A: { titulo: "Mix Lanzamiento Integral", diagnostico: "Tu proyecto necesita bases sólidas y credibilidad inmediata para competir y generar confianza.", solucion: "Identidad visual completa (Branding) + Diseño Web institucional + Gestión de Redes Sociales (Plan Esencial, $250.000/mes).", cta: "Cotizar Mix Lanzamiento" }, B: { titulo: "Mix Comercio & Presencia Visual", diagnostico: "Tu producto o servicio tiene potencial comercial, pero la calidad visual actual en redes te resta ventas.", solucion: "Plan Premium de Redes Sociales ($650.000/mes), que incluye sesión presencial quincenal de fotos y videos profesionales, 8 reels, asistencia con IA y dirección creativa.", cta: "Ver Plan Premium" }, C: { titulo: "Solución Eficiencia & Automatización", diagnostico: "Tu principal fuga de dinero es el tiempo de respuesta: consultas demoradas son ventas perdidas.", solucion: "Implementación de Automatizaciones con Asistentes Inteligentes para WhatsApp, Instagram y Facebook + Plan Impulso ($420.000/mes) para ordenar el flujo de mensajes.", cta: "Automatizar mi Atención" }, D: { titulo: "Mix Acelerador & Conversión", diagnostico: "Tu marca ya está ordenada visualmente; ahora necesita tráfico calificado y un sistema predecible de atracción de clientes.", solucion: "Servicio de Paid Media (Meta Ads + Google Ads) + Optimización de Landing Page / Catálogo + Creatividades publicitarias de alto impacto.", cta: "Escalar mis Ventas" }, E: { titulo: "Servicio Corporativo 360°", diagnostico: "Tu empresa busca liderazgo absoluto de mercado, unificación de imagen y tercerización completa del departamento de marketing.", solucion: "Plan Élite de Redes ($1.000.000/mes) + Branding Integral (packaging, cartelería física) + Pauta multicanal (Meta, TikTok, Google) + Reportes quincenales avanzados con KPIs.", cta: "Agendar Reunión Estratégica" }, F: { titulo: "Solución Autogestor / Servicios Puntuales", diagnostico: "Buscas resolver necesidades gráficas puntuales sin comprometerte con un abono mensual recurrente.", solucion: "Paquetes individuales a medida: Digitalización y vectorización de logo, Pack de plantillas editables personalizadas o Producción fotográfica por jornada.", cta: "Elegir Servicios Puntuales" } }; // Estado del cuestionario let preguntaActual = 0; let respuestas = []; // Función para calcular el perfil function calcularPerfil(respuestas) { const conteo = { A: 0, B: 0, C: 0, D: 0, E: 0, F: 0 }; respuestas.forEach(r => { if (conteo[r] !== undefined) conteo[r]++; }); // Encontrar la letra con mayor frecuencia let maxVotos = 0; let ganador = respuestas[1]; // Fallback por defecto: pregunta 2 (cuello de botella) for (const letra in conteo) { if (conteo[letra] > maxVotos) { maxVotos = conteo[letra]; ganador = letra; } else if (conteo[letra] === maxVotos && maxVotos > 0) { // Desempate: priorizar la respuesta de la Pregunta 2 if (respuestas[1] === letra) { ganador = letra; } } } return ganador; } // Función para renderizar pregunta function renderizarPregunta() { const contenedor = document.getElementById('cuestionario-contenedor'); const pregunta = preguntas[preguntaActual]; contenedor.innerHTML = `

${pregunta.titulo}

${pregunta.opciones.map(opcion => ` `).join('')}
`; // Agregar event listeners a las opciones document.querySelectorAll('.opcion-tarjeta').forEach(tarjeta => { tarjeta.addEventListener('click', () => seleccionarOpcion(tarjeta.dataset.letra)); }); } // Función para seleccionar opción function seleccionarOpcion(letra) { respuestas[preguntaActual] = letra; // Actualizar barra de progreso const progreso = ((preguntaActual + 1) / preguntas.length) * 100; document.getElementById('progreso-completado').style.width = `${progreso}%`; // Avanzar o mostrar resultado if (preguntaActual < preguntas.length - 1) { preguntaActual++; document.getElementById('progreso-texto').textContent = `Pregunta ${preguntaActual + 1} de ${preguntas.length}`; renderizarPregunta(); } else { mostrarResultado(); } } // Función para mostrar resultado function mostrarResultado() { const perfilLetra = calcularPerfil(respuestas); const perfil = perfiles[perfilLetra]; // Ocultar cuestionario y barra de progreso document.getElementById('cuestionario-contenedor').style.display = 'none'; document.querySelector('.progreso-barra').style.display = 'none'; document.getElementById('progreso-texto').style.display = 'none'; document.getElementById('btn-reiniciar').style.display = 'none'; // Mostrar resultado const resultadoContenedor = document.getElementById('resultado-contenedor'); resultadoContenedor.innerHTML = `

${perfil.titulo}

${perfil.diagnostico}

Solución Amor y Roma:
${perfil.solucion}
`; resultadoContenedor.style.display = 'block'; // Event listener al CTA (placeholder por ahora) document.querySelector('.resultado-cta').addEventListener('click', () => { alert('CTA - Por definir acción'); }); } // Función para reiniciar function reiniciarCuestionario() { preguntaActual = 0; respuestas = []; // Resetear barra de progreso document.getElementById('progreso-completado').style.width = '0%'; document.getElementById('progreso-texto').textContent = 'Pregunta 1 de 4'; // Mostrar elementos document.getElementById('cuestionario-contenedor').style.display = 'block'; document.querySelector('.progreso-barra').style.display = 'block'; document.getElementById('progreso-texto').style.display = 'block'; document.getElementById('btn-reiniciar').style.display = 'inline-flex'; document.getElementById('resultado-contenedor').style.display = 'none'; // Renderizar primera pregunta renderizarPregunta(); } /* ============================================ ANIMACIÓN AUTOMÁTICA DE METODOLOGÍA ============================================ */ function initMetodologiaAnimation() { const section = document.getElementById('metodologia'); if (!section) return; const pasos = section.querySelectorAll('.paso-item'); if (pasos.length === 0) return; let pasoActual = 0; let intervalo; const DURACION_PASO = 2500; // 2.5 segundos por paso // Función para actualizar los estados function actualizarEstados() { pasos.forEach((paso, index) => { // Remover todas las clases de estado paso.classList.remove('active', 'previous'); // Calcular el índice del paso anterior (con loop) const pasoAnterior = (pasoActual - 1 + pasos.length) % pasos.length; // Asignar estados if (index === pasoActual) { paso.classList.add('active'); } else if (index === pasoAnterior) { paso.classList.add('previous'); } }); } // Función para avanzar al siguiente paso function avanzarPaso() { pasoActual = (pasoActual + 1) % pasos.length; actualizarEstados(); } // Función para iniciar la animación function iniciarAnimacion() { // Inicializar con el primer paso activo actualizarEstados(); // Iniciar el intervalo intervalo = setInterval(avanzarPaso, DURACION_PASO); } // Función para detener la animación function detenerAnimacion() { clearInterval(intervalo); } // IntersectionObserver para detectar cuando la sección es visible const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // La sección está visible: iniciar animación iniciarAnimacion(); } else { // La sección no está visible: detener animación detenerAnimacion(); } }); }, { threshold: 0.3 // Se activa cuando el 30% de la sección es visible }); // Observar la sección observer.observe(section); // Inicializar el primer estado (sin animación aún) actualizarEstados(); } // Inicializar cuestionario al cargar la página document.addEventListener('DOMContentLoaded', () => { // Solo inicializar si estamos en la sección de diagnóstico if (document.getElementById('cuestionario-contenedor')) { renderizarPregunta(); // Event listener al botón de reiniciar document.getElementById('btn-reiniciar').addEventListener('click', reiniciarCuestionario); } initMetodologiaAnimation(); });