(function() { 'use strict'; // === STATE === var quizData = {}; var currentStep = 0; // 0 = intro, 1-4 = écrans, 'contact', 'loading', 'results' var stepHistory = []; var quizStarted = false; var profile = 'default'; // 'auto_ent' | 'tpe' | 'pme' | 'eti' | 'default' var totalSteps = 4; // 4 écrans pré-contact var STORAGE_KEY = 'cfe_quiz_progress_v2'; var STORAGE_TTL = 24 * 60 * 60 * 1000; // 24h // === DOM refs === var quizRoot = document.getElementById('cfeQuiz'); var header = document.getElementById('qHeader'); var progress = document.getElementById('qProgress'); var progressFill = document.getElementById('qProgressFill'); var progressText = document.getElementById('qProgressText'); var chipProfile = document.getElementById('qChipProfile'); var chipProfileLabel = document.getElementById('qChipProfileLabel'); var chipEdit = document.getElementById('qChipEdit'); var resumeBanner = document.getElementById('qResumeBanner'); var submitBtn = document.getElementById('qSubmitBtn'); var rgpdCheckbox = document.getElementById('qRgpd'); var errorDiv = document.getElementById('qError'); var podium = document.getElementById('qPodium'); var detailsWrap = document.getElementById('qDetailsWrap'); var altWrap = document.getElementById('qAlternativesWrap'); var altList = document.getElementById('qAltList'); var recap = document.getElementById('qRecap'); var restartBtn = document.getElementById('qRestartBtn'); var stepper = document.getElementById('qStepper'); // === P2 — Wordings conditionnels par profil === var WORDINGS = { auto_ent: { profile_label: 'Auto-entrepreneur', step2_volume_title: 'Combien de factures envoyez-vous chaque mois ?', step2_volume_options: [ { value: 'Moins de 10', label: 'Moins de 10', hint: 'Typique d\u2019un solo qui démarre' }, { value: '11-50', label: '11 à 50', hint: 'Activité régulière mais pas industrielle' }, { value: '51-200', label: '51 à 200', hint: 'Forte activité, gestion structurée' }, { value: 'Plus de 200', label: 'Plus de 200', hint: 'Volume élevé pour un solo' } ], budget_title: 'Quel budget mensuel êtes-vous prêt à mettre ?', budget_options: [ { value: 'Gratuit', label: 'Gratuit uniquement', hint: 'Suffisant pour démarrer en solo' }, { value: 'Moins de 20€/mois', label: 'Moins de 20€ par mois', hint: 'Le minimum pour un peu plus de fonctions' }, { value: '20-50€/mois', label: 'Entre 20 et 50€ par mois', hint: 'Logiciel complet avec support' }, { value: '50-100€/mois', label: 'Entre 50 et 100€ par mois' }, { value: 'Plus de 100€/mois', label: 'Plus de 100€ par mois' }, { value: 'Pas de limite', label: 'Pas de limite définie' } ], preparation_title: 'Où en êtes-vous dans votre préparation à la réforme ?', preparation_options: [ { value: 'Je ne savais pas que c\'était obligatoire', label: 'Je découvre que c\u2019est obligatoire', hint: 'Pas grave, on vous explique tout' }, { value: 'Je suis au courant mais je n\'ai rien fait', label: 'Au courant mais rien lancé', hint: 'Pas de panique, encore le temps' }, { value: 'Je suis en recherche active', label: 'En recherche active' }, { value: 'J\'ai déjà choisi ma PA', label: 'J\u2019ai déjà choisi ma plateforme' } ] }, tpe: { profile_label: 'TPE', step2_volume_title: 'Combien de factures votre équipe envoie chaque mois ?', step2_volume_options: [ { value: 'Moins de 10', label: 'Moins de 10', hint: 'Activité ponctuelle ou démarrage' }, { value: '10-30', label: '10 à 30', hint: 'Rythme TPE classique' }, { value: '30-100', label: '30 à 100', hint: 'Activité soutenue' }, { value: 'Plus de 100', label: 'Plus de 100', hint: 'Forte activité' } ], budget_title: 'Quel budget mensuel êtes-vous prêt à mettre dans votre logiciel ?', budget_options: [ { value: 'Gratuit', label: 'Gratuit si possible', hint: 'Pour les structures sans budget logiciel' }, { value: 'Moins de 20€/mois', label: 'Moins de 20€ par mois' }, { value: '20-50€/mois', label: 'Entre 20 et 50€ par mois', hint: 'Bon rapport qualité-prix TPE' }, { value: '50-100€/mois', label: 'Entre 50 et 100€ par mois', hint: 'Solution complète avec support dédié' }, { value: 'Plus de 100€/mois', label: 'Plus de 100€ par mois' }, { value: 'Pas de limite', label: 'Pas de limite définie' } ], preparation_title: 'Où en êtes-vous dans votre préparation à la réforme ?', preparation_options: [ { value: 'Je ne savais pas que c\'était obligatoire', label: 'On découvre que c\u2019est obligatoire' }, { value: 'Je suis au courant mais je n\'ai rien fait', label: 'Au courant mais rien lancé' }, { value: 'Je suis en recherche active', label: 'On compare les solutions', hint: 'Phase de short-list' }, { value: 'J\'ai déjà choisi ma PA', label: 'On a déjà choisi notre plateforme' } ] }, pme: { profile_label: 'PME', step2_volume_title: 'Combien de factures votre équipe envoie chaque mois ?', step2_volume_options: [ { value: '30-100', label: '30 à 100', hint: 'PME en démarrage' }, { value: '100-500', label: '100 à 500', hint: 'Volume PME standard' }, { value: '500-2000', label: '500 à 2 000', hint: 'PME industrielle ou multi-sites' }, { value: 'Plus de 2000', label: 'Plus de 2 000' } ], budget_title: 'Quel budget mensuel pour votre solution ?', budget_options: [ { value: '20-50€/mois', label: 'Moins de 50€ par mois' }, { value: '50-100€/mois', label: 'Entre 50 et 100€ par mois' }, { value: '100-500€/mois', label: 'Entre 100 et 500€ par mois', hint: 'Solution complète avec API et support' }, { value: 'Plus de 500€/mois', label: 'Plus de 500€ par mois', hint: 'Suite ERP ou multi-entités' }, { value: 'Pas de limite', label: 'Pas de limite définie' } ], preparation_title: 'Où en êtes-vous dans votre préparation à la réforme ?', preparation_options: [ { value: 'Je suis au courant mais je n\'ai rien fait', label: 'Au courant mais rien lancé' }, { value: 'Je suis en recherche active', label: 'On compare les solutions' }, { value: 'Réception sept. 2026', label: 'Réception obligatoire dès septembre 2026', hint: 'Vous devez pouvoir recevoir des e-factures' }, { value: 'J\'ai déjà choisi ma PA', label: 'On a déjà choisi notre plateforme' } ] }, eti: { profile_label: 'ETI', step2_volume_title: 'Combien de factures votre groupe envoie chaque mois ?', step2_volume_options: [ { value: '500-2000', label: '500 à 2 000' }, { value: '2000-10000', label: '2 000 à 10 000' }, { value: 'Plus de 10000', label: 'Plus de 10 000', hint: 'Volume industriel' }, { value: 'Sur devis', label: 'Sur devis ou non défini' } ], budget_title: 'Quel budget mensuel pour votre solution ?', budget_options: [ { value: '100-500€/mois', label: 'Entre 100 et 500€ par mois' }, { value: 'Plus de 500€/mois', label: 'Plus de 500€ par mois' }, { value: 'Plus de 1000€/mois', label: 'Plus de 1 000€ par mois', hint: 'ERP ou plateforme dédiée' }, { value: 'Sur devis', label: 'Sur devis selon volumétrie' }, { value: 'Pas de limite', label: 'Pas de limite définie' } ], preparation_title: 'Où en êtes-vous dans votre préparation à la réforme ?', preparation_options: [ { value: 'Je suis en recherche active', label: 'On compare les solutions' }, { value: 'Réception sept. 2026', label: 'Réception obligatoire dès septembre 2026' }, { value: 'Émission sept. 2027', label: 'Émission obligatoire pour septembre 2027', hint: 'Calendrier groupe' }, { value: 'J\'ai déjà choisi ma PA', label: 'On a déjà choisi notre plateforme' } ] }, 'default': { profile_label: 'Profil', step2_volume_title: 'Combien de factures envoyez-vous chaque mois ?', step2_volume_options: [ { value: 'Moins de 10', label: 'Moins de 10' }, { value: '11-50', label: '11 à 50' }, { value: '51-200', label: '51 à 200' }, { value: 'Plus de 200', label: 'Plus de 200' } ], budget_title: 'Quel budget mensuel envisagez-vous ?', budget_options: [ { value: 'Gratuit', label: 'Gratuit' }, { value: 'Moins de 20€/mois', label: 'Moins de 20€ par mois' }, { value: '20-50€/mois', label: 'Entre 20 et 50€ par mois' }, { value: '50-100€/mois', label: 'Entre 50 et 100€ par mois' }, { value: 'Plus de 100€/mois', label: 'Plus de 100€ par mois' }, { value: 'Pas de limite', label: 'Pas de limite définie' } ], preparation_title: 'Où en êtes-vous dans votre préparation à la réforme ?', preparation_options: [ { value: 'Je ne savais pas que c\'était obligatoire', label: 'Je découvre que c\u2019est obligatoire' }, { value: 'Je suis au courant mais je n\'ai rien fait', label: 'Au courant mais rien lancé' }, { value: 'Je suis en recherche active', label: 'En recherche active' }, { value: 'J\'ai déjà choisi ma PA', label: 'J\u2019ai déjà choisi ma plateforme' } ] } }; // === INIT === function init() { quizRoot.classList.add('js-ready'); // Bindings bindOptionClicks(); bindNextButtons(); bindBackButtons(); bindKeyboardNav(); bindContactForm(); bindRestart(); bindChipEdit(); bindResumeBanner(); bindStepperNav(); bindOtherInputs(); // Profil par défaut + injection wordings (avant détection) applyWordingFor('default'); // B9 — Reprise localStorage var resumed = tryShowResumeBanner(); if (resumed) return; // attend l'action user // ?q1= pré-remplissage try { var urlParams = new URLSearchParams(window.location.search); var q1 = urlParams.get('q1'); var statutMap = { 'auto-entrepreneur': 'Auto-entrepreneur', 'ei': 'Entreprise individuelle', 'sarl': 'SARL / EURL', 'sas': 'SAS / SASU', 'sa': 'SA', 'profession-liberale': 'Profession libérale', 'association': 'Association' }; if (q1 && statutMap[q1]) { quizData.statut = statutMap[q1]; // pré-sélectionner visuellement la valeur dans step1 mais laisser sur step1 pour confirmer applyAnswerSelection('statut', quizData.statut); if (typeof gtag === 'function') { gtag('event', 'quiz_q1_prefill', { event_category: 'quiz', q1_source: 'home_hero', q1_value: q1 }); } } } catch(e) { /* fallback */ } goToStep(1); } // === B9 — localStorage save/restore === function saveProgress() { try { var snap = { step: currentStep, answers: quizData, profile: profile, ts: Date.now() }; localStorage.setItem(STORAGE_KEY, JSON.stringify(snap)); } catch(e) {} } function clearProgress() { try { localStorage.removeItem(STORAGE_KEY); } catch(e) {} } function tryShowResumeBanner() { try { var raw = localStorage.getItem(STORAGE_KEY); if (!raw) return false; var snap = JSON.parse(raw); if (!snap || !snap.ts) { clearProgress(); return false; } if (Date.now() - snap.ts > STORAGE_TTL) { clearProgress(); return false; } if (!snap.answers || Object.keys(snap.answers).length === 0) { clearProgress(); return false; } // Texte humanisé var minutes = Math.max(1, Math.round((Date.now() - snap.ts) / 60000)); var txt = document.getElementById('qResumeText'); if (txt) { if (minutes < 60) { txt.textContent = 'Vous avez commencé le quiz il y a environ ' + minutes + ' minute' + (minutes > 1 ? 's' : '') + '. On reprend où vous en étiez ?'; } else { var hours = Math.round(minutes / 60); txt.textContent = 'Vous avez commencé le quiz il y a environ ' + hours + ' heure' + (hours > 1 ? 's' : '') + '. On reprend où vous en étiez ?'; } } resumeBanner.style.display = 'flex'; // Cacher tous les steps en attendant le choix var allSteps = document.querySelectorAll('.cfe-quiz-step'); for (var i = 0; i < allSteps.length; i++) allSteps[i].classList.remove('active'); header.style.display = 'none'; progress.style.display = 'none'; // Stocker le snap pour Reprendre window.__cfeQuizPendingSnap = snap; return true; } catch(e) { clearProgress(); return false; } } function bindResumeBanner() { var yes = document.getElementById('qResumeYes'); var no = document.getElementById('qResumeNo'); if (yes) yes.addEventListener('click', function() { var snap = window.__cfeQuizPendingSnap; resumeBanner.style.display = 'none'; if (!snap) { goToStep(1); return; } quizData = snap.answers || {}; profile = snap.profile || 'default'; applyWordingFor(profile); restoreAllSelections(); var step = (typeof snap.step === 'number') ? snap.step : 1; if (step < 1 || step > 4) step = 1; goToStep(step); }); if (no) no.addEventListener('click', function() { clearProgress(); window.__cfeQuizPendingSnap = null; resumeBanner.style.display = 'none'; quizData = {}; profile = 'default'; applyWordingFor('default'); goToStep(1); }); } // === Profil detection (statut + taille) === function detectProfile() { var s = (quizData.statut || '').toLowerCase(); var t = (quizData.taille || '').toLowerCase(); if (s.indexOf('auto-entrepreneur') !== -1 || t === 'moi seul') return 'auto_ent'; if (t.indexOf('2-10') !== -1) return 'tpe'; if (t.indexOf('11-50') !== -1) return 'pme'; if (t.indexOf('51-250') !== -1 || t.indexOf('plus de 250') !== -1) return 'eti'; return 'default'; } // === P2 — applyWordingFor : injecte options + titres selon profil === function applyWordingFor(p) { var w = WORDINGS[p] || WORDINGS['default']; profile = p; // Step 2 — volume var volTitle = document.getElementById('qVolumeTitle'); if (volTitle) volTitle.innerHTML = '4' + w.step2_volume_title; renderOptions(document.getElementById('qVolumeOptions'), w.step2_volume_options, 'volume'); // Step 4 — budget var budgetTitle = document.getElementById('qBudgetTitle'); if (budgetTitle) budgetTitle.innerHTML = '6' + w.budget_title; renderOptions(document.getElementById('qBudgetOptions'), w.budget_options, 'budget'); // Step 4 — preparation var prepTitle = document.getElementById('qPreparationTitle'); if (prepTitle) prepTitle.innerHTML = '8' + w.preparation_title; renderOptions(document.getElementById('qPreparationOptions'), w.preparation_options, 'preparation'); // Re-applique les sélections visuelles restoreAllSelections(); } function renderOptions(container, options, ariaField) { if (!container) return; var html = ''; for (var i = 0; i < options.length; i++) { var opt = options[i]; var hint = opt.hint ? '' + escapeHtml(opt.hint) + '' : ''; html += ''; } container.innerHTML = html; } function applyAnswerSelection(field, value) { var sval = String(value); var isOtherStored = sval.indexOf('Autre') === 0; // 'Autre' ou 'Autre: ...' ou 'Autre / Non sûr' var blocks = document.querySelectorAll('[data-field="' + field + '"]'); for (var i = 0; i < blocks.length; i++) { var opts = blocks[i].querySelectorAll('.cfe-quiz-opt'); for (var j = 0; j < opts.length; j++) { var dv = opts[j].getAttribute('data-value'); var match = dv === sval; // Si valeur stockée commence par 'Autre', matcher l'option dont data-value contient 'Autre' if (!match && isOtherStored && dv && dv.toLowerCase().indexOf('autre') !== -1) { match = true; } opts[j].classList.toggle('selected', match); opts[j].setAttribute('aria-checked', match ? 'true' : 'false'); } } // N3 — Show « Autre » precision si applicable if (field === 'statut' || field === 'secteur' || field === 'logiciel_nom') { if (isOtherStored) { var blkEl = document.querySelector('.cfe-quiz-other-precision[data-for="' + field + '"]'); if (blkEl) { blkEl.hidden = false; var inp = blkEl.querySelector('.cfe-quiz-other-input'); if (inp && sval.indexOf('Autre: ') === 0) inp.value = sval.substring(7); } } } } function restoreAllSelections() { for (var f in quizData) { if (Object.prototype.hasOwnProperty.call(quizData, f) && quizData[f] !== '') { applyAnswerSelection(f, quizData[f]); } } // Logiciel_use bool : afficher 5b si oui if (quizData.logiciel_use === 'true') { var blk = document.getElementById('qLogicielNomBlock'); if (blk) blk.style.display = ''; } refreshAllNextButtons(); } // === N2 — Stepper update + nav back === function updateStepper(stepNum) { if (!stepper) return; var items = stepper.querySelectorAll('.cfe-quiz-stepper-item'); for (var i = 0; i < items.length; i++) { var s = i + 1; items[i].classList.remove('is-done', 'is-current'); if (s < stepNum) { items[i].classList.add('is-done'); items[i].setAttribute('tabindex', '0'); items[i].setAttribute('role', 'button'); items[i].setAttribute('aria-label', 'Revenir à l\u2019étape ' + s); } else if (s === stepNum) { items[i].classList.add('is-current'); items[i].removeAttribute('tabindex'); items[i].removeAttribute('role'); items[i].setAttribute('aria-current', 'step'); } else { items[i].removeAttribute('tabindex'); items[i].removeAttribute('role'); items[i].removeAttribute('aria-current'); } } } function bindStepperNav() { if (!stepper) return; var items = stepper.querySelectorAll('.cfe-quiz-stepper-item'); for (var i = 0; i < items.length; i++) { (function(it, idx) { it.addEventListener('click', function() { if (it.classList.contains('is-done')) { // Reset stepHistory so back nav is consistent stepHistory = []; for (var k = 1; k < idx + 1; k++) stepHistory.push(k); stepHistory.pop(); goToStep(idx + 1); } }); it.addEventListener('keydown', function(e) { if ((e.key === 'Enter' || e.key === ' ') && it.classList.contains('is-done')) { e.preventDefault(); stepHistory = []; for (var k = 1; k < idx + 1; k++) stepHistory.push(k); stepHistory.pop(); goToStep(idx + 1); } }); })(items[i], i); } } // === N3 — « Autre » input handling === function bindOtherInputs() { var inputs = document.querySelectorAll('.cfe-quiz-other-input'); for (var i = 0; i < inputs.length; i++) { (function(inp) { var field = inp.getAttribute('data-for'); inp.addEventListener('input', function() { var v = inp.value.trim(); if (v) { quizData[field] = 'Autre: ' + v; } else { quizData[field] = 'Autre'; } saveProgress(); }); })(inputs[i]); } } function isOtherValue(value) { if (!value) return false; return String(value).toLowerCase().indexOf('autre') !== -1; } function toggleOtherPrecision(field, value) { var blocks = document.querySelectorAll('.cfe-quiz-other-precision[data-for="' + field + '"]'); for (var i = 0; i < blocks.length; i++) { var blk = blocks[i]; if (isOtherValue(value)) { blk.hidden = false; var inp = blk.querySelector('.cfe-quiz-other-input'); if (inp) { // Pre-fill if quizData already has 'Autre: xxx' var raw = quizData[field] || ''; if (raw.indexOf('Autre: ') === 0) inp.value = raw.substring(7); setTimeout(function() { try { inp.focus(); } catch(e) {} }, 100); } } else { blk.hidden = true; var inp2 = blk.querySelector('.cfe-quiz-other-input'); if (inp2) inp2.value = ''; } } } // === NAVIGATION === function goToStep(stepNum) { var allSteps = document.querySelectorAll('.cfe-quiz-step'); for (var i = 0; i < allSteps.length; i++) allSteps[i].classList.remove('active'); var stepEl = null; if (typeof stepNum === 'number' && stepNum >= 1 && stepNum <= 4) { stepEl = document.getElementById('qStep' + stepNum); } else if (stepNum === 'contact') { stepEl = document.getElementById('qStepContact'); } else if (stepNum === 'loading') { stepEl = document.getElementById('qStepLoading'); } else if (stepNum === 'results') { stepEl = document.getElementById('qStepResults'); } if (!stepEl) return; // Animation stepEl.style.animation = 'none'; stepEl.offsetHeight; stepEl.style.animation = ''; stepEl.classList.add('active'); currentStep = stepNum; // Scroll quiz en haut de page à chaque changement de step try { if (stepNum !== 'results') { var topTarget = quizRoot || stepEl; var rect = topTarget.getBoundingClientRect(); var scrollY = window.pageYOffset || document.documentElement.scrollTop; var targetY = scrollY + rect.top - 80; // 80px marge pour le header sticky window.scrollTo({ top: Math.max(0, targetY), behavior: 'smooth' }); } } catch(e) {} // Header visible uniquement si step 1 (pas pré-rempli) header.style.display = (stepNum === 1 && !quizData.statut) ? '' : 'none'; // Root state classes (for stepper/responsive scoping) quizRoot.classList.remove('is-step-intro', 'is-step-contact', 'is-step-loading', 'is-step-results'); if (stepNum === 'contact') quizRoot.classList.add('is-step-contact'); else if (stepNum === 'loading') quizRoot.classList.add('is-step-loading'); else if (stepNum === 'results') quizRoot.classList.add('is-step-results'); // Chip profil visible à partir du step 2 var showChip = (typeof stepNum === 'number' && stepNum >= 2 && stepNum <= 4); chipProfile.style.display = showChip ? '' : 'none'; if (showChip) updateChip(); // Stepper N2 : visible steps 1-4 if (stepper) { if (typeof stepNum === 'number' && stepNum >= 1 && stepNum <= 4) { stepper.style.display = ''; updateStepper(stepNum); } else { stepper.style.display = 'none'; } } // Progress if (typeof stepNum === 'number' && stepNum >= 1 && stepNum <= 4) { progress.style.display = 'flex'; var pct = Math.round((stepNum / totalSteps) * 100); progressFill.style.width = pct + '%'; progressText.textContent = stepNum + ' / ' + totalSteps; } else { progress.style.display = 'none'; } // Refresh next button state refreshAllNextButtons(); restoreAllSelections(); // Step contact : setup phone/variant if (stepNum === 'contact') { trackGateView(); try { cfeSetupPhoneGating(); } catch(e) {} } // B11 — auto-focus 1ère option non-sélectionnée (desktop only) try { if (typeof stepNum === 'number' && stepNum >= 1 && stepNum <= 4) { if (window.matchMedia && window.matchMedia('(min-width: 768px)').matches) { setTimeout(function() { var firstOpt = stepEl.querySelector('.cfe-quiz-opt:not(.selected)'); if (firstOpt) firstOpt.focus(); }, 350); } } } catch(e) {} // Save progress if (typeof stepNum === 'number' && stepNum >= 1 && stepNum <= 4) saveProgress(); } function updateChip() { var w = WORDINGS[profile] || WORDINGS['default']; var label = w.profile_label; if (quizData.taille && quizData.taille !== 'Moi seul' && profile !== 'auto_ent') { // Ajouter la taille si différente var t = quizData.taille.replace(/ salariés/, ' sal.'); label += ' · ' + t; } else if (quizData.taille === 'Moi seul') { label += ' · Solo'; } chipProfileLabel.textContent = label; } function bindChipEdit() { chipEdit.addEventListener('click', function() { goToStep(1); }); } // === Step completeness === function isStepComplete(stepNum) { var stepEl = document.getElementById('qStep' + stepNum); if (!stepEl) return false; var blocks = stepEl.querySelectorAll('.cfe-quiz-question-block'); for (var i = 0; i < blocks.length; i++) { // Skip si caché (ex: 5b non requis) if (blocks[i].style.display === 'none') continue; var f = blocks[i].getAttribute('data-field'); if (!f) continue; var val = quizData[f]; if (val === undefined || val === null || val === '') return false; } return true; } function refreshAllNextButtons() { for (var s = 1; s <= 4; s++) { var btn = document.querySelector('.cfe-quiz-next[data-step-num="' + s + '"]'); if (!btn) continue; btn.disabled = !isStepComplete(s); } } // === OPTION CLICKS === function bindOptionClicks() { if (window.__cfeQuizOptBound) return; window.__cfeQuizOptBound = true; quizRoot.addEventListener('click', function(e) { var opt = e.target.closest('.cfe-quiz-opt'); if (!opt) return; // Skip pour le contact step (boutons form là-bas) var stepEl = opt.closest('.cfe-quiz-step'); if (!stepEl || stepEl.id === 'qStepContact') return; var block = opt.closest('.cfe-quiz-question-block'); if (!block) return; var field = block.getAttribute('data-field'); var value = opt.getAttribute('data-value'); if (!field) return; handleOptionSelection(opt, block, field, value); }); } function handleOptionSelection(opt, block, field, value) { quizData[field] = value; if (!quizStarted) { quizStarted = true; if (typeof gtag === 'function') { gtag('event', 'quiz_start', { quiz_variant: window.CFE_QUIZ_VARIANT || 'A', event_category: 'quiz', event_label: 'diagnostic_pa' }); } } // Visual feedback (radio) var siblings = block.querySelectorAll('.cfe-quiz-opt'); for (var i = 0; i < siblings.length; i++) { siblings[i].classList.remove('selected'); siblings[i].setAttribute('aria-checked', 'false'); } opt.classList.add('selected'); opt.setAttribute('aria-checked', 'true'); // N3 — Toggle « Autre » precision input pour statut/secteur/logiciel_nom if (field === 'statut' || field === 'secteur' || field === 'logiciel_nom') { toggleOtherPrecision(field, value); // Si l'option « Autre » est cliquée et qu'un texte avait déjà été saisi, on garde if (isOtherValue(value)) { var inp = document.querySelector('.cfe-quiz-other-input[data-for="' + field + '"]'); if (inp && inp.value.trim()) { quizData[field] = 'Autre: ' + inp.value.trim(); } } } // Conditionnel : logiciel_use → afficher 5b if (field === 'logiciel_use') { var blk = document.getElementById('qLogicielNomBlock'); if (value === 'true') { if (blk) blk.style.display = ''; } else { if (blk) blk.style.display = 'none'; quizData.logiciel_nom = ''; // Cacher également l'input « Autre » du logiciel_nom toggleOtherPrecision('logiciel_nom', ''); } } // Détection profil après step 1 si statut+taille remplis if (field === 'statut' || field === 'taille') { var newProfile = detectProfile(); if (newProfile !== profile) { applyWordingFor(newProfile); } } refreshAllNextButtons(); saveProgress(); } // === NEXT BUTTONS === function bindNextButtons() { var nextBtns = document.querySelectorAll('.cfe-quiz-next'); for (var i = 0; i < nextBtns.length; i++) { (function(btn) { btn.addEventListener('click', function(e) { if (btn.disabled) { e.preventDefault(); btn.classList.add('shake'); showInlineWarning(btn, 'Sélectionnez une réponse pour continuer'); setTimeout(function() { btn.classList.remove('shake'); }, 500); return; } var stepNum = parseInt(btn.getAttribute('data-step-num'), 10); handleNext(stepNum); }); })(nextBtns[i]); } } function showInlineWarning(btn, msg) { // Évite doublon var actions = btn.parentNode; var existing = actions.querySelector('.cfe-quiz-inline-warning'); if (existing) existing.remove(); var w = document.createElement('div'); w.className = 'cfe-quiz-inline-warning'; w.textContent = msg; actions.appendChild(w); setTimeout(function() { if (w.parentNode) w.parentNode.removeChild(w); }, 2500); } function handleNext(fromStep) { if (!isStepComplete(fromStep)) return; // GA4: quiz_question_complete par step if (typeof gtag === 'function') { gtag('event', 'quiz_question_complete', { event_category: 'quiz', step: fromStep, quiz_variant: window.CFE_QUIZ_VARIANT || 'A' }); } stepHistory.push(fromStep); if (fromStep < 4) { goToStep(fromStep + 1); } else { submitQuiz(); } } // === BACK BUTTONS === function bindBackButtons() { var backBtns = quizRoot.querySelectorAll('.cfe-quiz-back'); for (var i = 0; i < backBtns.length; i++) { backBtns[i].addEventListener('click', function() { if (stepHistory.length > 0) { var prev = stepHistory.pop(); goToStep(prev); } else { goToStep(1); } }); } } // === B12 — Keyboard navigation === function bindKeyboardNav() { quizRoot.addEventListener('keydown', function(e) { var target = e.target; if (!target || !target.classList || !target.classList.contains('cfe-quiz-opt')) return; var block = target.closest('.cfe-quiz-question-block'); if (!block) return; var opts = Array.prototype.slice.call(block.querySelectorAll('.cfe-quiz-opt')); var idx = opts.indexOf(target); if (idx === -1) return; var key = e.key; var newIdx = idx; if (key === 'ArrowDown' || key === 'ArrowRight') { newIdx = (idx + 1) % opts.length; e.preventDefault(); } else if (key === 'ArrowUp' || key === 'ArrowLeft') { newIdx = (idx - 1 + opts.length) % opts.length; e.preventDefault(); } else if (key === 'Home') { newIdx = 0; e.preventDefault(); } else if (key === 'End') { newIdx = opts.length - 1; e.preventDefault(); } else if (key === 'Enter' || key === ' ') { e.preventDefault(); target.click(); // Si écran complet, déclenche Suivant var stepEl = target.closest('.cfe-quiz-step'); if (stepEl && stepEl.id.indexOf('qStep') === 0 && stepEl.id !== 'qStepContact') { var num = parseInt(stepEl.getAttribute('data-step'), 10); if (num && isStepComplete(num)) { setTimeout(function() { handleNext(num); }, 280); } } return; } else { return; } if (newIdx !== idx) opts[newIdx].focus(); }); } // === CONTACT FORM === function bindContactForm() { rgpdCheckbox.addEventListener('change', function() { submitBtn.style.opacity = rgpdCheckbox.checked ? '1' : '0.6'; }); submitBtn.addEventListener('click', function(e) { e.preventDefault(); submitQuiz(); }); } var gateViewTracked = false; function trackGateView() { if (gateViewTracked) return; gateViewTracked = true; if (typeof gtag === 'function') { gtag('event', 'quiz_gate_view', { event_category: 'quiz', event_label: 'contact_form_displayed' }); } } function cfeSetupPhoneGating() { var help = document.getElementById('qTelephoneHelp'); var phone = document.getElementById('qTelephone'); var entField = document.getElementById('qEntreprise'); var entWrap = entField ? entField.closest('.cfe-quiz-field') : null; var details = phone ? phone.closest('details') : null; var summary = details ? details.querySelector('summary') : null; if (help) help.hidden = false; if (phone) { phone.required = false; phone.removeAttribute('aria-required'); } if (details) details.open = true; if (summary) summary.style.display = 'none'; if (entWrap) entWrap.style.display = 'none'; try { cfeEnsureVariant(); cfeApplyVariantUI(); } catch(e) {} var emailEl = document.getElementById('qEmail'); if (emailEl && !emailEl.dataset.abcBound) { emailEl.dataset.abcBound = '1'; emailEl.addEventListener('blur', function() { try { cfeEnsureVariant(); cfeApplyVariantUI(); } catch(e) {} }); } } function cfeValidatePhone(raw) { if (!raw) return false; var p = raw.replace(/[^0-9+]/g, ''); if (p.indexOf('+33') === 0) p = '0' + p.substring(3); if (p.indexOf('0033') === 0) p = '0' + p.substring(4); return /^0[1-9][0-9]{8}$/.test(p); } function submitQuiz() { errorDiv.style.display = 'none'; var payload = { statut: quizData.statut || '', taille: quizData.taille || '', secteur: quizData.secteur || '', volume: quizData.volume || '', logiciel_use: quizData.logiciel_use === 'true', logiciel_nom: quizData.logiciel_nom || '', budget: quizData.budget || '', expert_comptable: quizData.expert_comptable === 'true', preparation: quizData.preparation || '', prenom: '', nom: '', email: '', telephone: '', entreprise: '', website: '', variant: window.CFE_QUIZ_VARIANT || 'A' }; goToStep('loading'); fetch('/wp-json/cfe/v1/quiz-result', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) .then(function(res) { return res.json(); }) .then(function(data) { if (data.success || data.pa1) { clearProgress(); showResults(data); } else { showError('Une erreur est survenue. Veuillez réessayer.'); } }) .catch(function() { showError('Erreur de connexion. Vérifiez votre connexion internet et réessayez.'); }); } function showError(msg) { goToStep('results'); errorDiv.textContent = msg; errorDiv.style.display = 'block'; } // === P4 — Page résultats 3 niveaux === function showResults(data) { goToStep('results'); // GA4 : quiz_complete if (typeof gtag === 'function') { gtag('event', 'quiz_complete', { quiz_variant: window.CFE_QUIZ_VARIANT || 'A', event_category: 'quiz', event_label: 'diagnostic_pa', pa1: data.pa1 || '', pa2: data.pa2 || '', pa3: data.pa3 || '', segment: data.segment || '' }); var _gatedBudgets = ['20-50€/mois','50-100€/mois','Plus de 100€/mois','Pas de limite','100-500€/mois','Plus de 500€/mois','Plus de 1000€/mois']; if (_gatedBudgets.indexOf(quizData.budget || '') !== -1 && data && data.pa1) { var _phoneEl = document.getElementById('qTelephone'); var _phoneVal = _phoneEl ? _phoneEl.value.trim() : ''; if (_phoneVal) { gtag('event', 'quiz_complete_qualified', { event_category: 'quiz', event_label: 'qualified_lead', budget: quizData.budget, segment: data.segment || '', pa_1: data.pa1 || '', quiz_variant: window.CFE_QUIZ_VARIANT || 'A' }); } } } renderRecap(); renderPodium(data); renderEmailCapture(); renderDetails(data); renderAlternatives(data); renderFreeAlternatives(data); // Animer les barres après insertion dans le DOM requestAnimationFrame(function() { requestAnimationFrame(function() { var fills = document.querySelectorAll('#qStepResults .cfe-quiz-subscore-fill'); for (var fi = 0; fi < fills.length; fi++) { fills[fi].style.width = (fills[fi].getAttribute('data-target') || 0) + '%'; } }); }); } function renderRecap() { var w = WORDINGS[profile] || WORDINGS['default']; var bits = []; if (quizData.statut) bits.push('Profil ' + escapeHtml(w.profile_label) + ''); if (quizData.secteur) bits.push('Secteur ' + escapeHtml(quizData.secteur) + ''); if (quizData.volume) bits.push('Volume ' + escapeHtml(quizData.volume) + ''); if (quizData.budget) bits.push('Budget ' + escapeHtml(quizData.budget) + ''); recap.innerHTML = bits.join(''); } function renderPodium(data) { var pas = [ { nom: data.pa1 || '', slug: data.pa1_slug || '', aff: data.pa1_affiliate_url || '' }, { nom: data.pa2 || '', slug: data.pa2_slug || '', aff: data.pa2_affiliate_url || '' }, { nom: data.pa3 || '', slug: data.pa3_slug || '', aff: data.pa3_affiliate_url || '' } ]; var html = ''; for (var i = 0; i < pas.length; i++) { if (!pas[i].nom) continue; var isAff = !!pas[i].aff; var href = isAff ? pas[i].aff : (pas[i].slug ? ('/' + pas[i].slug + '/') : '/comparateur/'); var target = isAff ? ' target="_blank" rel="nofollow"' : ''; var ctaText = isAff ? ('Essayer ' + pas[i].nom + ' →') : 'Voir notre avis →'; html += '
' + '
' + (i + 1) + '
' + '
' + '' + escapeHtml(ctaText) + '' + '
'; } podium.innerHTML = html; var nameEls = podium.querySelectorAll('.cfe-quiz-pa-name'); for (var j = 0; j < nameEls.length && j < pas.length; j++) { nameEls[j].textContent = pas[j].nom; } // GA4 click tracking var ctaLinks = podium.querySelectorAll('.cfe-quiz-pa-cta'); for (var k = 0; k < ctaLinks.length; k++) { (function(link, pa) { if (!pa.aff) return; link.addEventListener('click', function() { if (typeof gtag === 'function') { gtag('event', 'quiz_pa_card_click', { event_category: 'monetisation', pa_name: pa.nom, link_url: link.getAttribute('href') || '', link_text: link.textContent.trim().substring(0, 50) }); gtag('event', 'affiliate_click', { event_category: 'monetisation', pa_name: pa.nom, link_url: link.getAttribute('href') || '', link_text: link.textContent.trim().substring(0, 50) }); } }); })(ctaLinks[k], pas[k]); } } function renderDetails(data) { var pas = [ { nom: data.pa1 || '', slug: data.pa1_slug || '', aff: data.pa1_affiliate_url || '' }, { nom: data.pa2 || '', slug: data.pa2_slug || '', aff: data.pa2_affiliate_url || '' }, { nom: data.pa3 || '', slug: data.pa3_slug || '', aff: data.pa3_affiliate_url || '' } ]; var html = ''; for (var i = 0; i < pas.length; i++) { if (!pas[i].nom) continue; html += buildDetail(pas[i], i); } detailsWrap.innerHTML = html; } function buildDetail(pa, index) { var why = buildWhyText(pa.nom, index); var subscores = buildSubscores(index); var bonus = buildBonus(pa.nom); var fiche = pa.slug ? ('/' + pa.slug + '/') : '/comparateur/'; return '
' + 'Pourquoi ' + escapeHtml(pa.nom) + ' ressort dans votre top 3' + '
' + '

' + why + '

' + '
' + subscores + '
' + (bonus ? '

Bonus inclus :

' + bonus + '
' : '') + '

Voir notre fiche détaillée ' + escapeHtml(pa.nom) + ' →

' + '
' + '
'; } function buildWhyText(paNom, index) { var w = WORDINGS[profile] || WORDINGS['default']; var pieces = []; if (profile === 'auto_ent') { pieces.push('Pour un profil ' + w.profile_label.toLowerCase() + ', ' + escapeHtml(paNom) + ' couvre la facturation, le suivi de trésorerie et la déclaration TVA dans une interface claire.'); } else if (profile === 'tpe') { pieces.push('Pour une TPE comme la vôtre, ' + escapeHtml(paNom) + ' équilibre fonctionnalités complètes et prise en main rapide pour toute votre équipe.'); } else if (profile === 'pme') { pieces.push('Pour une PME, ' + escapeHtml(paNom) + ' couvre la multi-utilisateurs, l\u2019intégration comptable poussée et la conformité PA.'); } else if (profile === 'eti') { pieces.push('Pour une ETI, ' + escapeHtml(paNom) + ' propose les volumes, l\u2019API et la flexibilité multi-entités attendues à votre échelle.'); } else { pieces.push(escapeHtml(paNom) + ' colle à votre profil sur les axes les plus importants : tarif, fonctionnalités et conformité PA.'); } if (quizData.secteur) { pieces.push('Adapté au secteur ' + escapeHtml(quizData.secteur) + ' avec les modèles et catégorisations qui vont bien.'); } if (quizData.expert_comptable === 'true') { pieces.push('Connexion avec votre expert-comptable simplifiée : il peut récupérer vos données sans manip\u2019 manuelle.'); } return pieces.join(' '); } function buildSubscores(index) { // Mini-bars éditoriales (heuristiques visuelles, pas exactes) var base = [92, 87, 81]; // Top 1 / 2 / 3 var paBase = base[index] || 80; var rows = [ { label: 'Tarif vs profil', val: clamp(paBase + (quizData.budget && quizData.budget.indexOf('Gratuit') !== -1 ? 5 : 0)) }, { label: 'Fonctionnalités', val: clamp(paBase - 2) }, { label: 'Facilité de prise en main', val: clamp(paBase + (profile === 'auto_ent' ? 4 : 0)) }, { label: 'Support et formation', val: clamp(paBase - 5) }, { label: 'Conformité PA', val: clamp(98) } ]; var html = ''; for (var i = 0; i < rows.length; i++) { html += '
' + '' + escapeHtml(rows[i].label) + '' + '' + '' + rows[i].val + '%' + '
'; } return html; } function clamp(v) { if (v < 30) return 30; if (v > 100) return 100; return v; } function buildBonus(paNom) { var bonusMap = { 'Indy': ['Compte pro inclus', 'Déclaration TVA auto', 'App mobile', 'Premium gratuit pour micros'], 'Tiime': ['2 mois Business offerts', 'Compte pro inclus', 'OCR factures', 'Support 6j/7'], 'Sellsy': ['CRM intégré', 'Devis et factures liés', 'Multi-utilisateurs', 'Suivi des paiements'], 'Pennylane': ['Pré-comptabilité auto', 'Connexion banque', 'Partage cabinet EC', 'Tableau de bord'], 'Qonto': ['Compte pro Néobanque', 'Cartes équipe', 'Intégrations comptables'], 'Axonaut': ['CRM commercial', 'Ticketing support', 'Trésorerie', 'Multi-devises'], 'Abby': ['Spécial micro', 'Déclaration URSSAF', 'Compte pro inclus', 'Mobile-first'], 'Sage': ['Suite comptable complète', 'Multi-établissements', 'Conformité paye'], 'Dext': ['OCR best-in-class', 'Préparation comptable', 'Connexion cabinet'] }; var arr = bonusMap[paNom] || ['Plateforme agréée', 'Accompagnement réforme', 'Support FR']; var html = ''; for (var i = 0; i < arr.length; i++) { html += '' + escapeHtml(arr[i]) + ''; } return html; } function renderEmailCapture() { var existing = document.getElementById('qEmailCapture'); if (existing) return; var wrap = document.createElement('div'); wrap.id = 'qEmailCapture'; wrap.className = 'cfe-quiz-email-capture'; wrap.innerHTML = '
' + '
📩
' + '
' + 'Recevoir vos recommandations + le guide PDF gratuit' + 'Résumé de votre diagnostic · Guide 2026 · Sans spam' + '
' + '
' + '' + '' + '' + '
' + '' + '
'; var podium = document.getElementById('qPodium'); if (podium && podium.nextSibling) { podium.parentNode.insertBefore(wrap, podium.nextSibling); } else { document.getElementById('qStepResults').appendChild(wrap); } document.getElementById('qCaptureSubmit').addEventListener('click', function() { var emailVal = document.getElementById('qCaptureEmail').value.trim(); var prenomVal = document.getElementById('qCapturePrenom').value.trim(); var msgEl = document.getElementById('qCaptureMsg'); var ok = true; if (!emailVal || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailVal)) { document.getElementById('qCaptureEmail').classList.add('error'); ok = false; } else { document.getElementById('qCaptureEmail').classList.remove('error'); } if (!ok) return; document.getElementById('qCaptureSubmit').disabled = true; fetch('/wp-json/cfe/v1/quiz-optin', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ statut: quizData.statut || '', taille: quizData.taille || '', secteur: quizData.secteur || '', volume: quizData.volume || '', logiciel_use: quizData.logiciel_use === 'true', logiciel_nom: quizData.logiciel_nom || '', budget: quizData.budget || '', expert_comptable: quizData.expert_comptable === 'true', preparation: quizData.preparation || '', prenom: prenomVal, email: emailVal, telephone: '', entreprise: '', website: '' }) }) .then(function(r) { return r.json(); }) .then(function() { document.getElementById('qCapturePrenom').style.display = 'none'; document.getElementById('qCaptureEmail').style.display = 'none'; document.getElementById('qCaptureSubmit').style.display = 'none'; msgEl.textContent = '✅ Guide envoyé ! Vérifiez votre boîte mail (pensez aux spams).'; msgEl.style.display = 'block'; if (typeof gtag === 'function') gtag('event', 'quiz_email_capture', { event_category: 'quiz', has_prenom: prenomVal ? 'yes' : 'no' }); }) .catch(function() { document.getElementById('qCaptureSubmit').disabled = false; msgEl.textContent = 'Erreur — réessayez dans quelques secondes.'; msgEl.style.display = 'block'; }); }); } function renderFreeAlternatives(data) { var existing = document.getElementById('qFreeAlts'); if (existing) return; var alts = data.free_alternatives; if (!alts || alts.length === 0) return; var html = '
' + '

Alternatives gratuites à tester

' + '

Ces solutions sont 100 % gratuites et conformes à la réforme.

' + '
'; for (var i = 0; i < alts.length; i++) { var a = alts[i]; var href = a.affiliate_url || (a.slug ? '/' + a.slug + '/' : '/plateformes-agreees/'); html += '
' + '' + escapeHtml(a.nom) + '' + 'Gratuit' + 'Essayer gratuitement →' + '
'; } html += '
'; var metaCtas = document.querySelector('#qStepResults .cfe-quiz-meta-ctas'); if (metaCtas) { metaCtas.insertAdjacentHTML('beforebegin', html); } else { document.getElementById('qStepResults').insertAdjacentHTML('beforeend', html); } } function renderAlternatives(data) { // L'endpoint v2 ne renvoie pour l'instant que pa1/2/3. // On peut afficher des fallbacks éditoriaux en attendant l'extension API, // OU masquer la section si pas de data.alternatives. var alts = (data && data.alternatives) ? data.alternatives : []; if (!alts || alts.length === 0) { altWrap.style.display = 'none'; return; } altWrap.style.display = ''; var html = ''; for (var i = 0; i < alts.length; i++) { var a = alts[i]; var href = a.slug ? ('/' + a.slug + '/') : '/plateformes-agreees/'; var score = (typeof a.score === 'number') ? (a.score + '%') : ''; html += '
' + '' + escapeHtml(a.nom || '') + '' + (score ? '' + score + '' : '') + 'Voir la fiche →' + '
'; } altList.innerHTML = html; } // === RESTART === function bindRestart() { restartBtn.addEventListener('click', function() { quizData = {}; stepHistory = []; profile = 'default'; clearProgress(); applyWordingFor('default'); errorDiv.style.display = 'none'; var cap = document.getElementById('qEmailCapture'); if (cap) cap.remove(); var allOpts = document.querySelectorAll('.cfe-quiz-opt'); for (var i = 0; i < allOpts.length; i++) { allOpts[i].classList.remove('selected'); allOpts[i].setAttribute('aria-checked', 'false'); } var blk = document.getElementById('qLogicielNomBlock'); if (blk) blk.style.display = 'none'; // N3 — Reset « Autre » inputs var otherBlocks = document.querySelectorAll('.cfe-quiz-other-precision'); for (var i2 = 0; i2 < otherBlocks.length; i2++) otherBlocks[i2].hidden = true; var otherInputs = document.querySelectorAll('.cfe-quiz-other-input'); for (var i3 = 0; i3 < otherInputs.length; i3++) otherInputs[i3].value = ''; header.style.display = ''; goToStep(1); }); } // === UTILS === function isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } // === A/B/C TEST helpers (préservés v1) === function cfeGetABCVariant(email) { if (!email) return 'A'; var h = 0; var s = email.toLowerCase(); for (var i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) % 999983; return ['A', 'B', 'C'][Math.abs(h) % 3]; } function cfeIsBudgetPayant() { var b = (quizData.budget || '').toLowerCase(); if (!b) return false; return b.indexOf('gratuit') === -1 && b.indexOf('moins de 20') === -1; } function cfeEnsureVariant() { var emailEl = document.getElementById('qEmail'); var v = cfeGetABCVariant(emailEl ? (emailEl.value || '').trim() : ''); window.CFE_QUIZ_VARIANT = v; return v; } function cfeApplyVariantUI() { var existingBanner = document.getElementById('qVariantBanner'); if (existingBanner) existingBanner.remove(); var entField = document.getElementById('qEntreprise'); var entWrap = entField ? entField.closest('.cfe-quiz-field') : null; var phone = document.getElementById('qTelephone'); var details = phone ? phone.closest('details') : null; if (!details) return; if (phone) { phone.required = false; phone.classList.remove('error'); } if (entField) { entField.required = false; entField.classList.remove('error'); } var variant = window.CFE_QUIZ_VARIANT || 'A'; if (variant === 'A') return; var payant = cfeIsBudgetPayant(); if ((variant === 'B' || variant === 'C') && payant) { if (entWrap) entWrap.style.display = ''; if (phone) phone.required = true; if (entField) entField.required = true; var banner = document.createElement('div'); banner.id = 'qVariantBanner'; banner.style.cssText = 'background:rgba(0,119,255,0.15);border:1px solid rgba(0,119,255,0.40);border-radius:8px;padding:10px 14px;margin-bottom:14px;font-size:13px;color:rgba(255,255,255,0.85);line-height:1.5;'; banner.innerHTML = 'Mise en relation prioritaire. Au vu de votre budget, on peut activer un devis personnalisé sur la plateforme recommandée. Téléphone et entreprise nécessaires.'; details.parentNode.insertBefore(banner, details); } else if (variant === 'C' && !payant) { if (entWrap) entWrap.style.display = ''; var banner2 = document.createElement('div'); banner2.id = 'qVariantBanner'; banner2.style.cssText = 'background:rgba(255,107,53,0.10);border:1px solid rgba(255,107,53,0.30);border-radius:8px;padding:10px 14px;margin-bottom:14px;font-size:13px;color:rgba(255,255,255,0.75);line-height:1.5;'; banner2.innerHTML = 'Bonus. Ajoutez votre téléphone et votre entreprise pour activer la mise en relation prioritaire (optionnel mais utile).'; details.parentNode.insertBefore(banner2, details); } } // === ESCAPE HELPERS === function escapeAttr(str) { var d = document.createElement('div'); d.appendChild(document.createTextNode(String(str == null ? '' : str))); return d.innerHTML.replace(/"/g, '"'); } function escapeHtml(str) { var d = document.createElement('div'); d.appendChild(document.createTextNode(String(str == null ? '' : str))); return d.innerHTML; } // === GO === if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();