Aqui está o código completo para colar diretamente no Carrd. Antes de colar, substitui apenas as duas linhas no topo do <script>:
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MAH LDA — Pedido de Diagnóstico</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
background: transparent !important;
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
-webkit-font-smoothing: antialiased;
}
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 16px;
}
.card {
width: 100%;
max-width: 468px;
background: transparent;
border: 1.5px solid #de3c19;
border-radius: 18px;
overflow: hidden;
box-shadow: 0 0 40px rgba(222, 60, 25, 0.12);
}
.card-header {
padding: 26px 26px 18px;
border-bottom: 1px solid rgba(222, 60, 25, 0.22);
}
.brand-tag {
font-size: 9.5px;
font-weight: 700;
letter-spacing: 0.13em;
text-transform: uppercase;
color: #de3c19;
margin-bottom: 7px;
}
.card-title {
font-size: 19px;
font-weight: 700;
color: #ffffff;
line-height: 1.3;
margin-bottom: 3px;
}
.card-sub {
font-size: 11px;
color: rgba(255, 255, 255, 0.36);
}
.steps-wrap { padding: 20px 26px 0; }
.steps-row { display: flex; align-items: center; }
.step-dot {
width: 26px; height: 26px; border-radius: 50%;
border: 2px solid rgba(255,255,255,0.18);
display: flex; align-items: center; justify-content: center;
font-size: 10.5px; font-weight: 700;
color: rgba(255,255,255,0.22);
flex-shrink: 0;
transition: border-color .25s, background .25s, color .25s;
position: relative;
}
.step-dot.active { border-color: #de3c19; color: #de3c19; }
.step-dot.done { border-color: #de3c19; background: #de3c19; color: transparent; }
.step-dot.done::after {
content: '';
position: absolute;
width: 10px; height: 10px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='white' stroke-width='3' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M4.5 12.75l6 6 9-13.5'/%3E%3C/svg%3E") center/contain no-repeat;
}
.step-line {
flex: 1; height: 1px;
background: rgba(255,255,255,0.1);
margin: 0 7px;
transition: background .3s;
}
.step-line.done { background: #de3c19; }
.step-labels {
display: flex; justify-content: space-between;
padding: 5px 0 0;
}
.step-lbl {
font-size: 8.5px; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.08em;
color: rgba(255,255,255,0.22);
transition: color .25s;
}
.step-lbl.active, .step-lbl.done { color: rgba(255,255,255,0.55); }
.form-body { padding: 22px 26px 6px; display: none; }
.form-body.active { display: block; }
.step-h { font-size: 14.5px; font-weight: 600; color: #fff; margin-bottom: 3px; }
.step-p { font-size: 11px; color: rgba(255,255,255,0.36); margin-bottom: 18px; line-height: 1.5; }
.field { margin-bottom: 14px; }
.field:last-child { margin-bottom: 0; }
label {
display: block;
font-size: 9.5px; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.1em;
color: rgba(255,255,255,0.45);
margin-bottom: 5px;
}
.req { color: #de3c19; }
input, select, textarea {
width: 100%;
background: rgba(255,255,255,0.045);
border: 1px solid rgba(255,255,255,0.11);
border-radius: 9px;
padding: 10px 13px;
font-size: 13px;
color: #fff;
font-family: inherit;
outline: none;
transition: border-color .2s, box-shadow .2s;
-webkit-appearance: none;
appearance: none;
color-scheme: dark;
}
input::placeholder, textarea::placeholder { color: rgba(255,255,255,0.22); }
input:focus, select:focus, textarea:focus {
border-color: #de3c19;
box-shadow: 0 0 0 3px rgba(222,60,25,0.14);
}
select option { background: #1a0f0a; color: #fff; }
textarea { resize: none; line-height: 1.5; }
.row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
@media (max-width: 380px) { .row-2 { grid-template-columns: 1fr; } }
.summary {
background: rgba(255,255,255,0.035);
border: 1px solid rgba(255,255,255,0.09);
border-radius: 9px;
padding: 13px 14px;
margin-bottom: 14px;
}
.summary-ttl {
font-size: 8.5px; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.1em;
color: rgba(255,255,255,0.3);
margin-bottom: 9px;
}
.s-row { display: flex; gap: 8px; font-size: 12px; margin-bottom: 5px; }
.s-row:last-child { margin-bottom: 0; }
.s-key { color: rgba(255,255,255,0.32); min-width: 68px; flex-shrink: 0; }
.s-val { color: #fff; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rgpd-row {
display: flex; align-items: flex-start; gap: 10px;
cursor: pointer; margin-bottom: 0;
}
.rgpd-box {
width: 15px; height: 15px;
border: 2px solid rgba(255,255,255,0.28);
border-radius: 4px;
background: transparent;
flex-shrink: 0; margin-top: 1px;
display: flex; align-items: center; justify-content: center;
transition: all .2s; cursor: pointer;
position: relative;
}
.rgpd-box.on { background: #de3c19; border-color: #de3c19; }
.rgpd-box.on::after {
content: '';
position: absolute;
width: 9px; height: 9px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='white' stroke-width='3' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M4.5 12.75l6 6 9-13.5'/%3E%3C/svg%3E") center/contain no-repeat;
}
.rgpd-txt { font-size: 11px; color: rgba(255,255,255,0.38); line-height: 1.5; }
.rgpd-txt a { color: #de3c19; text-underline-offset: 2px; }
.err-box {
margin: 0 26px 8px;
background: rgba(239,68,68,0.1);
border: 1px solid rgba(239,68,68,0.28);
border-radius: 9px;
padding: 10px 13px;
font-size: 11.5px;
color: #fca5a5;
line-height: 1.5;
display: none;
}
.err-box.show { display: block; }
.nav {
padding: 16px 26px 22px;
border-top: 1px solid rgba(255,255,255,0.07);
display: flex; align-items: center; justify-content: space-between;
}
.counter { font-size: 10.5px; color: rgba(255,255,255,0.2); }
.btn-back {
display: flex; align-items: center; gap: 5px;
font-size: 12.5px; font-weight: 500;
color: rgba(255,255,255,0.4);
background: none; border: none; cursor: pointer;
font-family: inherit; padding: 0;
transition: color .2s;
}
.btn-back:hover:not(:disabled) { color: #fff; }
.btn-back:disabled { opacity: 0; pointer-events: none; }
.btn-next {
display: flex; align-items: center; gap: 7px;
background: #de3c19; color: #fff;
font-size: 12.5px; font-weight: 700;
padding: 9px 20px;
border: none; border-radius: 9px;
cursor: pointer; font-family: inherit;
transition: background .2s, opacity .2s;
}
.btn-next:hover:not(:disabled) { background: #f04824; }
.btn-next:disabled { opacity: 0.32; cursor: not-allowed; }
@keyframes _spin { to { transform: rotate(360deg); } }
.spin {
width: 14px; height: 14px;
border: 2px solid rgba(255,255,255,0.3);
border-top-color: #fff; border-radius: 50%;
animation: _spin .75s linear infinite;
display: none;
}
.success-screen {
display: none;
padding: 44px 26px;
text-align: center;
}
.ok-icon {
width: 52px; height: 52px; border-radius: 50%;
background: rgba(34,197,94,0.13);
display: flex; align-items: center; justify-content: center;
margin: 0 auto 18px;
}
.ok-title { font-size: 19px; font-weight: 700; color: #fff; margin-bottom: 9px; }
.ok-text { font-size: 12.5px; color: rgba(255,255,255,0.46); line-height: 1.65; margin-bottom: 22px; }
.ok-text strong { color: #fff; }
.btn-again {
font-size: 11.5px; color: #de3c19;
background: none; border: none; cursor: pointer;
text-decoration: underline; text-underline-offset: 2px;
font-family: inherit; transition: color .2s;
}
.btn-again:hover { color: #f04824; }
.foot {
text-align: center;
padding: 0 26px 18px;
font-size: 9.5px;
color: rgba(255,255,255,0.16);
}
</style>
</head>
<body>
<div class="card">
<div id="fs">
<div class="card-header">
<p class="brand-tag">MAH LDA — Reparação Eletrónica Industrial</p>
<h1 class="card-title">Pedido de Diagnóstico Gratuito</h1>
<p class="card-sub">Orçamento em 24h · Sem compromisso · RGPD</p>
</div>
<div class="steps-wrap">
<div class="steps-row">
<div class="step-dot" id="d0"><span>1</span></div>
<div class="step-line" id="l0"></div>
<div class="step-dot" id="d1"><span>2</span></div>
<div class="step-line" id="l1"></div>
<div class="step-dot" id="d2"><span>3</span></div>
</div>
<div class="step-labels">
<span class="step-lbl" id="lb0">Identificação</span>
<span class="step-lbl" id="lb1">Equipamento</span>
<span class="step-lbl" id="lb2">Contacto</span>
</div>
</div>
<!-- STEP 0 — Identificação -->
<div class="form-body" id="s0">
<p class="step-h">Quem é o responsável?</p>
<p class="step-p">Interlocutor técnico ou gestor de manutenção.</p>
<div class="field">
<label>Nome <span class="req">*</span></label>
<input id="nome" type="text" placeholder="Ex: Manuel Vieira" autocomplete="name" />
</div>
<div class="field">
<label>Empresa <span class="req">*</span></label>
<input id="empresa" type="text" placeholder="Ex: Têxtil Norte, SA" autocomplete="organization" />
</div>
<div class="field">
<label>Setor de Atividade</label>
<select id="setor">
<option value="">Selecione o setor...</option>
<option>Alimentar & Bebidas</option>
<option>Automóvel & Metalomecânica</option>
<option>Cerâmica & Vidro</option>
<option>Construção Civil</option>
<option>Farmacêutico & Saúde</option>
<option>Madeira & Mobiliário</option>
<option>Papel & Embalagem</option>
<option>Plástico & Borracha</option>
<option>Químico & Petroquímico</option>
<option>Têxtil & Vestuário</option>
<option>Outro</option>
</select>
</div>
</div>
<!-- STEP 1 — Equipamento -->
<div class="form-body" id="s1">
<p class="step-h">Qual o equipamento avariado?</p>
<p class="step-p">Mais detalhe = diagnóstico mais rápido e preciso.</p>
<div class="row-2">
<div class="field">
<label>Marca <span class="req">*</span></label>
<input id="marca" type="text" placeholder="Ex: Siemens, ABB" />
</div>
<div class="field">
<label>Modelo <span class="req">*</span></label>
<input id="modelo" type="text" placeholder="Ex: S7-300, ACS880" />
</div>
</div>
<div class="field">
<label>Tipo de Equipamento</label>
<select id="tipo">
<option value="">Selecione o tipo...</option>
<option>PLC / Autómato</option>
<option>Variador de Frequência / Inversor</option>
<option>Servo Drive / Servo Motor</option>
<option>HMI / Painel de Operador</option>
<option>Placa Eletrónica Industrial</option>
<option>Fonte de Alimentação Industrial</option>
<option>Robô Industrial</option>
<option>Outro</option>
</select>
</div>
<div class="field">
<label>Descrição da Avaria</label>
<textarea id="avaria" rows="3" placeholder="Sintomas: alarmes, códigos de erro, comportamento anormal..."></textarea>
</div>
</div>
<!-- STEP 2 — Contacto -->
<div class="form-body" id="s2">
<p class="step-h">Como podemos contactá-lo?</p>
<p class="step-p">Preencha pelo menos um dos campos abaixo.</p>
<div class="field">
<label>Telefone / WhatsApp</label>
<input id="tel" type="tel" placeholder="+351 912 000 000" autocomplete="tel" />
</div>
<div class="field">
<label>E-mail Profissional</label>
<input id="email" type="email" placeholder="engenharia@empresa.pt" autocomplete="email" />
</div>
<div class="summary">
<p class="summary-ttl">Resumo do pedido</p>
<div class="s-row"><span class="s-key">Responsável</span><span class="s-val" id="r-nome">—</span></div>
<div class="s-row"><span class="s-key">Empresa</span><span class="s-val" id="r-empresa">—</span></div>
<div class="s-row" id="r-setor-row" style="display:none"><span class="s-key">Setor</span><span class="s-val" id="r-setor">—</span></div>
<div class="s-row"><span class="s-key">Marca</span><span class="s-val" id="r-marca">—</span></div>
<div class="s-row"><span class="s-key">Modelo</span><span class="s-val" id="r-modelo">—</span></div>
</div>
<div class="rgpd-row" onclick="toggleRgpd()">
<div class="rgpd-box" id="rgpd"></div>
<span class="rgpd-txt">
Concordo com o tratamento dos meus dados para resposta a este pedido,
conforme a <a href="#" onclick="return false">Política de Privacidade</a> e o RGPD.
<span class="req">*</span>
</span>
</div>
</div>
<div class="err-box" id="err"></div>
<div class="nav">
<button class="btn-back" id="bk" onclick="prev()" disabled>
<svg width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5"/>
</svg>
Anterior
</button>
<span class="counter" id="ctr">Passo 1 de 3</span>
<button class="btn-next" id="nx" onclick="next()" disabled>
<span id="nlbl">Seguinte</span>
<div class="spin" id="spin"></div>
<svg id="nico" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/>
</svg>
</button>
</div>
</div>
<div class="success-screen" id="ss">
<div class="ok-icon">
<svg width="26" height="26" fill="none" stroke="#4ade80" stroke-width="2.5" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
</svg>
</div>
<p class="ok-title">Pedido Recebido!</p>
<p class="ok-text">
A nossa equipa técnica vai analisar o seu pedido<br>
e entrar em contacto em menos de <strong>24 horas</strong>.
</p>
<button class="btn-again" onclick="reset()">Enviar novo pedido</button>
</div>
<div class="foot">mah.pt · info@mah.pt · RGPD</div>
</div>
<script>
/*
* SETUP — substitua os dois valores abaixo:
* JOTFORM_KEY → jotform.com > Conta > API > Criar API Key
* JOTFORM_ID → número no URL do seu form: jotform.com/build/[ID AQUI]
*/
const JOTFORM_KEY = 'YOUR_API_KEY_HERE';
const JOTFORM_ID = 'YOUR_FORM_ID_HERE';
/*
* FIELDS — mapeie com os IDs reais das perguntas do seu form Jotform.
* No Jotform: Build > clique direito em campo > Properties > ver Question ID.
* Exemplo: se "Nome" tem ID 3 → 'submission[q3_nome]'
*/
const FIELDS = {
nome: 'submission[q1_nome]',
empresa: 'submission[q2_empresa]',
setor: 'submission[q3_setor]',
marca: 'submission[q4_marca]',
modelo: 'submission[q5_modelo]',
tipo: 'submission[q6_tipo]',
avaria: 'submission[q7_descricao]',
telefone: 'submission[q8_telefone]',
email: 'submission[q9_email]',
};
const g = (id) => document.getElementById(id);
const v = (id) => g(id).value.trim();
let step = 0;
let rgpd = false;
function canGo() {
if (step === 0) return v('nome') && v('empresa');
if (step === 1) return v('marca') && v('modelo');
if (step === 2) return (v('tel') || v('email')) && rgpd;
return false;
}
function tick() { g('nx').disabled = !canGo(); }
['nome','empresa','setor','marca','modelo','tipo','avaria','tel','email'].forEach(id => {
g(id).addEventListener('input', tick);
});
function toggleRgpd() {
rgpd = !rgpd;
g('rgpd').classList.toggle('on', rgpd);
tick();
}
function render() {
for (let i = 0; i < 3; i++) {
g('s' + i).classList.toggle('active', i === step);
const d = g('d' + i);
d.classList.remove('active', 'done');
if (i < step) d.classList.add('done');
else if (i === step) d.classList.add('active');
const ln = g('l' + i);
if (ln) ln.classList.toggle('done', i < step);
const lb = g('lb' + i);
lb.classList.remove('active', 'done');
if (i < step) lb.classList.add('done');
else if (i === step) lb.classList.add('active');
}
g('bk').disabled = step === 0;
g('ctr').textContent = 'Passo ' + (step + 1) + ' de 3';
if (step === 2) {
g('nlbl').textContent = 'Enviar Pedido';
g('nico').innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"/>';
fillSummary();
} else {
g('nlbl').textContent = 'Seguinte';
g('nico').innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/>';
}
tick();
hideErr();
}
function fillSummary() {
g('r-nome').textContent = v('nome') || '—';
g('r-empresa').textContent = v('empresa') || '—';
g('r-marca').textContent = v('marca') || '—';
g('r-modelo').textContent = v('modelo') || '—';
const st = v('setor');
if (st) { g('r-setor').textContent = st; g('r-setor-row').style.display = 'flex'; }
else { g('r-setor-row').style.display = 'none'; }
}
function next() {
if (!canGo()) return;
if (step < 2) { step++; render(); }
else submit();
}
function prev() {
if (step > 0) { step--; render(); }
}
function showErr(m) { g('err').textContent = m; g('err').classList.add('show'); }
function hideErr() { g('err').classList.remove('show'); }
function setLoading(on) {
g('nx').disabled = on;
g('bk').disabled = on;
g('spin').style.display = on ? 'inline-block' : 'none';
g('nico').style.display = on ? 'none' : 'inline';
g('nlbl').textContent = on ? 'A enviar...' : 'Enviar Pedido';
}
async function submit() {
if (!canGo()) return;
setLoading(true);
hideErr();
const body = new URLSearchParams();
body.append(FIELDS.nome, v('nome'));
body.append(FIELDS.empresa, v('empresa'));
body.append(FIELDS.setor, v('setor'));
body.append(FIELDS.marca, v('marca'));
body.append(FIELDS.modelo, v('modelo'));
body.append(FIELDS.tipo, v('tipo'));
body.append(FIELDS.avaria, v('avaria'));
body.append(FIELDS.telefone, v('tel'));
body.append(FIELDS.email, v('email'));
const url = 'https://api.jotform.com/form/' + JOTFORM_ID + '/submissions?apiKey=' + JOTFORM_KEY;
try {
const res = await fetch(url, { method: 'POST', body });
const json = await res.json();
if (json.responseCode === 200 || json.responseCode === 201) {
showSuccess();
} else {
showErr('Erro ao enviar: ' + (json.message || 'Tente novamente.'));
}
} catch {
showErr('Sem ligação. Verifique a sua internet e tente novamente.');
} finally {
setLoading(false);
}
}
function showSuccess() {
g('fs').style.display = 'none';
g('ss').style.display = 'block';
}
function reset() {
step = 0; rgpd = false;
['nome','empresa','marca','modelo','avaria','tel','email'].forEach(id => g(id).value = '');
['setor','tipo'].forEach(id => g(id).selectedIndex = 0);
g('rgpd').classList.remove('on');
g('fs').style.display = '';
g('ss').style.display = 'none';
render();
}
render();
</script>
</body>
</html>Antes de colar no Carrd, substitui apenas estas duas linhas:
const JOTFORM_KEY = 'SUA_API_KEY_AQUI';
const JOTFORM_ID = 'SEU_FORM_ID_AQUI';No Carrd Pro: + Add Element → Embed → Code → cola o HTML acima → Guardar.
O problema é o min-height: 100vh no body e o display: flex; align-items: center; justify-content: center — no Carrd isso força o embed a ocupar a altura total do ecrã, sobrepondo-se a tudo. Vou reescrever o código removendo qualquer altura forçada e posicionamento absoluto.
O problema está nas linhas 17-23: body tem display: flex, align-items: center, justify-content: center e min-height: 100vh. No Carrd isso força o embed a ocupar a altura total do ecrã sobrepondo tudo. Vou corrigir agora.
Agora aqui está o código completo e corrigido para colar diretamente no Carrd. Copia tudo a partir daqui:
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
background: transparent !important;
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
-webkit-font-smoothing: antialiased;
width: 100%;
}
.card {
width: 100%;
background: transparent;
border: 1.5px solid #de3c19;
border-radius: 18px;
overflow: hidden;
box-shadow: 0 0 40px rgba(222,60,25,0.12);
}
.card-header {
padding: 22px 22px 16px;
border-bottom: 1px solid rgba(222,60,25,0.22);
}
.brand-tag {
font-size: 9px; font-weight: 700;
letter-spacing: 0.13em; text-transform: uppercase;
color: #de3c19; margin-bottom: 6px;
}
.card-title { font-size: 17px; font-weight: 700; color: #fff; line-height: 1.3; margin-bottom: 3px; }
.card-sub { font-size: 10.5px; color: rgba(255,255,255,0.32); }
.steps-wrap { padding: 18px 22px 0; }
.steps-row { display: flex; align-items: center; }
.step-dot {
width: 24px; height: 24px; border-radius: 50%;
border: 2px solid rgba(255,255,255,0.15);
display: flex; align-items: center; justify-content: center;
font-size: 10px; font-weight: 700; color: rgba(255,255,255,0.20);
flex-shrink: 0; position: relative;
transition: border-color .25s, background .25s, color .25s;
}
.step-dot.active { border-color: #de3c19; color: #de3c19; }
.step-dot.done { border-color: #de3c19; background: #de3c19; color: transparent; }
.step-dot.done::after {
content: ''; position: absolute; width: 10px; height: 10px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='white' stroke-width='3' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M4.5 12.75l6 6 9-13.5'/%3E%3C/svg%3E") center/contain no-repeat;
}
.step-line { flex: 1; height: 1px; background: rgba(255,255,255,0.08); margin: 0 6px; transition: background .3s; }
.step-line.done { background: #de3c19; }
.step-labels { display: flex; justify-content: space-between; padding: 5px 0 0; }
.step-lbl { font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: rgba(255,255,255,0.18); transition: color .25s; }
.step-lbl.active, .step-lbl.done { color: rgba(255,255,255,0.50); }
.form-body { padding: 18px 22px 4px; display: none; }
.form-body.active { display: block; }
.step-h { font-size: 13.5px; font-weight: 600; color: #fff; margin-bottom: 2px; }
.step-p { font-size: 10.5px; color: rgba(255,255,255,0.32); margin-bottom: 14px; line-height: 1.5; }
.field { margin-bottom: 12px; }
.field:last-child { margin-bottom: 0; }
label { display: block; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.10em; color: rgba(255,255,255,0.40); margin-bottom: 5px; }
.req { color: #de3c19; }
input, select, textarea {
width: 100%; background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.10); border-radius: 8px;
padding: 9px 11px; font-size: 12.5px; color: #fff; font-family: inherit;
outline: none; transition: border-color .2s, box-shadow .2s;
-webkit-appearance: none; appearance: none; color-scheme: dark;
}
input::placeholder, textarea::placeholder { color: rgba(255,255,255,0.20); }
input:focus, select:focus, textarea:focus { border-color: #de3c19; box-shadow: 0 0 0 3px rgba(222,60,25,0.12); }
select option { background: #1a0a06; color: #fff; }
textarea { resize: none; line-height: 1.5; }
.row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 360px) { .row-2 { grid-template-columns: 1fr; } }
.summary { background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); border-radius: 8px; padding: 11px 13px; margin-bottom: 12px; }
.summary-ttl { font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.10em; color: rgba(255,255,255,0.25); margin-bottom: 8px; }
.s-row { display: flex; gap: 8px; font-size: 11.5px; margin-bottom: 4px; }
.s-row:last-child { margin-bottom: 0; }
.s-key { color: rgba(255,255,255,0.28); min-width: 62px; flex-shrink: 0; }
.s-val { color: #fff; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rgpd-row { display: flex; align-items: flex-start; gap: 9px; cursor: pointer; }
.rgpd-box { width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.25); border-radius: 3px; background: transparent; flex-shrink: 0; margin-top: 1px; display: flex; align-items: center; justify-content: center; transition: all .2s; position: relative; }
.rgpd-box.on { background: #de3c19; border-color: #de3c19; }
.rgpd-box.on::after { content: ''; position: absolute; width: 8px; height: 8px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='white' stroke-width='3' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M4.5 12.75l6 6 9-13.5'/%3E%3C/svg%3E") center/contain no-repeat; }
.rgpd-txt { font-size: 10.5px; color: rgba(255,255,255,0.34); line-height: 1.5; }
.rgpd-txt a { color: #de3c19; }
.err-box { margin: 4px 22px 0; background: rgba(239,68,68,0.10); border: 1px solid rgba(239,68,68,0.25); border-radius: 8px; padding: 9px 12px; font-size: 11px; color: #fca5a5; line-height: 1.5; display: none; }
.err-box.show { display: block; }
.nav { padding: 14px 22px 18px; border-top: 1px solid rgba(255,255,255,0.06); display: flex; align-items: center; justify-content: space-between; margin-top: 14px; }
.counter { font-size: 10px; color: rgba(255,255,255,0.18); }
.btn-back { display: flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 500; color: rgba(255,255,255,0.36); background: none; border: none; cursor: pointer; font-family: inherit; padding: 0; transition: color .2s; }
.btn-back:hover:not(:disabled) { color: #fff; }
.btn-back:disabled { opacity: 0; pointer-events: none; }
.btn-next { display: flex; align-items: center; gap: 6px; background: #de3c19; color: #fff; font-size: 12px; font-weight: 700; padding: 8px 18px; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; transition: background .2s, opacity .2s; white-space: nowrap; }
.btn-next:hover:not(:disabled) { background: #f04824; }
.btn-next:disabled { opacity: 0.30; cursor: not-allowed; }
@keyframes _spin { to { transform: rotate(360deg); } }
.spin { width: 13px; height: 13px; border: 2px solid rgba(255,255,255,0.28); border-top-color: #fff; border-radius: 50%; animation: _spin .75s linear infinite; display: none; flex-shrink: 0; }
.success-screen { display: none; padding: 38px 22px 30px; text-align: center; }
.ok-icon { width: 48px; height: 48px; border-radius: 50%; background: rgba(34,197,94,0.12); display: flex; align-items: center; justify-content: center; margin: 0 auto 16px; }
.ok-title { font-size: 17px; font-weight: 700; color: #fff; margin-bottom: 8px; }
.ok-text { font-size: 12px; color: rgba(255,255,255,0.42); line-height: 1.65; margin-bottom: 20px; }
.ok-text strong { color: #fff; }
.btn-again { font-size: 11px; color: #de3c19; background: none; border: none; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; font-family: inherit; }
.btn-again:hover { color: #f04824; }
.foot { text-align: center; padding: 0 22px 14px; font-size: 9px; color: rgba(255,255,255,0.14); }
</style>
</head>
<body>
<div class="card">
<div id="fs">
<div class="card-header">
<p class="brand-tag">MAH LDA — Reparação Eletrónica Industrial</p>
<h1 class="card-title">Pedido de Diagnóstico Gratuito</h1>
<p class="card-sub">Orçamento em 24h · Sem compromisso · RGPD</p>
</div>
<div class="steps-wrap">
<div class="steps-row">
<div class="step-dot" id="d0"><span>1</span></div>
<div class="step-line" id="l0"></div>
<div class="step-dot" id="d1"><span>2</span></div>
<div class="step-line" id="l1"></div>
<div class="step-dot" id="d2"><span>3</span></div>
</div>
<div class="step-labels">
<span class="step-lbl" id="lb0">Identificação</span>
<span class="step-lbl" id="lb1">Equipamento</span>
<span class="step-lbl" id="lb2">Contacto</span>
</div>
</div>
<div class="form-body" id="s0">
<p class="step-h">Quem é o responsável?</p>
<p class="step-p">Interlocutor técnico ou gestor de manutenção.</p>
<div class="field"><label>Nome <span class="req">*</span></label><input id="nome" type="text" placeholder="Ex: Manuel Vieira" autocomplete="name" /></div>
<div class="field"><label>Empresa <span class="req">*</span></label><input id="empresa" type="text" placeholder="Ex: Têxtil Norte, SA" autocomplete="organization" /></div>
<div class="field">
<label>Setor de Atividade</label>
<select id="setor">
<option value="">Selecione o setor...</option>
<option>Alimentar & Bebidas</option><option>Automóvel & Metalomecânica</option>
<option>Cerâmica & Vidro</option><option>Construção Civil</option>
<option>Farmacêutico & Saúde</option><option>Madeira & Mobiliário</option>
<option>Papel & Embalagem</option><option>Plástico & Borracha</option>
<option>Químico & Petroquímico</option><option>Têxtil & Vestuário</option>
<option>Outro</option>
</select>
</div>
</div>
<div class="form-body" id="s1">
<p class="step-h">Qual o equipamento avariado?</p>
<p class="step-p">Mais detalhe = diagnóstico mais rápido e preciso.</p>
<div class="row-2">
<div class="field"><label>Marca <span class="req">*</span></label><input id="marca" type="text" placeholder="Ex: Siemens, ABB" /></div>
<div class="field"><label>Modelo <span class="req">*</span></label><input id="modelo" type="text" placeholder="Ex: S7-300, ACS880" /></div>
</div>
<div class="field">
<label>Tipo de Equipamento</label>
<select id="tipo">
<option value="">Selecione o tipo...</option>
<option>PLC / Autómato</option><option>Variador de Frequência / Inversor</option>
<option>Servo Drive / Servo Motor</option><option>HMI / Painel de Operador</option>
<option>Placa Eletrónica Industrial</option><option>Fonte de Alimentação Industrial</option>
<option>Robô Industrial</option><option>Outro</option>
</select>
</div>
<div class="field"><label>Descrição da Avaria</label><textarea id="avaria" rows="3" placeholder="Sintomas: alarmes, códigos de erro, comportamento anormal..."></textarea></div>
</div>
<div class="form-body" id="s2">
<p class="step-h">Como podemos contactá-lo?</p>
<p class="step-p">Preencha pelo menos um dos campos abaixo.</p>
<div class="field"><label>Telefone / WhatsApp</label><input id="tel" type="tel" placeholder="+351 912 000 000" autocomplete="tel" /></div>
<div class="field"><label>E-mail Profissional</label><input id="email" type="email" placeholder="engenharia@empresa.pt" autocomplete="email" /></div>
<div class="summary">
<p class="summary-ttl">Resumo do pedido</p>
<div class="s-row"><span class="s-key">Responsável</span><span class="s-val" id="r-nome">—</span></div>
<div class="s-row"><span class="s-key">Empresa</span><span class="s-val" id="r-empresa">—</span></div>
<div class="s-row" id="r-setor-row" style="display:none"><span class="s-key">Setor</span><span class="s-val" id="r-setor">—</span></div>
<div class="s-row"><span class="s-key">Marca</span><span class="s-val" id="r-marca">—</span></div>
<div class="s-row"><span class="s-key">Modelo</span><span class="s-val" id="r-modelo">—</span></div>
</div>
<div class="rgpd-row" onclick="toggleRgpd()">
<div class="rgpd-box" id="rgpd-chk"></div>
<span class="rgpd-txt">Concordo com o tratamento dos meus dados para resposta a este pedido, conforme a <a href="#" onclick="return false">Política de Privacidade</a> e o RGPD. <span class="req">*</span></span>
</div>
</div>
<div class="err-box" id="err"></div>
<div class="nav">
<button class="btn-back" id="bk" onclick="prev()" disabled>
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5"/></svg>
Anterior
</button>
<span class="counter" id="ctr">Passo 1 de 3</span>
<button class="btn-next" id="nx" onclick="next()" disabled>
<span id="nlbl">Seguinte</span>
<div class="spin" id="spin"></div>
<svg id="nico" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
</button>
</div>
</div>
<div class="success-screen" id="ss">
<div class="ok-icon"><svg width="24" height="24" fill="none" stroke="#4ade80" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg></div>
<p class="ok-title">Pedido Recebido!</p>
<p class="ok-text">A nossa equipa técnica vai analisar o seu pedido<br>e entrar em contacto em menos de <strong>24 horas</strong>.</p>
<button class="btn-again" onclick="reset()">Enviar novo pedido</button>
</div>
<div class="foot">mah.pt · info@mah.pt · RGPD</div>
</div>
<script>
// ── CONFIGURAÇÃO ── Substitua os dois valores abaixo ──────────────────────────
var JOTFORM_KEY = 'YOUR_API_KEY_HERE'; // jotform.com > Conta > API > Criar Key
var JOTFORM_ID = 'YOUR_FORM_ID_HERE'; // número no URL: jotform.com/build/[ID]
// Mapeamento de campos: ajuste os IDs (q1, q2...) com os da sua form Jotform
// Build > clique direito num campo > Properties > Question ID
var FIELDS = {
nome: 'submission[q1_nome]',
empresa: 'submission[q2_empresa]',
setor: 'submission[q3_setor]',
marca: 'submission[q4_marca]',
modelo: 'submission[q5_modelo]',
tipo: 'submission[q6_tipo]',
avaria: 'submission[q7_descricao]',
tel: 'submission[q8_telefone]',
email: 'submission[q9_email]'
};
// ─────────────────────────────────────────────────────────────────────────────
var step = 0, rgpd = false;
function g(id) { return document.getElementById(id); }
function v(id) { return g(id).value.trim(); }
function canGo() {
if (step===0) return v('nome') && v('empresa');
if (step===1) return v('marca') && v('modelo');
if (step===2) return (v('tel') || v('email')) && rgpd;
}
function tick() { g('nx').disabled = !canGo(); }
['nome','empresa','setor','marca','modelo','tipo','avaria','tel','email'].forEach(function(id){
g(id).addEventListener('input', tick);
});
function toggleRgpd() {
rgpd = !rgpd;
g('rgpd-chk').classList.toggle('on', rgpd);
tick();
}
function render() {
for (var i=0; i<3; i++) {
g('s'+i).classList.toggle('active', i===step);
var d=g('d'+i); d.classList.remove('active','done');
if (i<step) d.classList.add('done'); else if(i===step) d.classList.add('active');
var ln=g('l'+i); if(ln) ln.classList.toggle('done', i<step);
var lb=g('lb'+i); lb.classList.remove('active','done');
if (i<step) lb.classList.add('done'); else if(i===step) lb.classList.add('active');
}
g('bk').disabled = step===0;
g('ctr').textContent = 'Passo '+(step+1)+' de 3';
if (step===2) {
g('nlbl').textContent='Enviar Pedido';
g('nico').innerHTML='<path stroke-linecap="round" stroke-linejoin="round" d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"/>';
var sn=v('setor');
g('r-nome').textContent=v('nome')||'—'; g('r-empresa').textContent=v('empresa')||'—';
g('r-marca').textContent=v('marca')||'—'; g('r-modelo').textContent=v('modelo')||'—';
if(sn){g('r-setor').textContent=sn;g('r-setor-row').style.display='flex';}
else{g('r-setor-row').style.display='none';}
} else {
g('nlbl').textContent='Seguinte';
g('nico').innerHTML='<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/>';
}
tick();
g('err').classList.remove('show');
}
function next() { if(!canGo()) return; if(step<2){step++;render();} else submit(); }
function prev() { if(step>0){step--;render();} }
function setLoading(on) {
g('nx').disabled=on; g('bk').disabled=on;
g('spin').style.display=on?'inline-block':'none';
g('nico').style.display=on?'none':'inline';
g('nlbl').textContent=on?'A enviar...':'Enviar Pedido';
}
function submit() {
setLoading(true);
g('err').classList.remove('show');
var body=new URLSearchParams();
body.append(FIELDS.nome,v('nome')); body.append(FIELDS.empresa,v('empresa'));
body.append(FIELDS.setor,v('setor')); body.append(FIELDS.marca,v('marca'));
body.append(FIELDS.modelo,v('modelo')); body.append(FIELDS.tipo,v('tipo'));
body.append(FIELDS.avaria,v('avaria')); body.append(FIELDS.tel,v('tel'));
body.append(FIELDS.email,v('email'));
fetch('https://api.jotform.com/form/'+JOTFORM_ID+'/submissions?apiKey='+JOTFORM_KEY,{method:'POST',body:body})
.then(function(r){return r.json();})
.then(function(j){
if(j.responseCode===200||j.responseCode===201){
g('fs').style.display='none'; g('ss').style.display='block';
} else {
g('err').textContent='Erro: '+(j.message||'Tente novamente.');
g('err').classList.add('show');
}
})
.catch(function(){ g('err').textContent='Sem ligação. Tente novamente.'; g('err').classList.add('show'); })
.finally(function(){setLoading(false);});
}
function reset() {
step=0; rgpd=false;
['nome','empresa','marca','modelo','avaria','tel','email'].forEach(function(id){g(id).value='';});
['setor','tipo'].forEach(function(id){g(id).selectedIndex=0;});
g('rgpd-chk').classList.remove('on');
g('fs').style.display=''; g('ss').style.display='none';
render();
}
render();
</script>
</body>
</html>O que foi corrigido: removido display: flex, align-items: center, justify-content: center e min-height: 100vh do body — eram a causa directa da sobreposição no Carrd. O formulário agora ocupa apenas o espaço do seu próprio conteúdo e adapta-se ao container do Carrd.
Lembra-te de substituir YOUR_API_KEY_HERE e YOUR_FORM_ID_HERE antes de colar no Carrd.
You can send messages while the preview loads