Construction — General Contractor Landing
A rugged general-contractor marketing page with a bold hi-vis hero and free-estimate call to action, services grid, featured project gallery, four-step process, licensed-and-insured trust badges, customer reviews, service-area list and a working estimate request form with inline validation.
MCP
Code
:root {
--hv: #f5c518; /* hi-vis yellow */
--hv-d: #d8a900;
--steel: #2b3440;
--steel-d: #1b222b;
--bg: #eceae6; /* concrete */
--surface: #ffffff;
--ink: #1a1d22;
--muted: #666c75;
--orange: #e8642a;
--line: #d6d3cc;
--line-steel: #3c4654;
--radius: 6px;
--radius-lg: 12px;
--shadow: 0 6px 20px rgba(27, 34, 43, 0.12);
--maxw: 1120px;
--font: 'Inter', system-ui, -apple-system, sans-serif;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--font);
color: var(--ink);
background: var(--bg);
line-height: 1.55;
-webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; line-height: 1.05; letter-spacing: -0.01em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 22px; }
.skip-link {
position: absolute; left: -999px; top: 0; z-index: 100;
background: var(--hv); color: var(--ink); padding: 10px 16px; font-weight: 700;
}
.skip-link:focus { left: 12px; top: 12px; }
:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; border-radius: 3px; }
/* ---------- Buttons ---------- */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
font-weight: 800; font-size: 0.95rem; letter-spacing: 0.02em; text-transform: uppercase;
padding: 13px 22px; border-radius: var(--radius); border: 2px solid transparent;
cursor: pointer; transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.btn:active { transform: translateY(1px); }
.btn-cta {
background: var(--hv); color: var(--steel-d);
box-shadow: 0 4px 0 var(--hv-d);
}
.btn-cta:hover { background: #ffd633; box-shadow: 0 6px 0 var(--hv-d); transform: translateY(-1px); }
.btn-ghost {
background: transparent; color: #fff; border-color: rgba(255,255,255,.45);
}
.btn-ghost:hover { border-color: #fff; background: rgba(255,255,255,.08); }
.btn-block { width: 100%; }
/* ---------- Header ---------- */
.site-header {
position: sticky; top: 0; z-index: 50;
background: var(--steel-d);
border-bottom: 3px solid var(--hv);
}
.header-inner { display: flex; align-items: center; gap: 24px; height: 66px; }
.brand { display: flex; align-items: center; gap: 10px; color: #fff; font-weight: 900; }
.brand-mark { color: var(--hv); font-size: 1.3rem; }
.brand-name { font-size: 1.02rem; letter-spacing: 0.04em; }
.brand-name em { color: var(--hv); font-style: normal; }
.nav { display: flex; gap: 22px; margin-left: auto; }
.nav a {
color: #c7ccd3; font-weight: 600; font-size: 0.92rem; padding: 6px 2px;
border-bottom: 2px solid transparent; transition: color .12s, border-color .12s;
}
.nav a:hover { color: #fff; border-color: var(--hv); }
.header-cta { padding: 10px 18px; }
/* ---------- Hero ---------- */
.hero {
position: relative; overflow: hidden;
background:
linear-gradient(180deg, var(--steel) 0%, var(--steel-d) 100%);
color: #fff;
border-bottom: 4px solid var(--hv);
}
.hazard {
position: absolute; inset: auto 0 0 0; height: 10px;
background: repeating-linear-gradient(45deg, var(--hv) 0 18px, var(--steel-d) 18px 36px);
opacity: .9;
}
.hero-inner {
display: grid; grid-template-columns: 1.3fr 0.9fr; gap: 48px;
align-items: center; padding: 72px 22px 84px;
}
.kicker {
display: inline-flex; align-items: center; gap: 8px;
text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.78rem; font-weight: 700;
color: var(--hv);
}
.kicker .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--orange); box-shadow: 0 0 0 3px rgba(232,100,42,.25); }
.hero h1 {
font-size: clamp(2.6rem, 6vw, 4.4rem); font-weight: 900; text-transform: uppercase;
margin: 14px 0 18px; letter-spacing: -0.02em;
}
.hero h1 .hi { color: var(--hv); }
.lede { font-size: 1.08rem; color: #cfd5dc; max-width: 44ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin: 26px 0 32px; }
.hero-stats { display: flex; gap: 30px; flex-wrap: wrap; }
.hero-stats li { display: flex; flex-direction: column; }
.hero-stats strong { font-size: 1.7rem; font-weight: 900; color: var(--hv); }
.hero-stats span { font-size: 0.82rem; color: #aab2bc; text-transform: uppercase; letter-spacing: .04em; }
.hero-card {
background: var(--surface); color: var(--ink); border-radius: var(--radius-lg);
padding: 26px; box-shadow: var(--shadow); border-top: 5px solid var(--hv);
}
.hero-card h2 { font-size: 1.4rem; font-weight: 900; text-transform: uppercase; }
.hero-card-sub { color: var(--muted); margin-top: 4px; font-size: 0.92rem; }
.counter-line {
margin: 16px 0; padding: 10px 12px; background: var(--bg); border-radius: var(--radius);
font-size: 0.9rem; font-weight: 600;
}
.counter-line #quoteCount { color: var(--orange); font-weight: 900; }
.hero-card-list { display: grid; gap: 8px; margin-bottom: 18px; font-size: 0.92rem; color: #303640; }
/* ---------- Sections ---------- */
.section { padding: 72px 0; }
.section-alt { background: #e3e0db; }
.section-steel { background: var(--steel-d); color: #fff; }
.section-head { margin-bottom: 38px; }
.eyebrow { text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.76rem; font-weight: 800; color: var(--orange); }
.section-title { font-size: clamp(1.9rem, 4vw, 2.8rem); font-weight: 900; text-transform: uppercase; margin-top: 6px; }
.section-head-light .eyebrow { color: var(--hv); }
.section-steel .section-title { color: #fff; }
.grid { display: grid; gap: 22px; }
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); }
/* ---------- Services ---------- */
.grid-services { grid-template-columns: repeat(3, 1fr); }
.service-card { padding: 26px; transition: transform .14s ease, box-shadow .14s ease, border-color .14s; border-left: 4px solid var(--steel); }
.service-card:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-left-color: var(--hv); }
.svc-ico { font-size: 2rem; display: block; margin-bottom: 12px; }
.service-card h3 { font-size: 1.18rem; font-weight: 800; margin-bottom: 8px; }
.service-card p { color: var(--muted); font-size: 0.95rem; }
/* ---------- Projects ---------- */
.grid-projects { grid-template-columns: repeat(2, 1fr); }
.project { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; transition: transform .14s ease, box-shadow .14s ease; }
.project:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.project-thumb { position: relative; height: 190px; display: flex; align-items: flex-start; }
.thumb-a { background: linear-gradient(135deg, #4a5667, #2b3440); }
.thumb-b { background: linear-gradient(135deg, #7a6a4f, #3c352a); }
.thumb-c { background: linear-gradient(135deg, #3d5a5a, #233636); }
.thumb-d { background: linear-gradient(135deg, #6b3f2e, #3a241b); }
.project-thumb .tag {
margin: 14px; background: var(--hv); color: var(--steel-d); font-weight: 800;
font-size: 0.74rem; text-transform: uppercase; letter-spacing: .04em; padding: 5px 10px; border-radius: 4px;
}
.project-body { padding: 18px 20px; }
.project-body h3 { font-size: 1.12rem; font-weight: 800; }
.project-body p { color: var(--muted); font-size: 0.9rem; margin-top: 4px; }
/* ---------- Process ---------- */
.process { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; counter-reset: step; }
.step { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 24px; position: relative; }
.step-num {
display: inline-block; font-size: 2.2rem; font-weight: 900; color: var(--hv);
-webkit-text-stroke: 1px var(--steel); margin-bottom: 8px; letter-spacing: -.03em;
}
.step h3 { font-size: 1.08rem; font-weight: 800; margin-bottom: 6px; }
.step p { color: var(--muted); font-size: 0.92rem; }
/* ---------- Why us / badges ---------- */
.grid-badges { grid-template-columns: repeat(4, 1fr); }
.badge-card {
background: var(--steel); border: 1px solid var(--line-steel); border-radius: var(--radius-lg);
padding: 24px; border-top: 4px solid var(--hv);
}
.badge-ico { font-size: 1.8rem; display: block; margin-bottom: 12px; }
.badge-card h3 { font-size: 1.05rem; font-weight: 800; color: #fff; margin-bottom: 6px; }
.badge-card p { color: #aeb6c0; font-size: 0.9rem; }
/* ---------- Reviews ---------- */
.grid-reviews { grid-template-columns: repeat(3, 1fr); }
.review { margin: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 24px; }
.stars { color: var(--hv-d); font-size: 1.05rem; letter-spacing: 2px; margin-bottom: 10px; }
.review blockquote { margin: 0 0 14px; font-size: 0.98rem; color: var(--ink); }
.review figcaption { font-weight: 700; font-size: 0.9rem; color: var(--muted); }
/* ---------- Service area ---------- */
.area-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 40px; align-items: center; }
.area-lede { color: var(--muted); margin: 14px 0 20px; max-width: 46ch; }
.area-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; max-width: 360px; }
.area-list li {
background: var(--surface); border: 1px solid var(--line); border-left: 4px solid var(--hv);
border-radius: var(--radius); padding: 10px 14px; font-weight: 600; font-size: 0.95rem;
}
.area-map {
position: relative; min-height: 240px; border-radius: var(--radius-lg);
background:
repeating-linear-gradient(0deg, rgba(43,52,64,.08) 0 1px, transparent 1px 40px),
repeating-linear-gradient(90deg, rgba(43,52,64,.08) 0 1px, transparent 1px 40px),
var(--steel);
border: 3px solid var(--steel-d); display: flex; align-items: center; justify-content: center;
}
.area-map .pin { position: absolute; font-size: 1.6rem; }
.pin-1 { top: 30%; left: 35%; } .pin-2 { top: 55%; left: 60%; } .pin-3 { top: 40%; left: 70%; }
.area-map-label { color: var(--hv); font-weight: 800; text-transform: uppercase; letter-spacing: .06em; font-size: 0.85rem; }
/* ---------- Estimate form ---------- */
.estimate-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 44px; align-items: start; }
.estimate-copy p { color: #cfd5dc; margin-top: 12px; }
.estimate-points { margin-top: 20px; display: grid; gap: 8px; color: #e6e9ed; font-size: 0.95rem; }
.estimate-form { background: var(--surface); color: var(--ink); padding: 28px; }
.field { display: flex; flex-direction: column; margin-bottom: 16px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.field label { font-weight: 700; font-size: 0.85rem; margin-bottom: 6px; text-transform: uppercase; letter-spacing: .03em; }
.field input, .field select, .field textarea {
font: inherit; padding: 11px 12px; border: 2px solid var(--line); border-radius: var(--radius);
background: #fafafa; color: var(--ink); transition: border-color .12s, box-shadow .12s;
}
.field input:focus, .field select:focus, .field textarea:focus {
outline: none; border-color: var(--steel); box-shadow: 0 0 0 3px rgba(245,197,24,.35); background: #fff;
}
.field textarea { resize: vertical; }
.field.invalid input, .field.invalid select { border-color: var(--orange); }
.error { color: var(--orange); font-size: 0.8rem; font-weight: 600; margin-top: 5px; min-height: 1em; }
.hint { color: var(--muted); font-size: 0.8rem; margin-top: 5px; min-height: 1em; }
.form-status { margin-top: 14px; font-weight: 700; text-align: center; min-height: 1.2em; }
.form-status.ok { color: #1d7a3a; }
.form-status.err { color: var(--orange); }
/* ---------- Footer ---------- */
.site-footer { background: var(--steel-d); color: #c7ccd3; border-top: 4px solid var(--hv); }
.footer-inner { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 30px; padding: 48px 22px 36px; }
.footer-brand .brand-name { color: #fff; font-size: 1.1rem; }
.footer-brand p { margin-top: 12px; font-size: 0.9rem; }
.footer-col h4 { color: #fff; text-transform: uppercase; letter-spacing: .05em; font-size: 0.85rem; margin-bottom: 12px; }
.footer-col p { font-size: 0.92rem; margin-bottom: 6px; }
.footer-col a:hover { color: var(--hv); }
.footer-bar { border-top: 1px solid var(--line-steel); padding: 16px 22px; text-align: center; font-size: 0.82rem; color: #8b939d; }
/* ---------- Responsive ---------- */
@media (max-width: 920px) {
.hero-inner { grid-template-columns: 1fr; gap: 36px; }
.grid-services { grid-template-columns: repeat(2, 1fr); }
.grid-badges { grid-template-columns: repeat(2, 1fr); }
.grid-reviews { grid-template-columns: 1fr; }
.process { grid-template-columns: repeat(2, 1fr); }
.area-grid, .estimate-grid { grid-template-columns: 1fr; }
.footer-inner { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
.nav { display: none; }
.header-cta { margin-left: auto; }
.section { padding: 52px 0; }
.hero-inner { padding: 48px 20px 60px; }
.hero-stats { gap: 18px; }
.grid-services, .grid-projects, .grid-badges, .process { grid-template-columns: 1fr; }
.field-row { grid-template-columns: 1fr; }
.area-list { grid-template-columns: 1fr; max-width: none; }
.footer-inner { grid-template-columns: 1fr; }
.hero-actions .btn { width: 100%; }
}(function () {
"use strict";
/* ---------- Live "quotes requested" counter ---------- */
var counterEl = document.getElementById("quoteCount");
var quoteCount = counterEl ? parseInt(counterEl.textContent, 10) || 0 : 0;
function bumpCounter() {
if (!counterEl) return;
quoteCount += 1;
counterEl.textContent = quoteCount;
counterEl.animate(
[{ transform: "scale(1)" }, { transform: "scale(1.35)" }, { transform: "scale(1)" }],
{ duration: 360, easing: "ease-out" }
);
}
/* ---------- Budget hint ---------- */
var budget = document.getElementById("budget");
var budgetHint = document.getElementById("budgetHint");
var hints = {
"Under $25k": "Great for repairs, decks and small remodels.",
"$25k – $75k": "Typical kitchen or bath remodel range.",
"$75k – $200k": "Additions and large renovations.",
"$200k+": "New construction and major projects.",
"": "We'll help you scope a realistic budget.",
};
if (budget && budgetHint) {
budget.addEventListener("change", function () {
budgetHint.textContent = hints[budget.value] || "";
});
}
/* ---------- Form validation ---------- */
var form = document.getElementById("estimateForm");
var status = document.getElementById("formStatus");
function setError(name, msg) {
var span = form.querySelector('.error[data-for="' + name + '"]');
var field = form.querySelector("#" + name);
if (span) span.textContent = msg || "";
if (field && field.parentElement) {
field.parentElement.classList.toggle("invalid", !!msg);
}
}
function validators(data) {
var errs = {};
if (!data.name.trim()) errs.name = "Please enter your name.";
var digits = data.phone.replace(/\D/g, "");
if (digits.length < 10) errs.phone = "Enter a 10-digit phone number.";
if (!/^\d{5}$/.test(data.zip.trim())) errs.zip = "Enter a valid 5-digit ZIP.";
if (!data.project) errs.project = "Pick a project type.";
return errs;
}
if (form) {
// Clear individual errors as the user types
["name", "phone", "zip", "project"].forEach(function (n) {
var el = form.querySelector("#" + n);
if (el) {
el.addEventListener("input", function () { setError(n, ""); });
el.addEventListener("change", function () { setError(n, ""); });
}
});
form.addEventListener("submit", function (e) {
e.preventDefault();
var data = {
name: form.name.value,
phone: form.phone.value,
zip: form.zip.value,
project: form.project.value,
};
var errs = validators(data);
["name", "phone", "zip", "project"].forEach(function (n) {
setError(n, errs[n] || "");
});
var keys = Object.keys(errs);
if (keys.length) {
status.textContent = "Please fix the highlighted fields.";
status.className = "form-status err";
var first = form.querySelector("#" + keys[0]);
if (first) first.focus();
return;
}
status.textContent =
"Thanks, " + data.name.trim().split(" ")[0] +
"! Your request is in — we'll call within 48 hours.";
status.className = "form-status ok";
bumpCounter();
form.reset();
if (budgetHint) budgetHint.textContent = "";
});
}
/* ---------- Smooth-scroll active nav highlight ---------- */
var navLinks = Array.prototype.slice.call(document.querySelectorAll(".nav a"));
var sections = navLinks
.map(function (a) { return document.querySelector(a.getAttribute("href")); })
.filter(Boolean);
if ("IntersectionObserver" in window && sections.length) {
var obs = new IntersectionObserver(
function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
navLinks.forEach(function (a) {
a.style.borderColor =
a.getAttribute("href") === "#" + entry.target.id ? "var(--hv)" : "transparent";
});
}
});
},
{ rootMargin: "-50% 0px -50% 0px" }
);
sections.forEach(function (s) { obs.observe(s); });
}
})();<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ironclad Construction — General Contractor</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<header class="site-header">
<div class="wrap header-inner">
<a class="brand" href="#top">
<span class="brand-mark" aria-hidden="true">▰</span>
<span class="brand-name">IRONCLAD <em>CONSTRUCTION</em></span>
</a>
<nav class="nav" aria-label="Primary">
<a href="#services">Services</a>
<a href="#projects">Projects</a>
<a href="#process">Process</a>
<a href="#reviews">Reviews</a>
<a href="#area">Service Area</a>
</nav>
<a class="btn btn-cta header-cta" href="#estimate">Free Estimate</a>
</div>
</header>
<main id="main" tabindex="-1">
<!-- HERO -->
<section class="hero" id="top">
<div class="hazard" aria-hidden="true"></div>
<div class="wrap hero-inner">
<div class="hero-copy">
<p class="kicker"><span class="dot"></span> Licensed · Bonded · Insured — Lic #C-48820</p>
<h1>BUILT TO LAST.<br /><span class="hi">DONE RIGHT.</span></h1>
<p class="lede">
Full-service general contracting for homes and businesses across the
Tri-County area. Remodels, additions, roofing and ground-up builds —
on schedule and on budget since 2004.
</p>
<div class="hero-actions">
<a class="btn btn-cta" href="#estimate">Get a Free Estimate</a>
<a class="btn btn-ghost" href="tel:+15205550148">Call (520) 555-0148</a>
</div>
<ul class="hero-stats">
<li><strong>1,240+</strong><span>Projects completed</span></li>
<li><strong>21 yrs</strong><span>In business</span></li>
<li><strong>4.9★</strong><span>Avg. rating</span></li>
</ul>
</div>
<aside class="hero-card" aria-label="Quick estimate">
<h2>Same-week quotes</h2>
<p class="hero-card-sub">Most estimates returned within 48 hours.</p>
<p class="counter-line">
<span id="quoteCount">312</span> quotes requested this month
</p>
<ul class="hero-card-list">
<li>✔ No-cost, no-obligation walkthrough</li>
<li>✔ Fixed-price written bid</li>
<li>✔ Crews, not subs you never meet</li>
</ul>
<a class="btn btn-cta btn-block" href="#estimate">Request Yours</a>
</aside>
</div>
</section>
<!-- SERVICES -->
<section class="section" id="services">
<div class="wrap">
<div class="section-head">
<p class="eyebrow">What we do</p>
<h2 class="section-title">Services</h2>
</div>
<div class="grid grid-services">
<article class="card service-card">
<span class="svc-ico" aria-hidden="true">🏠</span>
<h3>Additions & Remodels</h3>
<p>Kitchens, baths, bump-outs and whole-home renovations with one accountable crew.</p>
</article>
<article class="card service-card">
<span class="svc-ico" aria-hidden="true">🧱</span>
<h3>New Construction</h3>
<p>Ground-up custom homes and ADUs, from foundation pour to final walkthrough.</p>
</article>
<article class="card service-card">
<span class="svc-ico" aria-hidden="true">🛠️</span>
<h3>Roofing & Exteriors</h3>
<p>Asphalt, metal and flat roofs, siding, gutters and storm-damage repair.</p>
</article>
<article class="card service-card">
<span class="svc-ico" aria-hidden="true">🏢</span>
<h3>Commercial Build-Out</h3>
<p>Tenant improvements, retail fit-outs and office renovations on tight timelines.</p>
</article>
<article class="card service-card">
<span class="svc-ico" aria-hidden="true">🚿</span>
<h3>Concrete & Decks</h3>
<p>Driveways, patios, footings and framed decks engineered to code.</p>
</article>
<article class="card service-card">
<span class="svc-ico" aria-hidden="true">⚡</span>
<h3>Emergency Repairs</h3>
<p>Water, fire and storm damage stabilized fast, with insurance-ready docs.</p>
</article>
</div>
</div>
</section>
<!-- PROJECTS -->
<section class="section section-alt" id="projects">
<div class="wrap">
<div class="section-head">
<p class="eyebrow">Recent work</p>
<h2 class="section-title">Featured Projects</h2>
</div>
<div class="grid grid-projects">
<article class="project">
<div class="project-thumb thumb-a" aria-hidden="true"><span class="tag">Remodel</span></div>
<div class="project-body">
<h3>Hargrove Kitchen Reno</h3>
<p>Tucson, AZ · 6 weeks · $84k</p>
</div>
</article>
<article class="project">
<div class="project-thumb thumb-b" aria-hidden="true"><span class="tag">New Build</span></div>
<div class="project-body">
<h3>Mesa Ridge Custom Home</h3>
<p>Oro Valley, AZ · 7 months · $612k</p>
</div>
</article>
<article class="project">
<div class="project-thumb thumb-c" aria-hidden="true"><span class="tag">Commercial</span></div>
<div class="project-body">
<h3>Foothills Dental Build-Out</h3>
<p>Marana, AZ · 9 weeks · $148k</p>
</div>
</article>
<article class="project">
<div class="project-thumb thumb-d" aria-hidden="true"><span class="tag">Roofing</span></div>
<div class="project-body">
<h3>Cortez Standing-Seam Roof</h3>
<p>Sahuarita, AZ · 4 days · $31k</p>
</div>
</article>
</div>
</div>
</section>
<!-- PROCESS -->
<section class="section" id="process">
<div class="wrap">
<div class="section-head">
<p class="eyebrow">How it works</p>
<h2 class="section-title">Our Process</h2>
</div>
<ol class="process">
<li class="step">
<span class="step-num">01</span>
<h3>Free Walkthrough</h3>
<p>We visit, measure and listen — then talk honest scope and budget on the spot.</p>
</li>
<li class="step">
<span class="step-num">02</span>
<h3>Fixed-Price Bid</h3>
<p>A written, line-item proposal in 48 hours. No surprise change-orders.</p>
</li>
<li class="step">
<span class="step-num">03</span>
<h3>Build Phase</h3>
<p>A dedicated foreman, daily cleanup and weekly photo updates to your phone.</p>
</li>
<li class="step">
<span class="step-num">04</span>
<h3>Final Walk & Warranty</h3>
<p>Punch-list signed off and a 5-year written workmanship warranty in hand.</p>
</li>
</ol>
</div>
</section>
<!-- WHY US -->
<section class="section section-steel" id="why">
<div class="wrap">
<div class="section-head section-head-light">
<p class="eyebrow">Why hire us</p>
<h2 class="section-title">No Cut Corners</h2>
</div>
<div class="grid grid-badges">
<div class="badge-card">
<span class="badge-ico" aria-hidden="true">📋</span>
<h3>Licensed & Bonded</h3>
<p>State Lic #C-48820, fully bonded for projects up to $1.5M.</p>
</div>
<div class="badge-card">
<span class="badge-ico" aria-hidden="true">🛡️</span>
<h3>$2M Insured</h3>
<p>General liability and workers’ comp on every crew member.</p>
</div>
<div class="badge-card">
<span class="badge-ico" aria-hidden="true">📜</span>
<h3>5-Year Warranty</h3>
<p>Written workmanship warranty backs everything we build.</p>
</div>
<div class="badge-card">
<span class="badge-ico" aria-hidden="true">⏱️</span>
<h3>On-Time Pledge</h3>
<p>Miss our finish date and we credit you $250 per week.</p>
</div>
</div>
</div>
</section>
<!-- REVIEWS -->
<section class="section section-alt" id="reviews">
<div class="wrap">
<div class="section-head">
<p class="eyebrow">What clients say</p>
<h2 class="section-title">Reviews</h2>
</div>
<div class="grid grid-reviews">
<figure class="review">
<div class="stars" aria-label="5 out of 5 stars">★★★★★</div>
<blockquote>Crew showed up when they said, cleaned up daily, and the kitchen came in under bid. Rare these days.</blockquote>
<figcaption>— Denise Hargrove, Tucson</figcaption>
</figure>
<figure class="review">
<div class="stars" aria-label="5 out of 5 stars">★★★★★</div>
<blockquote>They built our home from a dirt lot in seven months with weekly photo updates. Zero surprise costs.</blockquote>
<figcaption>— Marcus & Lia Tran, Oro Valley</figcaption>
</figure>
<figure class="review">
<div class="stars" aria-label="5 out of 5 stars">★★★★☆</div>
<blockquote>Storm took our roof off on a Sunday. Ironclad had it tarped that night and replaced within the week.</blockquote>
<figcaption>— Roy Castillo, Sahuarita</figcaption>
</figure>
</div>
</div>
</section>
<!-- SERVICE AREA -->
<section class="section" id="area">
<div class="wrap area-grid">
<div>
<p class="eyebrow">Where we work</p>
<h2 class="section-title">Service Area</h2>
<p class="area-lede">
Family-owned and based in Tucson, we serve the Tri-County region.
Outside these cities? Ask — we travel for the right project.
</p>
<ul class="area-list">
<li>Tucson</li>
<li>Oro Valley</li>
<li>Marana</li>
<li>Sahuarita</li>
<li>Vail</li>
<li>Catalina</li>
<li>Green Valley</li>
<li>Rita Ranch</li>
</ul>
</div>
<div class="area-map" aria-hidden="true">
<span class="pin pin-1">📍</span>
<span class="pin pin-2">📍</span>
<span class="pin pin-3">📍</span>
<p class="area-map-label">Tri-County coverage</p>
</div>
</div>
</section>
<!-- ESTIMATE FORM -->
<section class="section section-steel" id="estimate">
<div class="wrap estimate-grid">
<div class="estimate-copy">
<p class="eyebrow">Let’s build it</p>
<h2 class="section-title">Get a Free Estimate</h2>
<p>Tell us about your project and we’ll get back within 48 hours with a written, fixed-price bid. No cost, no pressure.</p>
<ul class="estimate-points">
<li>✔ Reply within 48 hours</li>
<li>✔ Local crews, not unknown subs</li>
<li>✔ Honest budget, even if it’s a no</li>
</ul>
</div>
<form class="estimate-form card" id="estimateForm" novalidate>
<div class="field">
<label for="name">Full name</label>
<input id="name" name="name" type="text" autocomplete="name" required />
<span class="error" data-for="name"></span>
</div>
<div class="field-row">
<div class="field">
<label for="phone">Phone</label>
<input id="phone" name="phone" type="tel" inputmode="tel" autocomplete="tel" placeholder="(520) 555-0148" required />
<span class="error" data-for="phone"></span>
</div>
<div class="field">
<label for="zip">ZIP code</label>
<input id="zip" name="zip" type="text" inputmode="numeric" maxlength="5" placeholder="85718" required />
<span class="error" data-for="zip"></span>
</div>
</div>
<div class="field-row">
<div class="field">
<label for="project">Project type</label>
<select id="project" name="project" required>
<option value="">Select one…</option>
<option>Addition / Remodel</option>
<option>New Construction</option>
<option>Roofing / Exterior</option>
<option>Commercial Build-Out</option>
<option>Concrete / Deck</option>
<option>Emergency Repair</option>
</select>
<span class="error" data-for="project"></span>
</div>
<div class="field">
<label for="budget">Budget range</label>
<select id="budget" name="budget">
<option value="">Not sure yet</option>
<option>Under $25k</option>
<option>$25k – $75k</option>
<option>$75k – $200k</option>
<option>$200k+</option>
</select>
<span class="hint" id="budgetHint"></span>
</div>
</div>
<div class="field">
<label for="details">Project details</label>
<textarea id="details" name="details" rows="3" placeholder="Tell us what you're planning…"></textarea>
</div>
<button class="btn btn-cta btn-block" type="submit">Request My Free Estimate</button>
<p class="form-status" id="formStatus" role="status" aria-live="polite"></p>
</form>
</div>
</section>
</main>
<footer class="site-footer">
<div class="wrap footer-inner">
<div class="footer-brand">
<span class="brand-name">IRONCLAD <em>CONSTRUCTION</em></span>
<p>General contracting done right since 2004.<br />Lic #C-48820 · Bonded · Insured</p>
</div>
<div class="footer-col">
<h4>Contact</h4>
<p><a href="tel:+15205550148">(520) 555-0148</a></p>
<p><a href="mailto:[email protected]">[email protected]</a></p>
<p>3140 N Oracle Rd, Tucson, AZ</p>
</div>
<div class="footer-col">
<h4>Hours</h4>
<p>Mon–Fri · 7:00a–5:30p</p>
<p>Sat · 8:00a–noon</p>
<p>24/7 emergency line</p>
</div>
</div>
<div class="footer-bar">
<p>© 2026 Ironclad Construction (demo). Illustrative UI only.</p>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>General Contractor Landing
A sturdy, full marketing page for a general contractor styled with a rugged trades look — hi-vis yellow accents, steel and concrete tones, chunky condensed headings and diagonal hazard stripes. It opens with a bold hero and a Get a free estimate call to action, then walks visitors through services, featured projects, a four-step process and the reasons to hire (licensed, insured, written warranty).
Social proof comes from a row of customer reviews and a service-area list, and the page closes with a real estimate request form. The form validates name, phone, ZIP and project type inline, shows a filtered estimate-budget hint and confirms submission without reloading. Sticky header links scroll smoothly to each section and a live counter tracks how many quotes have been requested.
Everything is vanilla HTML, CSS and JavaScript — no frameworks, no build step.
Illustrative UI only — not a real contracting business or quote.