--c-purple: #4D0E97;
--c-purple-dark: #3a0a72;
--c-magenta: #E62A56;
--c-coral: #EC6849;
--c-purple-bg: rgba(77,14,151,0.06);
--c-magenta-glow: rgba(230,42,86,0.10);
--c-purple-ring: rgba(77,14,151,0.14);
}
html { scroll-behavior: smooth; }
#funnel-container { font-family: 'Encode Sans','Roboto',system-ui,sans-serif; color:#0f172a; background:radial-gradient(circle at top,var(--c-purple-bg),transparent 40%); }
.step { display:none; opacity:0; transform:translateY(10px); }
.step.active { display:block; animation:fadeInUp 0.32s ease forwards; }
@keyframes fadeInUp { from{opacity:0;transform:translateY(10px)} to{opacity:1;transform:translateY(0)} }
.option-card { background:#fff; border:1px solid #e2e8f0; transition:all 0.2s ease; box-shadow:0 2px 10px rgba(15,23,42,0.04); cursor:pointer; -webkit-tap-highlight-color:transparent; }
.option-card:hover { transform:translateY(-2px); border-color:var(--c-magenta); box-shadow:0 10px 25px var(--c-magenta-glow); }
.option-card.active { border-color:var(--c-purple); background:linear-gradient(180deg,#f3ecfd 0%,#ffffff 100%); box-shadow:0 0 0 3px var(--c-purple-ring); }
.counter-btn { width:40px;height:40px;border-radius:9999px;border:1px solid #d1d5db;background:#fff;font-size:1.2rem;display:inline-flex;align-items:center;justify-content:center;transition:all 0.2s ease;cursor:pointer;flex-shrink:0;-webkit-tap-highlight-color:transparent; }
@media(min-width:640px){.counter-btn{width:46px;height:46px;font-size:1.4rem}}
.counter-btn:hover:not(:disabled){border-color:var(--c-purple);transform:scale(1.05)}
.progress-bar{transition:width 0.3s ease}
.loader-ring{width:64px;height:64px;border-radius:9999px;border:5px solid #ede9f6;border-top-color:var(--c-purple);animation:spin 0.9s linear infinite;margin:0 auto}
@media(min-width:640px){.loader-ring{width:74px;height:74px;border-width:6px}}
@keyframes spin{to{transform:rotate(360deg)}}
.pulse-dot{animation:pulseDot 1.2s infinite}
@keyframes pulseDot{0%,100%{transform:scale(0.95);opacity:0.6}50%{transform:scale(1.08);opacity:1}}
.input-error{border-color:#e3232c!important;box-shadow:0 0 0 4px rgba(227,35,44,0.12)!important}
@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}50%{transform:translateX(5px)}75%{transform:translateX(-5px)}}
.shake{animation:shake 0.4s ease-in-out}
.hidden-honeypot{position:absolute!important;left:-9999px!important;opacity:0!important;pointer-events:none!important}
.device-img{width:48px;height:48px;object-fit:contain;background:white;padding:4px;border-radius:8px;border:1px solid #e2e8f0}
.tip-box{background:#f3ecfd;border:1px solid #ddd0f5;border-radius:12px;padding:10px 14px;font-size:0.78rem;color:#3a0a72;margin-bottom:16px;line-height:1.5}
.tip-box strong{font-weight:700}
.btn-primary{background:var(--c-purple);color:#fff;transition:background 0.2s ease}
.btn-primary:hover{background:var(--c-purple-dark)}
input:focus,select:focus{outline:none;border-color:var(--c-purple)!important;box-shadow:0 0 0 4px var(--c-purple-ring)!important}
#resumeBanner{background:linear-gradient(135deg,#f3ecfd,#fdf4ff);border:1px solid #ddd0f5;border-radius:16px;padding:14px 18px;margin-bottom:16px;display:none}
details>summary{list-style:none}
details>summary::-webkit-details-marker{display:none}
★★★★★ 4,9 en Google
+200 hogares protegidos en Murcia
Instalación en 24-48 h
Tecnología avanzada de seguridad inalámbrica
Configura tu Sistema de Alarma
Sistema AirShield · Detección inteligente · Sin cuotas de central
¿Continuar donde lo dejaste?
Tenemos tu configuración guardada
11%
Paso 1 de 9
¿Qué deseas proteger?
Hasta ~120 m² · Accesos en una planta · PIR-Cam cubre el salón
Terraza o patio propio · Kit reforzado con 2 PIR-Cam
Superficie amplia · Incluye pulsador de pánico y doble PIR
Dos plantas y acceso trasero · Escaleras y patios protegidos
Paso 2 de 9
Accesos directos
Puertas principales
Acceso desde portal o calle
1
Puertas traseras o patios
Acceso desde garaje, terraza o patio
0
Paso 3 de 9
¿Tienes zonas exteriores?
Puedes marcar todas las que tengas
Perímetro abierto · Fotodetector o cámara TiOC perimetral
Espacio semicerrado · Ideal cámara con disuasión activa
Acceso frecuente · Fotodetector con alta inmunidad a falsas alarmas
Protección 100% interior · Configuración más sencilla y económica
Paso 4 de 9
¿Detección antes de entrar?
Añadimos fotodetector AirShield exterior — alerta perimetral activa antes del acceso
Sensores PIR y contactos magnéticos en puertas y ventanas
Paso 5 de 9
¿Tienes mascotas?
PIR estándar — máxima sensibilidad de detección sin restricciones
Compatible de serie — el PIR AirShield ignora mascotas pequeñas sin modificación
Nuestro técnico adapta la instalación — visita previa sin compromiso
Paso 6 de 9 · ¡Ya queda poco!
¿Quieres cámaras de videovigilancia?
Cámara Dahua 360° de regalo para salón o entrada
Cámaras TiOC con sirena integrada y luz disuasoria activa
Cobertura total — 360° interior de regalo + TiOC exterior
La alarma AirShield funciona al 100% sin videovigilancia
Paso 7 de 9 · ¡Solo 2 pasos más!
¿Tienes internet en casa?
WiFi o Ethernet principal + SIM 4G de respaldo automático incluida
Activamos línea M2M — conectividad total sin depender de router
Paso 8 de 9 · ¡Último paso!
Déjanos tus datos y te mostramos el resultado
Te contactamos en menos de 24 h · Sin compromiso
Tu kit estimado
—
Desde
— €
Paso 9 de 9 · ¡Ya casi!
¿Cuándo necesitas la alarma?
Nos ayuda a darte prioridad
Instalación prioritaria — te llamamos hoy mismo
Coordinamos fecha de instalación a tu conveniencia
Te enviamos presupuesto detallado sin ningún compromiso
Preparando tu kit...
Analizando las opciones más adecuadas para tu hogar
Resultado preparado
Este es tu kit
Kit recomendado
Descripción.
Incluye
¿Por qué este kit y no otro?
Llamar ahora: 636 867 111
📩 Recibe tu configuración por email
Te enviamos el kit recomendado, precios y resumen completo
const AlarmFunnel = (function() {
const WHATSAPP_PHONE = "34636867111";
const FORMSUBMIT_URL = "https://formsubmit.co/ajax/jjmartinez@intelixsafety.com";
const BASE_IMG_URL = "https://alarmasgscontrol-9kt86it5ta.live-website.com/wp-content/uploads/2026/04/"; // TODO: migrar a intelix.es
const STORAGE_KEY = "airshield_config_v1";
const TOTAL_STEPS = 9; const IMGS = {
panel: BASE_IMG_URL + "dhi-arc3800h-fw2.jpg",
pircam: BASE_IMG_URL + "dhi-ard1731-w2868.jpg",
pir: BASE_IMG_URL + "dhi-ard1233-w2868.jpg",
magnetico: BASE_IMG_URL + "dhi-ard324-w2868.jpg",
mando: BASE_IMG_URL + "dhi-ara24-w2868.jpg",
teclado: BASE_IMG_URL + "DAHUA-9287.png",
tarjetaIC: BASE_IMG_URL + "dhi-ark30t-w2-ic.jpg",
panico: BASE_IMG_URL + "dhi-ard821-w2868.jpg",
generico: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2394a3b8'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z'/%3E%3C/svg%3E"
}; // B4: Kit Dúplex separado
const BASE_KITS = {
piso: {
publicName: "Dahua AirShield KIT PISO",
displayPrice: "392,22",
subtitle: "Kit base para pisos estándar. Panel con triple conectividad (Ethernet + WiFi + 4G), detección de movimiento inteligente y contacto en accesos principales.",
whyChosen: "Tu piso encaja con el kit base: cubre una planta con panel triple conectividad, PIR-Cam con verificación visual y contacto magnético en accesos. El Kit Ático añade un segundo PIR-Cam que no necesitarías; el Kit Chalet incluye pulsador de pánico y extras pensados para grandes superficies.",
items: [
{ text: "1× Hub Central Dahua AirShield DHI-ARC3800H-FW2(868)", img: IMGS.panel },
{ text: "1× Teclado Inalámbrico Dahua AirShield DHI-ARK30T-W2(868)", img: IMGS.teclado },
{ text: "2× Tarjeta IC Dahua AirShield DHI-ARK30T-W2-IC", img: IMGS.tarjetaIC },
{ text: "1× Mando a Distancia Dahua AirShield DHI-ARA24-W2(868)", img: IMGS.mando },
{ text: "1× PIR con Cámara 2MP Dahua AirShield DHI-ARD1731-W2(868)", img: IMGS.pircam },
{ text: "1× PIR Inalámbrico Dahua AirShield DHI-ARD1233-W2(868)", img: IMGS.pir },
{ text: "1× Contacto Magnético Dahua AirShield DHI-ARD324-W2(868)", img: IMGS.magnetico }
]
},
atico_bajo: {
publicName: "Dahua AirShield KIT ATICO",
displayPrice: "453,92",
subtitle: "Kit reforzado con doble PIR-Cam para áticos con terraza y plantas bajas con ventanas o patio expuesto. Mayor cobertura de movimiento interior.",
whyChosen: "Tu ático o bajo tiene accesos adicionales (terraza, patio, ventanas al exterior) que requieren un segundo PIR-Cam para cubrir ambas zonas sin puntos ciegos. El kit de piso solo cubriría un área de movimiento. El Kit Chalet incluye pulsador de pánico y elementos para superficies muy superiores.",
items: [
{ text: "1× Hub Central Dahua AirShield DHI-ARC3800H-FW2(868)", img: IMGS.panel },
{ text: "1× Teclado Inalámbrico Dahua AirShield DHI-ARK30T-W2(868)", img: IMGS.teclado },
{ text: "2× Tarjeta IC Dahua AirShield DHI-ARK30T-W2-IC", img: IMGS.tarjetaIC },
{ text: "1× Mando a Distancia Dahua AirShield DHI-ARA24-W2(868)", img: IMGS.mando },
{ text: "2× PIR con Cámara 2MP Dahua AirShield DHI-ARD1731-W2(868)", img: IMGS.pircam },
{ text: "1× PIR Inalámbrico Dahua AirShield DHI-ARD1233-W2(868)", img: IMGS.pir },
{ text: "1× Contacto Magnético Dahua AirShield DHI-ARD324-W2(868)", img: IMGS.magnetico }
]
},
duplex: {
publicName: "Dahua AirShield KIT CASA",
displayPrice: "453,92",
subtitle: "Kit para viviendas en dos plantas con acceso trasero. Cubre escaleras, planta baja y accesos laterales con doble PIR-Cam y dos contactos magnéticos.",
whyChosen: "Tu dúplex tiene dos plantas y posiblemente accesos traseros o laterales. El doble PIR-Cam cubre planta baja y escalera, y los dos contactos magnéticos protegen todos los accesos. El kit de piso se quedaría corto; el de chalet incluye extras (pulsador de pánico, PIR adicional) que elevarían el coste innecesariamente.",
items: [
{ text: "1× Hub Central Dahua AirShield DHI-ARC3800H-FW2(868)", img: IMGS.panel },
{ text: "1× Teclado Inalámbrico Dahua AirShield DHI-ARK30T-W2(868)", img: IMGS.teclado },
{ text: "2× Tarjeta IC Dahua AirShield DHI-ARK30T-W2-IC", img: IMGS.tarjetaIC },
{ text: "1× Mando a Distancia Dahua AirShield DHI-ARA24-W2(868)", img: IMGS.mando },
{ text: "2× PIR con Cámara 2MP Dahua AirShield DHI-ARD1731-W2(868)", img: IMGS.pircam },
{ text: "2× PIR Inalámbrico Dahua AirShield DHI-ARD1233-W2(868)", img: IMGS.pir },
{ text: "2× Contacto Magnético Dahua AirShield DHI-ARD324-W2(868)", img: IMGS.magnetico }
]
},
chalet: {
publicName: "Dahua AirShield KIT CHALET",
displayPrice: "1.134,08",
subtitle: "Kit avanzado para grandes superficies con múltiples accesos. Doble cobertura de movimiento, dos contactos magnéticos y pulsador de pánico incluido.",
whyChosen: "Tu chalet requiere cobertura de gran superficie, múltiples accesos y zonas exteriores. El kit incluye pulsador de pánico, doble PIR-Cam para cubrir distintas áreas, y dos contactos para todos los accesos. Los kits menores no tienen capacidad de expandirse a todas las zonas que necesitas proteger.",
items: [
{ text: "1× Hub Central Dahua AirShield DHI-ARC3800H-FW2(868)", img: IMGS.panel },
{ text: "1× Teclado Inalámbrico Dahua AirShield DHI-ARK30T-W2(868)", img: IMGS.teclado },
{ text: "2× Tarjeta IC Dahua AirShield DHI-ARK30T-W2-IC", img: IMGS.tarjetaIC },
{ text: "1× Mando a Distancia Dahua AirShield DHI-ARA24-W2(868)", img: IMGS.mando },
{ text: "2× PIR con Cámara 2MP Dahua AirShield DHI-ARD1731-W2(868)", img: IMGS.pircam },
{ text: "2× PIR Inalámbrico Dahua AirShield DHI-ARD1233-W2(868)", img: IMGS.pir },
{ text: "2× Contacto Magnético Dahua AirShield DHI-ARD324-W2(868)", img: IMGS.magnetico },
{ text: "1× Botón de Pánico Dahua AirShield DHI-ARD821-W2(868)", img: IMGS.panico }
]
}
}; const state = {
property: "", mainDoors: 1, rearDoors: 0, outdoorZones: [],
earlyDetection: "No aplica", pets: "", cameras: "", internet: "",
urgency: "", fullName: "", phone: "", email: "", city: "",
forFamiliar: false, recommendedKit: "", recommendedPrice: ""
}; const history = ["step1"];
let currentExtras = []; // --- B3: localStorage ---
const saveSession = () => {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify({
state: { ...state }, history: [...history],
currentStep: history[history.length - 1]
}));
} catch(e) {}
};
const loadSession = () => {
try { const r = localStorage.getItem(STORAGE_KEY); return r ? JSON.parse(r) : null; }
catch(e) { return null; }
};
const clearSession = () => { try { localStorage.removeItem(STORAGE_KEY); } catch(e) {} }; // --- D1: GA4 events ---
const trackEvent = (name, params) => {
try {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ event: name, ...params });
if (typeof gtag === 'function') gtag('event', name, params);
} catch(e) {}
}; const DOM = {
get: (s) => document.querySelector(s),
getAll: (s) => document.querySelectorAll(s),
shake: (el, errEl, msg) => {
el.classList.add('shake', 'input-error');
errEl.textContent = msg;
errEl.classList.remove('hidden');
setTimeout(() => el.classList.remove('shake'), 400);
}
}; const parsePrice = (s) => parseFloat(String(s).replace(/\./g,'').replace(',','.')) || 0;
const formatPrice = (n) => n.toFixed(2).replace('.',',').replace(/(\d)(?=(\d{3})+(?!\d))/g,'$1.'); const updateProgress = (stepId) => {
const el = DOM.get(`#${stepId}`);
if (!el) return;
const n = parseInt(el.dataset.step, 10);
if (n > TOTAL_STEPS) return;
const pct = Math.min(100, Math.round((n / TOTAL_STEPS) * 100));
const labels = {
1:"Tu propiedad...", 2:"Accesos...", 3:"Exterior...", 4:"Protección...",
5:"Mascotas...", 6:"¡Ya queda poco! — Cámaras...",
7:"¡Solo 2 pasos más! — Internet...", 8:"¡Último paso! — Tus datos...",
9:"¡Finalizando! — Urgencia..."
};
DOM.get('#progressBar').style.width = `${pct}%`;
DOM.get('#progressPercent').textContent = `${pct}%`;
DOM.get('#progressLabel').textContent = labels[n] || '¡Listo!';
}; const showStep = (id, track = true) => {
if (track && history[history.length - 1] !== id) history.push(id);
DOM.getAll('.step').forEach(s => s.classList.remove('active'));
const el = DOM.get(`#${id}`);
if (el) {
el.classList.add('active');
updateProgress(id);
syncUI();
if (id === 'step8') updatePricePreview();
window.scrollTo({ top: (DOM.get('#funnel-container').offsetTop || 0) - 20, behavior: 'smooth' });
saveSession();
}
}; const goBack = () => {
if (history.length > 1) { history.pop(); showStep(history[history.length - 1], false); }
}; const syncUI = () => {
DOM.get('#mainCount').textContent = state.mainDoors;
DOM.get('#rearCount').textContent = state.rearDoors;
DOM.getAll('.option-card').forEach(c => {
const field = c.dataset.field, val = c.dataset.value;
if (field === 'outdoorZones') {
const checked = state.outdoorZones.includes(val);
c.classList.toggle('active', checked);
c.setAttribute('aria-checked', checked ? 'true' : 'false');
} else {
c.classList.toggle('active', state[field] === val);
}
});
}; const getKitKey = () => {
switch (state.property) {
case "Piso": return "piso";
case "Chalet": return "chalet";
case "Ático o Bajo": return "atico_bajo";
case "Dúplex o adosado": return "duplex";
default: return "piso";
}
}; // A4: precio preview
const updatePricePreview = () => {
const base = BASE_KITS[getKitKey()];
if (!base) return;
DOM.get('#previewKitName').textContent = base.publicName;
DOM.get('#previewKitPrice').textContent = `${base.displayPrice} €`;
DOM.get('#pricePreviewBox').classList.remove('hidden');
}; const calculateRecommendedKit = () => {
const key = getKitKey();
const base = BASE_KITS[key];
const extras = [];
const hasOutdoor = state.outdoorZones.length > 0 && !state.outdoorZones.includes("No tengo");
const wantsIndoorCam = ["Solo interiores","Ambas"].includes(state.cameras);
const wantsOutdoorCam = ["Solo exteriores","Ambas"].includes(state.cameras);
const wantsEarly = state.earlyDetection === "Sí, es fundamental"; if (wantsIndoorCam) {
extras.push({ id:'cam360', type:'gift', text:'Cámara Dahua 360° interior',
desc:'Vigilancia panorámica del salón o entrada · Regalo incluido',
price:0, priceText:'GRATIS', selectable:false, selected:true });
} const totalDoors = state.mainDoors + state.rearDoors;
const includedContacts = (key === "chalet" || key === "duplex") ? 2 : 1;
if (totalDoors > includedContacts) {
const n = totalDoors - includedContacts;
const price = Math.round(n * 30.30 * 100) / 100;
extras.push({ id:'contactos_extra', type:'standard',
text:`${n}× Contacto Magnético Dahua AirShield DHI-ARD324-W2(868) adicional${n > 1 ? 'es' : ''}`,
desc:`${totalDoors} accesos · ${includedContacts} contacto${includedContacts > 1 ? 's' : ''} incluido${includedContacts > 1 ? 's' : ''} en el kit`,
price, priceText:`${formatPrice(price)} €`, selectable:true, selected:true });
} if (hasOutdoor) {
extras.push({ id:'fotodetector_ext', type:'exterior_choice', group:'exterior',
groupLabel:'Protección exterior — elige una opción:',
text:'Detector Exterior Triple Tecnología Dahua AirShield DHI-ARD2251E-W2(868)',
desc:'Triple tecnología · Alerta perimetral antes de que lleguen a la puerta · IP55',
price:132.71, priceText:'132,71 €', selectable:true,
selected: wantsEarly && !wantsOutdoorCam });
extras.push({ id:'camara_tioc_wifi', type:'exterior_choice', group:'exterior',
text:'Cámara minidomo WiFi 5MP exterior con disuasión activa Dahua DH-IPC-HDW1539DAP-SW-PV',
desc:'Sirena integrada + luz estroboscópica · Graba y disuade en tiempo real',
price:81.76, priceText:'81,76 €', selectable:true, selected:wantsOutdoorCam });
} else if (wantsOutdoorCam) {
extras.push({ id:'camara_tioc_wifi', type:'standard',
text:'Cámara minidomo WiFi 5MP exterior con disuasión activa Dahua DH-IPC-HDW1539DAP-SW-PV',
desc:'Sirena integrada + luz estroboscópica · Graba y disuade en tiempo real',
price:81.76, priceText:'81,76 €', selectable:true, selected:true });
} if (state.pets === "Sí, > 15kg") {
extras.push({ id:'pet_study', type:'gift', text:'Adaptación técnica para mascota grande',
desc:'Visita de nuestro técnico para ajustar la instalación',
price:0, priceText:'SIN COSTE', selectable:false, selected:true });
} state.recommendedKit = base.publicName;
state.recommendedPrice = base.displayPrice; let videoType = "none";
if (extras.find(e => e.id === 'fotodetector_ext')?.selected) videoType = "fotodetector";
else if (extras.find(e => e.id === 'camara_tioc_wifi')?.selected) videoType = "camera"; return { base, extras, videoType };
}; const getExpertTip = () => {
if (state.pets === "Sí, > 15kg")
return "Para mascotas grandes realizamos una visita técnica sin coste para decidir la altura y ángulo óptimo de los detectores PIR.";
if (state.internet === "No")
return "Sin router en casa, la SIM M2M integrada en el panel AirShield mantiene la alarma siempre conectada. Pregúntanos por las tarifas M2M disponibles.";
return "";
}; const validateLeadForm = () => {
const ni = DOM.get('#fullName'), pi = DOM.get('#phone'), ci = DOM.get('#city');
const ne = DOM.get('#fullNameError'), pe = DOM.get('#phoneError'), ce = DOM.get('#cityError');
state.fullName = ni.value.trim();
state.phone = pi.value.replace(/\s/g,"");
state.email = DOM.get('#email')?.value.trim() || "";
state.city = ci.value.trim();
state.forFamiliar = DOM.get('#forFamiliar')?.checked || false;
let ok = true;
const phoneDigits = state.phone.replace(/^(\+34|0034)/, '');
if (state.fullName.length < 3) { DOM.shake(ni, ne, 'Introduce un nombre de al menos 3 letras.'); ok = false; }
if (!/^[679][0-9]{8}$/.test(phoneDigits)) { DOM.shake(pi, pe, 'Introduce un teléfono válido (ej: 636867111 o +34636867111).'); ok = false; }
if (state.city.length {
const resData = calculateRecommendedKit();
DOM.get('#leadErrorBox')?.classList.add('hidden'); const ampliaciones = resData.extras
.filter(e => e.selected).map(e => `${e.text} (${e.priceText})`).join(' | '); const fd = new FormData();
fd.append("CLIENTE", state.fullName);
fd.append("TELEFONO", state.phone);
if (state.email) fd.append("EMAIL", state.email);
fd.append("MUNICIPIO", state.city);
fd.append("PARA_FAMILIAR", state.forFamiliar ? "Sí" : "No");
fd.append("URGENCIA", state.urgency);
fd.append("PROPIEDAD", state.property);
fd.append("ZONA_EXTERIOR", state.outdoorZones.join(', ') || "No tengo");
fd.append("DETECCION_ANTICIPADA", state.earlyDetection);
fd.append("CAMARAS_Deseadas", state.cameras);
fd.append("TIENE_INTERNET", state.internet);
fd.append("KIT_SUGERIDO", state.recommendedKit);
fd.append("AMPLIACIONES", ampliaciones);
fd.append("_subject", `LEAD WEB (AIRSHIELD): ${state.fullName} — ${state.urgency}`);
fd.append("_captcha", "false");
if (DOM.get('#website').value) return; showStep("step10");
trackEvent('configurador_lead_submit', { kit: state.recommendedKit, urgency: state.urgency }); try {
const r = await fetch(FORMSUBMIT_URL, { method:"POST", body:fd });
if (!r.ok) throw new Error('err');
clearSession();
} catch(err) {
DOM.get('#leadErrorBox')?.classList.remove('hidden');
showStep("step8");
return;
} setTimeout(() => { renderResults(resData); showStep("step11"); }, 1500);
}; // --- Extras rendering ---
const CHECK_SVG = ''; const renderExtraItemHTML = (extra) => {
if (!extra.selectable) {
const g = extra.price === 0;
const bg = g?'#f0fdf4':'#f3ecfd', bdr=g?'#bbf7d0':'#ddd0f5', clr=g?'#16a34a':'#3a0a72', bgt=g?'#dcfce7':'#ede9f6';
return `
${extra.text}
${extra.desc}
}
const sel=extra.selected, bdr=sel?'#4D0E97':'#e2e8f0', shd=sel?'box-shadow:0 0 0 3px rgba(77,14,151,0.10);':'';
const db=sel?'#4D0E97':'#fff', dd=sel?'#4D0E97':'#cbd5e1', pc=sel?'#4D0E97':'#94a3b8';
return `
${extra.text}
${extra.desc}
}; const renderExtras = (extras) => {
const eb = DOM.get('#extrasBlock'), el = DOM.get('#kitExtras'), tb = DOM.get('#kitTotalBlock');
if (!extras || !extras.length) { eb.classList.add('hidden'); tb?.classList.add('hidden'); return; }
eb.classList.remove('hidden');
const groups={}, ordered=[];
extras.forEach(e => {
if (e.group) { if(!groups[e.group]){groups[e.group]=[];ordered.push({type:'group',group:e.group});} groups[e.group].push(e); }
else ordered.push({type:'item',extra:e});
});
let html='';
ordered.forEach(entry => {
if (entry.type==='item') { html+=renderExtraItemHTML(entry.extra); }
else {
const items=groups[entry.group], label=items.find(i=>i.groupLabel)?.groupLabel||'Elige una opción:';
html+=`
${label}
- ${items.map(e=>renderExtraItemHTML(e)).join('')}
}
});
el.innerHTML=html; currentExtras=extras; updateExtrasTotal();
}; const updateExtrasTotal = () => {
const tb = DOM.get('#kitTotalBlock'); if(!tb) return;
const base = parsePrice(state.recommendedPrice);
let sum = 0;
const selectedPaid = [];
DOM.getAll('.extra-toggle').forEach(el => {
if (el.getAttribute('aria-checked')==='true') {
const e = currentExtras.find(x=>x.id===el.dataset.extraId);
if (e) { if (e.price > 0) { sum += e.price; selectedPaid.push(e); } }
}
});
DOM.get('#totalBasePrice').textContent = `${state.recommendedPrice} €`;
const li = DOM.get('#extrasLineItems');
if (li) {
li.innerHTML = selectedPaid.map(e =>
`
${formatPrice(e.price)} €
).join('');
li.classList.toggle('hidden', selectedPaid.length === 0);
}
DOM.get('#totalFinalPrice').textContent = `${formatPrice(base+sum)} €`;
tb.classList.remove('hidden');
}; const setItemState = (el, sel) => {
el.setAttribute('aria-checked', String(sel));
el.style.borderColor = sel?'#4D0E97':'#e2e8f0';
el.style.boxShadow = sel?'0 0 0 3px rgba(77,14,151,0.10)':'none';
const dot=el.querySelector('span:first-child'), pr=el.querySelector('span:last-child');
if(dot){ dot.style.background=sel?'#4D0E97':'#fff'; dot.style.borderColor=sel?'#4D0E97':'#cbd5e1'; dot.innerHTML=sel?CHECK_SVG:''; }
if(pr) pr.style.color=sel?'#4D0E97':'#94a3b8';
}; const toggleExtra = (el) => {
const group=el.dataset.extraGroup, id=el.dataset.extraId;
const extra=currentExtras.find(e=>e.id===id); if(!extra) return;
if (group) {
DOM.getAll(`.extra-toggle[data-extra-group="${group}"]`).forEach(item => {
const e=currentExtras.find(x=>x.id===item.dataset.extraId); if(e) e.selected=false; setItemState(item,false);
});
extra.selected=true; setItemState(el,true);
const vf=DOM.get('#videoContainerFotodetector'), vc=DOM.get('#videoContainerCamara');
[vf,vc].forEach(v=>v?.classList.add('hidden'));
DOM.get('#playerFotodetector')?.pause(); DOM.get('#playerCamara')?.pause();
if(id==='fotodetector_ext'){vf?.classList.remove('hidden');DOM.get('#playerFotodetector')?.play().catch(()=>{});}
if(id==='camara_tioc_wifi'){vc?.classList.remove('hidden');DOM.get('#playerCamara')?.play().catch(()=>{});}
} else {
extra.selected=!extra.selected; setItemState(el,extra.selected);
}
updateExtrasTotal();
trackEvent('configurador_extra_toggle',{extra_id:id,selected:extra.selected});
}; // C4: texto explicativo del kit
const renderKitComparison = (base) => {
const el=DOM.get('#kitComparison'); if(el && base.whyChosen) el.innerHTML=`${base.whyChosen}`;
}; const renderResults = (resData) => {
const ref = state.forFamiliar ? "para tu familiar" : "para ti";
DOM.get('#resultHeading').textContent = `${state.fullName}, este es tu kit ${ref}`;
DOM.get('#kitTitle').textContent = resData.base.publicName;
DOM.get('#kitSubtitle').textContent = resData.base.subtitle;
DOM.get('#kitPrice').innerHTML = `${resData.base.displayPrice} €`;
DOM.get('#kitItems').innerHTML = resData.base.items.map(item => `
${item.text}
renderExtras(resData.extras);
renderKitComparison(resData.base);
DOM.get('#internetAlert').classList.toggle('hidden', state.internet !== "No");
const tip=getExpertTip(), te=DOM.get('#expertTip'), tt=DOM.get('#expertTipText');
if(tip){te.classList.remove('hidden');tt.textContent=tip;}else{te.classList.add('hidden');}
const vf=DOM.get('#videoContainerFotodetector'), vc=DOM.get('#videoContainerCamara');
const pf=DOM.get('#playerFotodetector'), pc=DOM.get('#playerCamara');
[vf,vc].forEach(v=>v.classList.add('hidden')); [pf,pc].forEach(p=>p&&p.pause());
if(resData.videoType==="fotodetector"){vf.classList.remove('hidden');pf?.play().catch(()=>{});}
if(resData.videoType==="camera") {vc.classList.remove('hidden');pc?.play().catch(()=>{});}
trackEvent('configurador_result_shown',{kit:state.recommendedKit,urgency:state.urgency});
}; const sendToWhatsApp = (isFallback=false) => {
const paid=currentExtras.filter(e=>e.selected&&e.price>0);
const xt=paid.length?`\n*Ampliaciones:* ${paid.map(e=>`${e.text} (${e.priceText})`).join(', ')}`:'';
const base=parsePrice(state.recommendedPrice), sum=paid.reduce((s,e)=>s+e.price,0);
const fam=state.forFamiliar?" (para un familiar)":"";
const msg=isFallback
?`¡Hola Intelix Safety! He tenido un problema al enviar mis datos desde el configurador AirShield.\n\n👤 *Nombre:* ${state.fullName}${fam}\n📱 *Teléfono:* ${state.phone}\n📍 *Municipio:* ${state.city}\n🏠 *Propiedad:* ${state.property}\n🚪 *Accesos:* ${state.mainDoors} principal / ${state.rearDoors} trasero\n🌳 *Exterior:* ${state.outdoorZones.join(', ')||'No tengo'}\n📹 *Cámaras:* ${state.cameras}\n🌐 *Internet:* ${state.internet}`
:`¡Hola Intelix Safety! He completado el configurador AirShield y quiero saber el precio exacto.\n\n👤 *Nombre:* ${state.fullName}${fam}\n📱 *Teléfono:* ${state.phone}\n📍 *Municipio:* ${state.city}\n⏰ *Urgencia:* ${state.urgency}\n\n👉 *Kit:* ${state.recommendedKit} (${state.recommendedPrice} €)${xt}\n💰 *Total estimado:* ${formatPrice(base+sum)} €`;
window.open(`https://wa.me/${WHATSAPP_PHONE}?text=${encodeURIComponent(msg)}`,'_blank');
trackEvent('configurador_whatsapp_click',{is_fallback:isFallback});
}; // D2: enviar resultado por email
const sendEmailResult = async () => {
const ei=DOM.get('#resultEmail'), msg=DOM.get('#emailResultMsg');
const email=ei?.value.trim();
if(!email||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)){ei?.classList.add('input-error');return;}
ei.disabled=true;
const paid=currentExtras.filter(e=>e.selected&&e.price>0);
const base=parsePrice(state.recommendedPrice), sum=paid.reduce((s,e)=>s+e.price,0);
const fd=new FormData();
fd.append("CLIENTE", state.fullName);
fd.append("TELEFONO", state.phone);
fd.append("KIT", state.recommendedKit);
fd.append("TOTAL", `${formatPrice(base+sum)} €`);
fd.append("EMAIL_DEST", email);
fd.append("_subject", `Resultado configurador AirShield: ${state.fullName}`);
fd.append("_captcha", "false");
try { await fetch(FORMSUBMIT_URL,{method:"POST",body:fd}); msg?.classList.remove('hidden'); trackEvent('configurador_email_result',{}); } catch(e){}
ei.disabled=false;
}; const handleInteraction = (e) => {
const target=e.target; const tog=target.closest('.extra-toggle'); if(tog){toggleExtra(tog);return;} const card=target.closest('.option-card'), btn=target.closest('[data-action]'), cnt=target.closest('.counter-btn'); if(cnt){
const name=cnt.dataset.counter, inc=parseInt(cnt.dataset.action,10);
if(typeof state[name]==='number'&&state[name]+inc>=0){state[name]+=inc;syncUI();} return;
} if(card){
const field=card.dataset.field, value=card.dataset.value, next=card.dataset.next;
if(field==="outdoorZones"){
if(value==="No tengo"){
state.outdoorZones = state.outdoorZones.includes("No tengo") ? [] : ["No tengo"];
} else {
const idx = state.outdoorZones.indexOf(value);
if(idx>=0) state.outdoorZones.splice(idx,1);
else { state.outdoorZones = state.outdoorZones.filter(z=>z!=="No tengo"); state.outdoorZones.push(value); }
}
syncUI(); return;
}
state[field]=value;
// B1: urgency cards trigger submit directly
if(field==="urgency"){ state.urgency=value; syncUI(); submitLead(); return; }
if(next==="step8") updatePricePreview();
syncUI();
trackEvent('configurador_step',{step:next,field,value});
setTimeout(()=>showStep(next),200);
return;
} if(target.closest('#leadStepNext')){ if(validateLeadForm()) showStep("step9"); return; } if(btn){
const action=btn.dataset.action;
if (action==='back') goBack();
else if(action==='outdoor-continue'){
if(state.outdoorZones.length===0){ alert('Selecciona al menos una opción'); return; }
const hasOutdoor = !state.outdoorZones.includes("No tengo");
if(!hasOutdoor) state.earlyDetection="No aplica";
trackEvent('configurador_step',{step:'step4',field:'outdoorZones',value:state.outdoorZones.join(',')});
showStep(hasOutdoor ? 'step4' : 'step5');
}
else if(action==='next') showStep(btn.dataset.next);
else if(action==='restart') {clearSession();location.reload();}
else if(action==='whatsapp-final') sendToWhatsApp(false);
else if(action==='whatsapp-fallback')sendToWhatsApp(true);
else if(action==='send-email-result')sendEmailResult();
else if(action==='resume-session'){
const s=loadSession();
if(s){
Object.assign(state,s.state);
history.length=0; s.history.forEach(h=>history.push(h));
showStep(s.currentStep,false);
}
DOM.get('#resumeBanner').style.display='none';
}
else if(action==='discard-session'){clearSession();DOM.get('#resumeBanner').style.display='none';}
}
}; return {
init: () => {
DOM.get('#funnel-container').addEventListener('click',handleInteraction);
DOM.getAll('input[type="text"],input[type="tel"],input[type="email"]').forEach(i=>
i.addEventListener('input',()=>{
i.classList.remove('input-error');
DOM.get(`#${i.id}Error`)?.classList.add('hidden');
})
);
// B3: check saved session
const saved=loadSession();
if(saved&&saved.currentStep&&saved.currentStep!=='step1'){
DOM.get('#resumeBanner').style.display='block';
}
showStep('step1',false);
trackEvent('configurador_start',{});
}
};
})();
AlarmFunnel.init();
});