{"id":484,"date":"2026-08-23T21:43:08","date_gmt":"2026-08-23T21:43:08","guid":{"rendered":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/?page_id=484"},"modified":"2026-08-23T21:43:10","modified_gmt":"2026-08-23T21:43:10","slug":"devis","status":"publish","type":"page","link":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/devis\/","title":{"rendered":"Devis"},"content":{"rendered":"\n<meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\n  <title>Demande de Devis \u2014 Auto-\u00c9cole Vivaroise<\/title>\n\n  <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n  <link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin=\"\">\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Cormorant+Garamond:wght@400;500;600;700&amp;family=DM+Sans:wght@300;400;500;600&amp;display=swap\" rel=\"stylesheet\">\n  <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/@emailjs\/browser@4\/dist\/email.min.js\"><\/script>\n  <!-- html2canvas + jsPDF : capture HTML -> PDF pixel perfect -->\n  <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/html2canvas\/1.4.1\/html2canvas.min.js\"><\/script>\n  <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js\"><\/script>\n  <!-- Firebase SDK -->\n  <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-app-compat.js\"><\/script>\n  <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-firestore-compat.js\"><\/script>\n  <script src=\"https:\/\/www.gstatic.com\/firebasejs\/9.22.2\/firebase-auth-compat.js\"><\/script>\n  <style>\n    :root{--navy:#20315b;--navy-dark:#0d1b35;--cream:#fff9f1;--stone:#777569;--gold:#cfca77;--gold-dark:#b0ab5a;--error:#c0392b;--white:#ffffff;--shadow:0 8px 40px rgba(0,0,0,0.35);--radius:14px;--transition:0.35s cubic-bezier(0.4,0,0.2,1);}\n    \/* Scrollbar charte graphique *\/\n    ::-webkit-scrollbar{width:10px;height:10px;}\n    ::-webkit-scrollbar-track{background:#20315b;}\n    ::-webkit-scrollbar-thumb{background:#cfca77;border-radius:6px;border:2px solid #20315b;}\n    ::-webkit-scrollbar-thumb:hover{background:#b0ab5a;}\n    *{scrollbar-width:thin;scrollbar-color:#cfca77 #20315b;}\n    *,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}\n    html{scroll-behavior:smooth;}\n    \/* Scrollbar charte graphique *\/\n    ::-webkit-scrollbar{width:8px;height:8px;}\n    ::-webkit-scrollbar-track{background:var(--navy);}\n    ::-webkit-scrollbar-thumb{background:var(--gold);border-radius:4px;}\n    ::-webkit-scrollbar-thumb:hover{background:var(--gold-dark);}\n    * { scrollbar-width:thin; scrollbar-color:var(--gold) var(--navy); }\n    \/* \u2500\u2500 Force fond sombre sur body uniquement \u2014 les conteneurs Elementor restent transparents \u2500\u2500 *\/\n    body,\n    body.home,body.page,\n    body.elementor-default,\n    body.elementor-kit-active{\n      background-color:#0d1b35 !important;\n      background-image:none !important;\n    }\n    body{font-family:\"DM Sans\",sans-serif;background:var(--navy-dark)!important;color:var(--white);min-height:100vh;overflow-x:hidden;}\n    body::before{content:'';position:fixed;inset:0;background:radial-gradient(ellipse 900px 700px at 15% 25%,rgba(32,49,91,0.55) 0%,transparent 65%),radial-gradient(ellipse 700px 900px at 85% 75%,rgba(13,27,53,0.7) 0%,transparent 65%),radial-gradient(ellipse 600px 400px at 50% 0%,rgba(207,202,119,0.04) 0%,transparent 50%);pointer-events:none;z-index:0;}\n    main{position:relative;z-index:1;max-width:720px;margin:0 auto;padding:32px 24px 80px;}\n    .hero{text-align:center;margin-bottom:28px;animation:fadeInUp 0.6s ease both;}\n    .hero-eyebrow{display:inline-flex;align-items:center;gap:8px;background:rgba(207,202,119,0.18);border:1px solid rgba(207,202,119,0.4);color:var(--gold-dark);font-size:0.72rem;font-weight:600;letter-spacing:0.14em;text-transform:uppercase;padding:6px 16px;border-radius:100px;margin-bottom:18px;}\n    .hero h2{font-family:'Cormorant Garamond',serif;font-size:clamp(2rem,5vw,2.9rem);font-weight:700;line-height:1.15;color:var(--white);margin-bottom:14px;}\n    .hero h2 span{color:var(--gold-dark);}\n    .hero p{font-size:0.97rem;color:rgba(255,255,255,0.62);line-height:1.7;max-width:500px;margin:0 auto;}\n    .progress-wrapper{margin-bottom:24px;animation:fadeInUp 0.6s 0.1s ease both;}\n    .progress-meta{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;}\n    .progress-label{font-size:0.75rem;font-weight:600;color:rgba(255,255,255,0.5);letter-spacing:0.08em;text-transform:uppercase;}\n    .progress-count{font-size:0.75rem;font-weight:600;color:var(--gold);}\n    .progress-track{height:6px;background:rgba(255,255,255,0.12);border-radius:100px;overflow:hidden;}\n    .progress-fill{height:100%;background:linear-gradient(90deg,var(--navy),var(--gold));border-radius:100px;transition:width 0.5s cubic-bezier(0.4,0,0.2,1);width:0%;}\n    .card{background:var(--white);border-radius:var(--radius);box-shadow:0 12px 60px rgba(0,0,0,0.45),0 2px 8px rgba(0,0,0,0.2);border:1px solid rgba(255,255,255,0.08);overflow:hidden;animation:fadeInUp 0.5s 0.15s ease both;}\n    .card-header{background:linear-gradient(135deg,var(--navy) 0%,#2d4475 100%);padding:28px 36px 24px;position:relative;overflow:hidden;}\n    .card-header::after{content:'';position:absolute;top:-30px;right:-30px;width:120px;height:120px;border-radius:50%;background:rgba(207,202,119,0.12);}\n    .step-indicator{display:inline-flex;align-items:center;gap:8px;background:rgba(207,202,119,0.15);border:1px solid rgba(207,202,119,0.3);padding:4px 12px;border-radius:100px;margin-bottom:10px;}\n    .step-dot{width:7px;height:7px;background:var(--gold);border-radius:50%;}\n    .step-indicator span{font-size:0.7rem;font-weight:600;letter-spacing:0.1em;text-transform:uppercase;color:var(--gold);}\n    .card-header h3{font-family:'Cormorant Garamond',serif;font-size:1.55rem;font-weight:600;color:var(--white);line-height:1.25;}\n    .card-header p{font-size:0.85rem;color:rgba(255,255,255,0.6);margin-top:6px;line-height:1.5;}\n    .card-body{padding:32px 36px;}\n    .options{display:flex;flex-direction:column;gap:12px;}\n    .options.horizontal{flex-direction:row;flex-wrap:wrap;}\n    .option-btn{display:flex;align-items:center;gap:14px;padding:16px 20px;border:2px solid rgba(32,49,91,0.12);border-radius:10px;background:var(--cream);cursor:pointer;transition:var(--transition);text-align:left;font-family:\"DM Sans\",sans-serif;font-size:0.95rem;font-weight:400;color:var(--navy);position:relative;overflow:hidden;}\n    .option-btn::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--gold);transform:scaleY(0);transform-origin:bottom;transition:transform 0.25s ease;}\n    .option-btn:hover{border-color:var(--navy);background:rgba(32,49,91,0.04);transform:translateX(4px);}\n    .option-btn:hover::before{transform:scaleY(1);}\n    .option-btn .btn-icon{width:38px;height:38px;background:rgba(32,49,91,0.08);border-radius:8px;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:1.1rem;transition:var(--transition);}\n    .option-btn:hover .btn-icon{background:var(--navy);color:var(--white);}\n    .option-btn .btn-text{flex:1;}\n    .option-btn .btn-label{font-weight:500;}\n    .option-btn .btn-sub{font-size:0.78rem;color:var(--stone);margin-top:2px;line-height:1.4;}\n    .options.horizontal .option-btn{flex:1;min-width:140px;flex-direction:column;text-align:center;padding:20px 16px;gap:10px;}\n    .options.horizontal .option-btn .btn-icon{width:46px;height:46px;margin:0 auto;font-size:1.3rem;}\n    .checkbox-group{display:flex;flex-direction:column;gap:14px;}\n    .checkbox-item{display:flex;align-items:flex-start;gap:14px;padding:18px 20px;border:2px solid rgba(32,49,91,0.12);border-radius:10px;background:var(--cream);cursor:pointer;transition:var(--transition);}\n    .checkbox-item:hover{border-color:rgba(32,49,91,0.3);}\n    .checkbox-item.checked{border-color:var(--navy);background:rgba(32,49,91,0.04);}\n    .checkbox-item input[type=\"checkbox\"]{display:none;}\n    .check-box{width:22px;height:22px;flex-shrink:0;border:2px solid rgba(32,49,91,0.3);border-radius:6px;background:var(--white);display:flex;align-items:center;justify-content:center;transition:var(--transition);margin-top:1px;}\n    .checkbox-item.checked .check-box{background:var(--navy);border-color:var(--navy);}\n    .check-mark{color:var(--white);font-size:13px;opacity:0;transform:scale(0.5);transition:all 0.2s ease;}\n    .checkbox-item.checked .check-mark{opacity:1;transform:scale(1);}\n    .checkbox-text{font-size:0.9rem;line-height:1.55;color:var(--navy);}\n    .identity-form{display:flex;flex-direction:column;gap:18px;}\n    .form-row{display:flex;gap:12px;}\n    .form-group{display:flex;flex-direction:column;gap:7px;flex:1;}\n    .form-group label{font-size:0.78rem;font-weight:600;color:var(--navy);letter-spacing:0.06em;text-transform:uppercase;}\n    .form-group input{padding:13px 16px;border:2px solid rgba(32,49,91,0.15);border-radius:9px;background:var(--cream);font-family:\"DM Sans\",sans-serif;font-size:0.95rem;color:var(--navy);transition:var(--transition);outline:none;}\n    .form-group input:focus{border-color:var(--navy);background:var(--white);box-shadow:0 0 0 3px rgba(32,49,91,0.08);}\n    .form-group input::placeholder{color:rgba(119,117,105,0.5);}\n    .form-group input.field-error{border-color:var(--error)!important;box-shadow:0 0 0 3px rgba(192,57,43,0.12)!important;}\n    .field-error-msg{font-size:0.74rem;color:var(--error);margin-top:3px;display:none;}\n    .field-error-msg.visible{display:block;}\n    .form-group input.optional-field{border-style:dashed;}\n    .field-hint{font-size:0.74rem;color:var(--stone);margin-top:3px;}\n    \/* \u00c9tats d'erreur sur les champs *\/\n    .form-group input.field-error{border-color:var(--error)!important;background:rgba(192,57,43,0.04)!important;animation:shake 0.3s ease;}\n    .form-group input.field-error:focus{box-shadow:0 0 0 3px rgba(192,57,43,0.12)!important;}\n    .field-error-msg{font-size:0.72rem;color:var(--error);margin-top:3px;display:none;}\n    .field-error-msg.visible{display:block;}\n    .civilite-btn.civ-error{border-color:var(--error)!important;background:rgba(192,57,43,0.04)!important;}\n    @keyframes shake{0%,100%{transform:translateX(0);}25%{transform:translateX(-4px);}75%{transform:translateX(4px);}}\n    \/* Champ t\u00e9l\u00e9phone avec indicatif *\/\n    .tel-group{display:flex;gap:8px;align-items:stretch;}\n    .tel-prefix-wrap{position:relative;flex-shrink:0;}\n    .tel-prefix-select{padding:13px 28px 13px 10px;border:2px solid rgba(32,49,91,0.15);border-radius:9px;background:var(--cream);font-family:'DM Sans',sans-serif;font-size:0.88rem;color:var(--navy);appearance:none;-webkit-appearance:none;cursor:pointer;outline:none;transition:var(--transition);min-width:90px;}\n    .tel-prefix-select:focus{border-color:var(--navy);background:var(--white);box-shadow:0 0 0 3px rgba(32,49,91,0.08);}\n    .tel-prefix-wrap::after{content:'\u25be';position:absolute;right:8px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--stone);font-size:0.8rem;}\n    .tel-input-main{flex:1;padding:13px 16px;border:2px solid rgba(32,49,91,0.15);border-radius:9px;background:var(--cream);font-family:'DM Sans',sans-serif;font-size:0.95rem;color:var(--navy);transition:var(--transition);outline:none;}\n    .tel-input-main:focus{border-color:var(--navy);background:var(--white);box-shadow:0 0 0 3px rgba(32,49,91,0.08);}\n    .tel-input-main.field-error{border-color:var(--error)!important;}\n    \/* RGPD checkbox *\/\n    .rgpd-check-row{display:flex;align-items:flex-start;gap:12px;margin-top:14px;padding:12px 14px;background:rgba(32,49,91,0.05);border-radius:8px;border:2px solid rgba(32,49,91,0.1);cursor:pointer;transition:var(--transition);}\n    .rgpd-check-row:hover{border-color:rgba(32,49,91,0.25);}\n    .rgpd-check-row.checked{border-color:var(--navy);background:rgba(32,49,91,0.08);}\n    .rgpd-check-row.civ-error{border-color:var(--error)!important;}\n    .rgpd-chkbox{width:20px;height:20px;flex-shrink:0;border:2px solid rgba(32,49,91,0.3);border-radius:5px;background:var(--white);display:flex;align-items:center;justify-content:center;transition:var(--transition);margin-top:1px;}\n    .rgpd-check-row.checked .rgpd-chkbox{background:var(--navy);border-color:var(--navy);}\n    .rgpd-chk-mark{color:var(--white);font-size:11px;opacity:0;transform:scale(0.5);transition:all 0.2s;}\n    .rgpd-check-row.checked .rgpd-chk-mark{opacity:1;transform:scale(1);}\n    .rgpd-chk-text{font-size:0.8rem;color:var(--stone);line-height:1.55;}\n    .rgpd-chk-text strong{color:var(--navy);}\n    .civilite-label{font-size:0.78rem;font-weight:600;color:var(--navy);letter-spacing:0.06em;text-transform:uppercase;}\n    .civilite-group{display:flex;gap:10px;margin-top:7px;}\n    .civilite-btn{flex:1;padding:13px 8px;border:2px solid rgba(32,49,91,0.15);border-radius:9px;background:var(--cream);font-family:\"DM Sans\",sans-serif;font-size:0.9rem;font-weight:500;color:var(--navy);cursor:pointer;transition:var(--transition);text-align:center;}\n    .civilite-btn:hover{border-color:var(--navy);background:rgba(32,49,91,0.04);}\n    .civilite-btn.selected{border-color:var(--navy);background:var(--navy);color:var(--white);}\n    .form-section-title{font-size:0.75rem;font-weight:700;color:var(--stone);letter-spacing:0.1em;text-transform:uppercase;padding-bottom:8px;border-bottom:1px solid rgba(32,49,91,0.1);margin-top:4px;}\n    .rgpd-notice{margin-top:20px;background:rgba(32,49,91,0.04);border:1px solid rgba(32,49,91,0.15);border-left:4px solid var(--navy);border-radius:0 10px 10px 0;padding:16px 18px;}\n    .rgpd-notice .rgpd-title{display:flex;align-items:center;gap:8px;font-size:0.78rem;font-weight:700;color:var(--navy);letter-spacing:0.07em;text-transform:uppercase;margin-bottom:10px;}\n    .rgpd-notice p{font-size:0.8rem;color:var(--stone);line-height:1.65;margin-bottom:8px;}\n    .rgpd-notice p:last-child{margin-bottom:0;}\n    .rgpd-notice strong{color:var(--navy);}\n    .rgpd-notice a{color:var(--navy);text-decoration:underline;}\n    .btn-continue{margin-top:20px;width:100%;padding:16px 24px;background:linear-gradient(135deg,var(--navy),#2d4475);color:var(--white);border:none;border-radius:10px;font-family:\"DM Sans\",sans-serif;font-size:0.95rem;font-weight:600;cursor:pointer;letter-spacing:0.04em;display:flex;align-items:center;justify-content:center;gap:10px;transition:var(--transition);box-shadow:0 4px 16px rgba(32,49,91,0.25);}\n    .btn-continue:hover{transform:translateY(-2px);box-shadow:0 8px 28px rgba(32,49,91,0.35);}\n    .btn-continue:active{transform:translateY(0);}\n    .btn-continue:disabled{opacity:0.4;cursor:not-allowed;transform:none;box-shadow:none;}\n    .btn-arrow{font-size:1rem;transition:transform 0.2s;}\n    .btn-continue:hover:not(:disabled) .btn-arrow{transform:translateX(4px);}\n    .nav-row{display:flex;gap:10px;margin-top:14px;}\n    .btn-back{flex:1;display:flex;align-items:center;justify-content:center;gap:7px;padding:11px 16px;background:transparent;border:1.5px solid rgba(32,49,91,0.2);border-radius:9px;color:var(--stone);font-family:\"DM Sans\",sans-serif;font-size:0.82rem;font-weight:500;cursor:pointer;transition:var(--transition);}\n    .btn-back:hover{border-color:rgba(255,255,255,0.4);color:var(--white);background:rgba(255,255,255,0.1);}\n    .btn-reset{display:flex;align-items:center;justify-content:center;gap:7px;padding:11px 16px;background:transparent;border:1.5px solid rgba(192,57,43,0.25);border-radius:9px;color:rgba(192,57,43,0.7);font-family:\"DM Sans\",sans-serif;font-size:0.82rem;font-weight:500;cursor:pointer;transition:var(--transition);white-space:nowrap;}\n    .btn-reset:hover{border-color:var(--error);color:var(--error);background:rgba(192,57,43,0.04);}\n    .error-card{background:var(--white);border-radius:var(--radius);box-shadow:0 12px 60px rgba(0,0,0,0.45);border:2px solid rgba(192,57,43,0.25);overflow:hidden;animation:fadeInUp 0.4s ease both;}\n    .error-card .card-header{background:linear-gradient(135deg,var(--error),#a93226);}\n    .error-body{padding:32px 36px;}\n    .error-message{background:rgba(192,57,43,0.06);border-left:4px solid var(--error);border-radius:0 8px 8px 0;padding:16px 20px;font-size:0.93rem;line-height:1.6;color:var(--navy);margin-bottom:20px;}\n    .error-actions{display:flex;gap:10px;flex-wrap:wrap;}\n    .btn-modify{display:inline-flex;align-items:center;gap:8px;padding:13px 20px;background:var(--navy);border:2px solid var(--navy);border-radius:10px;color:var(--white);font-family:\"DM Sans\",sans-serif;font-size:0.88rem;font-weight:600;cursor:pointer;transition:var(--transition);}\n    .btn-modify:hover{background:#2d4475;border-color:#2d4475;}\n    .btn-restart-red{display:inline-flex;align-items:center;gap:8px;padding:13px 20px;background:transparent;border:2px solid rgba(192,57,43,0.4);border-radius:10px;color:var(--error);font-family:\"DM Sans\",sans-serif;font-size:0.88rem;font-weight:600;cursor:pointer;transition:var(--transition);}\n    .btn-restart-red:hover{background:var(--error);color:var(--white);border-color:var(--error);}\n    .success-card{background:var(--white);border-radius:var(--radius);box-shadow:0 12px 60px rgba(0,0,0,0.45);border:2px solid rgba(207,202,119,0.4);overflow:hidden;animation:fadeInUp 0.5s ease both;}\n    .success-card .card-header{background:linear-gradient(135deg,#1a6b3c,#27ae60);}\n    .success-body{padding:36px 36px 32px;}\n    .ref-box{background:linear-gradient(135deg,var(--navy),#2d4475);border-radius:12px;padding:22px 24px;margin-bottom:24px;text-align:center;position:relative;overflow:hidden;}\n    .ref-box::after{content:'';position:absolute;top:-20px;right:-20px;width:80px;height:80px;border-radius:50%;background:rgba(207,202,119,0.15);}\n    .ref-label{font-size:0.72rem;font-weight:600;letter-spacing:0.14em;text-transform:uppercase;color:rgba(255,255,255,0.55);margin-bottom:8px;}\n    .ref-number{font-family:'Courier New',monospace;font-size:2.8rem;font-weight:700;color:var(--gold);letter-spacing:0.3em;text-shadow:0 2px 8px rgba(0,0,0,0.2);}\n    .ref-sub{font-size:0.78rem;color:rgba(255,255,255,0.5);margin-top:8px;line-height:1.6;}\n    .recap-box{background:linear-gradient(135deg,rgba(32,49,91,0.05),rgba(207,202,119,0.1));border:1px solid rgba(207,202,119,0.4);border-radius:10px;padding:20px 22px;margin-bottom:20px;}\n    .recap-box h4{font-family:'Cormorant Garamond',serif;font-size:1.1rem;font-weight:700;color:var(--navy);margin-bottom:14px;}\n    .recap-row{display:flex;gap:10px;font-size:0.86rem;color:var(--stone);margin-bottom:6px;align-items:flex-start;}\n    .recap-row:last-child{margin-bottom:0;}\n    .recap-label{font-weight:600;color:var(--navy);min-width:130px;flex-shrink:0;}\n    .docs-box{background:rgba(207,202,119,0.1);border:1px solid rgba(207,202,119,0.35);border-radius:10px;padding:18px 20px;margin-bottom:20px;}\n    .docs-box h5{font-size:0.82rem;font-weight:700;color:var(--navy);letter-spacing:0.06em;text-transform:uppercase;margin-bottom:12px;}\n    .docs-box ul{padding-left:18px;}\n    .docs-box li{font-size:0.84rem;color:var(--navy);line-height:1.65;margin-bottom:4px;}\n    .docs-box li:last-child{margin-bottom:0;}\n    .btn-download-pdf{display:flex;align-items:center;justify-content:center;gap:12px;width:100%;padding:18px 24px;background:linear-gradient(135deg,var(--gold-dark),var(--gold));color:var(--navy);border:none;border-radius:10px;font-family:\"DM Sans\",sans-serif;font-size:1rem;font-weight:700;cursor:pointer;text-decoration:none;transition:var(--transition);box-shadow:0 4px 16px rgba(207,202,119,0.45);}\n    .btn-download-pdf:hover{transform:translateY(-2px);box-shadow:0 8px 28px rgba(207,202,119,0.55);}\n    .note-box{margin-top:16px;background:rgba(32,49,91,0.04);border-radius:8px;padding:14px 18px;font-size:0.82rem;color:var(--stone);line-height:1.55;}\n    .note-box strong{color:var(--navy);}\n    .sending-state{text-align:center;padding:10px 0 14px;}\n    .spinner{width:26px;height:26px;border:3px solid rgba(32,49,91,0.15);border-top-color:var(--navy);border-radius:50%;animation:spin 0.8s linear infinite;margin:0 auto 8px;}\n    @keyframes spin{to{transform:rotate(360deg);}}\n    .sending-text{font-size:0.82rem;color:var(--stone);}\n    .info-notice{background:rgba(32,49,91,0.18);border:1px solid rgba(255,255,255,0.06);border-radius:8px;padding:14px 18px;font-size:0.84rem;color:var(--navy);line-height:1.55;margin-bottom:20px;}\n    .success-notice{background:rgba(39,174,96,0.07);border:1px solid rgba(39,174,96,0.3);border-radius:8px;padding:14px 18px;font-size:0.84rem;color:#1a6b3c;line-height:1.55;margin-bottom:20px;}\n    @keyframes fadeInUp{from{opacity:0;transform:translateY(22px);}to{opacity:1;transform:translateY(0);}}\n    .step-enter{animation:fadeInRight 0.35s ease both;}\n    @keyframes fadeInRight{from{opacity:0;transform:translateX(20px);}to{opacity:1;transform:translateX(0);}}\n    \/* Scrollbar personnalis\u00e9e \u2014 or sur fond bleu marine *\/\n    ::-webkit-scrollbar{width:9px;height:9px;}\n    ::-webkit-scrollbar-track{background:var(--navy);}\n    ::-webkit-scrollbar-thumb{background:var(--gold);border-radius:100px;}\n    ::-webkit-scrollbar-thumb:hover{background:var(--gold-dark);}\n    html{scrollbar-color:var(--gold) var(--navy);scrollbar-width:thin;}\n    @media(max-width:600px){\n      main{padding:32px 16px 60px;}\n      .card-header{padding:22px 22px 18px;}\n      .card-body{padding:24px 22px;}\n      .error-body,.success-body{padding:24px 22px;}\n      .options.horizontal{flex-direction:column;}\n      .recap-label{min-width:100px;}\n      .form-row{flex-direction:column;}\n      .ref-number{font-size:2rem;letter-spacing:0.2em;}\n      .error-actions{flex-direction:column;}\n      .nav-row{flex-direction:column;}\n    }\n  <\/style>\n\n\n<main>\n  <div class=\"hero\">\n    <h2>Obtenez votre devis<br><span>personnalis\u00e9<\/span><\/h2>\n    <p>R\u00e9pondez a quelques questions rapides pour verifier votre \u00e9ligibilit\u00e9 et t\u00e9l\u00e9charger le devis correspondant \u00e0 votre profil.<\/p>\n  <\/div>\n  <div class=\"progress-wrapper\" id=\"progressWrapper\">\n    <div class=\"progress-meta\">\n      <span class=\"progress-label\">Progression<\/span>\n      <span class=\"progress-count\" id=\"progressCount\">\u00c9tape 1<\/span>\n    <\/div>\n    <div class=\"progress-track\"><div class=\"progress-fill\" id=\"progressFill\"><\/div><\/div>\n  <\/div>\n  <div id=\"stepContainer\">\n    <div id=\"devis-fallback\" style=\"display:none;background:#fff;border-radius:14px;padding:32px 36px;box-shadow:0 8px 40px rgba(32,49,91,0.13);text-align:center;color:#20315b;\">\n      <p style=\"font-size:1rem;font-weight:600;margin-bottom:8px;\">\u26a0\ufe0f Le formulaire ne se charge pas correctement.<\/p>\n      <p style=\"font-size:0.85rem;color:#777569;line-height:1.6;\">Veuillez d\u00e9sactiver votre bloqueur de publicit\u00e9s ou contacter l&rsquo;agence directement au <strong>04.75.52.54.75<\/strong>.<\/p>\n    <\/div>\n  <\/div>\n  <script>\n    \/\/ Fallback : si le formulaire n&#39;est pas charg\u00e9 apr\u00e8s 4 secondes, afficher le message\n    setTimeout(function(){\n      var sc = document.getElementById('stepContainer');\n      var fb = document.getElementById('devis-fallback');\n      if(sc && fb && sc.children.length <= 1){\n        fb.style.display = 'block';\n      }\n    }, 4000);\n  <\/script>\n<\/main>\n\n<script>\n(function(){\n'use strict';\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  FIREBASE \u2014 Remplissez ces valeurs avec votre projet Firebase\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nconst FIREBASE_CONFIG = {\n  apiKey:            \"AIzaSyAqsRO-fxwvp-Pci-0By2rKTt2OeYhlWNU\",\n  authDomain:        \"aev-devis.firebaseapp.com\",\n  projectId:         \"aev-devis\",\n  storageBucket:     \"aev-devis.firebasestorage.app\",\n  messagingSenderId: \"384934185791\",\n  appId:             \"1:384934185791:web:f8203b629c0a18c1fb218a\"\n};\n\nlet db = null;\ntry{\n  if(!firebase.apps.length) firebase.initializeApp(FIREBASE_CONFIG);\n  db = firebase.firestore();\n} catch(e){ console.warn('Firebase non disponible:', e); }\n\n\/\/ \u2500\u2500 Sauvegarde du devis dans Firestore \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nasync function saveDevis(){\n  if(!db){ console.warn('Firebase non initialis\u00e9'); return; }\n  try{\n    var devisData = buildDevisLines();\n    await db.collection('devis').doc(refDevis).set({\n      ref          : refDevis,\n      createdAt    : firebase.firestore.Timestamp.now(),\n      \/\/ Identit\u00e9\n      civilite     : state.civilite     || null,\n      nom          : state.nom          || null,\n      prenom       : state.prenom       || null,\n      email        : state.email        || null,\n      telephone    : state.telephone    || null,\n      \/\/ Profil\n      age          : state.age          || null,\n      autreAutoEcole: state.autreAutoEcole !== null ? state.autreAutoEcole : null,\n      statutEleve  : state.statutEleve  || null,\n      scolarise    : state.scolarise    !== null ? state.scolarise : null,\n      \/\/ Formation\n      agence       : state.agence       || null,\n      formation    : state.formation    || null,\n      boite        : state.boite        || null,\n      annulationPermis: state.annulationPermis || null,\n      aNeph        : state.aNeph        !== null ? state.aNeph : null,\n      codeSalle    : state.codeSalle    !== null ? state.codeSalle : null,\n      codeNet      : state.codeNet      !== null ? state.codeNet : null,\n      aLivre       : state.aLivre       !== null ? state.aLivre : null,\n      \/\/ Calcul\u00e9\n      totalTTC     : devisData.total,\n      formationLabel: getFormationLabel(state.formation),\n      agenceLabel  : getAgenceLabel(),\n      \/\/ Technique\n      ip           : techInfo.ip   || '',\n      pays         : techInfo.pays || '',\n      ville        : techInfo.ville|| '',\n    });\n    console.log('[Devis] Sauvegard\u00e9 Firebase:', refDevis);\n  } catch(e){ console.error('[Devis] Erreur sauvegarde Firebase:', e); }\n}\n\n\/\/ \u2500\u2500 Viewer : afficher un devis existant depuis Firebase \u2500\u2500\u2500\u2500\u2500\u2500\nasync function loadDevisViewer(ref){\n  if(!db){\n    document.getElementById('stepContainer').innerHTML =\n      '<div class=\"error-card\"><div class=\"card-header\"><h3>Base de donn\u00e9es indisponible<\/h3><\/div>'\n      +'<div class=\"error-body\"><div class=\"error-message\">La configuration Firebase n&#39;est pas encore renseign&#233;e.<\/div><\/div><\/div>';\n    return;\n  }\n  document.getElementById('progressWrapper').style.display = 'none';\n  document.getElementById('stepContainer').innerHTML =\n    '<div style=\"text-align:center;padding:60px 20px;color:rgba(255,255,255,0.7);\">'\n    +'<div style=\"width:32px;height:32px;border:3px solid rgba(207,202,119,0.3);border-top-color:#cfca77;border-radius:50%;animation:spin 0.8s linear infinite;margin:0 auto 16px;\"><\/div>'\n    +'<p>Chargement du devis <strong style=\"color:#cfca77;\">'+ref+'<\/strong>...<\/p><\/div>';\n\n  try{\n    var doc = await db.collection('devis').doc(ref.toUpperCase()).get();\n    if(!doc.exists){\n      document.getElementById('stepContainer').innerHTML =\n        '<div class=\"error-card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>Devis introuvable<\/span><\/div>'\n        +'<h3>R\u00e9f\u00e9rence inconnue<\/h3><\/div>'\n        +'<div class=\"error-body\"><div class=\"error-message\">Le devis <strong>'+ref+'<\/strong> n&#39;a pas &#233;t&#233; trouv&#233; dans notre syst&#232;me.<br>V&#233;rifiez la r&#233;f&#233;rence ou contactez l&#39;agence au 04.75.52.54.75.<\/div>'\n        +'<div class=\"error-actions\"><a href=\"\/devis\/\" class=\"btn-modify\">\u2190 Nouveau devis<\/a><\/div><\/div><\/div>';\n      return;\n    }\n    \/\/ Restaurer le state depuis Firebase\n    var data = doc.data();\n    Object.keys(state).forEach(function(k){\n      if(data[k] !== undefined) state[k] = data[k];\n    });\n    refDevis = data.ref;\n    techInfo.ip   = data.ip   || '';\n    techInfo.pays = data.pays || '';\n    techInfo.ville= data.ville|| '';\n\n    \/\/ Afficher le devis (m\u00eame fonction que le formulaire)\n    showDevis(true);\n  } catch(e){\n    console.error('[Devis] Erreur chargement viewer:', e);\n    document.getElementById('stepContainer').innerHTML =\n      '<div class=\"error-card\"><div class=\"card-header\"><h3>Erreur de chargement<\/h3><\/div>'\n      +'<div class=\"error-body\"><div class=\"error-message\">Impossible de charger le devis. Veuillez r\u00e9essayer ou contacter l&#39;agence.<\/div><\/div><\/div>';\n  }\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  CONFIG\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nconst EMAILJS_PUBLIC_KEY  = 'TZgCn6xkI-DeaZXFb';\nconst EMAILJS_SERVICE_ID  = 'service_v5e9xx1';\nconst EMAILJS_TEMPLATE_ID = 'template_p3ebvlj';\nconst DISCORD_WEBHOOK     = 'https:\/\/discord.com\/api\/webhooks\/1496304281458835518\/SIoIyJefIhUr4gR3PV75-6maKtJ4GezP4wySvRMytZrRpd7_8lw_aw-mM6GGxEEwZILT';\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  TARIFS (TTC, TVA 20%)\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nconst T = {\n  ANTS      : 30,\n  ADMIN     : 50,\n  EVAL_MAN  : 50,\n  EVAL_AUTO : 50,\n  CODE_SALLE: 120,\n  CODE_NET  : 50,\n  LIVRE     : 10,\n  HEURE_MAN : 52,\n  HEURE_AUT : 53,\n  RDV_PRE_MAN : 104,\n  RDV_PRE_AUT : 106,\n  RDV_PED_MAN : 104,  \/\/ unitaire (x2)\n  RDV_PED_AUT : 106,\n  EXAM_PRATIQUE: 50\n};\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  STATE\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nconst state = {\n  civilite:null, nom:null, prenom:null, email:null, telephone:null,\n  age:null, permisB:null, autreAutoEcole:null, statutEleve:null,\n  scolarise:null, agence:null, formation:null,\n  boite:null, annulationPermis:null, aNeph:null,\n  \/\/ Nouvelles questions th\u00e9orie\n  codeSalle:null,   \/\/ true|false\n  codeNet:null,     \/\/ true|false\n  aLivre:null       \/\/ true|false \u2014 poss\u00e8de d\u00e9j\u00e0 un livre ?\n};\n\nconst navStack = [];\nlet techInfo = { ip:'Non disponible', pays:'Non disponible', ville:'' };\nlet refDevis  = null;\n\n\/\/ \u2500\u2500 Force fond sombre sur tous les conteneurs WordPress \u2500\u2500\u2500\u2500\u2500\u2500\n(function forceDarkBg(){\n  var dark = '#0d1b35';\n  function applyBg(){\n    \/\/ On cible uniquement body : tous les conteneurs Elementor doivent \u00eatre\n    \/\/ transparents pour laisser appara\u00eetre le fond du body sur toute la largeur\n    document.body.style.setProperty('background-color', dark, 'important');\n    document.body.style.setProperty('background-image', 'none', 'important');\n    \/\/ Rendre les wrappers Elementor\/WordPress transparents s'ils ont un fond blanc ou clair\n    var clearSelectors = [\n      '.elementor-section-wrap',\n      '.elementor-inner',\n      '.elementor-container',\n      '.elementor-row',\n      '.elementor-column-wrap',\n      '.elementor-widget-wrap',\n      '.elementor-widget-container',\n      '.e-con','.e-con-inner',\n      '#content','.site-content','.entry-content',\n      '#main','.site-main','.wp-site-blocks'\n    ];\n    clearSelectors.forEach(function(sel){\n      try{\n        document.querySelectorAll(sel).forEach(function(el){\n          \/\/ Ne pas toucher le footer et ses enfants\n          if(el.closest('footer') || el.tagName==='FOOTER') return;\n          var bg = window.getComputedStyle(el).backgroundColor;\n          \/\/ Si fond blanc, clair ou opaque : le rendre transparent\n          if(bg && bg !== 'transparent' && bg !== 'rgba(0, 0, 0, 0)'){\n            el.style.setProperty('background-color', 'transparent', 'important');\n            el.style.setProperty('background-image', 'none', 'important');\n          }\n        });\n      }catch(e){}\n    });\n  }\n  applyBg();\n  document.addEventListener('DOMContentLoaded', applyBg);\n  window.addEventListener('load', applyBg);\n})();\n\n\/\/ EmailJS : init s\u00e9curis\u00e9 (ne bloque pas si le script CDN est inaccessible)\ntry{ if(typeof emailjs !== 'undefined') emailjs.init(EMAILJS_PUBLIC_KEY); }catch(e){ console.warn('EmailJS non disponible:', e); }\n\/\/ Charger IP\/pays d\u00e8s le d\u00e9marrage (avant toute soumission)\n(async function(){\n  try{\n    var r = await fetch('https:\/\/ipapi.co\/json\/');\n    var d = await r.json();\n    techInfo.ip   = d.ip           || 'Non disponible';\n    techInfo.pays = d.country_name || 'Non disponible';\n    techInfo.ville= d.city         || '';\n  } catch(e){\n    \/\/ Fallback : essayer un autre service\n    try{\n      var r2 = await fetch('https:\/\/api.ipify.org?format=json');\n      var d2 = await r2.json();\n      techInfo.ip = d2.ip || 'Non disponible';\n    } catch(e2){ \/* silencieux *\/ }\n  }\n})();\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  REFERENCE \u2014 4 caracteres sans O 0 I i l 1 U u\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nfunction genRef(){\n  \/\/ Format : 2 lettres nom + 2 lettres prenom + 4 caract\u00e8res al\u00e9atoires\n  \/\/ Alphabet sans confusion : sans O,0,I,i,l,1,U,u\n  var chars='ABCDEFGHJKMNPQRSTVWXYZ23456789';\n  \/\/ Extraire lettres du nom (g\u00e9rer noms compos\u00e9s)\n  var nom = (state.nom||'').toUpperCase().replace(\/[^A-Z]\/g,'');\n  var prenom = (state.prenom||'').toUpperCase().replace(\/[^A-Z]\/g,'');\n  \/\/ Pour noms compos\u00e9s: 1 lettre par partie\n  var nomParts = (state.nom||'').toUpperCase().replace(\/[^A-Z\\- ]\/g,'').split(\/[\\- ]\/);\n  var nomCode = nomParts.length > 1\n    ? nomParts.map(function(p){return p[0]||'';}).join('').substring(0,2)\n    : nom.substring(0,2);\n  nomCode = (nomCode+'XX').substring(0,2);\n  var prenomCode = (prenom+'XX').substring(0,2);\n  var rand='';\n  for(var i=0;i<4;i++) rand+=chars[Math.floor(Math.random()*chars.length)];\n  return (nomCode+prenomCode+rand).toUpperCase();\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  NAVIGATION\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nfunction goTo(fn){ navStack.push(fn); fn(); }\nfunction goBack(){\n  if(navStack.length<=1) return;\n  navStack.pop();\n  var prev=navStack.pop();\n  document.getElementById('progressWrapper').style.display='block';\n  goTo(prev);\n}\nfunction restart(){\n  Object.keys(state).forEach(k=>state[k]=null);\n  navStack.length=0; refDevis=null;\n  document.getElementById('progressWrapper').style.display='block';\n  goTo(step1_age);\n}\nfunction renderNavButtons(showBack){\n  var back=showBack?'<button class=\"btn-back\" id=\"btnBack\">\u2190 Modifier ma r\u00e9ponse pr\u00e9c\u00e9dente<\/button>':'';\n  return '<div class=\"nav-row\">'+back+'<button class=\"btn-reset\" id=\"btnReset\">\u21ba Recommencer \u00e0 z\u00e9ro<\/button><\/div>';\n}\nfunction attachNavEvents(){\n  var b=document.getElementById('btnBack');\n  var r=document.getElementById('btnReset');\n  if(b) b.addEventListener('click',goBack);\n  if(r) r.addEventListener('click',restart);\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  RENDER\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nfunction render(html){\n  var c=document.getElementById('stepContainer');\n  if(!c){ console.error('[Devis] stepContainer introuvable'); return; }\n  c.innerHTML=html;\n  c.classList.remove('step-enter');\n  void c.offsetWidth;\n  c.classList.add('step-enter');\n  try{\n    \/\/ \u00c9tape 1 (chargement initial) : scroll vers le haut de main pour afficher le titre hero\n    if(navStack.length <= 1){\n      var mainEl = document.querySelector('main');\n      var topOffset = mainEl ? mainEl.getBoundingClientRect().top + window.scrollY - 170 : 0;\n      window.scrollTo({top:Math.max(0, topOffset), behavior:'smooth'});\n    } else {\n      \/\/ \u00c9tapes suivantes : scroll vers le step container (header WP ~160px)\n      window.scrollTo({top:c.getBoundingClientRect().top+window.scrollY-160,behavior:'smooth'});\n    }\n  }catch(err){}\n}\n\nfunction setProgress(step,total){\n  var pf=document.getElementById('progressFill');\n  var pc=document.getElementById('progressCount');\n  if(pf) pf.style.width=Math.round((step\/total)*100)+'%';\n  if(pc) pc.textContent='\u00c9tape '+step+' \/ '+total;\n}\nfunction showError(title,msg,canBack){\n  document.getElementById('progressWrapper').style.display='none';\n  render('<div class=\"error-card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>Non \u00e9ligible<\/span><\/div><h3>'+title+'<\/h3><\/div><div class=\"error-body\"><div class=\"error-message\">'+msg+'<\/div><div class=\"error-actions\">'+(canBack?'<button class=\"btn-modify\" id=\"btnMod\">Modifier ma r\u00e9ponse<\/button>':'')+'<button class=\"btn-restart-red\" id=\"btnRR\">Recommencer depuis le debut<\/button><\/div><\/div><\/div>');\n  var bm=document.getElementById('btnMod');\n  var br=document.getElementById('btnRR');\n  if(bm) bm.addEventListener('click',goBack);\n  if(br) br.addEventListener('click',restart);\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  HELPERS METIER\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nfunction getFormationLabel(f){\n  return{\n    traditionnel:'Traditionnel',\n    aac:'Conduite Accompagn\u00e9e (AAC)',\n    cs:'Conduite Supervis\u00e9e (CS)',\n    perfectionnement:'Reprises de confiance \/ Perfectionnement',\n    annulation:'Annulation de permis \u2014 Code uniquement',\n    b78_vers_b:'Passerelle B78 vers B (bo\u00eete auto vers manuelle)'\n  }[f]||f;\n}\nfunction getAgenceLabel(){ return state.agence==='viviers'?'Auto \u00c9cole Vivaroise':'Meysse Auto \u00c9cole'; }\nfunction getAgenceAddr(){ return state.agence==='viviers'?'5 rue du Chemin Neuf, 07220 Viviers':'2 Place de la Cala, 07400 Meysse'; }\nfunction getAgenceHoraires(){\n  return state.agence==='viviers'\n    ?'Du Mercredi au Vendredi de 15h \u00e0 19h et le Samedi de 10h \u00e0 12h'\n    :'Les Mercredis et Vendredis de 17h30 \u00e0 19h et les Samedis de 11h \u00e0 12h';\n}\nfunction isManuelle(){ return state.boite==='manuelle'; }\nfunction isAAC()     { return state.formation==='aac'; }\nfunction isCS()      { return state.formation==='cs'; }\nfunction isPerf()    { return state.formation==='perfectionnement'; }\nfunction isB78()     { return state.formation==='b78_vers_b'; }\nfunction isAnnu()    { return state.formation==='annulation'; }\nfunction isTrad()    { return state.formation==='traditionnel'; }\n\n\/\/ \u2500\u2500 Calcul de la date de validite : 31\/12\/annee en cours \u2500\u2500\u2500\u2500\u2500\nfunction getValidite(){\n  var yr=new Date().getFullYear();\n  return '31\/12\/'+yr;\n}\nfunction getNow(){\n  var n=new Date();\n  return{\n    date:n.toLocaleDateString('fr-FR',{day:'2-digit',month:'2-digit',year:'numeric'}),\n    heure:n.toLocaleTimeString('fr-FR',{hour:'2-digit',minute:'2-digit',second:'2-digit'})\n  };\n}\n\n\/\/ \u2500\u2500 Calcul du prix de l'evaluation selon boite \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction evalPrice(){ return isManuelle()?T.EVAL_MAN:T.EVAL_AUTO; }\nfunction heurePrice(){ return isManuelle()?T.HEURE_MAN:T.HEURE_AUT; }\nfunction heureMin()  {\n  if(isB78()) return 7; \/\/ B78 = 7h manuelle\n  return isManuelle()?20:13;\n}\nfunction rdvPrePrice(){ return isManuelle()?T.RDV_PRE_MAN:T.RDV_PRE_AUT; }\nfunction rdvPedPrice(){ return isManuelle()?T.RDV_PED_MAN:T.RDV_PED_AUT; }\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  CONSTRUCTION DES LIGNES DU DEVIS\n\/\/  Retourne { rows:[], total:0 }\n\/\/  Chaque row = { cat, label, puHT, qty, tva, mntTVA, ttc, note }\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nfunction buildDevisLines(){\n  var rows=[];\n  var total=0;\n\n  function addRow(cat,label,ttc,qty,note){\n    qty=qty||1;\n    var puHT=ttc\/qty\/1.2;\n    var mntTVA=ttc\/qty-puHT;\n    rows.push({cat:cat,label:label,puHT:puHT,qty:qty,tva:'20%',mntTVA:mntTVA*qty,ttc:ttc,note:note||''});\n    total+=ttc;\n  }\n\n  \/\/ \u2500\u2500 FRAIS D'INSCRIPTION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  if(isPerf()){\n    \/\/ Perfectionnement : aucun frais d'inscription, pas d'ANTS, pas d'\u00e9val\n  } else if(isAnnu()){\n    \/\/ Annulation de permis (code seul) : ANTS uniquement, pas d'admin ni d'\u00e9val\n    addRow('inscription','Enregistrement du dossier ANTS',T.ANTS);\n  } else if(isB78()){\n    \/\/ B78 vers B : ANTS toujours factur\u00e9 (lev\u00e9e restriction) + admin, pas d'\u00e9val\n    addRow('inscription','Enregistrement du dossier ANTS',T.ANTS);\n    addRow('inscription','Fournitures administratives et p\u00e9dagogiques',T.ADMIN);\n  } else {\n    if(!state.aNeph) addRow('inscription','Enregistrement du dossier ANTS',T.ANTS);\n    addRow('inscription','Fournitures administratives et p\u00e9dagogiques',T.ADMIN);\n    addRow('inscription','\u00c9valuation de d\u00e9part',evalPrice());\n  }\n\n  \/\/ \u2500\u2500 TH\u00c9ORIE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ Pas de th\u00e9orie pour perfectionnement ni B78\n  \/\/ Si code d\u00e9j\u00e0 obtenu : pas de th\u00e9orie non plus\n  var skipTheorie = isPerf() || isB78() || state.statutEleve==='code_obtenu';\n  if(!skipTheorie){\n    if(state.codeSalle) addRow('theorie','Code en salle pendant 6 mois',T.CODE_SALLE);\n    if(state.codeNet)   addRow('theorie','Code sur internet pendant 4 mois',T.CODE_NET);\n    if(!state.aLivre)   addRow('theorie','Livre du Code de la Route',T.LIVRE);\n  }\n\n  \/\/ \u2500\u2500 PRATIQUE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ Annulation = code seulement, pas de pratique\n  if(isAnnu()) return {rows:rows,total:total};\n\n  var hMin=heureMin();\n  var hPrix=heurePrice();\n\n  if(isPerf()){\n    \/\/ Perfectionnement : 1 seule heure de conduite, c'est tout\n    addRow('pratique','Le\u00e7on de conduite en bo\u00eete '+(isManuelle()?'manuelle':'automatique'),hPrix,1);\n  } else {\n    addRow('pratique','Le\u00e7on de conduite en bo\u00eete '+(isManuelle()?'manuelle':'automatique'),hPrix*hMin,hMin);\n    if(isAAC()){\n      var noteRdvPed='1er rdv \u2248 1 500 km \u00b7 2\u00e8me rdv \u2248 3 000 km';\n      addRow('pratique','Rendez-vous pr\u00e9alable AAC (dur\u00e9e 2h, avec accompagnateur)',rdvPrePrice());\n      addRow('pratique','Rendez-vous p\u00e9dagogique AAC (dur\u00e9e 2h)',rdvPedPrice()*2,2,noteRdvPed);\n    }\n    if(isCS()){\n      addRow('pratique','Rendez-vous pr\u00e9alable CS (dur\u00e9e 2h)',rdvPrePrice());\n    }\n    if(isTrad()||isAAC()||isCS()){\n      addRow('pratique','Accompagnement \u00e0 l\\'examen pratique',T.EXAM_PRATIQUE);\n    }\n    \/\/ B78 : juste les heures, pas d'accompagnement exam\n  }\n\n  return{rows:rows,total:total};\n}\n\/\/ \u2500\u2500 Sous-totaux par categorie \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction getSubTotals(rows){\n  var st={inscription:0,theorie:0,pratique:0};\n  rows.forEach(function(r){ if(st[r.cat]!==undefined) st[r.cat]+=r.ttc; });\n  return st;\n}\n\n\/\/ \u2500\u2500 Calcul des modalit\u00e9s de paiement \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction buildModalites(rows,subT){\n  var modal=[];\n  var hMin=heureMin();\n  var hPrix=heurePrice();\n  var isMan=isManuelle();\n\n  if(isPerf()){\n    \/\/ Perfectionnement : payer \u00e0 la r\u00e9servation de l'heure\n    modal.push({label:'\u00c0 la r\u00e9servation de la le\u00e7on de conduite',amount:hPrix});\n    return modal;\n  }\n\n  if(isAnnu()){\n    \/\/ Annulation : tout \u00e0 l'inscription (ANTS + code)\n    var totalAnnu=subT.inscription+subT.theorie;\n    modal.push({label:'\u00c0 l\\'inscription (ANTS + code)',amount:totalAnnu});\n    return modal;\n  }\n\n  if(isB78()){\n    \/\/ B78 vers B : tout \u00e0 l'inscription\n    var totalB78=subT.inscription+subT.theorie+subT.pratique;\n    modal.push({label:'\u00c0 l\\'inscription (totalit\u00e9)',amount:totalB78});\n    return modal;\n  }\n\n  \/\/ Standard : inscription = frais inscription + th\u00e9orie\n  \/\/ Si code d\u00e9j\u00e0 obtenu : pas de th\u00e9orie dans le calcul inscription\n  var inscTotal=subT.inscription+(state.statutEleve==='code_obtenu'?0:subT.theorie);\n  var inscLabel=state.statutEleve==='code_obtenu'\n    ?'\u00c0 l\\'inscription (Frais admin. + \u00c9val.)'\n    :'\u00c0 l\\'inscription (Frais admin. + \u00c9val. + Code)';\n  modal.push({label:inscLabel,amount:inscTotal});\n\n  \/\/ Heures de conduite\n  if(isMan){\n    modal.push({label:'\u00c0 la 1\u00e8re heure de conduite (10 h \u00d7 '+hPrix+' \u20ac)',amount:10*hPrix});\n    modal.push({label:'\u00c0 la 10\u00e8me heure de conduite (10 h \u00d7 '+hPrix+' \u20ac)',amount:10*hPrix});\n  } else {\n    modal.push({label:'\u00c0 la 1\u00e8re heure de conduite (7 h \u00d7 '+hPrix+' \u20ac)',amount:7*hPrix});\n    modal.push({label:'\u00c0 la 7\u00e8me heure de conduite (6 h \u00d7 '+hPrix+' \u20ac)',amount:6*hPrix});\n  }\n\n  if(isAAC()){\n    modal.push({label:'\u00c0 la r\u00e9servation du rendez-vous pr\u00e9alable',amount:rdvPrePrice()});\n    modal.push({label:'\u00c0 la r\u00e9servation du 1er rdv p\u00e9dagogique',amount:rdvPedPrice()});\n    modal.push({label:'\u00c0 la r\u00e9servation du 2\u00e8me rdv p\u00e9dagogique',amount:rdvPedPrice()});\n  }\n  if(isCS()){\n    modal.push({label:'\u00c0 la r\u00e9servation du rendez-vous pr\u00e9alable',amount:rdvPrePrice()});\n  }\n  if(isTrad()||isAAC()||isCS()){\n    modal.push({label:'\u00c0 la r\u00e9servation de l\\'examen pratique',amount:T.EXAM_PRATIQUE});\n  }\n  return modal;\n}\n\/\/ \u2500\u2500 Documents \u00e0 apporter (selon profil NEPH + formation) \u2500\u2500\u2500\u2500\nfunction getDocsList(){\n  var isMineur = state.age === 'mineur';\n  var aNeph    = state.aNeph;\n  var codeObtenu = state.statutEleve === 'code_obtenu';\n  var docs = [];\n\n  \/\/ \u2500\u2500 CAS SP\u00c9CIAUX \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  if(isPerf()){\n    \/\/ Perfectionnement : pi\u00e8ce d'identit\u00e9 + permis de conduire seulement\n    docs.push({warn:true,  text:'Pi\u00e8ce d\\'identit\u00e9 du candidat en cours de validit\u00e9'});\n    docs.push({warn:true,  text:'Permis de conduire'});\n    return docs;\n  }\n\n  if(isAnnu()){\n    \/\/ Annulation de permis : dossier ANTS complet + documents sp\u00e9cifiques annulation\n    docs.push({warn:false, text:'E-Photos conformes ANTS, dat\u00e9es de moins de 6 mois (plaquette originale) \u2014 voir mod\u00e8le ci-contre'});\n    docs.push({warn:true,  text:'Pi\u00e8ce d\\'identit\u00e9 du candidat en cours de validit\u00e9'});\n    if(isMineur) docs.push({warn:true, text:'Pi\u00e8ce d\\'identit\u00e9 du repr\u00e9sentant l\u00e9gal en cours de validit\u00e9'});\n    docs.push({warn:true,  text:'Justificatif de domicile (facture de t\u00e9l\u00e9phone, avis d\\'imposition\u2026) de moins de 6 mois'});\n    docs.push({warn:false, text:'Attestation d\\'h\u00e9bergement avec adresse strictement identique au justificatif, sign\u00e9e par les parents et le candidat'});\n    docs.push({warn:true,  text:'Certificat de participation \u00e0 la journ\u00e9e d\\'appel (JDC)'});\n    docs.push({warn:true,  text:'ASSR 2'});\n    docs.push({warn:true,  text:'Document officiel d\\'annulation du permis de conduire'});\n    docs.push({warn:true,  text:'Visite m\u00e9dicale aupr\u00e8s d\\'un m\u00e9decin agr\u00e9\u00e9 pr\u00e9fecture (\u00e0 effectuer avant l\\'inscription)'});\n    docs.push({warn:false, text:'Test psychotechnique (si requis selon les motifs de l\\'annulation)'});\n    docs.push({warn:false, text:'D\u00e9cision de justice \/ jugement (si l\\'annulation fait suite \u00e0 une d\u00e9cision judiciaire)'});\n    docs.push({warn:false, text:'Adresse e-mail du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n    docs.push({warn:false, text:'Num\u00e9ro de t\u00e9l\u00e9phone du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n    return docs;\n  }\n\n  if(isB78()){\n    \/\/ Passerelle B78 vers B : dossier ANTS complet + CEPC\n    docs.push({warn:false, text:'E-Photos conformes ANTS, dat\u00e9es de moins de 6 mois (plaquette originale) \u2014 voir mod\u00e8le ci-contre'});\n    docs.push({warn:true,  text:'Pi\u00e8ce d\\'identit\u00e9 du candidat en cours de validit\u00e9'});\n    if(isMineur) docs.push({warn:true, text:'Pi\u00e8ce d\\'identit\u00e9 du repr\u00e9sentant l\u00e9gal en cours de validit\u00e9'});\n    docs.push({warn:true,  text:'Justificatif de domicile (facture de t\u00e9l\u00e9phone, avis d\\'imposition\u2026) de moins de 6 mois'});\n    docs.push({warn:false, text:'Attestation d\\'h\u00e9bergement avec adresse strictement identique au justificatif, sign\u00e9e par les parents et le candidat'});\n    docs.push({warn:true,  text:'Certificat de participation \u00e0 la journ\u00e9e d\\'appel (JDC)'});\n    docs.push({warn:true,  text:'ASSR 2'});\n    docs.push({warn:false, text:'Adresse e-mail du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n    docs.push({warn:false, text:'Num\u00e9ro de t\u00e9l\u00e9phone du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n    docs.push({warn:true,  text:'CEPC \u2014 Certificat de l\\'Examen du Permis de Conduire (t\u00e9l\u00e9chargeable sur RdvPermis.fr dans votre espace personnel)'});\n    _addSiConcerne(docs, isMineur);\n    return docs;\n  }\n\n  \/\/ \u2500\u2500 CAS STANDARD (AAC \/ CS \/ Traditionnel) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  if(aNeph){\n    \/\/ A d\u00e9j\u00e0 un dossier ANTS : uniquement pi\u00e8ce d'identit\u00e9 + AIPC\n    \/\/ (Pas d'e-photos car d\u00e9j\u00e0 dans le dossier existant)\n    docs.push({warn:true,  text:'Pi\u00e8ce d\\'identit\u00e9 du candidat en cours de validit\u00e9'});\n    if(isMineur) docs.push({warn:true, text:'Pi\u00e8ce d\\'identit\u00e9 du repr\u00e9sentant l\u00e9gal en cours de validit\u00e9'});\n    docs.push({warn:true,  text:'AIPC (Attestation d\\'Inscription au Permis de Conduire) \u2014 contient votre num\u00e9ro NEPH'});\n    if(codeObtenu){\n      \/\/ Code d\u00e9j\u00e0 obtenu : AIPC suffit + r\u00e9sultat favorable\n      docs.push({warn:true, text:'R\u00e9sultat favorable au code de la route (d\u00e9livr\u00e9 \u00e0 la suite de l\\'examen th\u00e9orique)'});\n    }\n    return docs;\n  }\n\n  \/\/ Nouveau dossier ANTS (pas encore de NEPH)\n  if(codeObtenu){\n    \/\/ Code obtenu mais pas de NEPH : impossible normalement, mais on liste les docs complets\n    \/\/ Le code n\u00e9cessite un NEPH\/AIPC donc on l'inclut\n    docs.push({warn:false, text:'E-Photos conformes ANTS, dat\u00e9es de moins de 6 mois (plaquette originale) \u2014 voir mod\u00e8le ci-contre'});\n    docs.push({warn:true,  text:'Pi\u00e8ce d\\'identit\u00e9 du candidat en cours de validit\u00e9'});\n    if(isMineur) docs.push({warn:true, text:'Pi\u00e8ce d\\'identit\u00e9 du repr\u00e9sentant l\u00e9gal en cours de validit\u00e9'});\n    docs.push({warn:true,  text:'AIPC (Attestation d\\'Inscription au Permis de Conduire) \u2014 contient votre num\u00e9ro NEPH'});\n    docs.push({warn:true,  text:'R\u00e9sultat favorable au code de la route (d\u00e9livr\u00e9 \u00e0 la suite de l\\'examen th\u00e9orique)'});\n    docs.push({warn:true,  text:'Justificatif de domicile (facture de t\u00e9l\u00e9phone, avis d\\'imposition\u2026) de moins de 6 mois'});\n    docs.push({warn:false, text:'Attestation d\\'h\u00e9bergement avec adresse strictement identique au justificatif, sign\u00e9e par les parents et le candidat'});\n    docs.push({warn:true,  text:'Certificat de recensement (si 16 ans) ou certificat de participation \u00e0 la journ\u00e9e d\\'appel (JDC, si entre 17 et 25 ans)'});\n    docs.push({warn:true,  text:'ASSR 2 (si entre 15 et 25 ans)'});\n    docs.push({warn:false, text:'Adresse e-mail du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n    docs.push({warn:false, text:'Num\u00e9ro de t\u00e9l\u00e9phone du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n    _addSiConcerne(docs, isMineur);\n    return docs;\n  }\n\n  \/\/ Nouveau dossier, code pas encore obtenu : dossier ANTS complet\n  docs.push({warn:false, text:'E-Photos conformes ANTS, dat\u00e9es de moins de 6 mois (plaquette originale) \u2014 voir mod\u00e8le ci-contre'});\n  docs.push({warn:true,  text:'Pi\u00e8ce d\\'identit\u00e9 du candidat en cours de validit\u00e9'});\n  if(isMineur) docs.push({warn:true, text:'Pi\u00e8ce d\\'identit\u00e9 du repr\u00e9sentant l\u00e9gal en cours de validit\u00e9'});\n  docs.push({warn:true,  text:'Justificatif de domicile (facture de t\u00e9l\u00e9phone, avis d\\'imposition\u2026) de moins de 6 mois'});\n  docs.push({warn:false, text:'Attestation d\\'h\u00e9bergement avec adresse strictement identique au justificatif, sign\u00e9e par les parents et le candidat'});\n  docs.push({warn:true,  text:'Certificat de recensement (si 16 ans) ou certificat de participation \u00e0 la journ\u00e9e d\\'appel (JDC, si entre 17 et 25 ans)'});\n  docs.push({warn:true,  text:'ASSR 2 (si entre 15 et 25 ans)'});\n  docs.push({warn:false, text:'Adresse e-mail du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n  docs.push({warn:false, text:'Num\u00e9ro de t\u00e9l\u00e9phone du candidat'+(isMineur?' et de ses responsables l\u00e9gaux':'')});\n  _addSiConcerne(docs, isMineur);\n  return docs;\n}\n\n\/\/ Bloc \"Si l'\u00e9l\u00e8ve est concern\u00e9\" \u2014 ajout\u00e9 pour tous les dossiers ANTS complets\nfunction _addSiConcerne(docs, isMineur){\n  docs.push({warn:false, text:'\u2500\u2500 SI L\\'\u00c9L\u00c8VE EST CONCERN\u00c9 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500'});\n  docs.push({warn:false, text:'Livret de famille complet (si le candidat est mineur et que le justificatif de domicile est au nom d\\'un parent dont le nom est diff\u00e9rent)'});\n  docs.push({warn:false, text:'Certificat du Service National Universel \u2014 phase 1 et 2 (SNU)'});\n  docs.push({warn:false, text:'Permis AM ou autres permis d\u00e9j\u00e0 obtenus'});\n}\n\/\/ \u2500\u2500 Lien aides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction getAidesUrl(){\n  return state.agence==='viviers'\n    ?'https:\/\/autoecolevivaroise.com\/auto-ecole-de-viviers\/'\n    :'https:\/\/autoecolevivaroise.com\/auto-ecole-de-meysse\/';\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  G\u00c9N\u00c9RATION PDF \u2014 buildDevisHTML + html2canvas -> jsPDF\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nfunction buildDevisHTML(){\n  var now=getNow();\n  var validite=getValidite();\n  var devisData=buildDevisLines();\n  var rows=devisData.rows;\n  var total=devisData.total;\n  var subT=getSubTotals(rows);\n  var modal=buildModalites(rows,subT);\n  var agenceLabel=getAgenceLabel();\n  var isViviers=state.agence==='viviers';\n  var isMan=isManuelle();\n  var year=new Date().getFullYear();\n\n  function fmt(n){\n    var s=n.toFixed(2).replace('.',',');\n    var parts=s.split(',');\n    parts[0]=parts[0].replace(\/\\B(?=(\\d{3})+(?!\\d))\/g,'\u00a0');\n    return parts.join(',')+'\u00a0\u20ac';\n  }\n  function fmtHT(ttc,qty){ return fmt(ttc\/qty\/1.2); }\n  function fmtTVAmnt(ttc,qty){ var ht=ttc\/qty\/1.2; return fmt((ttc\/qty-ht)*qty); }\n\n  \/\/ Tableau des prestations\n  var catOrder=['inscription','theorie','pratique'];\n  var catLabels={inscription:'Frais d\u2019inscription',theorie:'Partie th\u00e9orique',pratique:'Partie pratique'};\n  var tableHTML='';\n  catOrder.forEach(function(cat){\n    var catRows=rows.filter(function(r){return r.cat===cat;});\n    if(!catRows.length) return;\n    tableHTML+='<tr class=\"cat-header\"><td colspan=\"7\">'+catLabels[cat].toUpperCase()+'<\/td><\/tr>';\n    tableHTML+='<tr class=\"col-header\"><td style=\"width:42%\">D\u00e9signation<\/td><td>P.U.\u00a0HT<\/td><td>P.U.\u00a0TTC<\/td><td>Qt\u00e9<\/td><td>TVA<\/td><td>Mnt\u00a0TVA<\/td><td>Total\u00a0TTC<\/td><\/tr>';\n    catRows.forEach(function(r){\n      tableHTML+='<tr class=\"row-item\"><td>'+r.label+(r.note?'<br><span class=\"note\">'+r.note+'<\/span>':'')+'<\/td><td>'+fmtHT(r.ttc,r.qty)+'<\/td><td>'+fmt(r.ttc\/r.qty)+'<\/td><td>'+r.qty+'<\/td><td>'+r.tva+'<\/td><td>'+fmtTVAmnt(r.ttc,r.qty)+'<\/td><td>'+fmt(r.ttc)+'<\/td><\/tr>';\n    });\n    tableHTML+='<tr class=\"row-sub\"><td colspan=\"6\">Sous-total '+catLabels[cat]+'<\/td><td>'+fmt(subT[cat])+'<\/td><\/tr>';\n  });\n\n  \/\/ Modalit\u00e9s\n  var modalHTML=modal.map(function(m){\n    return '<tr><td class=\"ml\">'+m.label+'<\/td><td class=\"md\"><\/td><td class=\"mr\">'+fmt(m.amount)+'<\/td><\/tr>';\n  }).join('');\n\n  \/\/ Documents\n  var docsList=getDocsList();\n  var docsHTML=docsList.map(function(d){\n    \/\/ Cas sp\u00e9cial : ligne s\u00e9paratrice \"SI L'\u00c9L\u00c8VE EST CONCERN\u00c9\"\n    if(d.text.indexOf('SI L\\'\u00c9L\u00c8VE EST CONCERN\u00c9') !== -1 || d.text.indexOf('SI L&#39;\u00c9L\u00c8VE') !== -1){\n      return '<li class=\"doc-separator\"><span style=\"font-size:6pt;font-weight:700;text-transform:uppercase;letter-spacing:0.1em;color:#20315b;border-top:1px solid #cfca77;display:block;padding-top:5px;margin-top:3px;\">Si l\\'\u00e9l\u00e8ve est concern\u00e9<\/span><\/li>';\n    }\n    return '<li class=\"'+(d.warn?'warn':'normal')+'\"><span>'+(d.warn?'\u26a0\ufe0f':'\u25a1')+'<\/span><span>'+d.text+'<\/span><\/li>';\n  }).join('');\n\n  \/\/ Scanner (agence sp\u00e9cifique)\n  var scannerHTML=isViviers\n    ?'<div class=\"scan-box viviers\"><strong>Auto \u00c9cole Vivaroise (Viviers)\u00a0:<\/strong> Il est pr\u00e9f\u00e9rable d\u2019apporter les originaux. Nous nous chargeons de les scanner correctement pour garantir leur conformit\u00e9 aux normes ANTS (bonne qualit\u00e9, lisibles, non recadr\u00e9es).<\/div>'\n    :'<div class=\"scan-box meysse\"><strong>\u26a0\ufe0f\u00a0Meysse Auto \u00c9cole\u00a0:<\/strong> Merci d\u2019apporter des photocopies recto-verso, car aucun scanner n\u2019est disponible sur place. Veillez \u00e0 ce qu\u2019elles soient lisibles, compl\u00e8tes (non recadr\u00e9es ni coup\u00e9es) et \u00e0 taille originale.<\/div>';\n\n  \/\/ R\u00e9capitulatif complet\n  var recapData=[\n    ['Civilit\u00e9 \/ Pr\u00e9nom \/ Nom',state.civilite+' '+state.prenom+' '+state.nom],\n    ['E-mail',state.email],\n    ['T\u00e9l\u00e9phone',state.telephone||'\u2014'],\n    ['Profil',state.age==='mineur'?'Mineur':'Majeur'],\n    ['Agence',agenceLabel],\n    ['Formation',getFormationLabel(state.formation)],\n    ['Bo\u00eete',isMan?'Manuelle':'Automatique'],\n    ['Dossier ANTS \/ NEPH',state.aNeph?'Oui \u2014 dossier existant':'Non \u2014 premier dossier'],\n    ['D\u00e9j\u00e0 inscrit ailleurs',state.autreAutoEcole?'Oui':'Non'],\n    ['Statut dans autre auto-\u00e9cole',state.statutEleve==='code_non_obtenu'?'Code en cours':state.statutEleve==='code_obtenu'?'Code obtenu, conduite non commenc\u00e9e':'Non concern\u00e9'],\n    ['Scolaris\u00e9 Montel.\/Le Teil',state.scolarise===true?'Oui':state.scolarise===false?'Non':'Non concern\u00e9 (majeur)'],\n    ['Code de la route obtenu',state.statutEleve==='code_obtenu'?'Oui':'Non'],\n    ['Code en salle',state.codeSalle?'Oui':'Non concern\u00e9'],\n    ['Code internet',state.codeNet?'Oui':'Non concern\u00e9'],\n    ['Livre de code',state.aLivre?'D\u00e9j\u00e0 poss\u00e9d\u00e9':'Inclus dans le devis'],\n    ['Annulation permis',state.annulationPermis==='code_seul'?'Code uniquement':state.annulationPermis==='code_conduite'?'Code + conduite':'Non concern\u00e9'],\n    ['Date de g\u00e9n\u00e9ration',now.date+' \u00e0 '+now.heure],\n    ['R\u00e9f\u00e9rence devis',refDevis]\n  ];\n  var recapHTML=recapData.map(function(r){\n    var isRef=r[1]===refDevis;\n    return '<tr><td class=\"rl\">'+r[0]+'<\/td><td class=\"rv'+(isRef?' rv-ref':'')+'\">'+r[1]+'<\/td><\/tr>';\n  }).join('');\n\n  var payInfo=isViviers?'Ch\u00e8ques \u00b7 Esp\u00e8ces \u00b7 Virements bancaires \u00b7 CB':'Ch\u00e8ques \u00b7 Esp\u00e8ces \u00b7 Virements bancaires';\n  var aidesUrl=getAidesUrl();\n  var cachetUrl=isViviers?'https:\/\/autoecolevivaroise.com\/wp-content\/uploads\/2026\/04\/Cachet-Viviers.png':'https:\/\/autoecolevivaroise.com\/wp-content\/uploads\/2026\/04\/Cachet-Meysse.png';\n  var logoUrl='https:\/\/autoecolevivaroise.com\/wp-content\/uploads\/2026\/04\/Lo-Ic-Bl-Logo-AEV-blanc-icone.png';\n\n  \/\/ CSS inline\n  var CSS='*{box-sizing:border-box;margin:0;padding:0;}'\n    +'body{font-family:\"DM Sans\",sans-serif;font-size:8.5pt;color:#1a1a2e;background:#fff;}'\n    +'.page{width:210mm;min-height:297mm;display:flex;flex-direction:column;background:#fff;}'\n    +'.page-content{flex:1;}'\n    +'.page+.page{border-top:4px solid #20315b;margin-top:4px;}'\n    +'.hdr{background:#20315b;padding:13px 20px;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:10px;}'\n    +'.hdr-left .ae{color:#cfca77;font-size:11pt;font-weight:700;line-height:1.2;}'\n    +'.hdr-left .ae-siret,.hdr-left .ae-tel,.hdr-left .ae-web{font-size:6pt;margin-top:2px;}'\n    +'.hdr-left .ae-siret{color:rgba(255,255,255,0.4);}'\n    +'.hdr-left .ae-tel{color:rgba(255,255,255,0.65);}'\n    +'.hdr-left .ae-web{color:rgba(255,255,255,0.5);}'\n    +'.hdr-center{text-align:center;}'\n    +'.hdr-center .dw{font-size:22pt;font-weight:700;color:#cfca77;letter-spacing:0.18em;line-height:1;}'\n    +'.hdr-center .ref{font-family:\"DM Mono\",monospace;font-size:10pt;color:#cfca77;background:rgba(207,202,119,0.2);border:1px solid rgba(207,202,119,0.35);padding:2px 10px;border-radius:3px;display:inline-block;margin-top:4px;letter-spacing:0.2em;}'\n    +'.hdr-right{text-align:right;display:flex;align-items:center;justify-content:flex-end;}'\n    +'.hdr-logo{height:60px;width:auto;}'\n    +'.agrow{background:#fff9f1;border-bottom:2px solid #cfca77;padding:7px 20px;display:flex;justify-content:space-between;align-items:flex-start;}'\n    +'.agrow .al .ag-lbl{font-size:5.5pt;text-transform:uppercase;letter-spacing:0.12em;color:#aaa;margin-bottom:2px;}'\n    +'.agrow .al .ag-name{font-size:9pt;font-weight:700;color:#20315b;}'\n    +'.agrow .al .ag-det{font-size:6pt;color:#666;line-height:1.7;margin-top:2px;}'\n    +'.agrow .ar{text-align:right;}'\n    +'.agrow .ar .p-lbl{font-size:5.5pt;text-transform:uppercase;letter-spacing:0.12em;color:#aaa;margin-bottom:2px;}'\n    +'.agrow .ar .p-name{font-size:9pt;font-weight:700;color:#20315b;}'\n    +'.agrow .ar .p-info{font-size:6pt;color:#666;line-height:1.7;margin-top:2px;}'\n    +'.fbar{background:linear-gradient(135deg,#20315b,#2d4475);color:#fff;padding:7px 20px;display:flex;justify-content:space-between;align-items:center;}'\n    +'.fbar .ftitle{font-size:7.5pt;font-weight:600;}'\n    +'.fbar .fdate{font-size:6pt;background:rgba(207,202,119,0.2);border:1px solid rgba(207,202,119,0.35);color:#cfca77;padding:2px 7px;border-radius:3px;}'\n    +'.body{padding:10px 20px;}'\n    +'table.devis{width:100%;border-collapse:collapse;}'\n    +'.cat-header td:last-child,.col-header td:last-child,.row-item td:last-child,.row-sub td:last-child{border-right:0;}'\n    +'.cat-header{background:#20315b;}.cat-header td{background:#20315b;color:#cfca77;font-size:6.5pt;font-weight:700;letter-spacing:0.1em;padding:5px 8px;}'\n    +'.col-header td{background:#f5f1eb;color:#aaa;font-size:5.5pt;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;padding:3px 8px;border-bottom:1px solid #e8e2d8;}'\n    +'.row-item td{padding:4px 8px;border-bottom:1px solid #f2ede6;font-size:7pt;vertical-align:middle;}'\n    +'.row-item td:not(:first-child){text-align:center;color:#777;}'\n    +'.row-item td:last-child{text-align:right;font-weight:600;color:#20315b;white-space:nowrap;min-width:70px;padding-right:8px;}'\n    +'.note{font-size:6pt;color:#aaa;font-style:italic;}'\n    +'.row-sub td{background:#f9f6f1;padding:4px 8px;font-size:6.5pt;font-weight:700;color:#b0ab5a;text-align:right;border-top:1px solid #e0d8c8;}'\n    +'.row-sub td:last-child{white-space:nowrap;min-width:70px;padding-right:8px;}'\n    +'.row-sub td:first-child{text-align:left;}'\n    +'.total-bar{background:#20315b;color:#fff;padding:10px 16px;display:flex;justify-content:space-between;align-items:center;margin-top:5px;border-radius:3px;}'\n    +'.total-bar .tl{font-size:7.5pt;font-weight:600;}'\n    +'.total-bar .ta{font-family:\"DM Mono\",monospace;font-size:16pt;color:#cfca77;font-weight:500;}'\n    +'.bottom-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:12px;}'\n    +'.box-title{font-size:6pt;font-weight:700;text-transform:uppercase;letter-spacing:0.1em;color:#20315b;padding-bottom:4px;border-bottom:2px solid #cfca77;margin-bottom:7px;}'\n    +'table.modal{width:100%;border-collapse:collapse;}'\n    +'table.modal td{font-size:7pt;padding:2.5px 0;vertical-align:bottom;color:#20315b;}'\n    +'table.modal td.ml{width:65%;padding-right:3px;word-wrap:break-word;font-size:6.5pt;}'\n    +'table.modal td.md{border-bottom:1.5px dotted #ccc;}'\n    +'table.modal td.mr{width:20%;text-align:right;font-family:\"DM Mono\",monospace;font-size:7.5pt;font-weight:700;white-space:nowrap;padding-left:4px;}'\n    +'.notes-and-stamp{display:flex;flex-direction:column;gap:8px;}'\n    +'.notes-box{font-size:6.5pt;color:#555;line-height:1.75;}'\n    +'.notes-box p{margin-bottom:4px;padding-left:12px;position:relative;}'\n    +'.notes-box p::before{content:\"\\u2192\";position:absolute;left:0;color:#20315b;font-weight:700;}'\n    +'.stamp-block{display:flex;justify-content:flex-start;padding-top:6px;}'\n    +'.stamp-block img{height:68px;opacity:0.9;}'\n    +'.warn-box{background:#fff8e6;border-left:3px solid #cfca77;padding:7px 10px;font-size:6pt;color:#7a6200;line-height:1.6;margin-top:10px;}'\n    +'.warn-box strong{font-size:6.5pt;}'\n    +'.page-footer{background:#f5f1eb;border-top:2px solid #20315b;padding:7px 20px;display:flex;justify-content:space-between;align-items:center;margin-top:auto;}'\n    +'.page-footer .legal{font-size:5.5pt;color:#aaa;text-align:center;line-height:1.6;}'\n    +'.page-footer .valid{font-size:6.5pt;font-weight:700;color:#20315b;text-align:right;line-height:1.8;}'\n    +'.p2-hdr{background:#20315b;padding:9px 20px;display:flex;justify-content:space-between;align-items:center;}'\n    +'.p2-hdr .t{color:#cfca77;font-size:11pt;font-weight:700;}'\n    +'.p2-hdr .r{color:rgba(255,255,255,0.45);font-size:6pt;font-family:\"DM Mono\",monospace;}'\n    +'.p2-body{padding:12px 20px;display:grid;grid-template-columns:1fr 1fr;gap:18px;}'\n    +'.p2-col h4{font-size:6.5pt;font-weight:700;text-transform:uppercase;letter-spacing:0.1em;color:#20315b;padding-bottom:4px;border-bottom:2px solid #cfca77;margin-bottom:8px;}'\n    +'.ephoto-block{display:flex;gap:8px;background:#fff9f1;border:1px solid #e8e2d8;border-radius:4px;padding:7px 9px;margin-bottom:7px;align-items:flex-start;}'\n    +'.ephoto-block img{height:52px;border:1px solid #ddd;border-radius:2px;flex-shrink:0;}'\n    +'.ephoto-text{font-size:6pt;color:#555;line-height:1.6;}'\n    +'.ephoto-text strong{color:#20315b;display:block;margin-bottom:2px;font-size:6.5pt;}'\n    +'ul.doc-list{list-style:none;padding:0;margin:0;}'\n    +'ul.doc-list li{font-size:6.5pt;line-height:1.55;padding:2.5px 0;border-bottom:1px solid rgba(232,226,216,0.5);color:#444;display:flex;gap:4px;align-items:flex-start;}'\n    +'ul.doc-list li.warn span:first-child{color:#e07b00;flex-shrink:0;}'\n    +'ul.doc-list li.normal span:first-child{color:#aaa;flex-shrink:0;}'\n    +'.scan-box{border-radius:0 4px 4px 0;padding:7px 9px;font-size:6pt;line-height:1.6;margin-top:8px;}'\n    +'.scan-box.viviers{background:#fff9f0;border-left:3px solid #cfca77;color:#6a4200;}'\n    +'.scan-box.meysse{background:#fff3e0;border-left:3px solid #e07b00;color:#7a4000;}'\n    +'.scan-box strong{display:block;margin-bottom:2px;font-size:6.5pt;}'\n    +'.pay-box{background:#f5f1eb;border-radius:3px;padding:7px 9px;font-size:6.5pt;color:#20315b;margin-top:8px;line-height:1.7;}'\n    +'table.recap{width:100%;border-collapse:collapse;font-size:6.5pt;}'\n    +'table.recap td{padding:2px 4px;}'\n    +'table.recap td.rl{color:#aaa;width:48%;}'\n    +'table.recap td.rv{font-weight:600;color:#20315b;text-align:right;}'\n    +'table.recap td.rv-ref{font-family:\"DM Mono\",monospace;font-size:9pt;letter-spacing:0.1em;}'\n    +'.recap-wrap{background:#f5f1eb;border-radius:4px;padding:9px 10px;margin-bottom:12px;}'\n    +'.aids-box{background:linear-gradient(135deg,rgba(32,49,91,0.04),rgba(207,202,119,0.1));border:1px solid rgba(207,202,119,0.4);border-radius:4px;padding:9px 10px;font-size:6.5pt;color:#555;line-height:1.7;}'\n    +'.aids-box strong{color:#20315b;display:block;font-size:7pt;margin-bottom:3px;}'\n    +'.aids-box a{color:#20315b;font-weight:600;display:block;margin-top:4px;}'\n    +'.alert-box{border:1px solid #e8e2d8;border-top:2px solid #cfca77;border-radius:0 0 4px 4px;padding:8px 10px;font-size:6pt;color:#555;line-height:1.6;margin-top:10px;}'\n    +'.alert-box strong{color:#20315b;display:block;font-size:6.5pt;margin-bottom:3px;}'\n    +'.footer2{background:#f5f1eb;border-top:1px solid #e8e2d8;padding:6px 20px;font-size:5.5pt;color:#aaa;text-align:center;margin-top:auto;}';\n\n  var H='<!DOCTYPE html><html><head><meta charset=\"UTF-8\"\/>'\n    +'<link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:wght@300;400;500;600;700&#038;family=DM+Mono:wght@400;500&#038;display=swap\" rel=\"stylesheet\"\/>'\n    +'<style>'+CSS+'<\/style><\/head><body>'\n\n  \/\/ PAGE 1\n    +'<div class=\"page\">'\n    +'<div class=\"page-content\">'\n    +'<div class=\"hdr\">'\n    +'<div class=\"hdr-left\"><div class=\"ae\">Auto \u00c9cole Vivaroise<\/div>'\n    +'<div class=\"ae-siret\">SIRET 82856336100017<\/div>'\n    +'<div class=\"ae-tel\">04.75.52.54.75 \u2014 auto-ecole-vivaroise@orange.fr<\/div>'\n    +'<div class=\"ae-web\">www.autoecolevivaroise.com<\/div><\/div>'\n    +'<div class=\"hdr-center\"><div class=\"dw\">DEVIS<\/div><div class=\"ref\">'+refDevis+'<\/div><\/div>'\n    +'<div class=\"hdr-right\"><img decoding=\"async\" class=\"hdr-logo\" src=\"'+logoUrl+'\" alt=\"Logo\" onerror=\"this.style.display=\\'none\\'\"\/><\/div>'\n    +'<\/div>'\n    +'<div class=\"agrow\">'\n    +'<div class=\"al\"><div class=\"ag-lbl\">Agence<\/div><div class=\"ag-name\">'+agenceLabel+'<\/div>'\n    +'<div class=\"ag-det\">'+getAgenceAddr()+'<br>'+getAgenceHoraires()+'<\/div><\/div>'\n    +'<div class=\"ar\"><div class=\"p-lbl\">Devis \u00e9tabli pour<\/div>'\n    +'<div class=\"p-name\">'+state.civilite+'\u00a0'+state.prenom+'\u00a0'+state.nom+'<\/div>'\n    +'<div class=\"p-info\">'+state.email+(state.telephone&&state.telephone!=='\u2014'?'\u00a0\u00b7\u00a0'+state.telephone:'')+'<br>Emis le\u00a0: '+now.date+'\u00a0\u00b7\u00a0Valable jusqu\\'au\u00a0: '+validite+'<\/div><\/div>'\n    +'<\/div>'\n    +'<div class=\"fbar\">'\n    +'<span class=\"ftitle\">Formation\u00a0: '+getFormationLabel(state.formation)+' en bo\u00eete '+(isMan?'manuelle':'automatique')+'<\/span>'\n    +'<span class=\"fdate\">Tarifs du 01\/01\/'+year+' au 31\/12\/'+year+'<\/span>'\n    +'<\/div>'\n    +'<div class=\"body\">'\n    +'<table class=\"devis\">'+tableHTML+'<\/table>'\n    +'<div class=\"total-bar\"><span class=\"tl\">Minimum estim\u00e9 Total TTC<\/span><span class=\"ta\">'+fmt(total)+'<\/span><\/div>'\n    +'<div class=\"bottom-grid\">'\n    +'<div><div class=\"box-title\">Modalit\u00e9s de paiement \u2014 TVA\u00a020%\u00a0incluse<\/div>'\n    +'<table class=\"modal\">'+modalHTML+'<\/table>'\n    +'<div style=\"font-size:6pt;color:#777;margin-top:5px;\">Moyens de paiement\u00a0: '+payInfo+'<\/div>'\n    +'<\/div>'\n    +'<div class=\"notes-and-stamp\">'\n    +'<div><div class=\"box-title\">Notes importantes<\/div>'\n    +'<div class=\"notes-box\">'\n    +'<p>Toute prestation suppl\u00e9mentaire (renouvellement de code, le\u00e7ons suppl\u00e9mentaires, repr\u00e9sentation \u00e0 l\u2019examen) sera factur\u00e9e aux <strong>tarifs en vigueur de l\u2019ann\u00e9e en cours<\/strong>.<\/p>'\n    +'<p>Examen th\u00e9orique du code\u00a0: 30\u00a0\u20ac \u00e0 r\u00e9gler directement aupr\u00e8s d\u2019un op\u00e9rateur agr\u00e9\u00e9 priv\u00e9 (non inclus).<\/p>'\n    +'<p>CGV\u00a0: www.autoecolevivaroise.com\/cgv<\/p>'\n    +'<\/div><\/div>'\n    +'<div class=\"stamp-block\"><img decoding=\"async\" src=\"'+cachetUrl+'\" alt=\"Cachet\" onerror=\"this.style.display=\\'none\\'\"\/><\/div>'\n    +'<\/div>'\n    +'<\/div>'\n    +'<div class=\"warn-box\"><strong>\u26a0\ufe0f AVERTISSEMENT<\/strong> '\n    +'Tarifs valables du 01\/01\/'+year+' au 31\/12\/'+year+'. Ce devis est \u00e9tabli \u00e0 titre indicatif sur la base des d\u00e9clarations du candidat depuis le formulaire en ligne sur <strong>www.autoecolevivaroise.com<\/strong>. Il peut contenir des erreurs si de mauvaises d\u00e9clarations ont \u00e9t\u00e9 faites. Seul un entretien en pr\u00e9sentiel \u00e0 l\u2019agence confirmera d\u00e9finitivement la validit\u00e9 du devis et la possibilit\u00e9 de prise en charge du candidat.'\n    +'<\/div>'\n    +'<\/div>'\n    +'<\/div>'\n    +'<div class=\"page-footer\">'\n    +'<div class=\"legal\">Devis g\u00e9n\u00e9r\u00e9 automatiquement le '+now.date+' \u00e0 '+now.heure+' depuis www.autoecolevivaroise.com<br>SARL Auto \u00c9cole Vivaroise \u2014 SIRET 82856336100017<\/div>'\n    +'<div class=\"valid\">Valable jusqu\\'au\u00a0: <strong>'+validite+'<\/strong><br>R\u00e9f.\u00a0: <strong style=\"font-family:\\'DM Mono\\',monospace;font-size:9pt;letter-spacing:0.1em;\">'+refDevis+'<\/strong><\/div>'\n    +'<\/div>'\n    +'<\/div>'\n    +'<div class=\"page\">'\n    +'<div class=\"page-content\">'\n    +'<div class=\"p2-hdr\">'\n    +'<span class=\"t\">Documents \u00e0 fournir &amp; Informations compl\u00e9mentaires<\/span>'\n    +'<span class=\"r\">R\u00e9f. '+refDevis+' \u2014 '+state.civilite+' '+state.prenom+' '+state.nom+' \u2014 '+getFormationLabel(state.formation)+'<\/span>'\n    +'<\/div>'\n    +'<div class=\"p2-body\">'\n    +'<div class=\"p2-col\">'\n    +'<h4>Documents \u00e0 fournir (en mains propres \u00e0 l\u2019agence)<\/h4>'\n    +(isPerf()?''\n      :'<div class=\"ephoto-block\">'\n      +'<img decoding=\"async\" src=\"https:\/\/autoecolevivaroise.com\/wp-content\/uploads\/2026\/04\/ePhoto-ANTS.png\" alt=\"E-photo ANTS\" onerror=\"this.style.display=\\'none\\'\"\/>'\n      +'<div class=\"ephoto-text\"><strong>E-Photos conformes ANTS \u2014 voir mod\u00e8le ci-contre<\/strong>'\n      +'Plaquette originale \u00e0 fournir, dat\u00e9e de moins de 6 mois.<br>Photos agr\u00e9\u00e9es par les services en ligne ANTS.<\/div><\/div>')\n    +'<ul class=\"doc-list\">'+docsHTML+'<\/ul>'\n    +scannerHTML\n    +'<div class=\"pay-box\"><strong>Moyens de paiement accept\u00e9s\u00a0:<\/strong><br>'+payInfo+'<\/div>'\n    +'<\/div>'\n    +'<div class=\"p2-col\">'\n    +'<h4>R\u00e9capitulatif de la demande<\/h4>'\n    +'<div class=\"recap-wrap\"><table class=\"recap\">'+recapHTML+'<\/table><\/div>'\n    +'<h4>Aides au financement<\/h4>'\n    +'<div class=\"aids-box\"><strong>Des aides financi\u00e8res sont peut-\u00eatre disponibles\u00a0!<\/strong>'\n    +'D\u00e9couvrez vos droits et les conditions d\u2019acc\u00e8s pour b\u00e9n\u00e9ficier d\u2019aides au financement du permis de conduire\u00a0:'\n    +'<a href=\"'+aidesUrl+'\">'+aidesUrl+'<\/a><\/div>'\n    +'<div class=\"alert-box\"><strong>\u26a0\ufe0f Avertissement important<\/strong>'\n    +'Ce devis a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 automatiquement depuis <strong>www.autoecolevivaroise.com<\/strong> sur la base des d\u00e9clarations du candidat. Il est \u00e9tabli \u00e0 titre indicatif. <strong>Seul un \u00e9change en pr\u00e9sentiel avec l\u2019agence confirmera la validit\u00e9 r\u00e9elle du devis et la possibilit\u00e9 de prise en charge.<\/strong><\/div>'\n    +'<\/div>'\n    +'<\/div>'\n    +'<\/div>'\n    +'<div class=\"footer2\">Devis g\u00e9n\u00e9r\u00e9 automatiquement le '+now.date+' \u00e0 '+now.heure+' depuis www.autoecolevivaroise.com \u2014 SARL Auto \u00c9cole Vivaroise \u2014 SIRET 82856336100017 \u2014 R\u00e9f. '+refDevis+'<\/div>'\n    +'<\/div>';\n  H+='<\/body><\/html>';\n  return H;\n}\n\nasync function generatePDF(){\n  var { jsPDF } = window.jspdf;\n\n  \/\/ 1) Injecter le HTML dans un iframe hors-ecran\n  var iframe = document.createElement('iframe');\n  iframe.style.cssText = 'position:fixed;top:-9999px;left:-9999px;width:794px;height:1px;border:none;';\n  document.body.appendChild(iframe);\n\n  var htmlContent = buildDevisHTML();\n  iframe.contentDocument.open();\n  iframe.contentDocument.write(htmlContent);\n  iframe.contentDocument.close();\n\n  \/\/ 2) Attendre le chargement (fonts + images)\n  await new Promise(function(resolve){ setTimeout(resolve, 2000); });\n\n  var iDoc = iframe.contentDocument;\n  var pages = iDoc.querySelectorAll('.page');\n\n  var pdf = new jsPDF({orientation:'portrait', unit:'mm', format:'a4'});\n  var pdfW = 210; \/\/ mm\n\n  \/\/ 3) Capturer chaque page et l'ajouter au PDF\n  for(var i=0; i<pages.length; i++){\n    if(i > 0) pdf.addPage();\n    var canvas = await html2canvas(pages[i], {\n      scale: 2,           \/\/ Resolution x2 pour qualite\n      useCORS: true,\n      allowTaint: true,\n      backgroundColor: '#ffffff',\n      width: 794,\n      windowWidth: 794\n    });\n    var imgData = canvas.toDataURL('image\/jpeg', 0.92);\n    var imgH = (canvas.height * pdfW) \/ canvas.width;\n    pdf.addImage(imgData, 'JPEG', 0, 0, pdfW, imgH);\n  }\n\n  \/\/ 4) Nettoyage et sauvegarde\n  document.body.removeChild(iframe);\n  \/\/ Format: Devis_AA_MM_JJ_REF_NOM_P_AEVivaroise\/Meysse\n  var d=new Date();\n  var dd=String(d.getDate()).padStart(2,'0');\n  var mm=String(d.getMonth()+1).padStart(2,'0');\n  var yy=String(d.getFullYear()).slice(2);\n  var nomFich=(state.nom||'').toUpperCase().replace(\/[^A-Z0-9]\/g,'_');\n  var prenomInit=(state.prenom||'').toUpperCase().replace(\/[^A-Z]\/g,'')[0]||'X';\n  var agenceSuffix=state.agence==='viviers'?'AEVivaroise':'AEMeysse';\n  var filename='Devis_'+yy+'_'+mm+'_'+dd+'_'+refDevis+'_'+nomFich+'_'+prenomInit+'_'+agenceSuffix+'.pdf';\n  pdf.save(filename);\n  \/\/ Retourner le dataURL base64 pour Firebase\n  return pdf.output('datauristring');\n}\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  ENVOI NOTIFICATIONS\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nfunction buildPayload(){\n  var now=getNow();\n  var devisData=buildDevisLines();\n  \/\/ URL du devis : on stocke la r\u00e9f\u00e9rence pour que l'admin puisse acc\u00e9der au devis\n  var devisUrl='https:\/\/autoecolevivaroise.com\/devis\/?ref='+refDevis;\n  return{\n    ref_devis       : refDevis,\n    civilite        : state.civilite||'\u2014',\n    prenom          : state.prenom||'\u2014',\n    nom             : state.nom||'\u2014',\n    email           : state.email||'\u2014',\n    telephone       : state.telephone||'\u2014',\n    age             : state.age==='mineur'?'Mineur':'Majeur',\n    agence          : getAgenceLabel(),\n    formation       : getFormationLabel(state.formation)+' \u2014 bo\u00eete '+(isManuelle()?'manuelle':'automatique'),\n    boite           : isManuelle()?'Bo\u00eete manuelle':'Bo\u00eete automatique',\n    autre_autoecole : state.autreAutoEcole?'Oui':'Non',\n    statut_eleve    : state.statutEleve==='code_non_obtenu'?'Code en cours (pas encore obtenu)'\n                    : state.statutEleve==='code_obtenu'?'Code obtenu, conduite non commenc\u00e9e':'\u2014',\n    scolarise       : state.scolarise===true?'Oui (Mont\u00e9limar \/ Le Teil)'\n                    : state.scolarise===false?'Non \/ Non concern\u00e9 (majeur)':'\u2014',\n    a_neph          : state.aNeph?'Oui \u2014 dossier ANTS existant':'Non \u2014 premier dossier',\n    code_salle      : state.codeSalle?'Oui':'Non',\n    code_internet   : state.codeNet?'Oui':'Non',\n    livre_code      : state.aLivre?'D\u00e9j\u00e0 poss\u00e9d\u00e9':'Inclus dans le devis',\n    annulation_permis: state.annulationPermis==='code_seul'?'Code uniquement':state.annulationPermis==='code_conduite'?'Code + Conduite':'\u2014',\n    neph_present    : state.aNeph?'Oui':'Non',\n    date            : now.date,\n    heure           : now.heure,\n    ip              : techInfo.ip   || 'Non disponible',\n    pays            : techInfo.pays || 'Non disponible',\n    ville           : techInfo.ville||'',\n    total_ttc       : devisData.total.toFixed(2).replace('.',',')+'\u00a0\u20ac',\n    devis_url       : devisUrl\n  };\n}\nasync function sendDiscord(p){\n  try{\n    function safe(v){ return (v && String(v).trim()) ? String(v) : '\u2014'; }\n    var payload = {\n      username: 'Auto \u00c9cole Vivaroise \u2014 Devis',\n      content: '**Nouveau devis** r\u00e9f. `'+safe(p.ref_devis)+'` \u2014 '+safe(p.civilite)+' '+safe(p.prenom)+' '+safe(p.nom),\n      embeds: [{\n        title: '\ud83d\udccb Devis r\u00e9f. '+safe(p.ref_devis),\n        color: 2110811,\n        fields: [\n          {name:'\ud83d\udd16 R\u00e9f\u00e9rence',            value:safe(p.ref_devis),                                     inline:false},\n          {name:'\ud83d\udc64 Identit\u00e9',             value:safe(p.civilite)+' '+safe(p.prenom)+' '+safe(p.nom),   inline:true},\n          {name:'\ud83d\udce7 E-mail',               value:safe(p.email),                                          inline:true},\n          {name:'\ud83d\udcde T\u00e9l\u00e9phone',            value:safe(p.telephone),                                      inline:true},\n          {name:'\ud83c\udf82 Profil',               value:safe(p.age),                                            inline:true},\n          {name:'\ud83d\udccd Agence',               value:safe(p.agence),                                         inline:true},\n          {name:'\ud83c\udf93 Formation',            value:safe(p.formation),                                      inline:false},\n          {name:'\ud83c\udd94 Dossier ANTS\/NEPH',   value:safe(p.a_neph),                                         inline:true},\n          {name:'\ud83c\udfeb Autre auto-\u00e9cole',    value:safe(p.autre_autoecole),                                inline:true},\n          {name:'\ud83d\udcd6 Statut \u00e9l\u00e8ve',         value:safe(p.statut_eleve),                                   inline:true},\n          {name:'\ud83c\udfeb Scolaris\u00e9',              value:safe(p.scolarise),                                       inline:true},\n          {name:'\ud83d\udcbb Code en salle',        value:safe(p.code_salle),                                     inline:true},\n          {name:'\ud83c\udf10 Code internet',        value:safe(p.code_internet),                                  inline:true},\n          {name:'\ud83d\udcda Livre de code',        value:safe(p.livre_code),                                     inline:true},\n          {name:'\u26a0 Annulation permis',        value:safe(p.annulation_permis),                              inline:true},\n          {name:'\ud83d\udcc5 Date',                 value:safe(p.date),                                           inline:true},\n          {name:'\ud83d\udd50 Heure',                value:safe(p.heure),                                          inline:true},\n          {name:'\ud83c\udf0d Pays \/ Ville',         value:safe(p.pays)+(p.ville?' \/ '+p.ville:''),                inline:true},\n          {name:'\ud83d\udd12 IP',                   value:safe(p.ip),                                             inline:true},\n          {name:'\ud83d\udcb0 Total estim\u00e9 TTC',    value:safe(p.total_ttc),                                      inline:false},\n          {name:'\ud83d\udd17 Lien du devis',        value:safe(p.devis_url),                                      inline:false}\n        ],\n        footer: {text:'Demande effectu\u00e9e depuis www.autoecolevivaroise.com'},\n        timestamp: new Date().toISOString()\n      }]\n    };\n    var resp = await fetch(DISCORD_WEBHOOK, {\n      method: 'POST',\n      headers: {'Content-Type': 'application\/json'},\n      body: JSON.stringify(payload)\n    });\n    if(!resp.ok){\n      var txt = await resp.text();\n      console.error('Discord erreur HTTP '+resp.status+':', txt);\n    }\n  } catch(e){\n    console.error('Discord fetch error:', e);\n  }\n}\nasync function sendEmail(p){\n  try{\n    if(typeof emailjs === 'undefined'){ console.warn('EmailJS non disponible'); return; }\n    await emailjs.send(EMAILJS_SERVICE_ID, EMAILJS_TEMPLATE_ID, p);\n  } catch(e){ console.warn('EmailJS envoi \u00e9chou\u00e9:', e); }\n}\nasync function sendAll(pdfDataUrl){\n  var p=buildPayload();\n  await Promise.allSettled([sendDiscord(p), sendEmail(p)]);\n}\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  ETAPES DU FORMULAIRE\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nvar TOTAL_STEPS=12;\n\n\/\/ 1 \u2014 Mineur \/ Majeur\nfunction step1_age(){\n  setProgress(1,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 1<\/span><\/div><h3>\u00cates-vous mineur ou majeur ?<\/h3><p>Cette information nous permettra d\\'adapter votre parcours.<\/p><\/div><div class=\"card-body\"><div class=\"options horizontal\"><button class=\"option-btn\" id=\"btnMineur\"><div class=\"btn-icon\">\ud83e\uddd1<\/div><div class=\"btn-text\"><div class=\"btn-label\">Mineur<\/div><div class=\"btn-sub\">Moins de 18 ans<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnMajeur\"><div class=\"btn-icon\">\ud83e\uddd1\u200d\ud83d\udcbc<\/div><div class=\"btn-text\"><div class=\"btn-label\">Majeur<\/div><div class=\"btn-sub\">18 ans et plus<\/div><\/div><\/button><\/div>'+renderNavButtons(navStack.length>1)+'<\/div><\/div>');\n  document.getElementById('btnMineur').addEventListener('click',function(){state.age='mineur';goTo(step2_permisB);});\n  document.getElementById('btnMajeur').addEventListener('click',function(){state.age='majeur';goTo(step2_permisB);});\n  attachNavEvents();\n}\n\n\/\/ 2 \u2014 Permis B\nfunction step2_permisB(){\n  setProgress(2,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 2<\/span><\/div><h3>Souhaitez-vous passer le permis B (voiture) ?<\/h3><p>Nous dispensons uniquement des formations pour le permis de conduire voiture (permis B).<\/p><\/div><div class=\"card-body\"><div class=\"options horizontal\"><button class=\"option-btn\" id=\"btnOuiB\"><div class=\"btn-icon\">\ud83d\ude97<\/div><div class=\"btn-text\"><div class=\"btn-label\">Oui, le permis B<\/div><div class=\"btn-sub\">Formation voiture<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnNonB\"><div class=\"btn-icon\">\ud83c\udfcd\ufe0f<\/div><div class=\"btn-text\"><div class=\"btn-label\">Non, autre permis<\/div><div class=\"btn-sub\">Moto, camion, etc.<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  document.getElementById('btnOuiB').addEventListener('click',function(){state.permisB=true;goTo(step3_autreAutoEcole);});\n  document.getElementById('btnNonB').addEventListener('click',function(){state.permisB=false;showError('Formation non disponible','Nous proposons <strong>uniquement la formation au permis B (voiture)<\/strong>. Nous ne dispensons pas de formation pour d\\'autres types de permis.',true);});\n  attachNavEvents();\n}\n\n\/\/ 3 \u2014 D\u00e9j\u00e0 inscrit ailleurs\nfunction step3_autreAutoEcole(){\n  setProgress(3,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 3<\/span><\/div><h3>\u00cates-vous d\u00e9j\u00e0 inscrit dans une autre auto-ecole ?<\/h3><\/div><div class=\"card-body\"><div class=\"options horizontal\"><button class=\"option-btn\" id=\"btnNonAE\"><div class=\"btn-icon\">\u2728<\/div><div class=\"btn-text\"><div class=\"btn-label\">Non<\/div><div class=\"btn-sub\">Premi\u00e8re inscription<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnOuiAE\"><div class=\"btn-icon\">\ud83c\udfeb<\/div><div class=\"btn-text\"><div class=\"btn-label\">Oui<\/div><div class=\"btn-sub\">Dossier en cours ailleurs<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  document.getElementById('btnNonAE').addEventListener('click',function(){state.autreAutoEcole=false;goTo(step4_scolarise);});\n  document.getElementById('btnOuiAE').addEventListener('click',function(){state.autreAutoEcole=true;goTo(step3b_statut);});\n  attachNavEvents();\n}\n\n\/\/ 3b \u2014 Statut\nfunction step3b_statut(){\n  setProgress(3,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>Etape 3 - Precision<\/span><\/div><h3>Ou en \u00eates-vous dans votre formation actuelle ?<\/h3><\/div><div class=\"card-body\"><div class=\"options\"><button class=\"option-btn\" id=\"btnCodeNon\"><div class=\"btn-icon\">\ud83d\udcd6<\/div><div class=\"btn-text\"><div class=\"btn-label\">Pr\u00e9paration au code uniquement<\/div><div class=\"btn-sub\">Je prepare le code, je n\\'ai pas commence la conduite dans une autre ecole<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnCodeOui\"><div class=\"btn-icon\">\u2705<\/div><div class=\"btn-text\"><div class=\"btn-label\">Code obtenu, conduite non commencee<\/div><div class=\"btn-sub\">J\\'ai mon code mais je n\\'ai pas commence les heures de conduite dans une autre ecole<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnHeures\"><div class=\"btn-icon\">\ud83d\udea6<\/div><div class=\"btn-text\"><div class=\"btn-label\">J\\'ai d\u00e9j\u00e0 commence les heures de conduite<\/div><div class=\"btn-sub\">J\\'ai effectue des heures de conduite dans une autre ecole<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  document.getElementById('btnCodeNon').addEventListener('click',function(){state.statutEleve='code_non_obtenu';goTo(step4_scolarise);});\n  document.getElementById('btnCodeOui').addEventListener('click',function(){state.statutEleve='code_obtenu';goTo(step4_scolarise);});\n  document.getElementById('btnHeures').addEventListener('click',function(){state.statutEleve='heures_commencees';showError('Reprise de dossier impossible','Nous ne pouvons pas <strong>reprendre un dossier pour lequel des heures de conduite ont d\u00e9j\u00e0 \u00e9t\u00e9 effectu\u00e9es dans une autre auto-ecole<\/strong>.',true);});\n  attachNavEvents();\n}\n\n\/\/ 4 \u2014 Scolarise (mineurs)\nfunction step4_scolarise(){\n  if(state.age==='mineur'){\n    setProgress(4,TOTAL_STEPS);\n    render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 4<\/span><\/div><h3>\u00cates-vous scolarise \u00e0 Mont\u00e9limar ou \u00e0 Le Teil ?<\/h3><p>College ou lycee dans l\\'une de ces communes.<\/p><\/div><div class=\"card-body\"><div class=\"info-notice\">\u2139\ufe0f Cette information nous permet de savoir si nous pouvons vous r\u00e9cup\u00e9rer \u00e0 votre \u00e9tablissement pour les heures de conduite.<\/div><div class=\"options horizontal\"><button class=\"option-btn\" id=\"btnScoOui\"><div class=\"btn-icon\">\ud83c\udfeb<\/div><div class=\"btn-text\"><div class=\"btn-label\">Oui<\/div><div class=\"btn-sub\">Mont\u00e9limar ou Le Teil<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnScoNon\"><div class=\"btn-icon\">\ud83c\udfe0<\/div><div class=\"btn-text\"><div class=\"btn-label\">Non<\/div><div class=\"btn-sub\">Autre commune<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n    document.getElementById('btnScoOui').addEventListener('click',function(){state.scolarise=true;goTo(function(){step5_conditions(true);});});\n    document.getElementById('btnScoNon').addEventListener('click',function(){state.scolarise=false;goTo(function(){step5_conditions(false);});});\n    attachNavEvents();\n  } else {\n    state.scolarise=false;\n    goTo(function(){step5_conditions(false);});\n  }\n}\n\n\/\/ 5 \u2014 Conditions\nfunction step5_conditions(scolarise){\n  setProgress(5,TOTAL_STEPS);\n  var bonne=scolarise?'<div class=\"success-notice\"><strong>Bonne nouvelle !<\/strong> Etant scolaris\u00e9(e) \u00e0 Mont\u00e9limar ou Le Teil, nous pouvons venir vous r\u00e9cup\u00e9rer directement \u00e0 votre lycee, ou vous accueillir depuis nos agences (d\u00e9part agence uniquement, pas domicile).<\/div>':'';\n  var lieuTxt=scolarise?'Les d\u00e9parts s\\'effectuent depuis les agences de Viviers et de Meysse, ainsi que depuis les lycees de Mont\u00e9limar et Le Teil. Aucun ramassage a domicile.':'Les d\u00e9parts s\\'effectuent uniquement depuis les agences de Viviers et de Meysse. Aucun ramassage a domicile.';\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 5<\/span><\/div><h3>'+(scolarise?'Bonne nouvelle - Conditions a accepter':'Conditions importantes a accepter')+'<\/h3><\/div><div class=\"card-body\">'+bonne+'<div class=\"checkbox-group\"><label class=\"checkbox-item\" id=\"chkLieu\"><input type=\"checkbox\" id=\"chkLieuVal\"\/><div class=\"check-box\"><span class=\"check-mark\">\u2713<\/span><\/div><div class=\"checkbox-text\"><strong>Je comprends les lieux de d\u00e9part.<\/strong> '+lieuTxt+'<\/div><\/label><label class=\"checkbox-item\" id=\"chkInscr\"><input type=\"checkbox\" id=\"chkInscrVal\"\/><div class=\"check-box\"><span class=\"check-mark\">\u2713<\/span><\/div><div class=\"checkbox-text\"><strong>Je comprends les modalites d\\'inscription.<\/strong> Pour finaliser mon inscription, je devrai me deplacer <strong>en personne \u00e0 l\\'agence<\/strong>. Un entretien confirmera mon \u00e9ligibilit\u00e9 definitive.<\/div><\/label><\/div><button class=\"btn-continue\" id=\"btnC5\" disabled>Continuer <span class=\"btn-arrow\">\u2192<\/span><\/button>'+renderNavButtons(true)+'<\/div><\/div>');\n  function chk(lid,iid){var l=document.getElementById(lid),i=document.getElementById(iid);l.addEventListener('click',function(){i.checked=!i.checked;l.classList.toggle('checked',i.checked);var c1=document.getElementById('chkLieuVal').checked,c2=document.getElementById('chkInscrVal').checked;document.getElementById('btnC5').disabled=!(c1&&c2);});}\n  chk('chkLieu','chkLieuVal'); chk('chkInscr','chkInscrVal');\n  document.getElementById('btnC5').addEventListener('click',function(){goTo(step6_agence);});\n  attachNavEvents();\n}\n\n\/\/ 6 \u2014 Agence\nfunction step6_agence(){\n  setProgress(6,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 6<\/span><\/div><h3>Pour quelle agence souhaitez-vous un devis ?<\/h3><\/div><div class=\"card-body\"><div class=\"options horizontal\"><button class=\"option-btn\" id=\"btnViv\"><div class=\"btn-icon\">\ud83d\udccd<\/div><div class=\"btn-text\"><div class=\"btn-label\">Auto Ecole Vivaroise<\/div><div class=\"btn-sub\">Viviers<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnMey\"><div class=\"btn-icon\">\ud83d\udccd<\/div><div class=\"btn-text\"><div class=\"btn-label\">Meysse Auto Ecole<\/div><div class=\"btn-sub\">Meysse<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  document.getElementById('btnViv').addEventListener('click',function(){state.agence='viviers';goTo(step7_formation);});\n  document.getElementById('btnMey').addEventListener('click',function(){state.agence='meysse';goTo(step7_formation);});\n  attachNavEvents();\n}\n\n\/\/ 7 \u2014 Formation\nfunction step7_formation(){\n  setProgress(7,TOTAL_STEPS);\n  var isMajeur=state.age==='majeur', isViviers=state.agence==='viviers';\n  var opts=[];\n  if(!isMajeur&&isViviers) opts=[\n    {id:'fAac',val:'aac',icon:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66',label:'Conduite Accompagnee (AAC)',sub:'A partir de 15 ans, accompagne d\\'un adulte referent'},\n    {id:'fTrad',val:'traditionnel',icon:'\ud83c\udf93',label:'Traditionnel',sub:'Formation classique \u00e0 partir de 17 ans'},\n    {id:'fB78',val:'b78_vers_b',icon:'\ud83d\udd04',label:'Passerelle boite auto vers boite manuelle (B78 vers B)',sub:'Vous avez le permis boite auto et souhaitez passer en manuelle'}\n  ];\n  else if(isMajeur&&isViviers) opts=[\n    {id:'fTrad',val:'traditionnel',icon:'\ud83c\udf93',label:'Traditionnel',sub:'Formation classique'},\n    {id:'fCs',val:'cs',icon:'\ud83e\udd1d',label:'Conduite Supervisee (CS)',sub:'Des 18 ans, accompagne d\\'un adulte referent titulaire du permis'},\n    {id:'fPerf',val:'perfectionnement',icon:'\ud83d\udee1\ufe0f',label:'Reprises de confiance \/ Perfectionnement',sub:'Reprendre le volant sereinement, ex. apres un accident traumatisant'},\n    {id:'fAnnu',val:'annulation',icon:'\u26a0\ufe0f',label:'Annulation de permis',sub:'Repasser a la suite d\\'une annulation de permis'},\n    {id:'fB78',val:'b78_vers_b',icon:'\ud83d\udd04',label:'Passerelle boite auto vers boite manuelle (B78 vers B)',sub:'Vous avez le permis boite auto et souhaitez passer en manuelle'}\n  ];\n  else if(!isMajeur&&!isViviers) opts=[\n    {id:'fAac',val:'aac',icon:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66',label:'Conduite Accompagnee (AAC)',sub:'A partir de 15 ans, accompagne d\\'un adulte referent'},\n    {id:'fTrad',val:'traditionnel',icon:'\ud83c\udf93',label:'Traditionnel',sub:'Formation classique \u00e0 partir de 17 ans'}\n  ];\n  else opts=[\n    {id:'fTrad',val:'traditionnel',icon:'\ud83c\udf93',label:'Traditionnel',sub:'Formation classique'},\n    {id:'fCs',val:'cs',icon:'\ud83e\udd1d',label:'Conduite Supervisee (CS)',sub:'Des 18 ans, accompagne d\\'un adulte referent titulaire du permis'},\n    {id:'fPerf',val:'perfectionnement',icon:'\ud83d\udee1\ufe0f',label:'Reprises de confiance \/ Perfectionnement',sub:'Reprendre le volant sereinement, ex. apres un accident traumatisant'},\n    {id:'fAnnu',val:'annulation',icon:'\u26a0\ufe0f',label:'Annulation de permis',sub:'Repasser a la suite d\\'une annulation de permis'}\n  ];\n  var btns=opts.map(function(o){return '<button class=\"option-btn\" id=\"'+o.id+'\"><div class=\"btn-icon\">'+o.icon+'<\/div><div class=\"btn-text\"><div class=\"btn-label\">'+o.label+'<\/div><div class=\"btn-sub\">'+o.sub+'<\/div><\/div><\/button>';}).join('');\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 7<\/span><\/div><h3>Quelle formation souhaitez-vous suivre ?<\/h3><p>'+getAgenceLabel()+' \u2014 Profil '+(isMajeur?'majeur':'mineur')+'<\/p><\/div><div class=\"card-body\"><div class=\"options\">'+btns+'<\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  opts.forEach(function(o){document.getElementById(o.id).addEventListener('click',function(){state.formation=o.val;if(o.val==='b78_vers_b'){goTo(step8_boite);}else if(o.val==='annulation'){goTo(step7b_annulation);}else{goTo(step8_boite);}});});\n  attachNavEvents();\n}\n\n\/\/ 7b \u2014 Annulation\nfunction step7b_annulation(){\n  setProgress(8,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>Precision<\/span><\/div><h3>Annulation de permis \u2014 que devez-vous repasser ?<\/h3><\/div><div class=\"card-body\"><div class=\"options\"><button class=\"option-btn\" id=\"btnCS\"><div class=\"btn-icon\">\ud83d\udcd6<\/div><div class=\"btn-text\"><div class=\"btn-label\">Le code uniquement<\/div><div class=\"btn-sub\">Je dois repasser uniquement l\\'\u00e9preuve th\u00e9orique<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnCC\"><div class=\"btn-icon\">\ud83d\udcd6\ud83d\ude97<\/div><div class=\"btn-text\"><div class=\"btn-label\">Le code et la conduite<\/div><div class=\"btn-sub\">Je dois tout repasser (theorie + pratique)<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  document.getElementById('btnCS').addEventListener('click',function(){state.annulationPermis='code_seul';goTo(step9_neph);});\n  document.getElementById('btnCC').addEventListener('click',function(){state.annulationPermis='code_conduite';showError('Prise en charge partielle uniquement','Nous pouvons vous accompagner pour la <strong>pr\u00e9paration au code uniquement<\/strong>. La partie conduite n\\'est pas proposee pour ce cas dans nos agences pour le moment.',true);});\n  attachNavEvents();\n}\n\n\/\/ 8 \u2014 Boite\nfunction step8_boite(){\n  setProgress(8,TOTAL_STEPS);\n  \/\/ Passerelle B78 -> pas de choix boite (toujours manuelle)\n  if(isB78()){state.boite='manuelle';goTo(step9_neph);return;}\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 8<\/span><\/div><h3>Quelle boite de vitesses souhaitez-vous ?<\/h3><\/div><div class=\"card-body\"><div class=\"info-notice\">\u2139\ufe0f <strong>Bon a savoir :<\/strong> Avec une formation en boite automatique, votre permis sera limite aux vehicules a boite automatique (mention B78).<\/div><div class=\"options horizontal\"><button class=\"option-btn\" id=\"btnMan\"><div class=\"btn-icon\">\u2699\ufe0f<\/div><div class=\"btn-text\"><div class=\"btn-label\">Boite manuelle<\/div><div class=\"btn-sub\">Permis sans restriction<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnAut\"><div class=\"btn-icon\">\ud83d\udd27<\/div><div class=\"btn-text\"><div class=\"btn-label\">Boite automatique<\/div><div class=\"btn-sub\">Permis B78<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  document.getElementById('btnMan').addEventListener('click',function(){state.boite='manuelle';goTo(step9_neph);});\n  document.getElementById('btnAut').addEventListener('click',function(){state.boite='automatique';goTo(step9_neph);});\n  attachNavEvents();\n}\n\n\/\/ 9 \u2014 NEPH \/ ANTS (skip pour perfectionnement et B78)\nfunction step9_neph(){\n  \/\/ Perfectionnement : pas d'ANTS du tout, ne pas poser la question\n  if(isPerf()){\n    state.aNeph=false;\n    goTo(step10_theorie);\n    return;\n  }\n  \/\/ B78 vers B : ANTS toujours factur\u00e9 par l'auto-\u00e9cole, ne pas poser la question\n  if(isB78()){\n    state.aNeph=false;\n    goTo(step10_theorie);\n    return;\n  }\n  \/\/ Annulation de permis : ANTS toujours factur\u00e9, pas besoin de demander\n  if(isAnnu()){\n    state.aNeph=false;\n    goTo(step10_theorie);\n    return;\n  }\n  \/\/ Code d\u00e9j\u00e0 obtenu : dossier ANTS via l'ancienne auto-\u00e9cole, pas de frais ANTS ici\n  if(state.statutEleve==='code_obtenu'){\n    state.aNeph=true;\n    goTo(step10_theorie);\n    return;\n  }\n  setProgress(9,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 9<\/span><\/div><h3>Avez-vous d\u00e9j\u00e0 un dossier ANTS \/ num\u00e9ro NEPH ?<\/h3><p>Le NEPH est le num\u00e9ro d\\'inscription au permis de conduire, attribu\u00e9 lors de votre premi\u00e8re d\u00e9marche sur le site ANTS.<\/p><\/div><div class=\"card-body\"><div class=\"info-notice\">\u2139\ufe0f Si vous avez d\u00e9j\u00e0 cr\u00e9\u00e9 un dossier sur <strong>ants.gouv.fr<\/strong> pour le permis de conduire, vous poss\u00e9dez un num\u00e9ro NEPH. Cette information influence les documents \u00e0 apporter et les frais d\\'inscription.<\/div><div class=\"options horizontal\"><button class=\"option-btn\" id=\"btnNOui\"><div class=\"btn-icon\">\u2705<\/div><div class=\"btn-text\"><div class=\"btn-label\">Oui, j\\'ai un num\u00e9ro NEPH<\/div><div class=\"btn-sub\">J\\'ai d\u00e9j\u00e0 fait une d\u00e9marche sur ANTS<\/div><\/div><\/button><button class=\"option-btn\" id=\"btnNNon\"><div class=\"btn-icon\">\ud83d\udcdd<\/div><div class=\"btn-text\"><div class=\"btn-label\">Non, pas encore<\/div><div class=\"btn-sub\">Premi\u00e8re d\u00e9marche permis<\/div><\/div><\/button><\/div>'+renderNavButtons(true)+'<\/div><\/div>');\n  document.getElementById('btnNOui').addEventListener('click',function(){state.aNeph=true;goTo(step10_theorie);});\n  document.getElementById('btnNNon').addEventListener('click',function(){state.aNeph=false;goTo(step10_theorie);});\n  attachNavEvents();\n}\n\n\n\/\/ 10 \u2014 Questions th\u00e9orie\nfunction step10_theorie(){\n  \/\/ Pas pertinent pour perfectionnement et B78\n  if(isPerf()||isB78()){\n    state.codeSalle=false; state.codeNet=false; state.aLivre=true;\n    goTo(step11_identite); return;\n  }\n  \/\/ Si le code est d\u00e9j\u00e0 obtenu : pas de question th\u00e9orie\n  if(state.statutEleve==='code_obtenu'){\n    state.codeSalle=false; state.codeNet=false; state.aLivre=true;\n    goTo(step11_identite); return;\n  }\n  \/\/ Annulation ET tous les autres cas : afficher la question th\u00e9orie\n  setProgress(10,TOTAL_STEPS);\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 10<\/span><\/div><h3>Vos pr\u00e9f\u00e9rences pour la th\u00e9orie<\/h3><p>Les options ci-dessous sont pr\u00e9s\u00e9lectionn\u00e9es. D\u00e9cochez celles dont vous n\\'avez pas besoin.<\/p><\/div><div class=\"card-body\"><div class=\"checkbox-group\"><label class=\"checkbox-item checked\" id=\"chkSalle\"><input type=\"checkbox\" id=\"chkSalleVal\" checked\/><div class=\"check-box\"><span class=\"check-mark\">\u2713<\/span><\/div><div class=\"checkbox-text\"><strong>Code en salle<\/strong><br><span style=\"font-size:0.8rem;color:var(--stone);\">Acc\u00e8s illimit\u00e9 aux s\u00e9ances de code en salle dans votre agence pendant 6 mois<\/span><\/div><\/label><label class=\"checkbox-item checked\" id=\"chkNet\"><input type=\"checkbox\" id=\"chkNetVal\" checked\/><div class=\"check-box\"><span class=\"check-mark\">\u2713<\/span><\/div><div class=\"checkbox-text\"><strong>Code sur internet<\/strong><br><span style=\"font-size:0.8rem;color:var(--stone);\">Acc\u00e8s en ligne \u00e0 de nombreuses s\u00e9ries de questions pendant 4 mois, accessible 24h\/24<\/span><\/div><\/label><label class=\"checkbox-item checked\" id=\"chkLivre\"><input type=\"checkbox\" id=\"chkLivreVal\" checked\/><div class=\"check-box\"><span class=\"check-mark\">\u2713<\/span><\/div><div class=\"checkbox-text\"><strong>Livre du Code de la Route<\/strong><br><span style=\"font-size:0.8rem;color:var(--stone);\">D\u00e9cochez si vous poss\u00e9dez d\u00e9j\u00e0 un livre du code de la route<\/span><\/div><\/label><\/div><p style=\"font-size:0.78rem;color:var(--stone);margin-top:12px;\">Les tarifs de chaque option seront d\u00e9taill\u00e9s sur votre devis.<\/p><button class=\"btn-continue\" id=\"btnC10\">Continuer <span class=\"btn-arrow\">\u2192<\/span><\/button>'+renderNavButtons(true)+'<\/div><\/div>');\n  function chk2(lid,iid){var l=document.getElementById(lid),i=document.getElementById(iid);l.addEventListener('click',function(){i.checked=!i.checked;l.classList.toggle('checked',i.checked);});}\n  chk2('chkSalle','chkSalleVal'); chk2('chkNet','chkNetVal'); chk2('chkLivre','chkLivreVal');\n  document.getElementById('btnC10').addEventListener('click',function(){\n    state.codeSalle=document.getElementById('chkSalleVal').checked;\n    state.codeNet=document.getElementById('chkNetVal').checked;\n    \/\/ Livre coch\u00e9 = \"je veux le livre\" = je ne l'ai PAS encore \u2192 aLivre = false\n    \/\/ Livre d\u00e9coch\u00e9 = \"je n'en veux pas\/j'en ai d\u00e9j\u00e0\" \u2192 aLivre = true\n    state.aLivre=!document.getElementById('chkLivreVal').checked;\n    goTo(step11_identite);\n  });\n  attachNavEvents();\n}\n\n\/\/ 11 \u2014 Identit\u00e9 + RGPD\nfunction step11_identite(){\n  setProgress(11,TOTAL_STEPS);\n  var prefixes=[\n    {code:'+33',flag:'\ud83c\uddeb\ud83c\uddf7',name:'France'},\n    {code:'+32',flag:'\ud83c\udde7\ud83c\uddea',name:'Belgique'},\n    {code:'+41',flag:'\ud83c\udde8\ud83c\udded',name:'Suisse'},\n    {code:'+352',flag:'\ud83c\uddf1\ud83c\uddfa',name:'Luxembourg'},\n    {code:'+377',flag:'\ud83c\uddf2\ud83c\udde8',name:'Monaco'},\n    {code:'+44',flag:'\ud83c\uddec\ud83c\udde7',name:'Royaume-Uni'},\n    {code:'+49',flag:'\ud83c\udde9\ud83c\uddea',name:'Allemagne'},\n    {code:'+34',flag:'\ud83c\uddea\ud83c\uddf8',name:'Espagne'},\n    {code:'+39',flag:'\ud83c\uddee\ud83c\uddf9',name:'Italie'},\n    {code:'+351',flag:'\ud83c\uddf5\ud83c\uddf9',name:'Portugal'},\n  ];\n  var prefixOptions=prefixes.map(function(p){\n    return '<option value=\"'+p.code+'\"'+(p.code==='+33'?' selected':'')+'>'+p.flag+' '+p.code+'<\/option>';\n  }).join('');\n\n  render('<div class=\"card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>\u00c9tape 11<\/span><\/div><h3>Vos coordonn\u00e9es<\/h3><p>Pour personnaliser votre devis et pouvoir vous recontacter si n\u00e9cessaire.<\/p><\/div><div class=\"card-body\"><div class=\"identity-form\">'\n    +'<div class=\"form-section-title\">Identit\u00e9<\/div>'\n    +'<div><div class=\"civilite-label\">Civilit\u00e9 *<\/div>'\n    +'<div class=\"civilite-group\">'\n    +'<button class=\"civilite-btn\" id=\"civM\">\ud83d\udc68 M.<\/button>'\n    +'<button class=\"civilite-btn\" id=\"civMme\">\ud83d\udc69 Mme<\/button>'\n    +'<\/div>'\n    +'<div class=\"field-error-msg\" id=\"errCiv\">Veuillez s\u00e9lectionner votre civilit\u00e9.<\/div>'\n    +'<\/div>'\n    +'<div class=\"form-row\">'\n    +'<div class=\"form-group\">'\n    +'<label>Nom *<\/label>'\n    +'<input type=\"text\" id=\"inputNom\" placeholder=\"Votre nom de famille\" autocomplete=\"family-name\"\/>'\n    +'<div class=\"field-error-msg\" id=\"errNom\">Ce champ est obligatoire.<\/div>'\n    +'<\/div>'\n    +'<div class=\"form-group\">'\n    +'<label>Pr\u00e9nom *<\/label>'\n    +'<input type=\"text\" id=\"inputPrenom\" placeholder=\"Votre pr\u00e9nom\" autocomplete=\"given-name\"\/>'\n    +'<div class=\"field-error-msg\" id=\"errPrenom\">Ce champ est obligatoire.<\/div>'\n    +'<\/div>'\n    +'<\/div>'\n    +'<div class=\"form-section-title\" style=\"margin-top:8px;\">Contact<\/div>'\n    +'<div class=\"form-group\">'\n    +'<label>Adresse e-mail *<\/label>'\n    +'<input type=\"email\" id=\"inputEmail\" placeholder=\"exemple@mail.com\" autocomplete=\"email\"\/>'\n    +'<div class=\"field-error-msg\" id=\"errEmail\">Veuillez saisir une adresse e-mail valide.<\/div>'\n    +'<\/div>'\n    +'<div class=\"form-group\">'\n    +'<label>T\u00e9l\u00e9phone *<\/label>'\n    +'<div class=\"tel-group\">'\n    +'<div class=\"tel-prefix-wrap\"><select id=\"telPrefix\">'+prefixOptions+'<\/select><\/div>'\n    +'<input type=\"tel\" id=\"inputTel\" class=\"tel-input-main\" placeholder=\"06 00 00 00 00\" autocomplete=\"tel\"\/>'\n    +'<\/div>'\n    +'<div class=\"field-hint\">Format : 06 12 34 56 78 \u2014 Le num\u00e9ro sera pr\u00e9c\u00e9d\u00e9 de l\\'indicatif pays.<\/div>'\n    +'<div class=\"field-error-msg\" id=\"errTel\">Veuillez saisir un num\u00e9ro de t\u00e9l\u00e9phone valide (10 chiffres).<\/div>'\n    +'<\/div>'\n    +'<\/div>'\n    +'<div class=\"rgpd-notice\">'\n    +'<div class=\"rgpd-title\">\ud83d\udd12 Protection de vos donn\u00e9es personnelles<\/div>'\n    +'<p>Vos donn\u00e9es <strong>(civilit\u00e9, nom, pr\u00e9nom, e-mail, t\u00e9l\u00e9phone, crit\u00e8res du devis)<\/strong> ainsi que des donn\u00e9es techniques <strong>(adresse IP, pays de connexion, date et heure)<\/strong> sont collect\u00e9es et transmises \u00e0 l\\'auto-\u00e9cole pour le traitement de votre demande (art. 6.1.b RGPD). Conservation : <strong>3 ans<\/strong>. Droits : <a href=\"mailto:auto-ecole-vivaroise@orange.fr\">auto-ecole-vivaroise@orange.fr<\/a>.<\/p>'\n    +'<label class=\"rgpd-check-row\" id=\"rgpdCheckRow\">'\n    +'<input type=\"checkbox\" id=\"rgpdVal\" style=\"display:none\"\/>'\n    +'<div class=\"rgpd-chkbox\"><span class=\"rgpd-chk-mark\">\u2713<\/span><\/div>'\n    +'<div class=\"rgpd-chk-text\"><strong>J\\'accepte que mes donn\u00e9es soient utilis\u00e9es pour traiter ma demande de devis.<\/strong> Cette case est obligatoire pour obtenir votre devis.<\/div>'\n    +'<\/label>'\n    +'<div class=\"field-error-msg\" id=\"errRgpd\">Vous devez accepter pour continuer.<\/div>'\n    +'<\/div>'\n    +'<button class=\"btn-continue\" id=\"btnId\" disabled>Obtenir mon devis <span class=\"btn-arrow\">\u2192<\/span><\/button>'\n    +renderNavButtons(true)\n    +'<\/div><\/div>');\n\n  \/\/ Gestion civilit\u00e9\n  document.getElementById('civM').addEventListener('click',function(){\n    state.civilite='M.';\n    document.getElementById('civM').classList.add('selected');\n    document.getElementById('civMme').classList.remove('selected');\n    document.getElementById('errCiv').classList.remove('visible');\n    chkId();\n  });\n  document.getElementById('civMme').addEventListener('click',function(){\n    state.civilite='Mme';\n    document.getElementById('civMme').classList.add('selected');\n    document.getElementById('civM').classList.remove('selected');\n    document.getElementById('errCiv').classList.remove('visible');\n    chkId();\n  });\n\n  \/\/ NOM en MAJUSCULES\n  document.getElementById('inputNom').addEventListener('input',function(){\n    var p=this.selectionStart;\n    this.value=this.value.toUpperCase();\n    this.setSelectionRange(p,p);\n    this.classList.remove('field-error');\n    document.getElementById('errNom').classList.remove('visible');\n    chkId();\n  });\n\n  \/\/ Pr\u00e9nom capitalize\n  document.getElementById('inputPrenom').addEventListener('input',function(){\n    var p=this.selectionStart;\n    this.value=this.value.replace(\/\\b\\w\/g,function(l){return l.toUpperCase();});\n    this.setSelectionRange(p,p);\n    this.classList.remove('field-error');\n    document.getElementById('errPrenom').classList.remove('visible');\n    chkId();\n  });\n\n  \/\/ Email\n  document.getElementById('inputEmail').addEventListener('input',function(){\n    this.classList.remove('field-error');\n    document.getElementById('errEmail').classList.remove('visible');\n    chkId();\n  });\n\n  \/\/ T\u00e9l\u00e9phone : normalisation automatique\n  document.getElementById('inputTel').addEventListener('input',function(){\n    var raw = this.value;\n    \/\/ Normaliser les num\u00e9ros autofill : +330612345678, 0612345678, 33612345678, etc.\n    var digits = raw.replace(\/\\D\/g,'');\n\n    \/\/ D\u00e9tecter et retirer l'indicatif +33 si pr\u00e9sent\n    if(digits.startsWith('330') && digits.length === 12){\n      \/\/ Ex: 330612345678 \u2192 0612345678\n      digits = '0' + digits.slice(3);\n    } else if(digits.startsWith('33') && digits.length === 11 && !digits.startsWith('330')){\n      \/\/ Ex: 33612345678 \u2192 0612345678\n      digits = '0' + digits.slice(2);\n    } else if(digits.length === 9 && !digits.startsWith('0')){\n      \/\/ Ex: 612345678 \u2192 0612345678\n      digits = '0' + digits;\n    }\n\n    \/\/ Garder max 10 chiffres\n    digits = digits.substring(0,10);\n\n    \/\/ Formater XX XX XX XX XX\n    var groups = digits.match(\/.{1,2}\/g);\n    this.value = groups ? groups.join(' ') : '';\n\n    this.classList.remove('field-error');\n    document.getElementById('errTel').classList.remove('visible');\n    chkId();\n  });\n\n  \/\/ Paste sur t\u00e9l\u00e9phone\n  document.getElementById('inputTel').addEventListener('paste',function(e){\n    e.preventDefault();\n    var pasted = (e.clipboardData||window.clipboardData).getData('text');\n    this.value = pasted;\n    \/\/ D\u00e9clencher input pour normaliser\n    this.dispatchEvent(new Event('input'));\n  });\n\n  \/\/ RGPD checkbox\n  document.getElementById('rgpdCheckRow').addEventListener('click',function(){\n    var inp = document.getElementById('rgpdVal');\n    inp.checked = !inp.checked;\n    this.classList.toggle('checked', inp.checked);\n    document.getElementById('errRgpd').classList.remove('visible');\n    chkId();\n  });\n\n  \/\/ Validation\n  function chkId(){\n    var n=(document.getElementById('inputNom').value||'').trim();\n    var p=(document.getElementById('inputPrenom').value||'').trim();\n    var e=(document.getElementById('inputEmail').value||'').trim();\n    var t=(document.getElementById('inputTel').value||'').replace(\/\\D\/g,'');\n    var emailOk=\/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test(e);\n    var rgpd=document.getElementById('rgpdVal').checked;\n    document.getElementById('btnId').disabled=!(state.civilite&&n&&p&&emailOk&&t.length>=10&&rgpd);\n  }\n\n  \/\/ Clic bouton : afficher les erreurs sur les champs vides\n  document.getElementById('btnId').addEventListener('click',function(){\n    var n=(document.getElementById('inputNom').value||'').trim();\n    var p=(document.getElementById('inputPrenom').value||'').trim();\n    var e=(document.getElementById('inputEmail').value||'').trim();\n    var t=(document.getElementById('inputTel').value||'').replace(\/\\D\/g,'');\n    var emailOk=\/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test(e);\n    var rgpd=document.getElementById('rgpdVal').checked;\n    var ok=true;\n\n    if(!state.civilite){\n      document.getElementById('errCiv').classList.add('visible');\n      document.getElementById('civM').classList.add('civ-error');\n      document.getElementById('civMme').classList.add('civ-error');\n      ok=false;\n    }\n    if(!n){ document.getElementById('inputNom').classList.add('field-error'); document.getElementById('errNom').classList.add('visible'); ok=false; }\n    if(!p){ document.getElementById('inputPrenom').classList.add('field-error'); document.getElementById('errPrenom').classList.add('visible'); ok=false; }\n    if(!emailOk){ document.getElementById('inputEmail').classList.add('field-error'); document.getElementById('errEmail').classList.add('visible'); ok=false; }\n    if(t.length<10){ document.getElementById('inputTel').classList.add('field-error'); document.getElementById('errTel').classList.add('visible'); ok=false; }\n    if(!rgpd){ document.getElementById('rgpdCheckRow').classList.add('civ-error'); document.getElementById('errRgpd').classList.add('visible'); ok=false; }\n\n    if(!ok) return;\n\n    \/\/ Construire le num\u00e9ro complet avec indicatif\n    var prefix=document.getElementById('telPrefix').value;\n    var telLocal=(document.getElementById('inputTel').value||'').trim();\n    \/\/ Retirer le 0 initial si l'indicatif n&#39;est pas +33 ou si on veut format international\n    var telFormatted = prefix + ' ' + telLocal;\n\n    state.nom=document.getElementById('inputNom').value.trim();\n    state.prenom=document.getElementById('inputPrenom').value.trim();\n    state.email=e;\n    state.telephone=telFormatted;\n    refDevis=genRef();\n    showDevis();\n  });\n\n  attachNavEvents();\n}\n\n\n\/\/ \u2500\u2500 FINALE \u2014 Affichage + generation PDF \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nasync function showDevis(isViewer){\n  setProgress(12,TOTAL_STEPS);\n  var devisData=buildDevisLines();\n  var total=devisData.total;\n  var agenceLabel=getAgenceLabel();\n  var formationLabel=getFormationLabel(state.formation);\n  var docs=getDocsList();\n\n  render('<div class=\"success-card\"><div class=\"card-header\"><div class=\"step-indicator\"><div class=\"step-dot\"><\/div><span>Devis pret !<\/span><\/div><h3>'+state.civilite+' '+state.prenom+' '+state.nom+', vous etes \u00e9ligible !<\/h3><p>Votre devis personnalis\u00e9 est en cours de generation...<\/p><\/div><div class=\"success-body\"><div class=\"ref-box\"><div class=\"ref-label\">Votre r\u00e9f\u00e9rence de devis<\/div><div class=\"ref-number\">'+refDevis+'<\/div><div class=\"ref-sub\">Conservez ce code. Communiquez-le lors de votre venue \u00e0 l\\'agence ou si vous nous contactez.'+(state.aNeph?'<br>Pensez a apporter votre AIPC qui contient votre numero NEPH.':'')+'<\/div><\/div><div class=\"recap-box\"><h4>Recapitulatif<\/h4><div class=\"recap-row\"><span class=\"recap-label\">Identite :<\/span><span>'+state.civilite+' '+state.prenom+' '+state.nom+'<\/span><\/div><div class=\"recap-row\"><span class=\"recap-label\">Agence :<\/span><span>'+agenceLabel+'<\/span><\/div><div class=\"recap-row\"><span class=\"recap-label\">Formation :<\/span><span>'+formationLabel+' - boite '+(isManuelle()?'manuelle':'automatique')+'<\/span><\/div><div class=\"recap-row\"><span class=\"recap-label\">Total estime :<\/span><span style=\"font-weight:700;color:var(--navy);\">'+total.toFixed(2).replace('.',',')+' EUR TTC<\/span><\/div><\/div><div class=\"sending-state\" id=\"sendingState\"><div class=\"spinner\"><\/div><div class=\"sending-text\">Generation du PDF et envoi en cours...<\/div><\/div><button class=\"btn-download-pdf\" id=\"btnPDF\" style=\"opacity:0.4;cursor:not-allowed;\" disabled>\u2b07\ufe0f T\u00e9l\u00e9charger mon devis personnalis\u00e9 (PDF)<\/button><div class=\"note-box\" style=\"margin-top:16px;\"><strong>Rappel :<\/strong> Pour finaliser votre inscription, vous devrez vous presenter <strong>en personne \u00e0 l\\'agence<\/strong>.<br><br><strong>Ref. : <span style=\"font-family:\\'Courier New\\',monospace;font-size:1.1em;letter-spacing:0.15em;\">'+refDevis+'<\/span><\/strong> \u2014 a conserver et a communiquer lors de votre venue.<\/div><button class=\"btn-restart-red\" id=\"btnNew\" style=\"margin-top:20px;\">Nouvelle demande<\/button><\/div><\/div>');\n  document.getElementById('btnNew').addEventListener('click',restart);\n\n  \/\/ Activer bouton PDF immediatement (avant meme la fin du chargement)\n  var btnPdf=document.getElementById('btnPDF');\n  if(btnPdf){\n    btnPdf.disabled=false;\n    btnPdf.style.opacity='1';\n    btnPdf.style.cursor='pointer';\n    btnPdf.addEventListener('click',function(){\n      this.disabled=true;\n      this.textContent='Generation en cours...';\n      var self=this;\n      generatePDF().then(function(){\n        self.disabled=false;\n        self.innerHTML='\u2b07\ufe0f Ret\u00e9l\u00e9charger mon devis (PDF)';\n      }).catch(function(e){\n        self.disabled=false;\n        self.innerHTML='\u2b07\ufe0f Ret\u00e9l\u00e9charger mon devis (PDF)';\n        console.error(e);\n      });\n    });\n  }\n\n  \/\/ Mode viewer : afficher le devis recharg\u00e9 depuis Firebase (pas de re-sauvegarde ni re-envoi)\n  if(isViewer){\n    var sv=document.getElementById('sendingState');\n    if(sv) sv.innerHTML='<p style=\"font-size:0.82rem;color:#27ae60;text-align:center;padding-bottom:10px;\">\ud83d\udcc2 Devis charg\u00e9 depuis notre base de donn\u00e9es.<\/p>';\n    var btnPdfV=document.getElementById('btnPDF');\n    if(btnPdfV){ btnPdfV.disabled=false; btnPdfV.style.opacity='1'; btnPdfV.style.cursor='pointer'; btnPdfV.addEventListener('click',function(){this.disabled=true;this.textContent='G\u00e9n\u00e9ration...';var self=this;generatePDF().then(function(){self.disabled=false;self.innerHTML='\u2b07\ufe0f Ret\u00e9l\u00e9charger (PDF)';}).catch(function(e){self.disabled=false;self.innerHTML='\u2b07\ufe0f Ret\u00e9l\u00e9charger (PDF)';});});}\n    return;\n  }\n\n  \/\/ Mode normal : sauvegarder, g\u00e9n\u00e9rer PDF, envoyer notifications\n  Promise.allSettled([\n    saveDevis(),\n    generatePDF().then(function(pdfDataUrl){ return sendAll(pdfDataUrl); })\n  ]).then(function(){\n    var s=document.getElementById('sendingState');\n    if(s) s.innerHTML='<p style=\"font-size:0.82rem;color:#27ae60;text-align:center;padding-bottom:10px;\">\u2705 Votre demande a bien \u00e9t\u00e9 transmise \u00e0 notre \u00e9quipe.<\/p>';\n  }).catch(function(e){\n    console.error('Erreur envoi:', e);\n    var s=document.getElementById('sendingState');\n    if(s) s.innerHTML='<p style=\"font-size:0.82rem;color:var(--stone);text-align:center;padding-bottom:10px;\">\u2139\ufe0f Votre devis a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9. Une erreur est survenue lors de la transmission.<\/p>';\n  });\n}\n\n\/\/ \u2500\u2500 INIT \u2014 compatible WordPress (DOMContentLoaded + setTimeout) \u2500\u2500\nfunction devisInit(){\n  var container = document.getElementById('stepContainer');\n  if(!container){\n    setTimeout(devisInit, 100);\n    return;\n  }\n  \/\/ \u2500\u2500 D\u00e9tecter si on est en mode viewer (?ref=XXXX dans l'URL) \u2500\u2500\n  try{\n    var urlParams = new URLSearchParams(window.location.search);\n    var refParam  = urlParams.get('ref') || urlParams.get('REF');\n    if(refParam && refParam.trim()){\n      loadDevisViewer(refParam.trim());\n      return;\n    }\n  } catch(e){}\n  \/\/ \u2500\u2500 Mode formulaire normal \u2500\u2500\n  try {\n  goTo(step1_age);\n} catch(e) {\n  console.error('Erreur chargement:', e);\n  var sc=document.getElementById('stepContainer');\n  var pw=document.getElementById('progressWrapper');\n  if(pw) pw.style.display='none';\n  if(sc) sc.innerHTML='<div style=\"background:#fff;border-radius:14px;padding:32px;text-align:center;\"><div style=\"font-size:2rem;\">\u26a0\ufe0f<\/div><h3 style=\"color:#20315b;\">Une erreur est survenue<\/h3><p style=\"color:#777569;\">Veuillez recharger la page ou contacter l&#39;auto-\u00e9cole.<\/p><br><a href=\"tel:0475525475\" style=\"padding:12px 22px;background:#20315b;color:#cfca77;border-radius:9px;text-decoration:none;\">\ud83d\udcde 04.75.52.54.75<\/a><\/div>';\n}\n}\nif(document.readyState === 'loading'){\n  document.addEventListener('DOMContentLoaded', devisInit);\n} else {\n  \/\/ DOM d\u00e9j\u00e0 pr\u00eat (script charg\u00e9 en defer ou apr\u00e8s DOMContentLoaded)\n  devisInit();\n}\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Demande de Devis \u2014 Auto-\u00c9cole Vivaroise Obtenez votre devispersonnalis\u00e9 R\u00e9pondez a quelques questions rapides pour verifier votre \u00e9ligibilit\u00e9 et t\u00e9l\u00e9charger [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"disabled","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-484","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"rttpg_featured_image_url":null,"rttpg_author":{"display_name":"admin","author_link":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/author\/busy-bardeen_6hs7yr65\/"},"rttpg_comment":0,"rttpg_category":null,"rttpg_excerpt":"Demande de Devis \u2014 Auto-\u00c9cole Vivaroise Obtenez votre devispersonnalis\u00e9 R\u00e9pondez a quelques questions rapides pour verifier votre \u00e9ligibilit\u00e9 et t\u00e9l\u00e9charger [&hellip;]","_links":{"self":[{"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/pages\/484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/comments?post=484"}],"version-history":[{"count":2,"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/pages\/484\/revisions"}],"predecessor-version":[{"id":572,"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/pages\/484\/revisions\/572"}],"wp:attachment":[{"href":"https:\/\/busy-bardeen.51-210-15-39.plesk.page\/index.php\/wp-json\/wp\/v2\/media?parent=484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}