{"id":2548,"date":"2026-05-08T11:05:50","date_gmt":"2026-05-08T09:05:50","guid":{"rendered":"https:\/\/labienveillance.fr\/?page_id=2548"},"modified":"2026-05-08T11:33:41","modified_gmt":"2026-05-08T09:33:41","slug":"elementor-2548","status":"publish","type":"page","link":"https:\/\/labienveillance.fr\/?page_id=2548","title":{"rendered":"Devis estimatif monte escalier 2"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2548\" class=\"elementor elementor-2548\">\n\t\t\t\t<div class=\"elementor-element elementor-element-077cb43 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent\" data-id=\"077cb43\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6feb42e elementor-widget elementor-widget-html\" data-id=\"6feb42e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div id=\"jlmLiteAppRoot\"><\/div>\r\n\r\n<script>\r\n(function () {\r\n  var root = document.getElementById(\"jlmLiteAppRoot\");\r\n  if (!root) return;\r\n\r\n  var ADMIN_CODE = \"Loli424720\";\r\n\r\n  function clone(o) {\r\n    return JSON.parse(JSON.stringify(o));\r\n  }\r\n\r\n  function escapeHtml(s) {\r\n    return String(s == null ? \"\" : s)\r\n      .replace(\/&\/g, \"&amp;\")\r\n      .replace(\/<\/g, \"&lt;\")\r\n      .replace(\/>\/g, \"&gt;\")\r\n      .replace(\/\"\/g, \"&quot;\");\r\n  }\r\n\r\n  function deepMerge(target, source) {\r\n    Object.keys(source || {}).forEach(function (key) {\r\n      if (source[key] && typeof source[key] === \"object\" && !Array.isArray(source[key])) {\r\n        if (!target[key] || typeof target[key] !== \"object\") target[key] = {};\r\n        deepMerge(target[key], source[key]);\r\n      } else {\r\n        target[key] = source[key];\r\n      }\r\n    });\r\n    return target;\r\n  }\r\n\r\n  var DEF = {\r\n    companyLine: \"La Bienveillance \u2014 Devis estimatif\",\r\n    contactUrl: \"#contact\",\r\n    contactLabel: \"CONTACTEZ-NOUS\",\r\n    comments: {\r\n      home: \"\",\r\n      type: \"\",\r\n      brand: \"\",\r\n      depart: \"\",\r\n      obstacle: \"\",\r\n      rail: \"\",\r\n      longueur: \"\",\r\n      arrivee: \"\",\r\n      pivot: \"\",\r\n      recap: \"\",\r\n      garanties: \"\",\r\n      aides: \"\",\r\n      price: \"\"\r\n    },\r\n    prices: {\r\n      includedMeters: 5,\r\n      up: {\r\n        droit: { base: 3500, mo: 650, railSup: 350, railRelevable: 680, extPlus: 300, pivotElec: 0 },\r\n        courbe: { base: 7900, mo: 900, railSup: 300, courbe: 280, railRelevable: 750, pivotElec: 0 }\r\n      },\r\n      acorn: {\r\n        droit: { base: 3200, mo: 650, railSup: 350, railRelevable: 600, extPlus: 300, pivotElec: 600 },\r\n        courbe: { base: 5700, mo: 750, railSup: 350, courbe: 450, railRelevable: 600, pivotElec: 600 }\r\n      }\r\n    },\r\n    images: {\r\n      logo: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/logomakr-0c1pju.png\" },\r\n      type_droit: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/escalier-droit.jpg\" },\r\n      type_90: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/escalier-90.jpg\" },\r\n      type_180: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/escalier-180c2b0.jpg\" },\r\n      type_ext: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/serenite-monte-escalier-monte-escaliers7-390x380-1.jpeg\" },\r\n      marque_up: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/camscanner-23-02-2026-15.20_1.jpg\" },\r\n      marque_acorn: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/0abcd33b-7191-4d4f-81fe-5097d415b3cc_image1.png\" },\r\n      depart_std: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-04-at-14.44.17.jpeg\" },\r\n      depart_rall: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-04-at-14.45.07.jpeg\" },\r\n      depart_p90: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-04-at-15.20.00.jpeg\" },\r\n      depart_p180: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2024-11-17-a-15.19.52_789038bb.jpg\" },\r\n      obstacle_ex1: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2025-07-23-at-16.55.59-1-768x1024-1.jpeg\" },\r\n      obstacle_ex2: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-02-02-at-15.22.57.jpeg\" },\r\n      obstacle_yes: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/IMG_4902.jpeg\" },\r\n      obstacle_no: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2024-11-17-a-15.19.52_38b0d7f8.jpg\" },\r\n      rail_1: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-02-02-at-15.22.57.jpeg\" },\r\n      rail_2: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/IMG_4902.jpeg\" },\r\n      rail_yes: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-04-at-14.54.44.jpeg\" },\r\n      rail_no: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2024-11-17-a-15.19.52_38b0d7f8.jpg\" },\r\n      arr_nez: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/WhatsApp-Image-2026-03-04-at-14.51.48.jpeg\" },\r\n      arr_prol: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-01-at-08.10.01.jpeg\" },\r\n      arr_90: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-01-at-08.08.50.jpeg\" },\r\n      arr_180: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2024-11-17-a-15.19.53_562a3c5e-1.jpg\" },\r\n      pivot_manuel: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-04-at-15.21.03.jpeg\" },\r\n      pivot_elec: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-04-at-14.51.48.jpeg\" },\r\n      garanties_photo: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-01-at-08.11.43.jpeg\" },\r\n      aides_photo: { url: \"https:\/\/laseptiemecom.wpcomstaging.com\/wp-content\/uploads\/2026\/03\/whatsapp-image-2026-03-01-at-08.16.15.jpeg\" }\r\n    }\r\n  };\r\n\r\n  var cfg = clone(DEF);\r\n  var adminUnlocked = false;\r\n  var app = null;\r\n\r\n  var state = {\r\n    step: 0,\r\n    msg: \"\",\r\n    showAlert: false,\r\n    type: \"\",\r\n    brand: \"\",\r\n    depart: \"\",\r\n    obstacle: \"\",\r\n    railChoice: \"\",\r\n    nbMarches: 17,\r\n    longueur: 5.1,\r\n    arrivee: \"\",\r\n    pivotMode: \"\"\r\n  };\r\n\r\n  function scrollTop() {\r\n    root.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\r\n  }\r\n\r\n  function getLongueurEstimee() {\r\n    return Number((Number(state.nbMarches || 0) * 0.30).toFixed(2));\r\n  }\r\n\r\n  function syncLongueur() {\r\n    state.nbMarches = Math.max(1, Math.round(Number(state.nbMarches || 0)));\r\n    state.longueur = getLongueurEstimee();\r\n  }\r\n\r\n  async function wpLoadConfig() {\r\n    try {\r\n      var r = await fetch(\"\/wp-admin\/admin-ajax.php?action=jlm_get_config\");\r\n      var j = await r.json();\r\n      if (j && j.success && j.data && typeof j.data === \"object\") {\r\n        cfg = deepMerge(clone(DEF), j.data);\r\n      } else {\r\n        cfg = clone(DEF);\r\n      }\r\n    } catch (e) {\r\n      cfg = clone(DEF);\r\n    }\r\n  }\r\n\r\n  async function wpSaveConfig() {\r\n    try {\r\n      var r = await fetch(\"\/wp-admin\/admin-ajax.php?action=jlm_save_config\", {\r\n        method: \"POST\",\r\n        credentials: \"same-origin\",\r\n        headers: { \"Content-Type\": \"application\/json\" },\r\n        body: JSON.stringify(cfg)\r\n      });\r\n      var j = await r.json();\r\n      if (j && j.success) return true;\r\n      alert(\"Erreur : \" + (j && j.data ? j.data : \"sauvegarde impossible\"));\r\n      return false;\r\n    } catch (e) {\r\n      alert(\"Erreur serveur\");\r\n      return false;\r\n    }\r\n  }\r\n\r\n  function getImg(key) {\r\n    return cfg.images[key] ? cfg.images[key].url : \"\";\r\n  }\r\n\r\n  function setImageUrl(key, val) {\r\n    if (!cfg.images[key]) cfg.images[key] = { url: \"\" };\r\n    cfg.images[key].url = String(val || \"\").trim();\r\n  }\r\n\r\n  function isStraightFamily() {\r\n    return state.type === \"droit\" || state.type === \"exterieur\";\r\n  }\r\n\r\n  function isCurvedFamily() {\r\n    return state.type === \"courbe90\" || state.type === \"courbe180\";\r\n  }\r\n\r\n  function isUP() { return state.brand === \"UP\"; }\r\n  function isACORN() { return state.brand === \"ACORN\"; }\r\n  function hasRailRelevable() { return state.railChoice === \"oui\"; }\r\n\r\n  function normalizeState() {\r\n    syncLongueur();\r\n    if (isStraightFamily()) {\r\n      state.depart = \"standard\";\r\n      state.arrivee = \"nez\";\r\n      state.obstacle = \"\";\r\n      if (isUP()) state.pivotMode = \"electrique\";\r\n      else if (!state.pivotMode) state.pivotMode = \"manuel\";\r\n    } else {\r\n      if (isUP() && state.arrivee === \"nez\") state.pivotMode = \"electrique\";\r\n      else if (state.arrivee !== \"nez\") state.pivotMode = \"\";\r\n    }\r\n  }\r\n\r\n  function typeCurveCount() {\r\n    if (state.type === \"courbe90\") return 1;\r\n    if (state.type === \"courbe180\") return 2;\r\n    return 0;\r\n  }\r\n\r\n  function departCurveCount() {\r\n    if (state.depart === \"p90\") return 1;\r\n    if (state.depart === \"p180\") return 2;\r\n    return 0;\r\n  }\r\n\r\n  function arriveeCurveCount() {\r\n    if (state.arrivee === \"p90\") return 1;\r\n    if (state.arrivee === \"p180\") return 2;\r\n    return 0;\r\n  }\r\n\r\n  function totalCurveCount() {\r\n    return typeCurveCount() + departCurveCount() + arriveeCurveCount();\r\n  }\r\n\r\n  function extraMeters() {\r\n    syncLongueur();\r\n    var longueur = Number(state.longueur || 0);\r\n    if (state.brand === \"ACORN\" && (state.type === \"courbe90\" || state.type === \"courbe180\")) {\r\n      return longueur;\r\n    }\r\n    var inc = Number(cfg.prices.includedMeters || 5);\r\n    return Math.max(0, Math.ceil(longueur - inc));\r\n  }\r\n\r\n  function needsPivotChoice() {\r\n    return state.arrivee === \"nez\" && isACORN();\r\n  }\r\n\r\n  function steps() {\r\n    normalizeState();\r\n    var s = [\"home\", \"type\", \"brand\", \"depart\"];\r\n    if (isCurvedFamily() && state.depart === \"standard\") {\r\n      s.push(\"obstacle\");\r\n      if (state.obstacle === \"oui\") s.push(\"rail\");\r\n    }\r\n    if (isStraightFamily()) s.push(\"rail\");\r\n    if (isCurvedFamily() && state.depart !== \"standard\") s.push(\"rail\");\r\n    s.push(\"longueur\", \"arrivee\");\r\n    if (needsPivotChoice()) s.push(\"pivot\");\r\n    s.push(\"recap\", \"garanties\", \"aides\", \"price\");\r\n    return s;\r\n  }\r\n\r\n  function pricingProfile() {\r\n    if (isUP()) return isCurvedFamily() ? cfg.prices.up.courbe : cfg.prices.up.droit;\r\n    return isCurvedFamily() ? cfg.prices.acorn.courbe : cfg.prices.acorn.droit;\r\n  }\r\n\r\n  function calcPriceBreakdown() {\r\n    normalizeState();\r\n    var p = pricingProfile();\r\n    var extraM = extraMeters();\r\n    var curves = totalCurveCount();\r\n    var base = Number(p.base || 0);\r\n    var mo = Number(p.mo || 0);\r\n    var railSup = extraM * Number(p.railSup || 0);\r\n    var curveCost = isCurvedFamily() ? curves * Number(p.courbe || 0) : 0;\r\n    var railRelevable = hasRailRelevable() ? Number(p.railRelevable || 0) : 0;\r\n    var pivotElec = state.pivotMode === \"electrique\" ? Number(p.pivotElec || 0) : 0;\r\n    var extPlus = state.type === \"exterieur\" ? Number(p.extPlus || 0) : 0;\r\n    return {\r\n      total: base + mo + railSup + curveCost + railRelevable + pivotElec + extPlus,\r\n      curves: curves,\r\n      extraMeters: extraM\r\n    };\r\n  }\r\n\r\n  function money(n) {\r\n    return Number(n || 0).toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \" \") + \" \u20ac\";\r\n  }\r\n\r\n  function showComment(key) {\r\n    var t = (cfg.comments[key] || \"\").trim();\r\n    if (!t) return \"\";\r\n    return (\r\n      '<div class=\"commentWrap\">' +\r\n        '<button type=\"button\" class=\"commentToggle\" data-comment-open=\"' + escapeHtml(key) + '\">' +\r\n          '<span class=\"commentToggleIcon\">\u2726<\/span> Conseils' +\r\n        '<\/button>' +\r\n      '<\/div>'\r\n    );\r\n  }\r\n\r\n  function renderCommentModal() {\r\n    return (\r\n      '<div class=\"commentModalOverlay\" id=\"commentModalOverlay\">' +\r\n        '<div class=\"commentModal\" role=\"dialog\" aria-modal=\"true\">' +\r\n          '<div class=\"commentModalGlow\"><\/div>' +\r\n          '<div class=\"commentModalHead\">' +\r\n            '<div>' +\r\n              '<div class=\"commentModalEyebrow\">La Bienveillance<\/div>' +\r\n              '<div class=\"commentModalTitle\">Conseils<\/div>' +\r\n            '<\/div>' +\r\n            '<button type=\"button\" class=\"commentModalX\" data-comment-close=\"1\">\u00d7<\/button>' +\r\n          '<\/div>' +\r\n          '<div class=\"commentModalBody\" id=\"commentModalBody\"><\/div>' +\r\n          '<div class=\"commentModalActions\">' +\r\n            '<button type=\"button\" class=\"btn pri\" data-comment-close=\"1\">Fermer<\/button>' +\r\n          '<\/div>' +\r\n        '<\/div>' +\r\n      '<\/div>'\r\n    );\r\n  }\r\n\r\n  function openCommentModal(key) {\r\n    var txt = (cfg.comments[key] || \"\").trim();\r\n    if (!txt) return;\r\n    var overlay = document.getElementById(\"commentModalOverlay\");\r\n    var body = document.getElementById(\"commentModalBody\");\r\n    if (!overlay || !body) return;\r\n    body.innerHTML = escapeHtml(txt).replace(\/\\n\/g, \"<br>\");\r\n    overlay.classList.add(\"show\");\r\n    document.body.classList.add(\"jlmNoScroll\");\r\n  }\r\n\r\n  function closeCommentModal() {\r\n    var overlay = document.getElementById(\"commentModalOverlay\");\r\n    var body = document.getElementById(\"commentModalBody\");\r\n    if (overlay) overlay.classList.remove(\"show\");\r\n    if (body) body.innerHTML = \"\";\r\n    document.body.classList.remove(\"jlmNoScroll\");\r\n  }\r\n\r\n  function choice(key, label, img, selected) {\r\n    return (\r\n      '<div class=\"choice ' + (selected ? \"sel\" : \"\") + '\" data-choice=\"' + escapeHtml(key) + '\">' +\r\n        '<div class=\"media\"><img decoding=\"async\" src=\"' + escapeHtml(img) + '\" alt=\"' + escapeHtml(label) + '\"><\/div>' +\r\n        '<div class=\"label\">' + escapeHtml(label) + \"<\/div>\" +\r\n      \"<\/div>\"\r\n    );\r\n  }\r\n\r\n  function validate(page) {\r\n    if (page === \"type\" && !state.type) return \"MERCI DE CHOISIR UN TYPE D'ESCALIER AVANT DE CONTINUER\";\r\n    if (page === \"brand\" && !state.brand) return \"MERCI DE CHOISIR UNE MARQUE AVANT DE CONTINUER\";\r\n    if (page === \"depart\" && !state.depart) return \"MERCI DE CHOISIR UN D\u00c9PART AVANT DE CONTINUER\";\r\n    if (page === \"obstacle\" && !state.obstacle) return \"MERCI D'INDIQUER OUI OU NON POUR L'OBSTACLE\";\r\n    if (page === \"rail\" && !state.railChoice) return \"MERCI D'INDIQUER OUI OU NON POUR LE RAIL RELEVABLE\";\r\n    if (page === \"longueur\" && !state.nbMarches) return \"MERCI D'INDIQUER LE NOMBRE DE MARCHES\";\r\n    if (page === \"arrivee\" && !state.arrivee) return \"MERCI DE CHOISIR UNE ARRIV\u00c9E AVANT DE CONTINUER\";\r\n    if (page === \"pivot\" && !state.pivotMode) return \"MERCI DE CHOISIR LE TYPE DE SI\u00c8GE PIVOTANT\";\r\n    return \"\";\r\n  }\r\n\r\n  function recapMaterial() {\r\n    normalizeState();\r\n    var b = calcPriceBreakdown();\r\n    var typeMap = { droit: \"Escalier droit\", courbe90: \"Escalier courbe 90\u00b0\", courbe180: \"Escalier courbe 180\u00b0\", exterieur: \"Escalier ext\u00e9rieur\" };\r\n    var departMap = { standard: \"D\u00e9part standard\", rallonge: \"D\u00e9part rallong\u00e9\", p90: \"D\u00e9part parking 90\u00b0\", p180: \"D\u00e9part parking 180\u00b0\" };\r\n    var arriveeMap = { nez: \"Arriv\u00e9e nez de marche - si\u00e8ge pivotant\", prolonge: \"Arriv\u00e9e prolong\u00e9e\", p90: \"Arriv\u00e9e parking 90\u00b0\", p180: \"Arriv\u00e9e parking 180\u00b0\" };\r\n    var out = [];\r\n    if (state.type) out.push(typeMap[state.type] || state.type);\r\n    if (state.brand) out.push(\"Marque : \" + (state.brand === \"UP\" ? \"UP Stairlift\" : \"ACORN\"));\r\n    if (state.depart) out.push(departMap[state.depart] || state.depart);\r\n    if (isCurvedFamily() && state.depart === \"standard\") out.push(\"Obstacle au d\u00e9part : \" + (state.obstacle === \"oui\" ? \"Oui\" : \"Non\"));\r\n    out.push(\"Rail relevable : \" + (state.railChoice === \"oui\" ? \"Oui\" : \"Non\"));\r\n    out.push(\"Nombre de marches : \" + Number(state.nbMarches || 0));\r\n    out.push(\"Longueur estim\u00e9e : \" + Number(state.longueur || 0).toFixed(2) + \" m\");\r\n    if (state.arrivee) out.push(arriveeMap[state.arrivee] || state.arrivee);\r\n    if (state.arrivee === \"nez\") {\r\n      if (isUP()) out.push(\"Pivot \u00e9lectrique : inclus\");\r\n      else out.push(\"Pivot : \" + (state.pivotMode === \"electrique\" ? \"\u00c9lectrique\" : \"Manuel\"));\r\n    }\r\n    if (isCurvedFamily()) out.push(\"Nombre total de courbes \u00e0 90\u00b0 : \" + b.curves);\r\n    out.push(\"M\u00e8tres factur\u00e9s : \" + b.extraMeters);\r\n    return out;\r\n  }\r\n\r\n  function renderImageField(key, label) {\r\n    return (\r\n      '<div class=\"hr\"><\/div>' +\r\n      '<label class=\"lbl\">' + escapeHtml(label) + ' \u2014 URL<\/label>' +\r\n      '<input class=\"inp\" id=\"img_' + escapeHtml(key) + '\" value=\"' + escapeHtml((cfg.images[key] || {}).url || \"\") + '\">'\r\n    );\r\n  }\r\n\r\n  function renderPage() {\r\n    normalizeState();\r\n    var id = steps()[state.step];\r\n    var breakdown = calcPriceBreakdown();\r\n\r\n    if (id === \"home\") return '<div class=\"card\"><div class=\"h1\">BONJOUR<\/div><div class=\"txt\">Bienvenue.<br><br>En quelques \u00e9tapes simples, obtenez une estimation claire et rassurante de votre monte-escalier.<br><br>Visite technique gratuite et absolument sans engagement.<\/div>' + showComment(\"home\") + '<\/div>';\r\n\r\n    if (id === \"type\") return '<div class=\"card\"><div class=\"h2\">TYPE D\\'ESCALIER<\/div><div class=\"txt\">Cliquez sur une image pour choisir.<\/div><div class=\"grid\">' +\r\n      choice(\"droit\", \"Droit\", getImg(\"type_droit\"), state.type === \"droit\") +\r\n      choice(\"courbe90\", \"Courbe 90\u00b0\", getImg(\"type_90\"), state.type === \"courbe90\") +\r\n      choice(\"courbe180\", \"Courbe 180\u00b0\", getImg(\"type_180\"), state.type === \"courbe180\") +\r\n      choice(\"exterieur\", \"Ext\u00e9rieur\", getImg(\"type_ext\"), state.type === \"exterieur\") +\r\n      '<\/div>' + showComment(\"type\") + '<\/div>';\r\n\r\n    if (id === \"brand\") return '<div class=\"card\"><div class=\"h2\">MARQUE<\/div><div class=\"txt\">Cliquez sur une image pour choisir.<\/div><div class=\"grid\">' +\r\n      choice(\"UP\", \"UP Stairlift\", getImg(\"marque_up\"), state.brand === \"UP\") +\r\n      choice(\"ACORN\", \"ACORN\", getImg(\"marque_acorn\"), state.brand === \"ACORN\") +\r\n      '<\/div>' + showComment(\"brand\") + '<\/div>';\r\n\r\n    if (id === \"depart\") {\r\n      if (isStraightFamily()) return '<div class=\"card\"><div class=\"h2\">D\u00c9PART<\/div><div class=\"txt\">Pour cette configuration, le d\u00e9part est uniquement standard.<\/div><div class=\"grid\">' +\r\n        choice(\"standard\", \"Standard\", getImg(\"depart_std\"), true) +\r\n        '<\/div>' + showComment(\"depart\") + '<\/div>';\r\n      return '<div class=\"card\"><div class=\"h2\">D\u00c9PART<\/div><div class=\"txt\">Cliquez sur une image pour choisir.<\/div><div class=\"grid\">' +\r\n        choice(\"standard\", \"Standard\", getImg(\"depart_std\"), state.depart === \"standard\") +\r\n        choice(\"rallonge\", \"Rallong\u00e9\", getImg(\"depart_rall\"), state.depart === \"rallonge\") +\r\n        choice(\"p90\", \"Parking 90\u00b0\", getImg(\"depart_p90\"), state.depart === \"p90\") +\r\n        choice(\"p180\", \"Parking 180\u00b0\", getImg(\"depart_p180\"), state.depart === \"p180\") +\r\n        '<\/div>' + showComment(\"depart\") + '<\/div>';\r\n    }\r\n\r\n    if (id === \"obstacle\") return '<div class=\"card\"><div class=\"h2\">OBSTACLE AU D\u00c9PART<\/div><div class=\"txt\">Exemples ci-dessous, puis cliquez sur OUI ou NON.<\/div><div class=\"grid\">' +\r\n      '<div class=\"fixedCard\"><div class=\"media\"><img decoding=\"async\" src=\"' + escapeHtml(getImg(\"obstacle_ex1\")) + '\" alt=\"\"><\/div><div class=\"label\">Exemple<\/div><\/div>' +\r\n      '<div class=\"fixedCard\"><div class=\"media\"><img decoding=\"async\" src=\"' + escapeHtml(getImg(\"obstacle_ex2\")) + '\" alt=\"\"><\/div><div class=\"label\">Exemple<\/div><\/div>' +\r\n      '<\/div><div class=\"grid\">' +\r\n      choice(\"oui\", \"OUI\", getImg(\"obstacle_yes\"), state.obstacle === \"oui\") +\r\n      choice(\"non\", \"NON\", getImg(\"obstacle_no\"), state.obstacle === \"non\") +\r\n      '<\/div>' + showComment(\"obstacle\") + '<\/div>';\r\n\r\n    if (id === \"rail\") return '<div class=\"card\"><div class=\"h2\">RAIL RELEVABLE<\/div><div class=\"txt\">Voici deux exemples d\\'obstacle. Puis cliquez sur OUI ou NON.<\/div><div class=\"grid\">' +\r\n      '<div class=\"fixedCard\"><div class=\"media\"><img decoding=\"async\" src=\"' + escapeHtml(getImg(\"rail_1\")) + '\" alt=\"\"><\/div><div class=\"label\">Exemple obstacle<\/div><\/div>' +\r\n      '<div class=\"fixedCard\"><div class=\"media\"><img decoding=\"async\" src=\"' + escapeHtml(getImg(\"rail_2\")) + '\" alt=\"\"><\/div><div class=\"label\">Exemple obstacle<\/div><\/div>' +\r\n      '<\/div><div class=\"grid\">' +\r\n      choice(\"rail_oui\", \"OUI\", getImg(\"rail_yes\"), state.railChoice === \"oui\") +\r\n      choice(\"rail_non\", \"NON\", getImg(\"rail_no\"), state.railChoice === \"non\") +\r\n      '<\/div>' + showComment(\"rail\") + '<\/div>';\r\n\r\n    if (id === \"longueur\") return '<div class=\"card\">' +\r\n      '<div class=\"h2\">NOMBRE DE MARCHES<\/div>' +\r\n      '<div class=\"measure\">' +\r\n        '<div class=\"bigVal\">' + Number(state.nbMarches || 0) + ' marches<\/div>' +\r\n        '<div class=\"measureSub\">' + Number(state.longueur || 0).toFixed(2) + ' m<\/div>' +\r\n        '<div class=\"measureRow\">' +\r\n          '<button class=\"arr\" data-act=\"minusMarches\">\u2212<\/button>' +\r\n          '<input class=\"range\" type=\"range\" min=\"1\" max=\"30\" step=\"1\" value=\"' + Number(state.nbMarches || 1) + '\" data-act=\"rangeMarches\">' +\r\n          '<button class=\"arr\" data-act=\"plusMarches\">+<\/button>' +\r\n        '<\/div>' +\r\n      '<\/div>' +\r\n      showComment(\"longueur\") + '<\/div>';\r\n\r\n    if (id === \"arrivee\") {\r\n      if (isStraightFamily()) return '<div class=\"card\"><div class=\"h2\">ARRIV\u00c9E<\/div><div class=\"txt\">Pour cette configuration, l\\'arriv\u00e9e est uniquement nez de marche.<\/div><div class=\"grid\">' +\r\n        choice(\"nez\", \"Nez de marche - si\u00e8ge pivotant\", getImg(\"arr_nez\"), true) +\r\n        '<\/div>' + showComment(\"arrivee\") + '<\/div>';\r\n      return '<div class=\"card\"><div class=\"h2\">ARRIV\u00c9E<\/div><div class=\"txt\">Cliquez sur une image pour choisir.<\/div><div class=\"grid\">' +\r\n        choice(\"nez\", \"Nez de marche - si\u00e8ge pivotant\", getImg(\"arr_nez\"), state.arrivee === \"nez\") +\r\n        choice(\"prolonge\", \"Prolong\u00e9e\", getImg(\"arr_prol\"), state.arrivee === \"prolonge\") +\r\n        choice(\"p90\", \"Parking 90\u00b0\", getImg(\"arr_90\"), state.arrivee === \"p90\") +\r\n        choice(\"p180\", \"Parking 180\u00b0\", getImg(\"arr_180\"), state.arrivee === \"p180\") +\r\n        '<\/div>' + showComment(\"arrivee\") + '<\/div>';\r\n    }\r\n\r\n    if (id === \"pivot\") return '<div class=\"card\"><div class=\"h2\">SI\u00c8GE PIVOTANT<\/div><div class=\"txt\">Choisissez manuel ou \u00e9lectrique.<\/div><div class=\"grid\">' +\r\n      choice(\"manuel\", \"Manuel\", getImg(\"pivot_manuel\"), state.pivotMode === \"manuel\") +\r\n      choice(\"electrique\", \"\u00c9lectrique\", getImg(\"pivot_elec\"), state.pivotMode === \"electrique\") +\r\n      '<\/div>' + showComment(\"pivot\") + '<\/div>';\r\n\r\n    if (id === \"recap\") return '<div class=\"card\"><div class=\"h2\">R\u00c9CAPITULATIF UNIQUEMENT MAT\u00c9RIEL<\/div><div class=\"recap\"><ul>' +\r\n      recapMaterial().map(function (x) { return \"<li>\" + escapeHtml(x) + \"<\/li>\"; }).join(\"\") +\r\n      '<\/ul><\/div>' + showComment(\"recap\") + '<\/div>';\r\n\r\n    if (id === \"garanties\") return '<div class=\"card\"><div class=\"h2\">GARANTIES<\/div><div class=\"guaranteePhoto\"><img decoding=\"async\" src=\"' + escapeHtml(getImg(\"garanties_photo\")) + '\" alt=\"Garanties\"><\/div><div class=\"guaranteeBig\">GARANTIE 4 ANS PI\u00c8CES, MAIN D\\'\u0152UVRE ET D\u00c9PLACEMENT<br><br>2 VISITES TECHNIQUES COMPRISES DANS LE PRIX<\/div>' + showComment(\"garanties\") + '<\/div>';\r\n\r\n    if (id === \"aides\") return '<div class=\"card\"><div class=\"h2\">LES AIDES ET AUTRES POSSIBILIT\u00c9S<\/div><div class=\"guaranteePhoto\"><img decoding=\"async\" src=\"' + escapeHtml(getImg(\"aides_photo\")) + '\" alt=\"Aides\"><\/div><div class=\"txt\">Certaines aides peuvent \u00eatre \u00e9tudi\u00e9es selon votre situation.<br><br>Des solutions de financement peuvent \u00e9galement \u00eatre envisag\u00e9es.<br><br>Un conseiller pourra vous orienter lors de la visite technique gratuite et sans engagement.<\/div>' + showComment(\"aides\") + '<\/div>';\r\n\r\n    if (id === \"price\") return '<div class=\"card\"><div class=\"h2\">VOTRE PRIX FINAL TTC POS\u00c9<\/div><div class=\"price\"><div class=\"big\">' + money(breakdown.total) + '<\/div><div style=\"font-size:13px;color:rgba(255,255,255,.75);margin-top:6px\">Estimation TTC pos\u00e9e<\/div><\/div><div class=\"txt\" style=\"margin-top:14px\">Ce prix est une estimation. Il sera confirm\u00e9 lors de la visite technique gratuite, sans engagement.<\/div>' + showComment(\"price\") + '<div class=\"nav\" style=\"margin-top:14px\"><a class=\"btn pri\" href=\"' + escapeHtml(cfg.contactUrl) + '\">' + escapeHtml(cfg.contactLabel) + '<\/a><\/div><div style=\"margin-top:22px;text-align:center;font-size:19px;font-weight:700;color:#F97316;border-top:1px solid rgba(255,255,255,.10);padding-top:18px\">Pour les informations sur un monte escalier reconditionn\u00e9 ou en location, contactez nous<\/div><\/div>';\r\n\r\n    return '<div class=\"card\"><div class=\"txt\">Page inconnue.<\/div><\/div>';\r\n  }\r\n\r\n  function renderBO() {\r\n    if (!adminUnlocked) return \"\";\r\n    return (\r\n      '<div class=\"boOverlay\" id=\"boOverlay\">' +\r\n        '<div class=\"bo\">' +\r\n          '<div class=\"boHead\"><strong>Back Office complet WordPress<\/strong><button class=\"btn\" data-act=\"closeBo\">Fermer<\/button><\/div>' +\r\n          '<div class=\"boBody\">' +\r\n            '<fieldset class=\"fs\"><legend>Global<\/legend>' +\r\n              '<label class=\"lbl\">Ligne d\\'en-t\u00eate<\/label><input class=\"inp\" id=\"boCompanyLine\" value=\"' + escapeHtml(cfg.companyLine) + '\">' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">URL bouton contact<\/label><input class=\"inp\" id=\"boContactUrl\" value=\"' + escapeHtml(cfg.contactUrl) + '\">' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Texte bouton contact<\/label><input class=\"inp\" id=\"boContactLabel\" value=\"' + escapeHtml(cfg.contactLabel) + '\">' +\r\n              '<div class=\"hr\"><\/div>' +\r\n              '<label class=\"lbl\">Logo \u2014 URL<\/label><input class=\"inp\" id=\"boLogo\" value=\"' + escapeHtml((cfg.images.logo || {}).url || \"\") + '\">' +\r\n            '<\/fieldset>' +\r\n            '<fieldset class=\"fs\"><legend>Prix<\/legend>' +\r\n              '<div class=\"row2\"><div><label class=\"lbl\">M\u00e8tres inclus standard<\/label><input class=\"num\" id=\"boIncludedMeters\" type=\"number\" value=\"' + cfg.prices.includedMeters + '\"><\/div><div><\/div><\/div>' +\r\n              '<div class=\"hr\"><\/div><div class=\"lbl\" style=\"font-weight:700;\">UP droit \/ ext\u00e9rieur<\/div>' +\r\n              '<div class=\"row2\"><div><label class=\"lbl\">Base<\/label><input class=\"num\" id=\"boUpDroitBase\" type=\"number\" value=\"' + cfg.prices.up.droit.base + '\"><\/div><div><label class=\"lbl\">Main d\\'\u0153uvre<\/label><input class=\"num\" id=\"boUpDroitMo\" type=\"number\" value=\"' + cfg.prices.up.droit.mo + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Rail sup \/ m<\/label><input class=\"num\" id=\"boUpDroitRailSup\" type=\"number\" value=\"' + cfg.prices.up.droit.railSup + '\"><\/div><div><label class=\"lbl\">Rail relevable<\/label><input class=\"num\" id=\"boUpDroitRailRel\" type=\"number\" value=\"' + cfg.prices.up.droit.railRelevable + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Plus-value ext\u00e9rieur<\/label><input class=\"num\" id=\"boUpDroitExtPlus\" type=\"number\" value=\"' + cfg.prices.up.droit.extPlus + '\"><\/div><div><label class=\"lbl\">Pivot \u00e9lectrique<\/label><input class=\"num\" id=\"boUpDroitPivot\" type=\"number\" value=\"' + cfg.prices.up.droit.pivotElec + '\"><\/div><\/div>' +\r\n              '<div class=\"hr\"><\/div><div class=\"lbl\" style=\"font-weight:700;\">UP courbe<\/div>' +\r\n              '<div class=\"row2\"><div><label class=\"lbl\">Base<\/label><input class=\"num\" id=\"boUpCourbeBase\" type=\"number\" value=\"' + cfg.prices.up.courbe.base + '\"><\/div><div><label class=\"lbl\">Main d\\'\u0153uvre<\/label><input class=\"num\" id=\"boUpCourbeMo\" type=\"number\" value=\"' + cfg.prices.up.courbe.mo + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Rail sup \/ m<\/label><input class=\"num\" id=\"boUpCourbeRailSup\" type=\"number\" value=\"' + cfg.prices.up.courbe.railSup + '\"><\/div><div><label class=\"lbl\">Valeur par courbe<\/label><input class=\"num\" id=\"boUpCourbeCourbe\" type=\"number\" value=\"' + cfg.prices.up.courbe.courbe + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Rail relevable<\/label><input class=\"num\" id=\"boUpCourbeRailRel\" type=\"number\" value=\"' + cfg.prices.up.courbe.railRelevable + '\"><\/div><div><label class=\"lbl\">Pivot \u00e9lectrique<\/label><input class=\"num\" id=\"boUpCourbePivot\" type=\"number\" value=\"' + cfg.prices.up.courbe.pivotElec + '\"><\/div><\/div>' +\r\n              '<div class=\"hr\"><\/div><div class=\"lbl\" style=\"font-weight:700;\">ACORN droit \/ ext\u00e9rieur<\/div>' +\r\n              '<div class=\"row2\"><div><label class=\"lbl\">Base<\/label><input class=\"num\" id=\"boAcornDroitBase\" type=\"number\" value=\"' + cfg.prices.acorn.droit.base + '\"><\/div><div><label class=\"lbl\">Main d\\'\u0153uvre<\/label><input class=\"num\" id=\"boAcornDroitMo\" type=\"number\" value=\"' + cfg.prices.acorn.droit.mo + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Rail sup \/ m<\/label><input class=\"num\" id=\"boAcornDroitRailSup\" type=\"number\" value=\"' + cfg.prices.acorn.droit.railSup + '\"><\/div><div><label class=\"lbl\">Rail relevable<\/label><input class=\"num\" id=\"boAcornDroitRailRel\" type=\"number\" value=\"' + cfg.prices.acorn.droit.railRelevable + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Plus-value ext\u00e9rieur<\/label><input class=\"num\" id=\"boAcornDroitExtPlus\" type=\"number\" value=\"' + cfg.prices.acorn.droit.extPlus + '\"><\/div><div><label class=\"lbl\">Pivot \u00e9lectrique<\/label><input class=\"num\" id=\"boAcornDroitPivot\" type=\"number\" value=\"' + cfg.prices.acorn.droit.pivotElec + '\"><\/div><\/div>' +\r\n              '<div class=\"hr\"><\/div><div class=\"lbl\" style=\"font-weight:700;\">ACORN courbe<\/div>' +\r\n              '<div class=\"row2\"><div><label class=\"lbl\">Base<\/label><input class=\"num\" id=\"boAcornCourbeBase\" type=\"number\" value=\"' + cfg.prices.acorn.courbe.base + '\"><\/div><div><label class=\"lbl\">Main d\\'\u0153uvre<\/label><input class=\"num\" id=\"boAcornCourbeMo\" type=\"number\" value=\"' + cfg.prices.acorn.courbe.mo + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Rail sup \/ m<\/label><input class=\"num\" id=\"boAcornCourbeRailSup\" type=\"number\" value=\"' + cfg.prices.acorn.courbe.railSup + '\"><\/div><div><label class=\"lbl\">Valeur par courbe<\/label><input class=\"num\" id=\"boAcornCourbeCourbe\" type=\"number\" value=\"' + cfg.prices.acorn.courbe.courbe + '\"><\/div><\/div>' +\r\n              '<div class=\"row2\" style=\"margin-top:10px\"><div><label class=\"lbl\">Rail relevable<\/label><input class=\"num\" id=\"boAcornCourbeRailRel\" type=\"number\" value=\"' + cfg.prices.acorn.courbe.railRelevable + '\"><\/div><div><label class=\"lbl\">Pivot \u00e9lectrique<\/label><input class=\"num\" id=\"boAcornCourbePivot\" type=\"number\" value=\"' + cfg.prices.acorn.courbe.pivotElec + '\"><\/div><\/div>' +\r\n            '<\/fieldset>' +\r\n            '<fieldset class=\"fs\"><legend>Commentaires<\/legend>' +\r\n              '<label class=\"lbl\">Accueil<\/label><textarea class=\"ta\" id=\"boHome\">' + escapeHtml(cfg.comments.home) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Type<\/label><textarea class=\"ta\" id=\"boType\">' + escapeHtml(cfg.comments.type) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Marque<\/label><textarea class=\"ta\" id=\"boBrand\">' + escapeHtml(cfg.comments.brand) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">D\u00e9part<\/label><textarea class=\"ta\" id=\"boDepart\">' + escapeHtml(cfg.comments.depart) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Obstacle<\/label><textarea class=\"ta\" id=\"boObstacle\">' + escapeHtml(cfg.comments.obstacle) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Rail<\/label><textarea class=\"ta\" id=\"boRail\">' + escapeHtml(cfg.comments.rail) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Longueur<\/label><textarea class=\"ta\" id=\"boLongueur\">' + escapeHtml(cfg.comments.longueur) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Arriv\u00e9e<\/label><textarea class=\"ta\" id=\"boArrivee\">' + escapeHtml(cfg.comments.arrivee) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Pivot<\/label><textarea class=\"ta\" id=\"boPivot\">' + escapeHtml(cfg.comments.pivot) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">R\u00e9capitulatif<\/label><textarea class=\"ta\" id=\"boRecap\">' + escapeHtml(cfg.comments.recap) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Garanties<\/label><textarea class=\"ta\" id=\"boGaranties\">' + escapeHtml(cfg.comments.garanties) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Aides<\/label><textarea class=\"ta\" id=\"boAides\">' + escapeHtml(cfg.comments.aides) + '<\/textarea>' +\r\n              '<label class=\"lbl\" style=\"margin-top:10px\">Prix final<\/label><textarea class=\"ta\" id=\"boPrice\">' + escapeHtml(cfg.comments.price) + '<\/textarea>' +\r\n            '<\/fieldset>' +\r\n            '<fieldset class=\"fs\"><legend>URLs images<\/legend>' +\r\n              renderImageField(\"type_droit\", \"Type droit\") +\r\n              renderImageField(\"type_90\", \"Type courbe 90\u00b0\") +\r\n              renderImageField(\"type_180\", \"Type courbe 180\u00b0\") +\r\n              renderImageField(\"type_ext\", \"Type ext\u00e9rieur\") +\r\n              renderImageField(\"marque_up\", \"Marque UP\") +\r\n              renderImageField(\"marque_acorn\", \"Marque ACORN\") +\r\n              renderImageField(\"depart_std\", \"D\u00e9part standard\") +\r\n              renderImageField(\"depart_rall\", \"D\u00e9part rallong\u00e9\") +\r\n              renderImageField(\"depart_p90\", \"D\u00e9part parking 90\u00b0\") +\r\n              renderImageField(\"depart_p180\", \"D\u00e9part parking 180\u00b0\") +\r\n              renderImageField(\"obstacle_ex1\", \"Obstacle exemple 1\") +\r\n              renderImageField(\"obstacle_ex2\", \"Obstacle exemple 2\") +\r\n              renderImageField(\"obstacle_yes\", \"Obstacle oui\") +\r\n              renderImageField(\"obstacle_no\", \"Obstacle non\") +\r\n              renderImageField(\"rail_1\", \"Rail exemple 1\") +\r\n              renderImageField(\"rail_2\", \"Rail exemple 2\") +\r\n              renderImageField(\"rail_yes\", \"Rail oui cliquable\") +\r\n              renderImageField(\"rail_no\", \"Rail non cliquable\") +\r\n              renderImageField(\"arr_nez\", \"Arriv\u00e9e nez\") +\r\n              renderImageField(\"arr_prol\", \"Arriv\u00e9e prolong\u00e9e\") +\r\n              renderImageField(\"arr_90\", \"Arriv\u00e9e 90\u00b0\") +\r\n              renderImageField(\"arr_180\", \"Arriv\u00e9e 180\u00b0\") +\r\n              renderImageField(\"pivot_manuel\", \"Pivot manuel\") +\r\n              renderImageField(\"pivot_elec\", \"Pivot \u00e9lectrique\") +\r\n              renderImageField(\"garanties_photo\", \"Garanties image\") +\r\n              renderImageField(\"aides_photo\", \"Aides image\") +\r\n            '<\/fieldset>' +\r\n          '<\/div>' +\r\n          '<div class=\"boActions\">' +\r\n            '<button class=\"btn\" data-act=\"closeBo\">Fermer<\/button>' +\r\n            '<button class=\"btn pri\" data-act=\"saveBo\">Enregistrer<\/button>' +\r\n          '<\/div>' +\r\n        '<\/div>' +\r\n      '<\/div>'\r\n    );\r\n  }\r\n\r\n  function saveBOToCfg() {\r\n    cfg.companyLine = app.querySelector(\"#boCompanyLine\").value;\r\n    cfg.contactUrl = app.querySelector(\"#boContactUrl\").value;\r\n    cfg.contactLabel = app.querySelector(\"#boContactLabel\").value;\r\n    cfg.prices.includedMeters = Number(app.querySelector(\"#boIncludedMeters\").value || 5);\r\n    cfg.prices.up.droit.base = Number(app.querySelector(\"#boUpDroitBase\").value || 0);\r\n    cfg.prices.up.droit.mo = Number(app.querySelector(\"#boUpDroitMo\").value || 0);\r\n    cfg.prices.up.droit.railSup = Number(app.querySelector(\"#boUpDroitRailSup\").value || 0);\r\n    cfg.prices.up.droit.railRelevable = Number(app.querySelector(\"#boUpDroitRailRel\").value || 0);\r\n    cfg.prices.up.droit.extPlus = Number(app.querySelector(\"#boUpDroitExtPlus\").value || 0);\r\n    cfg.prices.up.droit.pivotElec = Number(app.querySelector(\"#boUpDroitPivot\").value || 0);\r\n    cfg.prices.up.courbe.base = Number(app.querySelector(\"#boUpCourbeBase\").value || 0);\r\n    cfg.prices.up.courbe.mo = Number(app.querySelector(\"#boUpCourbeMo\").value || 0);\r\n    cfg.prices.up.courbe.railSup = Number(app.querySelector(\"#boUpCourbeRailSup\").value || 0);\r\n    cfg.prices.up.courbe.courbe = Number(app.querySelector(\"#boUpCourbeCourbe\").value || 0);\r\n    cfg.prices.up.courbe.railRelevable = Number(app.querySelector(\"#boUpCourbeRailRel\").value || 0);\r\n    cfg.prices.up.courbe.pivotElec = Number(app.querySelector(\"#boUpCourbePivot\").value || 0);\r\n    cfg.prices.acorn.droit.base = Number(app.querySelector(\"#boAcornDroitBase\").value || 0);\r\n    cfg.prices.acorn.droit.mo = Number(app.querySelector(\"#boAcornDroitMo\").value || 0);\r\n    cfg.prices.acorn.droit.railSup = Number(app.querySelector(\"#boAcornDroitRailSup\").value || 0);\r\n    cfg.prices.acorn.droit.railRelevable = Number(app.querySelector(\"#boAcornDroitRailRel\").value || 0);\r\n    cfg.prices.acorn.droit.extPlus = Number(app.querySelector(\"#boAcornDroitExtPlus\").value || 0);\r\n    cfg.prices.acorn.droit.pivotElec = Number(app.querySelector(\"#boAcornDroitPivot\").value || 0);\r\n    cfg.prices.acorn.courbe.base = Number(app.querySelector(\"#boAcornCourbeBase\").value || 0);\r\n    cfg.prices.acorn.courbe.mo = Number(app.querySelector(\"#boAcornCourbeMo\").value || 0);\r\n    cfg.prices.acorn.courbe.railSup = Number(app.querySelector(\"#boAcornCourbeRailSup\").value || 0);\r\n    cfg.prices.acorn.courbe.courbe = Number(app.querySelector(\"#boAcornCourbeCourbe\").value || 0);\r\n    cfg.prices.acorn.courbe.railRelevable = Number(app.querySelector(\"#boAcornCourbeRailRel\").value || 0);\r\n    cfg.prices.acorn.courbe.pivotElec = Number(app.querySelector(\"#boAcornCourbePivot\").value || 0);\r\n    cfg.comments.home = app.querySelector(\"#boHome\").value;\r\n    cfg.comments.type = app.querySelector(\"#boType\").value;\r\n    cfg.comments.brand = app.querySelector(\"#boBrand\").value;\r\n    cfg.comments.depart = app.querySelector(\"#boDepart\").value;\r\n    cfg.comments.obstacle = app.querySelector(\"#boObstacle\").value;\r\n    cfg.comments.rail = app.querySelector(\"#boRail\").value;\r\n    cfg.comments.longueur = app.querySelector(\"#boLongueur\").value;\r\n    cfg.comments.arrivee = app.querySelector(\"#boArrivee\").value;\r\n    cfg.comments.pivot = app.querySelector(\"#boPivot\").value;\r\n    cfg.comments.recap = app.querySelector(\"#boRecap\").value;\r\n    cfg.comments.garanties = app.querySelector(\"#boGaranties\").value;\r\n    cfg.comments.aides = app.querySelector(\"#boAides\").value;\r\n    cfg.comments.price = app.querySelector(\"#boPrice\").value;\r\n    setImageUrl(\"logo\", app.querySelector(\"#boLogo\").value);\r\n    [\"type_droit\",\"type_90\",\"type_180\",\"type_ext\",\"marque_up\",\"marque_acorn\",\r\n     \"depart_std\",\"depart_rall\",\"depart_p90\",\"depart_p180\",\r\n     \"obstacle_ex1\",\"obstacle_ex2\",\"obstacle_yes\",\"obstacle_no\",\r\n     \"rail_1\",\"rail_2\",\"rail_yes\",\"rail_no\",\r\n     \"arr_nez\",\"arr_prol\",\"arr_90\",\"arr_180\",\r\n     \"pivot_manuel\",\"pivot_elec\",\"garanties_photo\",\"aides_photo\"].forEach(function(k) {\r\n      setImageUrl(k, app.querySelector(\"#img_\" + k).value);\r\n    });\r\n  }\r\n\r\n  function render() {\r\n    normalizeState();\r\n    var ids = steps();\r\n    if (state.step > ids.length - 1) state.step = ids.length - 1;\r\n    var current = ids[state.step];\r\n    var progress = Math.round(((state.step + 1) \/ ids.length) * 100);\r\n\r\n    app.innerHTML =\r\n      '<div class=\"top\">' +\r\n        '<div class=\"brand\">' +\r\n          '<div class=\"logo\"><img decoding=\"async\" src=\"' + escapeHtml(getImg(\"logo\")) + '\" alt=\"Logo\"><\/div>' +\r\n          '<div><div class=\"small\">' + escapeHtml(cfg.companyLine) + '<\/div><\/div>' +\r\n        '<\/div>' +\r\n        '<div class=\"progress\"><div class=\"pill\">' + (state.step + 1) + ' \/ ' + ids.length + '<\/div><div class=\"bar\"><i style=\"width:' + progress + '%\"><\/i><\/div><\/div>' +\r\n      '<\/div>' +\r\n      '<div class=\"alertBand ' + (state.showAlert ? 'show' : '') + '\">' + escapeHtml(state.msg || 'MERCI DE FAIRE UN CHOIX AVANT DE CONTINUER') + '<\/div>' +\r\n      renderPage() +\r\n      '<div class=\"nav\">' +\r\n        '<button class=\"btn reset\" data-act=\"reset\">R\u00c9INITIALISER<\/button>' +\r\n        '<button class=\"btn\" data-act=\"prev\" ' + (state.step === 0 ? 'disabled' : '') + '>RETOUR<\/button>' +\r\n        '<button class=\"btn pri\" data-act=\"next\">' + (current === 'price' ? 'TERMINER' : 'SUIVANT') + '<\/button>' +\r\n      '<\/div>' +\r\n      renderBO() +\r\n      renderCommentModal();\r\n\r\n    \/\/ Choix avec scroll\r\n    app.querySelectorAll(\".choice[data-choice]\").forEach(function (el) {\r\n      el.addEventListener(\"click\", function () {\r\n        var k = el.getAttribute(\"data-choice\");\r\n        if (current === \"type\") { state.type = k; state.depart = \"\"; state.obstacle = \"\"; state.railChoice = \"\"; state.arrivee = \"\"; state.pivotMode = \"\"; }\r\n        if (current === \"brand\") { state.brand = k; state.depart = \"\"; state.obstacle = \"\"; state.railChoice = \"\"; state.arrivee = \"\"; state.pivotMode = \"\"; }\r\n        if (current === \"depart\") { state.depart = k; state.obstacle = \"\"; state.railChoice = \"\"; }\r\n        if (current === \"obstacle\") { state.obstacle = k; state.railChoice = \"\"; }\r\n        if (current === \"rail\") { state.railChoice = (k === \"rail_oui\") ? \"oui\" : \"non\"; }\r\n        if (current === \"arrivee\") { state.arrivee = k; state.pivotMode = \"\"; }\r\n        if (current === \"pivot\") { state.pivotMode = k; }\r\n        state.msg = \"\"; state.showAlert = false;\r\n        render();\r\n        scrollTop();\r\n      });\r\n    });\r\n\r\n    \/\/ Reset avec scroll\r\n    app.querySelectorAll('[data-act=\"reset\"]').forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () {\r\n        if (window.confirm(\"Voulez-vous vraiment r\u00e9initialiser le configurateur ?\")) {\r\n          state = { step: 0, msg: \"\", showAlert: false, type: \"\", brand: \"\", depart: \"\", obstacle: \"\", railChoice: \"\", nbMarches: 17, longueur: 5.1, arrivee: \"\", pivotMode: \"\" };\r\n          closeCommentModal();\r\n          render();\r\n          scrollTop();\r\n        }\r\n      });\r\n    });\r\n\r\n    \/\/ Suivant avec scroll\r\n    app.querySelectorAll('[data-act=\"next\"]').forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () {\r\n        var err = validate(steps()[state.step]);\r\n        if (err) { state.msg = err; state.showAlert = true; render(); return; }\r\n        if (state.step < steps().length - 1) {\r\n          closeCommentModal();\r\n          state.step++;\r\n          state.msg = \"\"; state.showAlert = false;\r\n          render();\r\n          scrollTop();\r\n        }\r\n      });\r\n    });\r\n\r\n    \/\/ Retour avec scroll\r\n    app.querySelectorAll('[data-act=\"prev\"]').forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () {\r\n        if (state.step > 0) {\r\n          closeCommentModal();\r\n          state.step--;\r\n          state.msg = \"\"; state.showAlert = false;\r\n          render();\r\n          scrollTop();\r\n        }\r\n      });\r\n    });\r\n\r\n    app.querySelectorAll('[data-act=\"minusMarches\"]').forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () { state.nbMarches = Math.max(1, Number(state.nbMarches || 1) - 1); syncLongueur(); render(); });\r\n    });\r\n    app.querySelectorAll('[data-act=\"plusMarches\"]').forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () { state.nbMarches = Math.min(30, Number(state.nbMarches || 1) + 1); syncLongueur(); render(); });\r\n    });\r\n    app.querySelectorAll('[data-act=\"rangeMarches\"]').forEach(function (r) {\r\n      r.addEventListener(\"input\", function () { state.nbMarches = Number(r.value); syncLongueur(); render(); });\r\n    });\r\n\r\n    app.querySelectorAll(\"[data-comment-open]\").forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () { openCommentModal(btn.getAttribute(\"data-comment-open\")); });\r\n    });\r\n    app.querySelectorAll(\"[data-comment-close]\").forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () { closeCommentModal(); });\r\n    });\r\n    var modalOverlay = document.getElementById(\"commentModalOverlay\");\r\n    if (modalOverlay) modalOverlay.addEventListener(\"click\", function (e) { if (e.target === modalOverlay) closeCommentModal(); });\r\n\r\n    app.querySelectorAll('[data-act=\"closeBo\"]').forEach(function (btn) {\r\n      btn.addEventListener(\"click\", function () { var bo = document.getElementById(\"boOverlay\"); if (bo) bo.classList.remove(\"show\"); });\r\n    });\r\n    app.querySelectorAll('[data-act=\"saveBo\"]').forEach(function (btn) {\r\n      btn.addEventListener(\"click\", async function () {\r\n        saveBOToCfg();\r\n        var ok = await wpSaveConfig();\r\n        if (!ok) return;\r\n        var bo = document.getElementById(\"boOverlay\");\r\n        if (bo) bo.classList.remove(\"show\");\r\n        render();\r\n        alert(\"Configuration enregistr\u00e9e dans WordPress.\");\r\n      });\r\n    });\r\n  }\r\n\r\n  var styleNode = document.createElement(\"style\");\r\n  styleNode.textContent = `\r\n:root{--bg:#071327;--bg2:#050C19;--bd:rgba(255,255,255,.14);--txt:#fff;--muted:rgba(255,255,255,.78);--orange:#F97316;--orange2:#EA580C;--danger1:#DC2626;--danger2:#F97316}\r\nbody.jlmNoScroll{overflow:hidden}\r\n#jlmLiteAppRoot *{box-sizing:border-box}\r\n#jlmLiteAppRoot{font-family:Arial,Helvetica,sans-serif;color:var(--txt);background:radial-gradient(1200px 560px at 15% 0%,rgba(249,115,22,.18),transparent 60%),radial-gradient(1000px 700px at 85% 10%,rgba(59,130,246,.12),transparent 60%),linear-gradient(180deg,var(--bg),var(--bg2) 58%,#040A14);border-radius:20px;padding:14px 10px 18px;overflow:hidden}\r\n#jlmLiteAppRoot .app{width:100%;max-width:1120px;margin:0 auto}\r\n#jlmLiteAppRoot .top{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:0 2px 2px;margin-bottom:4px}\r\n#jlmLiteAppRoot .brand{display:flex;align-items:center;gap:8px;min-width:0}\r\n#jlmLiteAppRoot .logo{width:138px;height:138px;border-radius:18px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.05);display:flex;align-items:center;justify-content:center;overflow:hidden;flex:0 0 auto}\r\n#jlmLiteAppRoot .logo img{width:100%;height:100%;object-fit:contain;display:block}\r\n#jlmLiteAppRoot .small{font-size:9px;color:var(--muted);line-height:1.05;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\r\n#jlmLiteAppRoot .progress{display:flex;align-items:center;gap:5px;min-width:120px;flex:0 1 220px}\r\n#jlmLiteAppRoot .pill{font-size:9px;padding:3px 6px;border-radius:999px;border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.04)}\r\n#jlmLiteAppRoot .bar{height:5px;flex:1;border-radius:999px;border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.04);overflow:hidden}\r\n#jlmLiteAppRoot .bar i{display:block;height:100%;width:0%;background:linear-gradient(90deg,var(--orange),#FDBA74)}\r\n#jlmLiteAppRoot .alertBand{display:none;width:100%;margin:0 0 10px;padding:14px 18px;border-radius:18px;background:linear-gradient(90deg,var(--danger1),var(--danger2));color:#fff;font-size:18px;font-weight:800;text-align:center;box-shadow:0 18px 40px rgba(0,0,0,.24)}\r\n#jlmLiteAppRoot .alertBand.show{display:block}\r\n#jlmLiteAppRoot .card{background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,.035));border:1px solid var(--bd);border-radius:24px;padding:18px 16px;box-shadow:0 20px 50px rgba(0,0,0,.28)}\r\n#jlmLiteAppRoot .h1,#jlmLiteAppRoot .h2{text-align:center;margin:2px 0 10px}\r\n#jlmLiteAppRoot .h1{font-size:34px}\r\n#jlmLiteAppRoot .h2{font-size:25px}\r\n#jlmLiteAppRoot .txt{max-width:980px;margin:0 auto;text-align:center;line-height:1.7;font-size:16px;color:rgba(255,255,255,.94)}\r\n#jlmLiteAppRoot .grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:14px}\r\n#jlmLiteAppRoot .choice,#jlmLiteAppRoot .fixedCard{border-radius:22px;border:1px solid rgba(255,255,255,.12);background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,.035));overflow:hidden;box-shadow:0 10px 24px rgba(0,0,0,.14)}\r\n#jlmLiteAppRoot .choice{cursor:pointer;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease;position:relative}\r\n#jlmLiteAppRoot .choice:hover{transform:translateY(-4px);border-color:rgba(249,115,22,.55);box-shadow:0 16px 34px rgba(0,0,0,.22)}\r\n#jlmLiteAppRoot .choice.sel{border-color:rgba(249,115,22,.92);box-shadow:0 0 0 2px rgba(249,115,22,.22) inset,0 16px 34px rgba(0,0,0,.22)}\r\n#jlmLiteAppRoot .choice.sel:after{content:\"\u2713\";position:absolute;top:10px;right:12px;width:34px;height:34px;border-radius:999px;display:flex;align-items:center;justify-content:center;background:linear-gradient(180deg,var(--orange),var(--orange2));color:#fff;font-weight:900;font-size:18px}\r\n#jlmLiteAppRoot .media{aspect-ratio:1\/1;background:rgba(255,255,255,.03);display:flex;align-items:center;justify-content:center}\r\n#jlmLiteAppRoot .media img{width:100%;height:100%;object-fit:contain;display:block;background:rgba(255,255,255,.03)}\r\n#jlmLiteAppRoot .label{padding:12px 12px 14px;text-align:center;font-size:15px;font-weight:700}\r\n#jlmLiteAppRoot .measure{max-width:980px;margin:10px auto 0;text-align:center}\r\n#jlmLiteAppRoot .measureRow{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;margin-top:12px}\r\n#jlmLiteAppRoot .measureSub{font-size:28px;font-weight:800;margin-top:10px;color:rgba(255,255,255,.94)}\r\n#jlmLiteAppRoot .arr{width:58px;height:46px;border-radius:16px;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.06);color:#fff;font-size:22px;cursor:pointer}\r\n#jlmLiteAppRoot .range{width:min(680px,92vw);accent-color:var(--orange)}\r\n#jlmLiteAppRoot .bigVal{font-size:32px;font-weight:800;margin-top:6px}\r\n#jlmLiteAppRoot .recap{max-width:980px;margin:16px auto 0;border-radius:20px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.16);padding:16px;text-align:center}\r\n#jlmLiteAppRoot .recap ul{display:inline-block;text-align:left;line-height:1.7;margin:0;padding-left:18px}\r\n#jlmLiteAppRoot .guaranteePhoto{max-width:980px;margin:10px auto 0;border-radius:20px;border:1px solid rgba(255,255,255,.14);overflow:hidden;background:rgba(255,255,255,.05);display:flex;align-items:center;justify-content:center}\r\n#jlmLiteAppRoot .guaranteePhoto img{width:100%;display:block;aspect-ratio:16\/7;object-fit:cover;background:rgba(255,255,255,.03)}\r\n#jlmLiteAppRoot .guaranteeBig{max-width:980px;margin:16px auto 0;text-align:center;font-size:30px;line-height:1.45;font-weight:900}\r\n#jlmLiteAppRoot .price{text-align:center;margin-top:12px}\r\n#jlmLiteAppRoot .price .big{font-size:52px;font-weight:900}\r\n#jlmLiteAppRoot .commentWrap{max-width:980px;margin:18px auto 0;text-align:center}\r\n#jlmLiteAppRoot .commentToggle{appearance:none;border:1px solid rgba(249,115,22,.48);background:linear-gradient(180deg,rgba(249,115,22,.22),rgba(234,88,12,.16)),rgba(255,255,255,.06);color:#fff;border-radius:999px;padding:11px 18px;font-size:14px;font-weight:700;cursor:pointer;transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease;box-shadow:0 10px 30px rgba(0,0,0,.16),inset 0 1px 0 rgba(255,255,255,.08)}\r\n#jlmLiteAppRoot .commentToggle:hover{transform:translateY(-2px);border-color:rgba(249,115,22,.72)}\r\n#jlmLiteAppRoot .commentToggleIcon{margin-right:8px;opacity:.95}\r\n#jlmLiteAppRoot .commentModalOverlay{position:fixed;inset:0;background:rgba(2,8,18,.64);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:none;align-items:center;justify-content:center;padding:22px;z-index:1000000}\r\n#jlmLiteAppRoot .commentModalOverlay.show{display:flex}\r\n#jlmLiteAppRoot .commentModal{position:relative;width:min(760px,100%);max-height:min(84vh,820px);overflow:auto;border-radius:28px;border:1px solid rgba(255,255,255,.14);background:radial-gradient(900px 320px at 0% 0%,rgba(249,115,22,.16),transparent 55%),radial-gradient(700px 280px at 100% 0%,rgba(59,130,246,.10),transparent 58%),linear-gradient(180deg,rgba(11,18,32,.96),rgba(8,16,29,.98));box-shadow:0 30px 80px rgba(0,0,0,.46)}\r\n#jlmLiteAppRoot .commentModalGlow{position:absolute;inset:auto -20% -35% -20%;height:200px;background:radial-gradient(circle,rgba(249,115,22,.12),transparent 65%);pointer-events:none}\r\n#jlmLiteAppRoot .commentModalHead{position:relative;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:18px 20px 16px;border-bottom:1px solid rgba(255,255,255,.10)}\r\n#jlmLiteAppRoot .commentModalEyebrow{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:rgba(255,255,255,.62);margin-bottom:6px}\r\n#jlmLiteAppRoot .commentModalTitle{font-size:28px;font-weight:900;line-height:1.1}\r\n#jlmLiteAppRoot .commentModalX{appearance:none;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.06);color:#fff;width:44px;height:44px;border-radius:999px;font-size:26px;line-height:1;cursor:pointer;flex:0 0 auto}\r\n#jlmLiteAppRoot .commentModalBody{position:relative;padding:24px 22px 12px;color:#fff;text-align:center;font-weight:700;line-height:1.9;font-size:18px}\r\n#jlmLiteAppRoot .commentModalActions{padding:0 22px 22px;display:flex;justify-content:center}\r\n#jlmLiteAppRoot .nav{display:flex;gap:12px;justify-content:center;align-items:center;flex-wrap:wrap;margin-top:18px}\r\n#jlmLiteAppRoot .btn{appearance:none;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.06);color:#fff;border-radius:999px;padding:12px 18px;font-size:14px;font-weight:700;cursor:pointer;min-width:150px;text-decoration:none}\r\n#jlmLiteAppRoot .btn.pri{background:linear-gradient(180deg,var(--orange),var(--orange2));border-color:rgba(249,115,22,.65)}\r\n#jlmLiteAppRoot .btn.reset{margin-right:26px;background:rgba(255,255,255,.04)}\r\n#jlmLiteAppRoot .boOverlay{position:fixed;inset:0;background:rgba(0,0,0,.62);display:none;z-index:999999}\r\n#jlmLiteAppRoot .boOverlay.show{display:block}\r\n#jlmLiteAppRoot .bo{position:absolute;inset:5%;background:#0B1220;border:1px solid rgba(255,255,255,.14);border-radius:22px;overflow:hidden;display:flex;flex-direction:column;box-shadow:0 24px 60px rgba(0,0,0,.35)}\r\n#jlmLiteAppRoot .boHead{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 14px;border-bottom:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.04)}\r\n#jlmLiteAppRoot .boBody{overflow:auto;padding:14px}\r\n#jlmLiteAppRoot .fs{border:1px solid rgba(255,255,255,.14);border-radius:18px;padding:12px;margin-bottom:12px;background:rgba(255,255,255,.03)}\r\n#jlmLiteAppRoot .fs legend{padding:0 8px;color:rgba(255,255,255,.86);font-size:13px;font-weight:700}\r\n#jlmLiteAppRoot .lbl{display:block;font-size:12px;color:rgba(255,255,255,.78);margin-bottom:6px;text-align:left}\r\n#jlmLiteAppRoot .inp,#jlmLiteAppRoot .ta,#jlmLiteAppRoot .num{width:100%;border-radius:12px;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.06);color:#fff;padding:10px;outline:none}\r\n#jlmLiteAppRoot .ta{min-height:82px;resize:vertical}\r\n#jlmLiteAppRoot .boActions{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap;padding:12px 14px;border-top:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.03)}\r\n#jlmLiteAppRoot .row2{display:grid;grid-template-columns:1fr 1fr;gap:10px}\r\n#jlmLiteAppRoot .hr{height:1px;background:rgba(255,255,255,.10);margin:10px 0}\r\n@media (max-width:700px){#jlmLiteAppRoot .row2{grid-template-columns:1fr}}\r\n@media (max-width:560px){\r\n  #jlmLiteAppRoot .grid{grid-template-columns:1fr}\r\n  #jlmLiteAppRoot .logo{width:108px;height:108px}\r\n  #jlmLiteAppRoot .alertBand{font-size:16px}\r\n  #jlmLiteAppRoot .guaranteeBig{font-size:22px}\r\n  #jlmLiteAppRoot .commentModalTitle{font-size:23px}\r\n  #jlmLiteAppRoot .commentModalBody{font-size:16px;line-height:1.8}\r\n}\r\n`;\r\n\r\n  root.appendChild(styleNode);\r\n  app = document.createElement(\"div\");\r\n  app.className = \"app\";\r\n  root.appendChild(app);\r\n\r\n  function hotkey(e) {\r\n    var isA = (e.code === \"KeyA\") || (String(e.key || \"\").toLowerCase() === \"a\");\r\n    if (e.ctrlKey && e.altKey && isA) {\r\n      e.preventDefault(); e.stopPropagation();\r\n      if (!adminUnlocked) {\r\n        var code = window.prompt(\"Entrez le code d'acc\u00e8s au Back Office :\");\r\n        if (code === null) return;\r\n        if (String(code || \"\").trim() !== ADMIN_CODE) { alert(\"Code incorrect.\"); return; }\r\n        adminUnlocked = true; render();\r\n        var bo = document.getElementById(\"boOverlay\");\r\n        if (bo) bo.classList.add(\"show\");\r\n        return;\r\n      }\r\n      var bo2 = document.getElementById(\"boOverlay\");\r\n      if (bo2) bo2.classList.toggle(\"show\");\r\n    }\r\n    if (e.key === \"Escape\") {\r\n      var bo3 = document.getElementById(\"boOverlay\");\r\n      if (bo3 && bo3.classList.contains(\"show\")) { bo3.classList.remove(\"show\"); e.preventDefault(); return; }\r\n      var cm = document.getElementById(\"commentModalOverlay\");\r\n      if (cm && cm.classList.contains(\"show\")) { closeCommentModal(); e.preventDefault(); }\r\n    }\r\n  }\r\n\r\n  window.addEventListener(\"keydown\", hotkey, true);\r\n  document.addEventListener(\"keydown\", hotkey, true);\r\n\r\n  wpLoadConfig().then(function () {\r\n    syncLongueur();\r\n    render();\r\n  });\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1180ad5 e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no e-con e-parent\" data-id=\"1180ad5\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2548","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Devis estimatif monte escalier 2 - Bien vieillir chez soi<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/labienveillance.fr\/?page_id=2548\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Devis estimatif monte escalier 2 - Bien vieillir chez soi\" \/>\n<meta property=\"og:url\" content=\"https:\/\/labienveillance.fr\/?page_id=2548\" \/>\n<meta property=\"og:site_name\" content=\"Bien vieillir chez soi\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-08T09:33:41+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data1\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/labienveillance.fr\/?page_id=2548\",\"url\":\"https:\/\/labienveillance.fr\/?page_id=2548\",\"name\":\"Devis estimatif monte escalier 2 - Bien vieillir chez soi\",\"isPartOf\":{\"@id\":\"https:\/\/labienveillance.fr\/#website\"},\"datePublished\":\"2026-05-08T09:05:50+00:00\",\"dateModified\":\"2026-05-08T09:33:41+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/labienveillance.fr\/?page_id=2548#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/labienveillance.fr\/?page_id=2548\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/labienveillance.fr\/?page_id=2548#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/labienveillance.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Devis estimatif monte escalier 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/labienveillance.fr\/#website\",\"url\":\"https:\/\/labienveillance.fr\/\",\"name\":\"Bien vieillir chez soi\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/labienveillance.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/labienveillance.fr\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/labienveillance.fr\/#organization\",\"name\":\"Bien vieillir chez soi\",\"url\":\"https:\/\/labienveillance.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/labienveillance.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/labienveillance.fr\/wp-content\/uploads\/2025\/09\/LogoMakr-0C1PJU-1.png\",\"contentUrl\":\"https:\/\/labienveillance.fr\/wp-content\/uploads\/2025\/09\/LogoMakr-0C1PJU-1.png\",\"width\":199,\"height\":110,\"caption\":\"Bien vieillir chez soi\"},\"image\":{\"@id\":\"https:\/\/labienveillance.fr\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Devis estimatif monte escalier 2 - Bien vieillir chez soi","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/labienveillance.fr\/?page_id=2548","og_locale":"fr_FR","og_type":"article","og_title":"Devis estimatif monte escalier 2 - Bien vieillir chez soi","og_url":"https:\/\/labienveillance.fr\/?page_id=2548","og_site_name":"Bien vieillir chez soi","article_modified_time":"2026-05-08T09:33:41+00:00","twitter_card":"summary_large_image","twitter_misc":{"Dur\u00e9e de lecture estim\u00e9e":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/labienveillance.fr\/?page_id=2548","url":"https:\/\/labienveillance.fr\/?page_id=2548","name":"Devis estimatif monte escalier 2 - Bien vieillir chez soi","isPartOf":{"@id":"https:\/\/labienveillance.fr\/#website"},"datePublished":"2026-05-08T09:05:50+00:00","dateModified":"2026-05-08T09:33:41+00:00","breadcrumb":{"@id":"https:\/\/labienveillance.fr\/?page_id=2548#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/labienveillance.fr\/?page_id=2548"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/labienveillance.fr\/?page_id=2548#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/labienveillance.fr\/"},{"@type":"ListItem","position":2,"name":"Devis estimatif monte escalier 2"}]},{"@type":"WebSite","@id":"https:\/\/labienveillance.fr\/#website","url":"https:\/\/labienveillance.fr\/","name":"Bien vieillir chez soi","description":"","publisher":{"@id":"https:\/\/labienveillance.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/labienveillance.fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/labienveillance.fr\/#organization","name":"Bien vieillir chez soi","url":"https:\/\/labienveillance.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/labienveillance.fr\/#\/schema\/logo\/image\/","url":"https:\/\/labienveillance.fr\/wp-content\/uploads\/2025\/09\/LogoMakr-0C1PJU-1.png","contentUrl":"https:\/\/labienveillance.fr\/wp-content\/uploads\/2025\/09\/LogoMakr-0C1PJU-1.png","width":199,"height":110,"caption":"Bien vieillir chez soi"},"image":{"@id":"https:\/\/labienveillance.fr\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/labienveillance.fr\/index.php?rest_route=\/wp\/v2\/pages\/2548","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/labienveillance.fr\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/labienveillance.fr\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/labienveillance.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/labienveillance.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2548"}],"version-history":[{"count":11,"href":"https:\/\/labienveillance.fr\/index.php?rest_route=\/wp\/v2\/pages\/2548\/revisions"}],"predecessor-version":[{"id":2560,"href":"https:\/\/labienveillance.fr\/index.php?rest_route=\/wp\/v2\/pages\/2548\/revisions\/2560"}],"wp:attachment":[{"href":"https:\/\/labienveillance.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2548"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}