<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>FixForward.xyz — Natalie Van Der Westhuizen WITH N</title><style>body{font-family:system-ui,sans-serif;background:#F5F1E8;color:#1E201B;margin:0;padding:16px;line-height:1.6}.card{background:#fff;border:1px solid #E2DDD0;border-radius:20px;padding:20px;max-width:800px;margin:16px auto;box-shadow:0 10px 30px rgba(0,0,0,.06)}h1{font-size:28px}input,select,textarea{width:100%;padding:12px;border-radius:12px;border:1px solid #E2DDD0;font-size:14px;margin:6px 0 10px;box-sizing:border-box}button.btn{background:#5A6B3A;color:#F5F1E8;border:0;padding:12px 20px;border-radius:999px;font-weight:700}label{font-size:11px;font-weight:700;text-transform:uppercase;color:#6B6E68;display:block;margin-top:8px}</style></head><body><div class="card"><h1>FixForward.xyz</h1><p><strong>Natalie Van Der Westhuizen WITH N</strong> — Johannesburg, Gauteng — POPIA Compliant</p><p>Virtual admin support — ad-hoc per hour, once-off clear-outs, FREE 1-Hour Admin Health Check (3 spots left)</p><h3 style="margin-top:16px">Send a message — replies from natalie@fixforward.xyz</h3><p style="font-size:13px;color:#6B6E68">Fixed: blocks test@com, works for fixforward.xyz + www, keeps typing if fails.</p><form id="f"><label>Name *</label><input required name="name" id="n" placeholder="Natalie"><label>Company</label><input name="company" id="c" placeholder="Optional"><label>Email *</label><input required type="email" name="email" id="e" placeholder="you@company.co.za"><label>Phone</label><input name="phone" id="p" placeholder="Optional"><label>Service *</label><select required name="service" id="s"><option value="">Select</option><option>Ad-hoc per hour</option><option>Once-off clear-out</option><option>FREE Health Check</option></select><label>Message *</label><textarea required name="message" id="m" rows="4" placeholder="Tell me about your admin pile..."></textarea><div style="margin-top:12px"><button type="submit" id="b" class="btn">Send message →</button> <span id="st" style="font-size:13px"></span></div></form></div><script>(function(){const ids=['n','c','e','p','s','m'];const K='ff_form';function save(){const d={};ids.forEach(id=>{const el=document.getElementById(id);if(el)d[id]=el.value});localStorage.setItem(K,JSON.stringify(d))}function load(){try{const r=localStorage.getItem(K);if(!r)return;const data=JSON.parse(r);ids.forEach(id=>{if(data[id]!==undefined){const el=document.getElementById(id);if(el)el.value=data[id]}})}catch(e){}}load();ids.forEach(id=>{const el=document.getElementById(id);if(el)el.addEventListener('input',save)});function validEmail(v){if(!v)return false;v=v.trim();if(v.length<6||v.length>254)return false;const re=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;if(!re.test(v))return false;if(v.includes('..'))return false;if(v.split('@')[1].split('.').some(x=>x.length<2))return false;return true}const form=document.getElementById('f');const st=document.getElementById('st');const b=document.getElementById('b');form.addEventListener('submit',async(e)=>{e.preventDefault();const fd=new FormData(form);const p=Object.fromEntries(fd.entries());if(!p.name||p.name.trim().length<2){st.textContent='Name min 2 chars';return}if(!validEmail(p.email)){st.textContent='Use real email like you@company.co.za';return}if(!p.service){st.textContent='Select service';return}if(!p.message||p.message.trim().length<10){st.textContent='Message min 10 chars';return}b.disabled=true;b.textContent='Sending...';try{const r=await fetch('/api/contact',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(p)});const d=await r.json();if(!r.ok||!d.ok)throw new Error(d.error||'Rejected');st.textContent='✓ Sent! I will reply from natalie@fixforward.xyz';localStorage.removeItem(K);form.reset()}catch(err){st.textContent='✗ '+err.message+' — your typing is saved';}finally{b.disabled=false;b.textContent='Send message →'}})})();</script></body></html>