/* Único bloco de contacto. O CSS vive aqui, no shadow DOM, para nenhuma página o alterar. */ (function () { if (customElements.get("bright-contacto")) return; var MARK = ''; var CSS = [ "@font-face{font-family:Delight;src:url(/assets/delight-vf.woff2) format('woff2');font-weight:100 900;font-display:swap}", ":host{all:initial;display:block;box-sizing:border-box;width:100%;max-width:none;min-height:100vh;height:auto;margin:0;padding:0;border:0;background:#0A0A0A;color:#fff;position:relative;overflow:visible;transform:none;font:400 14px/1.44 Geist,'Helvetica Neue',Arial,sans-serif;text-align:left;}", "*,*::before,*::after{box-sizing:border-box;border-radius:0;}", ".wrap{position:relative;z-index:1;min-height:100vh;display:flex;flex-direction:column;padding:128px var(--c-pad,clamp(24px,6vw,96px)) 22px;background:#0A0A0A;color:#fff;}", ".wm{position:absolute;z-index:0;right:0;top:50%;transform:translateY(-50%);width:min(46vw,560px);height:auto;aspect-ratio:285/286;margin:0;pointer-events:none;color:#1a1a1a;}", ".wm svg{display:block;width:100%;height:100%;}", ".top{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:0;align-items:start;}", ".infos{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:28px 36px;min-width:0;align-content:start;padding-right:32px;}", ".infos-l,.infos-r{display:flex;flex-direction:column;gap:28px;min-width:0;}", ".ci{display:flex;flex-direction:column;gap:8px;min-width:0;margin:0;}", ".ci dt{margin:0;color:rgba(255,255,255,.4);font:400 14px/1.3 Geist,'Helvetica Neue',Arial,sans-serif;}", ".ci dd{margin:0;color:rgba(255,255,255,.8);font:400 14px/1.44 Geist,'Helvetica Neue',Arial,sans-serif;font-style:normal;}", ".ci dd a{color:inherit;text-decoration:none;}", ".ci dd a:hover{color:#fff;}", ".copy,.infos-foot{grid-column:1 / -1;}", ".ci-redes a{display:block;color:#fff;text-decoration:none;font:400 14px/1.44 Geist,'Helvetica Neue',Arial,sans-serif;}", ".ci-redes a:hover{color:#fff;}", ".copy{display:block;margin:0;max-width:100%;color:rgba(255,255,255,.8);font:400 14px/1.44 Geist,'Helvetica Neue',Arial,sans-serif;white-space:normal;}", ".copy-a,.copy-b{white-space:nowrap;}", ".copy a{color:inherit;text-decoration:none;}", ".copy a:hover{color:#fff;}", ".infos-foot{display:flex;flex-direction:column;align-items:flex-start;gap:12px;min-width:0;margin:0;}", ".fund{display:flex;align-items:center;justify-content:flex-start;flex-wrap:nowrap;gap:28px;margin:0;padding:0;background:transparent;width:max-content;max-width:100%;}", ".fund img{display:block;height:24px;width:auto;flex:0 0 auto;}", "@media (max-width:520px){", ".fund{gap:16px;}", "}", ".formcol{min-width:0;position:relative;z-index:1;}", ".kicker{margin:0 0 10px;color:rgba(255,255,255,.55);font:400 13px/1.3 Geist,'Helvetica Neue',Arial,sans-serif;letter-spacing:.02em;}.phrase{margin:0 0 12px;color:rgba(255,255,255,.8);font:500 clamp(22px,1.7vw,30px)/1.2 Geist,'Helvetica Neue',Arial,sans-serif;letter-spacing:-.02em;}.phrase-sub{margin:0 0 28px;color:rgba(255,255,255,.75);font:400 15px/1.45 Geist,'Helvetica Neue',Arial,sans-serif;}", "form{margin:0;padding:0;border:0;background:none;display:flex;flex-direction:column;}", ".fi{display:flex;flex-direction:column;gap:6px;margin:0;padding:0 0 16px;border:0;background:none;box-shadow:none;}", ".fi span{display:block;margin:0;padding:0;border:0;background:none;box-shadow:none;color:rgba(255,255,255,.8);font:400 15px/1.3 Geist,'Helvetica Neue',Arial,sans-serif;}", ".fi input,.fi textarea{display:block;width:100%;margin:0;padding:4px 0 8px;border:0;border-bottom:1px solid rgba(255,255,255,.32);border-radius:0;outline:none;box-shadow:none;background:transparent;background-image:none;appearance:none;-webkit-appearance:none;color:#fff;font:400 15px/1.4 Geist,'Helvetica Neue',Arial,sans-serif;resize:none;}", ".fi textarea{height:88px;overflow:auto;}", ".fi input::placeholder,.fi textarea::placeholder{color:rgba(255,255,255,.4);}", ".fi input:focus,.fi textarea:focus{border-bottom-color:#fff;outline:none;box-shadow:none;}", ".err{display:block;min-height:0;margin:0;padding:0;border:0;background:none;font:400 12px/1.35 Geist,'Helvetica Neue',Arial,sans-serif;font-style:normal;color:rgba(255,255,255,.55);}", ".err:not(:empty){margin-top:6px;}", ".hp{position:absolute;left:-10000px;width:1px;height:1px;opacity:0;pointer-events:none;}", "form .fi:last-of-type{padding-bottom:0;}", ".note{height:0;min-height:0;margin:0;padding:0;overflow:hidden;font:400 12px/16px Geist,'Helvetica Neue',Arial,sans-serif;color:rgba(255,255,255,.55);}", ".note:not(:empty){height:auto;overflow:visible;margin-top:8px;}", ".thanks{margin:0;color:rgba(255,255,255,.8);font:400 15px/1.45 Geist,'Helvetica Neue',Arial,sans-serif;}", ".bottom{position:relative;z-index:1;margin-top:32px;padding-top:0;}", ".base{position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:0;align-items:start;}", ".base-l{min-width:0;height:0;}", ".base-r{min-width:0;}", ".word{position:absolute;left:0;bottom:0;margin:0;padding:0;color:#fff;font-weight:500;font-family:Delight,Geist,'Helvetica Neue',Arial,sans-serif;font-size:min(156px,calc((50vw - var(--c-pad,clamp(24px,6vw,96px)) - 48px) / 4.73));line-height:1;letter-spacing:-.06em;white-space:nowrap;overflow:visible;}", ".send{display:inline-block;width:100%;margin:0;padding:16px 12px;border:1px solid #fff;border-radius:0;background:transparent;box-shadow:none;color:#fff;cursor:pointer;text-align:center;font:400 15px/1 Geist,'Helvetica Neue',Arial,sans-serif;appearance:none;-webkit-appearance:none;}", ".send:hover{background:#fff;color:#0A0A0A;}", ".send:disabled{cursor:default;background:transparent;color:#fff;}", ".send:disabled:hover,.send.sent:hover{background:transparent;color:#fff;}", ".legal{display:flex;justify-content:flex-end;align-items:center;flex-wrap:wrap;gap:16px;margin:12px 0 0;padding:0;}", ".legal a{color:#a4a4a4;text-decoration:none;font:400 15px/1.3 Geist,'Helvetica Neue',Arial,sans-serif;white-space:nowrap;}", ".legal a:hover{color:#fff;}", ".legal .lr{display:inline-flex;align-items:center;line-height:0;}", ".legal .lr img{display:block;height:24px;width:auto;max-height:24px;}", "@media (max-width:900px){", ".wrap{padding-top:148px;}", ".top,.base{grid-template-columns:minmax(0,1fr);row-gap:28px;}", ".infos{grid-template-columns:minmax(0,1fr) minmax(0,1fr);padding-right:0;}", ".base-l{height:auto;}", ".word{position:relative;left:auto;bottom:auto;transform:none;font-size:min(18vw,92px);}", ".wm{width:min(70vw,280px);}", "}" ].join(""); var HTML = '' + '
' + '' + '
' + '
' + '
' + '' + '
Sede
BrightCity, S.A.
Lugar do Espido, Via Norte
Apartado 1011
4470-909 Maia, Portugal
' + '
' + '
' + '' + '
Hora local · Maia
--:--
' + '' + '
' + '
' + '

© 2026 BrightCity SA, uma empresa Sonae Sierra | NOS

' + '
PRR — Plano de Recuperação e ResiliênciaRepública PortuguesaFinanciado pela União Europeia — NextGenerationEU
' + '
' + '
' + '
' + '

Vamos construir o futuro

O próximo território inteligente
pode começar aqui.

Fale connosco sobre os desafios da sua cidade, edifício ou comunidade.

' + '
' + '' + '' + '' + '' + '' + '

' + '
' + '
' + '
' + '
' + '
' + '

contacto

' + '
' + '
' + '' + '
' + '
'; var HTML_EN = '' + '
' + '' + '
' + '
' + '
' + '' + '
Head office
BrightCity, S.A.
Lugar do Espido, Via Norte
Apartado 1011
4470-909 Maia, Portugal
' + '
' + '
' + '' + '
Local time · Maia
--:--
' + '
Networks
LinkedIn
' + '
' + '
' + '

© 2026 BrightCity SA, a Sonae Sierra | NOS company

' + '
PRR — Recovery and Resilience PlanPortuguese RepublicFunded by the European Union — NextGenerationEU
' + '
' + '
' + '
' + '

Let’s build the future

The next smart territory
can start here.

Talk to us about the challenges of your city, building or community.

' + '
' + '' + '' + '' + '' + '' + '

' + '
' + '
' + '
' + '
' + '
' + '

contact

' + '
' + '
' + '' + '
' + '
'; var HTML_ES = '' + '
' + '' + '
' + '
' + '
' + '' + '
Sede
BrightCity, S.A.
Lugar do Espido, Via Norte
Apartado 1011
4470-909 Maia, Portugal
' + '
' + '
' + '' + '
Hora local · Maia
--:--
' + '' + '
' + '
' + '

© 2026 BrightCity SA, una empresa Sonae Sierra | NOS

' + '
PRR — Plan de Recuperación y ResilienciaRepública PortuguesaFinanciado por la Unión Europea — NextGenerationEU
' + '
' + '
' + '
' + '

Construyamos el futuro

El próximo territorio inteligente
puede empezar aquí.

Háblenos de los retos de su ciudad, edificio o comunidad.

' + '
' + '' + '' + '' + '' + '' + '

' + '
' + '
' + '
' + '
' + '
' + '

contacto

' + '
' + '
' + '' + '
' + '
'; function guard() { if (document.getElementById("bright-contacto-guard")) return; var s = document.createElement("style"); s.id = "bright-contacto-guard"; s.textContent = "html body bright-contacto#contacto.bright-contacto{all:unset!important;display:block!important;box-sizing:border-box!important;width:100%!important;max-width:none!important;height:auto!important;min-height:100vh!important;max-height:none!important;margin:0!important;padding:0!important;border:0!important;background:#0A0A0A!important;color:#fff!important;position:relative!important;overflow:visible!important;transform:none!important;filter:none!important;float:none!important;inset:auto!important;font:400 14px/1.44 Geist,'Helvetica Neue',Arial,sans-serif!important;text-align:left!important;z-index:1!important;}"; document.head.appendChild(s); } class BrightContacto extends HTMLElement { connectedCallback() { guard(); if (this.shadowRoot) return; var lang = (document.documentElement.lang || "pt").toLowerCase(); var isEn = lang.slice(0, 2) === "en"; var isEs = lang.slice(0, 2) === "es"; var root = this.attachShadow({ mode: "open" }); root.innerHTML = "" + (isEn ? HTML_EN : isEs ? HTML_ES : HTML); var wrap = root.querySelector(".wrap"); var syncPad = function () { var header = document.querySelector("header#top, header.top"); var pad = header ? getComputedStyle(header).paddingLeft : ""; if (!pad) pad = getComputedStyle(document.documentElement).getPropertyValue("--pad").trim(); if (pad && wrap) wrap.style.setProperty("--c-pad", pad); }; syncPad(); addEventListener("resize", syncPad); var clock = root.getElementById("clock"); var tick = function () { clock.textContent = new Intl.DateTimeFormat( isEn ? "en-GB" : isEs ? "es-ES" : "pt-PT", isEn || isEs ? { hour: "2-digit", minute: "2-digit", hourCycle: "h23", timeZone: "Europe/Lisbon" } : { hour: "2-digit", minute: "2-digit", timeZone: "Europe/Lisbon" } ).format(new Date()); }; tick(); setInterval(tick, 15000); var form = root.getElementById("bc-form"); var fit = function () { var word = root.querySelector(".word"); var btn = root.querySelector(".send"); if (!word || !btn) return; word.style.transform = ""; if (!matchMedia("(min-width:901px)").matches) return; var probe = document.createElement("span"); probe.style.cssText = "display:inline-block;width:0;height:0;vertical-align:baseline;overflow:hidden;padding:0;margin:0;border:0;"; word.appendChild(probe); var baseY = probe.getBoundingClientRect().top; probe.remove(); var dy = btn.getBoundingClientRect().bottom - baseY; if (Math.abs(dy) > 0.4) word.style.transform = "translateY(" + dy.toFixed(2) + "px)"; }; function setErr(name, msg) { var el = root.querySelector('[data-err="' + name + '"]'); var input = form.elements[name]; if (el) el.textContent = msg || ""; if (input) input.setAttribute("aria-invalid", msg ? "true" : "false"); } ["nome", "email", "msg"].forEach(function (name) { form.elements[name].addEventListener("input", function () { setErr(name, ""); }); }); var sending = false; var done = false; var started = Date.now(); function showThanks() { done = true; var formEl = root.getElementById("bc-form"); var note = document.createElement("p"); note.className = "thanks"; note.setAttribute("role", "status"); note.textContent = isEn ? "Thank you. We received your message and will be in touch shortly." : isEs ? "Gracias. Hemos recibido su mensaje y nos pondremos en contacto en breve." : "Obrigado. Recebemos a sua mensagem e entraremos em contacto brevemente."; if (formEl) formEl.replaceWith(note); var btn = root.querySelector(".send"); if (btn) btn.remove(); fit(); } form.addEventListener("submit", function (e) { e.preventDefault(); if (sending || done) return; var nome = form.nome.value.trim(); var email = form.email.value.trim(); var org = form.org.value.trim(); var msg = form.msg.value.trim(); var emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email); setErr("nome", nome ? "" : (isEn ? "Enter your name." : isEs ? "Indique el nombre." : "Indique o nome.")); setErr("email", !email ? (isEn ? "Enter your email." : isEs ? "Indique el correo." : "Indique o email.") : (emailOk ? "" : (isEn ? "This email does not look valid." : isEs ? "Este correo no parece válido." : "Este email não parece válido."))); setErr("msg", msg ? "" : (isEn ? "Write the message." : isEs ? "Escriba el mensaje." : "Escreva a mensagem.")); var nt = root.getElementById("nt"); if (nt) nt.textContent = ""; if (!nome || !emailOk || !msg) return; var honey = form.querySelector('[name="_honey"]'); if ((honey && honey.value) || Date.now() - started < 800) { showThanks(); return; } sending = true; var btn = root.querySelector(".send"); if (btn) btn.disabled = true; var body = isEn ? { _subject: "Contact via the website – " + org, _template: "table", _captcha: "false", _next: location.origin + "/en/contacto/obrigado", _replyto: email, _honey: "", Name: nome, Email: email, "Municipality or company": org, Message: msg } : isEs ? { _subject: "Contacto desde el sitio – " + org, _template: "table", _captcha: "false", _next: location.origin + "/es/contacto/obrigado", _replyto: email, _honey: "", Nombre: nome, Email: email, "Municipio o empresa": org, Mensaje: msg } : { _subject: "Contacto pelo site – " + org, _template: "table", _captcha: "false", _next: location.origin + "/contacto/obrigado", _replyto: email, _honey: "", Nome: nome, Email: email, "Município ou empresa": org, Mensagem: msg }; var ctrl = new AbortController(); var timer = setTimeout(function () { ctrl.abort(); }, 12000); fetch("https://formsubmit.co/ajax/geral%40brightcity.pt", { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify(body), signal: ctrl.signal }).then(function (res) { return res.json().catch(function () { return {}; }).then(function (data) { var accepted = data && (data.success === true || data.success === "true"); if (!res.ok || !accepted) throw new Error("fail"); showThanks(); }); }).catch(function () { sending = false; if (btn) btn.disabled = false; if (nt) nt.textContent = isEn ? "Could not send. Write to us at geral@brightcity.pt." : isEs ? "No se pudo enviar. Escríbanos a geral@brightcity.pt." : "Não foi possível enviar. Escreva-nos para geral@brightcity.pt."; }).then(function () { clearTimeout(timer); }); }); fit(); addEventListener("resize", fit); if (document.fonts && document.fonts.ready) document.fonts.ready.then(fit); } } customElements.define("bright-contacto", BrightContacto); })();