{"id":8167,"date":"2026-10-05T13:44:02","date_gmt":"2026-10-05T11:44:02","guid":{"rendered":"https:\/\/nuevaweb.ecocero.com\/showroom-lisboa\/"},"modified":"2026-10-05T20:21:45","modified_gmt":"2026-10-05T18:21:45","slug":"showroom-lisboa","status":"publish","type":"page","link":"https:\/\/ecocero.com\/fr\/showroom-lisboa\/","title":{"rendered":"Showroom Lisbonne"},"content":{"rendered":"\n<style data-wp-block-html=\"css\">\n\/*\n  Estilos del formulario \"Showroom Lisboa\" \u2014 generado por ECOapp.\n  Acompa\u00f1a a \"showroom-lisboa.html\". Acotados a .eco-f-4629e976.\n\n  \u26a0\ufe0f NO se actualiza solo: si cambias el aspecto en ECOapp, vuelve a descargarlo.\n*\/\n.page-showroom-lisboa .wp-block-post-title {\n  text-align: center;\n  }\n.eco-f-root, .eco-f-root *, .eco-f-root *::before, .eco-f-root *::after { box-sizing: border-box; }\n.eco-f-root { margin: 0; padding: 0 20px 28px; font-family: var(--eco-font);\n  font-size: var(--eco-font-size); line-height: 1.45; text-align: left;\n  color: var(--eco-text); background: var(--eco-bg); }\n.eco-f-inner { max-width: var(--eco-max-width); margin: 0 auto; }\n.eco-f-title { margin: 0 0 18px; font-size: calc(var(--eco-font-size) + 6px); font-weight: 700;\n  line-height: 1.25; color: inherit; }\n.eco-f-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--eco-gap); }\n.eco-f-full { grid-column: span 12; min-width: 0; }\n.eco-f-half { grid-column: span 6; min-width: 0; }\n.eco-f-third { grid-column: span 4; min-width: 0; }\n@media (max-width: 720px) { .eco-f-third { grid-column: span 6; } }\n@media (max-width: 560px) { .eco-f-half, .eco-f-third { grid-column: span 12; } }\n.eco-f-label { display: block; margin: 0 0 6px; font-size: calc(var(--eco-font-size) - 1px);\n  font-weight: 600; line-height: 1.35; color: var(--eco-label); }\n.eco-f-req { color: var(--eco-error); margin-left: 2px; }\n.eco-f-control { display: block; width: 100%; margin: 0; font-family: inherit;\n  font-size: var(--eco-font-size); line-height: 1.4; color: var(--eco-field-text);\n  background: var(--eco-field-bg); border: var(--eco-border-width) solid var(--eco-border);\n  border-radius: var(--eco-radius); padding: var(--eco-pad-y) var(--eco-pad-x); box-shadow: none;\n  transition: border-color .15s ease; }\n.eco-f-control:focus { outline: var(--eco-focus-width) solid var(--eco-focus); outline-offset: 1px;\n  border-color: var(--eco-focus); }\n.eco-f-control[aria-invalid=\"true\"] { border-color: var(--eco-error); }\n.eco-f-control::placeholder { color: currentColor; opacity: .5; }\ntextarea.eco-f-control { min-height: 104px; resize: vertical; }\nselect[multiple].eco-f-control { min-height: 132px; padding: 6px; }\n.eco-f-check { display: flex; align-items: flex-start; gap: 10px; margin: 0;\n  font-size: var(--eco-font-size); line-height: 1.45; cursor: pointer; }\n.eco-f-check input { flex: 0 0 auto; width: 18px; height: 18px; margin: 1px 0 0;\n  accent-color: var(--eco-primary); }\n.eco-f-options { display: flex; flex-direction: column; gap: 8px; padding-top: 2px; }\n.eco-f-options.is-invalid { padding-left: 10px; border-left: 2px solid var(--eco-error); }\n.eco-f-error { margin-top: 5px; font-size: calc(var(--eco-font-size) - 2px); color: var(--eco-error); }\n.eco-f-help { margin-top: 5px; font-size: calc(var(--eco-font-size) - 2px); opacity: .68;\n  line-height: 1.4; }\n.eco-f-actions { display: flex; justify-content: var(--eco-btn-justify); }\n.eco-f-btn { width: var(--eco-btn-width); max-width: 100%; margin: 0; font-family: inherit;\n  font-size: calc(var(--eco-font-size) + 1px); font-weight: 700; line-height: 1.3;\n  text-align: center; text-decoration: none; cursor: pointer;\n  padding: calc(var(--eco-pad-y) + 3px) 24px; border-radius: var(--eco-radius);\n  background: var(--eco-btn-bg); color: var(--eco-btn-fg);\n  border: var(--eco-btn-border-width) solid var(--eco-btn-border); }\n.eco-f-btn:disabled { opacity: .6; cursor: default; }\n.eco-f-btn:focus-visible { outline: var(--eco-focus-width) solid var(--eco-focus); outline-offset: 2px; }\n.eco-f-note { margin: 0; padding: 14px 16px; border-radius: var(--eco-radius);\n  border: 1px solid var(--eco-border); font-size: calc(var(--eco-font-size) + 1px); line-height: 1.5; }\n.eco-f-note.is-error { border-color: var(--eco-error); color: var(--eco-error); }\n.eco-f-done { text-align: center; padding: 32px 16px; font-size: calc(var(--eco-font-size) + 3px);\n  line-height: 1.6; font-weight: 600; }\n.eco-f-heading { margin: 8px 0 0; font-size: calc(var(--eco-font-size) + 2px); font-weight: 700;\n  letter-spacing: .2px; color: inherit; }\n.eco-f-subheading { margin: 4px 0 0; font-size: calc(var(--eco-font-size) - 1px); line-height: 1.5;\n  opacity: .72; white-space: pre-wrap; }\n.eco-f-paragraph { margin: 0; font-size: calc(var(--eco-font-size) - 1px); line-height: 1.6;\n  opacity: .82; white-space: pre-wrap; }\n.eco-f-divider { height: 0; margin: 4px 0; border: 0; border-top: 1px solid var(--eco-border); }\n.eco-f-fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }\n.eco-f-legend { padding: 0; margin-bottom: 8px; font-size: calc(var(--eco-font-size) - 1px);\n  font-weight: 700; color: var(--eco-label); }\n.eco-f-sub { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 12px; }\n.eco-f-empty { border: 1px dashed var(--eco-border); border-radius: var(--eco-radius);\n  padding: 26px 16px; text-align: center; font-size: calc(var(--eco-font-size) - 1px); opacity: .7; }\n.eco-f-4629e976 {\n  --eco-primary: #000000;\n  --eco-bg: #FFFFFF;\n  --eco-text: #1A2233;\n  --eco-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n  --eco-font-size: 14px;\n  --eco-radius: 0px;\n  --eco-gap: 16px;\n  --eco-pad-y: 10px;\n  --eco-pad-x: 12px;\n  --eco-border: rgba(0,0,0,0.23);\n  --eco-border-width: 1px;\n  --eco-field-bg: transparent;\n  --eco-field-text: #1A2233;\n  --eco-label: #1A2233;\n  --eco-focus: #000000;\n  --eco-focus-width: 2px;\n  --eco-error: #D32F2F;\n  --eco-max-width: 720px;\n  --eco-btn-bg: #000000;\n  --eco-btn-fg: #FFFFFF;\n  --eco-btn-border: #000000;\n  --eco-btn-border-width: 1px;\n  --eco-btn-width: 100%;\n  --eco-btn-justify: center;\n}\n<\/style>\n\n<!--\n  Formulario \"Showroom Lisboa\" \u2014 generado por ECOapp.\n\n  SON DOS FICHEROS: este y \"showroom-lisboa.css\". S\u00fabelos JUNTOS, en la misma\n  carpeta, o el formulario saldr\u00e1 sin estilos.\n\n  \u26a0\ufe0f Esta copia NO se actualiza sola. Si cambias el formulario en ECOapp\n  (campos, textos o aspecto), vuelve a descargar LOS DOS ficheros.\n\n  Si los pones en carpetas distintas, corrige el href del <link> de abajo.\n  Puedes moverlo al <head> de la p\u00e1gina, que es donde mejor va.\n  Los estilos est\u00e1n acotados a .eco-f-4629e976: no tocan nada del resto de la web.\n  El texto va en UTF-8: la p\u00e1gina que lo aloje deber\u00eda declarar esa codificaci\u00f3n.\n-->\n<link rel=\"stylesheet\" href=\"showroom-lisboa.css\">\n<div id=\"eco-form-4629e976\" class=\"eco-f-root eco-f-4629e976\" data-eco-success=\"Merci ! Nous avons bien re\u00e7u vos informations et nous vous contacterons sous peu.\" data-eco-redirect=\"\" data-eco-name=\"Showroom Lisboa\">\n  <div class=\"eco-f-inner\">\n    <form novalidate>\n      <div class=\"eco-f-grid\">\n        <div class=\"eco-f-full\" data-eco-field=\"empresa\" data-eco-kind=\"text\" data-eco-required=\"1\">\n          <label class=\"eco-f-label\" for=\"eco-f-empresa\">Entreprise<span class=\"eco-f-req\">*<\/span><\/label>\n          <input id=\"eco-f-empresa\" name=\"empresa\" class=\"eco-f-control\" type=\"text\">\n        <\/div>\n        <div class=\"eco-f-full\" data-eco-field=\"nombre\" data-eco-kind=\"text\" data-eco-required=\"1\">\n          <label class=\"eco-f-label\" for=\"eco-f-nombre\">Nom et pr\u00e9nom<span class=\"eco-f-req\">*<\/span><\/label>\n          <input id=\"eco-f-nombre\" name=\"nombre\" class=\"eco-f-control\" type=\"text\">\n        <\/div>\n        <div class=\"eco-f-full\" data-eco-field=\"telefono\" data-eco-kind=\"text\" data-eco-required=\"1\">\n          <label class=\"eco-f-label\" for=\"eco-f-telefono\">T\u00e9l\u00e9phone<span class=\"eco-f-req\">*<\/span><\/label>\n          <input id=\"eco-f-telefono\" name=\"telefono\" class=\"eco-f-control\" type=\"tel\" autocomplete=\"tel\">\n        <\/div>\n        <div class=\"eco-f-full\" data-eco-field=\"email\" data-eco-kind=\"email\" data-eco-required=\"1\">\n          <label class=\"eco-f-label\" for=\"eco-f-email\">E-mail<span class=\"eco-f-req\">*<\/span><\/label>\n          <input id=\"eco-f-email\" name=\"email\" class=\"eco-f-control\" type=\"email\" autocomplete=\"email\">\n        <\/div>\n        <div class=\"eco-f-full\" data-eco-field=\"mensaje\" data-eco-kind=\"text\">\n          <label class=\"eco-f-label\" for=\"eco-f-mensaje\">Parlez-nous de votre projet<\/label>\n          <textarea id=\"eco-f-mensaje\" name=\"mensaje\" class=\"eco-f-control\" rows=\"4\" placeholder=\"Surface, d\u00e9lais, type d'espace\u2026\"><\/textarea>\n        <\/div>\n        <div class=\"eco-f-full eco-f-actions\">\n          <button type=\"submit\" class=\"eco-f-btn\">Envoyer<\/button>\n        <\/div>\n      <\/div>\n    <\/form>\n  <\/div>\n<\/div>\n<script>\n(function () {\n  var root = document.getElementById(\"eco-form-4629e976\");\n  if (!root) return;\n  var form = root.querySelector('form');\n  var btn = root.querySelector('.eco-f-btn');\n  if (!form || !btn) return;\n\n  var ENDPOINT = \"https:\/\/app.ecocero.net\/api\/v1\/crm-intake\/4629e97625989756d9eedf496fb9050f395df7c369e52f40a6595646a1505ccb\";\n  var M = {\"requiredCheck\":\"Vous devez cocher cette case\",\"requiredChoice\":\"Choisissez au moins une option\",\"requiredOption\":\"Choisissez une option\",\"required\":\"Ce champ est obligatoire\",\"invalidEmail\":\"Saisissez une adresse e-mail valide\",\"invalidUrl\":\"Saisissez une adresse web valide\",\"sending\":\"Envoi en cours\u2026\",\"retrying\":\"Nouvel essai\u2026\",\"sendError\":\"Impossible d'envoyer. V\u00e9rifiez votre connexion et r\u00e9essayez.\",\"queued\":\"Nous n'avons pas pu l'envoyer pour le moment. Nous l'avons enregistr\u00e9 et r\u00e9essaierons automatiquement : ne fermez pas cette page.\"};\n  var EMAIL = \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$\/;\n  \/* Comprobaci\u00f3n de URL DELIBERADAMENTE PERMISIVA: algo con un punto y sin\n     espacios. Aqu\u00ed un falso negativo no es un aviso, es un lead perdido. *\/\n  var WEB = \/^(?:[a-z][a-z0-9+.-]*:\\\/\\\/)?[^\\s\\\/?#.]+\\.[^\\s]{2,}$\/i;\n  var busy = false;\n  var etiqueta = btn.textContent;\n  \/* Clave de la cola de envios de ESTE formulario: la direccion a la que se\n     manda, que lleva su token. NO el nombre: dos formularios distintos que se\n     llamen igual en la misma web (\u00abContacto\u00bb en la pagina en espa\u00f1ol y en la\n     inglesa) compartirian cola, y el envio de uno acabaria en el otro, con su\n     propietario y sus valores fijos. *\/\n  var COLA_KEY = 'ecoapp.intakeQueue.' + ENDPOINT;\n  var reintentosEnMarcha = false;\n  \/* El envio de ESTA visita que se quedo pendiente: el que la persona espera. *\/\n  var esperando = null;\n  var enVuelo = 0;\n\n  function fields() { return root.querySelectorAll('[data-eco-field]'); }\n\n  function control(box) {\n    return box.matches('input, select, textarea') ? box : box.querySelector('input, select, textarea');\n  }\n\n  function read(box) {\n    var kind = box.getAttribute('data-eco-kind');\n    if (kind === 'checkbox') { var one = control(box); return !!(one && one.checked); }\n    if (kind === 'multi-select') {\n      return Array.prototype.slice.call(box.querySelectorAll('option'))\n        .filter(function (o) { return o.selected; })\n        .map(function (o) { return o.value; });\n    }\n    if (kind === 'multi-check') {\n      return Array.prototype.slice.call(box.querySelectorAll('input'))\n        .filter(function (i) { return i.checked; })\n        .map(function (i) { return i.value; });\n    }\n    if (kind === 'choice-radio') {\n      var picked = box.querySelector('input:checked');\n      return picked ? picked.value : '';\n    }\n    var el = control(box);\n    var value = el && el.value != null ? String(el.value) : '';\n    \/* El oculto viaja tal cual: su valor lo fij\u00f3 el constructor, no el visitante. *\/\n    return kind === 'hidden' ? value : value.replace(\/^\\s+|\\s+$\/g, '');\n  }\n\n  function setError(box, message) {\n    var el = control(box);\n    if (el && el.setAttribute) {\n      if (message) el.setAttribute('aria-invalid', 'true'); else el.removeAttribute('aria-invalid');\n    }\n    var group = box.querySelector('.eco-f-options');\n    if (group) group.className = 'eco-f-options' + (message ? ' is-invalid' : '');\n    var slot = box.querySelector('.eco-f-error');\n    if (!message) { if (slot) slot.parentNode.removeChild(slot); return; }\n    if (!slot) {\n      slot = document.createElement('div');\n      slot.className = 'eco-f-error';\n      box.appendChild(slot);\n    }\n    slot.textContent = message;\n  }\n\n  function validate() {\n    var first = null;\n    Array.prototype.forEach.call(fields(), function (box) {\n      var kind = box.getAttribute('data-eco-kind');\n      \/* Un campo OCULTO no lo rellena nadie: exigirlo dejar\u00eda el formulario\n         imposible de enviar y sin ning\u00fan error visible junto a un campo. *\/\n      if (kind === 'hidden') return;\n      var need = box.getAttribute('data-eco-required') === '1';\n      var value = read(box);\n      var message = '';\n      if (kind === 'checkbox') {\n        if (need && value !== true) message = M.requiredCheck;\n      } else if (kind === 'multi-select' || kind === 'multi-check') {\n        if (need && value.length === 0) message = M.requiredChoice;\n      } else {\n        var text = String(value);\n        if (need && !text) message = (kind === 'choice' || kind === 'choice-radio') ? M.requiredOption : M.required;\n        else if (kind === 'email' && text && !EMAIL.test(text)) message = M.invalidEmail;\n        else if (kind === 'url' && text && !WEB.test(text)) message = M.invalidUrl;\n      }\n      setError(box, message);\n      if (message && !first) first = box;\n    });\n    return first;\n  }\n\n  function notice(text) {\n    var actions = btn.parentNode;\n    var slot = root.querySelector('.eco-f-sendfail');\n    if (!slot) {\n      slot = document.createElement('p');\n      slot.className = 'eco-f-note is-error eco-f-full eco-f-sendfail';\n      slot.setAttribute('role', 'alert');\n      actions.parentNode.insertBefore(slot, actions);\n    }\n    slot.textContent = text;\n  }\n\n  \/* Fin del camino: el formulario NO se vuelve a pintar. Reenviar es la primera\n     causa de leads duplicados. *\/\n  function done() {\n    var inner = root.querySelector('.eco-f-inner');\n    var to = root.getAttribute('data-eco-redirect') || '';\n\n    \/* AVISO A GOOGLE. Se deja el evento en el dataLayer para que Tag Manager\n       dispare la conversion de Google Ads. Se crea el array si no existe: GTM\n       lo consume igual cuando cargue, y asi esto nunca revienta en una web sin\n       contenedor.\n\n       Se manda el nombre INTERNO (data-eco-name), no el titulo visible: el\n       interno es el que identifica al formulario en las metricas, y cambiar el\n       titular de la web no puede partir en dos el historico de conversiones. *\/\n    var navegado = false;\n    function irse() {\n      if (navegado || !to) return;\n      navegado = true;\n      window.location.replace(to);\n    }\n    window.dataLayer = window.dataLayer || [];\n    var nota = { event: 'form_submit', form_name: root.getAttribute('data-eco-name') || '' };\n    if (to) { nota.eventCallback = irse; nota.eventTimeout = 2000; }\n    window.dataLayer.push(nota);\n\n    \/* CON ENLACE NO SE PINTA NADA: se vacia el formulario y se sale. El\n       navegador tarda en resolver la URL nueva y mientras tanto ESTA pagina\n       sigue a la vista, asi que un cartel aqui no es un parpadeo: se queda\n       hasta que carga el destino, que es justo la pagina de gracias del\n       cliente. Serian dos gracias seguidos.\n       Se usa replace y no href para que Atras no devuelva al formulario ya\n       enviado: reenviar es la primera causa de leads duplicados. El atributo\n       solo puede llevar http\/https, lo sanea resolveFormTheme ANTES de\n       generar este HTML.\n       LA ESPERA NO ES OPCIONAL, y el respaldo por tiempo tampoco: replace\n       corta las peticiones en vuelo y mataria el tag a medio salir, pero\n       eventCallback solo lo llama GTM \u2014 sin contenedor en la pagina no se\n       ejecutaria nunca y el formulario se quedaria clavado sin redirigir.\n       OJO: este JS vive dentro de un template literal de TypeScript, asi\n       que aqui NO caben comillas invertidas ni acentos escapados. *\/\n    while (inner.firstChild) inner.removeChild(inner.firstChild);\n    if (to) { window.setTimeout(irse, 2000); return; }\n    var box = document.createElement('div');\n    box.className = 'eco-f-done';\n    box.setAttribute('role', 'status');\n    box.textContent = root.getAttribute('data-eco-success') || '';\n    inner.appendChild(box);\n  }\n\n  form.addEventListener('submit', function (event) {\n    event.preventDefault();\n    if (busy) return;\n\n    var bad = validate();\n    if (bad) {\n      var target = control(bad);\n      if (target && target.focus) target.focus();\n      return;\n    }\n\n    \/* Se manda TODO el formulario, con o sin mapeo: lo que no llena una columna\n       del lead queda en el env\u00edo y se puede mapear despu\u00e9s. *\/\n    var payload = {};\n    Array.prototype.forEach.call(fields(), function (box) {\n      payload[box.getAttribute('data-eco-field')] = read(box);\n    });\n\n    busy = true;\n    btn.disabled = true;\n    btn.textContent = M.sending;\n\n    \/* Se guarda ANTES de intentarlo: si el navegador se queda sin red a mitad\n       del envio, el dato ya esta a salvo en este equipo. *\/\n    var envio = { sid: nuevoSid(), payload: payload, createdAt: Date.now() };\n    guardar(envio);\n\n    \/* El primer envio cuenta como EN VUELO: si quedaba algo de una visita\n       anterior, la ronda de reintento de esa cola no puede mandar a la vez este\n       mismo envio (esta ya en la cola) y sumar un golpe contra el limite. *\/\n    enVuelo += 1;\n    enviar(envio).then(function (r) {\n      enVuelo -= 1;\n      if (r === 'ok') { borrar(envio.sid); done(); return; }\n      if (r === 'descartar') {\n        \/* Rechazado, y repetirlo daria lo mismo: fuera de la cola y el aviso\n           de siempre, para que la persona pueda corregir y volver a enviar. *\/\n        borrar(envio.sid);\n        recover(M.sendError);\n        return;\n      }\n      \/* No se ha podido, pero NO se ha perdido: queda en cola y se reintenta al\n         volver la conexion y, mientras la pagina siga abierta, a los 15 s y\n         cada vez mas espaciado (hasta 5 min). El\n         boton se queda BLOQUEADO: un segundo clic seria otro envio con otro\n         sid, o sea un lead gemelo en cuanto vuelva la API. *\/\n      esperando = envio;\n      btn.textContent = M.retrying;\n      notice(M.queued);\n      programarReintentos();\n    });\n  });\n\n  function recover(text) {\n    busy = false;\n    btn.disabled = false;\n    btn.textContent = etiqueta;\n    notice(text);\n  }\n\n  \/* ------------------------------------------------------------------ COLA\n     Un envio que falla por red o por un servidor que no contesta se guarda en\n     ESTE navegador y se reintenta. Cada envio lleva su identificador en ?sid=,\n     asi que si el primer intento llego a entrar y lo que se perdio fue la\n     respuesta, el reintento se reconoce en el servidor y no crea un lead\n     gemelo.\n\n     Lo que esto NO hace, para no prometer de mas: si la persona cierra la\n     pesta\u00f1a y no vuelve, lo que quede aqui no se manda. Por eso el aviso le\n     pide que no cierre, en vez de decirle que ya esta enviado. *\/\n  function nuevoSid() {\n    if (window.crypto && window.crypto.randomUUID) return window.crypto.randomUUID();\n    return String(Date.now()) + '-' + Math.random().toString(36).slice(2, 12);\n  }\n\n  function leerCola() {\n    try {\n      var raw = window.localStorage.getItem(COLA_KEY);\n      var lista = raw ? JSON.parse(raw) : [];\n      if (!lista || !lista.length) return [];\n      var vivos = [];\n      for (var i = 0; i < lista.length; i++) {\n        \/* Una semana: un envio mas viejo ya no le interesa a nadie. *\/\n        if (lista[i] &#038;&#038; lista[i].sid &#038;&#038; Date.now() - (lista[i].createdAt || 0) < 604800000) {\n          vivos.push(lista[i]);\n        }\n      }\n      return vivos.slice(-20);\n    } catch (e) {\n      \/* Navegacion privada o almacenamiento lleno: sin cola, como antes. *\/\n      return [];\n    }\n  }\n\n  function escribirCola(lista) {\n    try { window.localStorage.setItem(COLA_KEY, JSON.stringify(lista.slice(-20))); } catch (e) {}\n  }\n\n  function guardar(envio) {\n    var cola = leerCola();\n    cola.push(envio);\n    escribirCola(cola);\n  }\n\n  function borrar(sid) {\n    var cola = leerCola();\n    var resto = [];\n    for (var i = 0; i < cola.length; i++) if (cola[i].sid !== sid) resto.push(cola[i]);\n    escribirCola(resto);\n  }\n\n  \/* Resuelve a 'ok' (entregado), 'reintentar' (sin red, un 5xx o un 429: se\n     pasan solos) o 'descartar' (cualquier otro 4xx: repetirlo daria lo\n     mismo). Solo 'reintentar' se queda en la cola. *\/\n  function enviar(envio) {\n    return fetch(ENDPOINT + '?sid=' + encodeURIComponent(envio.sid), {\n      method: 'POST',\n      headers: { 'Content-Type': 'application\/json' },\n      body: JSON.stringify(envio.payload)\n    }).then(function (res) {\n      if (res.ok) return 'ok';\n      if (res.status >= 500 || res.status === 429) return 'reintentar';\n      return 'descartar';\n    }).catch(function () {\n      return 'reintentar';\n    });\n  }\n\n  \/* Uno a la vez y EN ORDEN, y el primer fallo corta la ronda. Si la API no\n     contesta, o contesta 429, al primero, le dira lo mismo al resto: mandarlos\n     igual solo suma golpes contra el limite de 5 por minuto, que cuenta TAMBIEN\n     los rechazados, y la IP (la de una oficina entera, detras de su router) se\n     quedaria bloqueada para cualquier visitante nuevo. *\/\n  function vaciarCola() {\n    if (enVuelo) return Promise.resolve();\n    var cola = leerCola();\n    \/* El envio que se esta ESPERANDO en pantalla va el PRIMERO: como el primer\n       fallo corta la ronda, detras de lo que quedara de una visita anterior se\n       quedaria sin cupo y no saldria nunca. Va aunque no este en la cola: sin\n       almacenamiento (navegacion privada) vive solo en memoria, y sin esto el\n       formulario se quedaria bloqueado para siempre. *\/\n    if (esperando) {\n      var resto = [esperando];\n      for (var j = 0; j < cola.length; j++) if (cola[j].sid !== esperando.sid) resto.push(cola[j]);\n      cola = resto;\n    }\n    var i = 0;\n    enVuelo += 1;\n    function siguiente() {\n      if (i >= cola.length) { enVuelo -= 1; return Promise.resolve(); }\n      var envio = cola[i++];\n      return enviar(envio).then(function (r) {\n        if (r === 'reintentar') { enVuelo -= 1; return; }\n        borrar(envio.sid);\n        \/* El GRACIAS sale solo si el que entra es el que se esta esperando en\n           pantalla. Uno de una visita anterior se entrega en silencio: si no,\n           abrir el formulario para mandar otro daria las gracias antes de\n           escribir nada. *\/\n        if (esperando && envio.sid === esperando.sid) {\n          esperando = null;\n          \/* Protegido: este HTML lo puede retocar el cliente, y si pintar el\n             aviso fallara, sin esto la cola se quedaria EN VUELO para siempre\n             y no se reintentaria nada mas. *\/\n          try {\n            if (r === 'ok') { busy = false; done(); } else { recover(M.sendError); }\n          } catch (e) {}\n        }\n        return siguiente();\n      });\n    }\n    return siguiente();\n  }\n\n  \/* Espera entre rondas: 15 s, y se DOBLA cada vez que una ronda deja algo\n     pendiente, hasta 5 min; vuelve a 15 s en cuanto la cola se vacia. Con un\n     intervalo fijo, dos pesta\u00f1as (o dos envios) detras de la misma IP la\n     mantenian por encima del limite mientras siguieran abiertas. *\/\n  var ESPERA_INICIAL = 15000;\n  var ESPERA_MAX = 300000;\n  \/* Con alguien DELANTE esperando (se le ha pedido que no cierre), no mas de un\n     minuto: cinco serian un lead perdido. Una ronda por minuto sigue muy por\n     debajo del limite. *\/\n  var ESPERA_CON_VISITANTE = 60000;\n  var espera = ESPERA_INICIAL;\n  function ronda() {\n    vaciarCola().then(function () {\n      espera = (leerCola().length || esperando)\n        ? Math.min(espera * 2, esperando ? ESPERA_CON_VISITANTE : ESPERA_MAX)\n        : ESPERA_INICIAL;\n      window.setTimeout(ronda, espera);\n    });\n  }\n\n  function programarReintentos() {\n    if (reintentosEnMarcha) return;\n    reintentosEnMarcha = true;\n    window.addEventListener('online', vaciarCola);\n    window.setTimeout(ronda, espera);\n  }\n\n  \/* Al cargar: lo que quedara de una visita anterior. *\/\n  if (leerCola().length) { programarReintentos(); vaciarCola(); }\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Entreprise* Nom et pr\u00e9nom* T\u00e9l\u00e9phone* E-mail* Parlez-nous de votre projet Envoyer<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":82,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_dss_enabled":false,"footnotes":""},"class_list":["post-8167","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Showroom Lisbonne - EcoCero<\/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:\/\/ecocero.com\/fr\/showroom-lisboa\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Showroom Lisbonne - EcoCero\" \/>\n<meta property=\"og:description\" content=\"Entreprise* Nom et pr\u00e9nom* T\u00e9l\u00e9phone* E-mail* Parlez-nous de votre projet Envoyer\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ecocero.com\/fr\/showroom-lisboa\/\" \/>\n<meta property=\"og:site_name\" content=\"EcoCero\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-05T18:21:45+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=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/showroom-lisboa\\\/\",\"url\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/showroom-lisboa\\\/\",\"name\":\"Showroom Lisbonne - EcoCero\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/#website\"},\"datePublished\":\"2026-10-05T11:44:02+00:00\",\"dateModified\":\"2026-10-05T18:21:45+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/showroom-lisboa\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ecocero.com\\\/fr\\\/showroom-lisboa\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/showroom-lisboa\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Showroom Lisbonne\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/#website\",\"url\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/\",\"name\":\"EcoCero\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/#organization\",\"name\":\"EcoCero\",\"url\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/ecocero.com\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/ecocero-logo.png\",\"contentUrl\":\"https:\\\/\\\/ecocero.com\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/ecocero-logo.png\",\"width\":284,\"height\":63,\"caption\":\"EcoCero\"},\"image\":{\"@id\":\"https:\\\/\\\/ecocero.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Showroom Lisbonne - EcoCero","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:\/\/ecocero.com\/fr\/showroom-lisboa\/","og_locale":"fr_FR","og_type":"article","og_title":"Showroom Lisbonne - EcoCero","og_description":"Entreprise* Nom et pr\u00e9nom* T\u00e9l\u00e9phone* E-mail* Parlez-nous de votre projet Envoyer","og_url":"https:\/\/ecocero.com\/fr\/showroom-lisboa\/","og_site_name":"EcoCero","article_modified_time":"2026-10-05T18:21:45+00:00","twitter_card":"summary_large_image","twitter_misc":{"Dur\u00e9e de lecture estim\u00e9e":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/ecocero.com\/fr\/showroom-lisboa\/","url":"https:\/\/ecocero.com\/fr\/showroom-lisboa\/","name":"Showroom Lisbonne - EcoCero","isPartOf":{"@id":"https:\/\/ecocero.com\/fr\/#website"},"datePublished":"2026-10-05T11:44:02+00:00","dateModified":"2026-10-05T18:21:45+00:00","breadcrumb":{"@id":"https:\/\/ecocero.com\/fr\/showroom-lisboa\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ecocero.com\/fr\/showroom-lisboa\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/ecocero.com\/fr\/showroom-lisboa\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/ecocero.com\/fr\/"},{"@type":"ListItem","position":2,"name":"Showroom Lisbonne"}]},{"@type":"WebSite","@id":"https:\/\/ecocero.com\/fr\/#website","url":"https:\/\/ecocero.com\/fr\/","name":"EcoCero","description":"","publisher":{"@id":"https:\/\/ecocero.com\/fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ecocero.com\/fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/ecocero.com\/fr\/#organization","name":"EcoCero","url":"https:\/\/ecocero.com\/fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/ecocero.com\/fr\/#\/schema\/logo\/image\/","url":"https:\/\/ecocero.com\/wp-content\/uploads\/2026\/03\/ecocero-logo.png","contentUrl":"https:\/\/ecocero.com\/wp-content\/uploads\/2026\/03\/ecocero-logo.png","width":284,"height":63,"caption":"EcoCero"},"image":{"@id":"https:\/\/ecocero.com\/fr\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/pages\/8167","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/comments?post=8167"}],"version-history":[{"count":1,"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/pages\/8167\/revisions"}],"predecessor-version":[{"id":8213,"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/pages\/8167\/revisions\/8213"}],"wp:attachment":[{"href":"https:\/\/ecocero.com\/fr\/wp-json\/wp\/v2\/media?parent=8167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}