// Cta.jsx — closing CTA + contact form (delivers to info@greysurface.com via Forms.jsx) const CTA_INBOX = 'info@greysurface.com'; const CTA_SUBJECT = 'Website enquiry — greysurface.com'; // ponytail: Forms.jsx is not yet on every page that loads Cta.jsx — resolve its helpers // at render/submit time so a missing include degrades to the mailto fallback, never a blank page. const CtaTrap = () => { const H = window.Honeypot; return H ? : null; }; const Cta = () => { const [status, setStatus] = React.useState('idle'); // idle | sending | sent | error const onSubmit = async (e) => { e.preventDefault(); const form = e.currentTarget; setStatus('sending'); try { if (!window.submitToInbox || !window.formToObject) throw new Error('Form delivery is not loaded on this page'); await window.submitToInbox(window.formToObject(form), { subject: CTA_SUBJECT }); setStatus('sent'); } catch (_) { setStatus('error'); } }; return (

Get started

Talk to our team

Tell us about your environment and what you need tested. One of our testers will reply within one business day to set up a scoping call.

{[ { icon: 'mail', l: CTA_INBOX, href: `mailto:${CTA_INBOX}` }, { icon: 'lock', l: 'PGP key available on request' }, ].map(c => (
{c.href ? {c.l} : {c.l}}
))}
{status === 'sent' ? (

Message received

One of our testers will reply within one business day.

) : (
{status === 'error' && (

Your message could not be sent. Please email us directly at{' '} {CTA_INBOX}.

)}

Sent to {CTA_INBOX}. We reply within one business day.

)}
); }; const Field = ({ name, label, placeholder, type = 'text', textarea, required }) => { const Tag = textarea ? 'textarea' : 'input'; return ( ); }; const SelectField = ({ name, label, options }) => ( ); Object.assign(window, { Cta });