Contact
Routed enquiry form
Picking a department rewrites the form around it
Picking a department rewrites the form around it
Build a contact form with Tailwind CSS that adapts to the chosen department. Use a max-w-xl card. At the top, a heading and a muted line about response times. The first control is a row of four selectable department tiles — Sales, Support, Billing and Press — each a bordered rounded-xl button with a glyph and a label, the active one dark. Under it, name and email fields side by side, a subject field, a message textarea, and a contextual helper block that changes with the department: a bordered neutral-50 note giving the expected reply time, a suggested self-serve link and, for Support only, an extra input asking for the workspace name. Finish with a submit button whose label names the department and a footnote about attachments. Then add JavaScript that switches the active tile, swaps the helper copy and links from a map, shows or hides the workspace field, and updates the button label. <section class="mx-auto max-w-xl px-6 py-14">
<div class="rounded-2xl border border-neutral-200 bg-white p-8 shadow-sm">
<h1 class="text-2xl font-semibold tracking-tight text-neutral-900">Get in touch</h1>
<p class="mt-1.5 text-sm text-neutral-500">Pick where it should land and we will route it straight there.</p>
<div id="deptTiles" class="mt-7 grid grid-cols-2 gap-2 sm:grid-cols-4">
<button data-dept="sales" class="dept rounded-xl border border-neutral-900 bg-neutral-900 p-3 text-center transition">
<span class="block text-lg text-white"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="m12 3 9 9-9 9-9-9 9-9Z"/><path d="m12 7 5 5-5 5-5-5 5-5Z"/></svg></span>
<span class="mt-1 block text-xs font-medium text-white">Sales</span>
</button>
<button data-dept="support" class="dept rounded-xl border border-neutral-200 p-3 text-center transition hover:bg-neutral-50">
<span class="block text-lg text-neutral-700"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M20 15a3 3 0 0 1-3 3H9l-5 3v-6a3 3 0 0 1-1-2V7a3 3 0 0 1 3-3h11a3 3 0 0 1 3 3v8Z"/></svg></span>
<span class="mt-1 block text-xs font-medium text-neutral-700">Support</span>
</button>
<button data-dept="billing" class="dept rounded-xl border border-neutral-200 p-3 text-center transition hover:bg-neutral-50">
<span class="block text-lg text-neutral-700"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><rect x="3" y="5" width="18" height="4" rx="1"/><path d="M5 9v10h14V9M10 13h4"/></svg></span>
<span class="mt-1 block text-xs font-medium text-neutral-700">Billing</span>
</button>
<button data-dept="press" class="dept rounded-xl border border-neutral-200 p-3 text-center transition hover:bg-neutral-50">
<span class="block text-lg text-neutral-700"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m4 7 8 6 8-6"/></svg></span>
<span class="mt-1 block text-xs font-medium text-neutral-700">Press</span>
</button>
</div>
<div class="mt-6 grid gap-4 sm:grid-cols-2">
<div>
<label class="mb-1.5 block text-xs font-medium text-neutral-700">Name</label>
<input type="text" placeholder="Rae Mensah" class="w-full rounded-xl border border-neutral-200 px-3.5 py-2.5 text-sm outline-none transition focus:border-neutral-900 focus:ring-4 focus:ring-neutral-900/10" />
</div>
<div>
<label class="mb-1.5 block text-xs font-medium text-neutral-700">Email</label>
<input type="email" placeholder="[email protected]" class="w-full rounded-xl border border-neutral-200 px-3.5 py-2.5 text-sm outline-none transition focus:border-neutral-900 focus:ring-4 focus:ring-neutral-900/10" />
</div>
</div>
<div id="workspaceField" class="mt-4 hidden">
<label class="mb-1.5 block text-xs font-medium text-neutral-700">Workspace</label>
<input type="text" placeholder="studioform.northwind.app" class="w-full rounded-xl border border-neutral-200 px-3.5 py-2.5 font-mono text-sm outline-none transition focus:border-neutral-900 focus:ring-4 focus:ring-neutral-900/10" />
<p class="mt-1.5 text-xs text-neutral-400">Helps us pull the right logs before we reply.</p>
</div>
<div class="mt-4">
<label class="mb-1.5 block text-xs font-medium text-neutral-700">Subject</label>
<input id="subjectField" type="text" placeholder="Pricing for 40 seats" class="w-full rounded-xl border border-neutral-200 px-3.5 py-2.5 text-sm outline-none transition focus:border-neutral-900 focus:ring-4 focus:ring-neutral-900/10" />
</div>
<div class="mt-4">
<label class="mb-1.5 block text-xs font-medium text-neutral-700">Message</label>
<textarea rows="5" placeholder="As much detail as you have…" class="w-full resize-none rounded-xl border border-neutral-200 px-3.5 py-2.5 text-sm outline-none transition focus:border-neutral-900 focus:ring-4 focus:ring-neutral-900/10"></textarea>
</div>
<div id="deptHelper" class="mt-4 rounded-xl border border-neutral-200 bg-neutral-50 p-4 text-sm">
<p id="helperTime" class="font-medium text-neutral-900">Typical reply: within 1 business day</p>
<p id="helperCopy" class="mt-1 text-neutral-500">Faster still: <a href="#" class="underline underline-offset-2 hover:text-neutral-900">book a 20-minute call</a> and skip the back and forth.</p>
</div>
<button id="deptSubmit" class="mt-6 w-full rounded-xl bg-neutral-900 py-3 text-sm font-medium text-white transition hover:bg-neutral-800">Send to sales</button>
<p class="mt-3 text-center text-xs text-neutral-400">Need to attach a file? Reply to our confirmation email — it accepts up to 25 MB.</p>
</div>
</section> var DEPTS = {
sales: {
time: "Typical reply: within 1 business day",
copy: 'Faster still: <a href="#" class="underline underline-offset-2 hover:text-neutral-900">book a 20-minute call</a> and skip the back and forth.',
subject: "Pricing for 40 seats",
workspace: false,
label: "Send to sales",
},
support: {
time: "Typical reply: 41 minutes, 07:00–20:00 UTC",
copy: 'Many answers are already in the <a href="#" class="underline underline-offset-2 hover:text-neutral-900">help centre</a> — worth thirty seconds before you write.',
subject: "Sync failing on the Snowflake source",
workspace: true,
label: "Send to support",
},
billing: {
time: "Typical reply: within 1 business day",
copy: 'Invoices, VAT numbers and payment methods can be changed yourself in <a href="#" class="underline underline-offset-2 hover:text-neutral-900">billing settings</a>.',
subject: "VAT number on the August invoice",
workspace: false,
label: "Send to billing",
},
press: {
time: "Typical reply: within 2 business days",
copy: 'Logos, screenshots and boilerplate live in the <a href="#" class="underline underline-offset-2 hover:text-neutral-900">press kit</a>.',
subject: "Interview request",
workspace: false,
label: "Send to press",
},
};
var tiles = Array.prototype.slice.call(document.querySelectorAll(".dept"));
var time = document.getElementById("helperTime");
var copy = document.getElementById("helperCopy");
var subject = document.getElementById("subjectField");
var workspace = document.getElementById("workspaceField");
var submit = document.getElementById("deptSubmit");
function select(key) {
var d = DEPTS[key];
tiles.forEach(function (tile) {
var on = tile.dataset.dept === key;
tile.classList.toggle("bg-neutral-900", on);
tile.classList.toggle("border-neutral-900", on);
tile.classList.toggle("border-neutral-200", !on);
tile.querySelector("span:first-child").classList.toggle("text-white", on);
tile.querySelector("span:first-child").classList.toggle("text-neutral-700", !on);
tile.querySelector("span:last-child").classList.toggle("text-white", on);
tile.querySelector("span:last-child").classList.toggle("text-neutral-700", !on);
});
time.textContent = d.time;
copy.innerHTML = d.copy;
subject.placeholder = d.subject;
workspace.classList.toggle("hidden", !d.workspace);
submit.textContent = d.label;
}
tiles.forEach(function (tile) {
tile.addEventListener("click", function () {
select(tile.dataset.dept);
});
});
select("sales");