Construction — Home Remodel Landing
A design-build remodeling landing page with an aspirational hero and portfolio teaser, service cards for kitchen, bath, additions and whole-home, a four-step process, a filterable project gallery, client testimonials and a free-consultation call-to-action with a sturdy rugged-trades palette.
MCP
Code
:root {
--hv: #f5c518; /* hi-vis yellow */
--orange: #e8642a; /* safety orange */
--steel: #2b3440;
--steel-d: #1b222b;
--bg: #eceae6; /* concrete */
--surface: #ffffff;
--ink: #1a1d22;
--muted: #666c75;
--line: #d6d3cc;
--radius: 10px;
--shadow: 0 10px 30px rgba(27, 34, 43, 0.12);
--wrap: 1140px;
--ease: cubic-bezier(0.22, 0.61, 0.36, 1);
--font: 'Inter', system-ui, -apple-system, sans-serif;
}
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { scroll-behavior: smooth; }
body {
font-family: var(--font);
color: var(--ink);
background: var(--bg);
line-height: 1.55;
-webkit-font-smoothing: antialiased;
}
h1, h2, h3 { line-height: 1.05; letter-spacing: -0.02em; font-weight: 900; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
.wrap { width: min(100% - 40px, var(--wrap)); margin-inline: auto; }
.skip-link {
position: absolute; left: 12px; top: -48px;
background: var(--hv); color: var(--ink); padding: 10px 14px;
border-radius: 8px; font-weight: 700; z-index: 100; transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 12px; }
:focus-visible {
outline: 3px solid var(--orange);
outline-offset: 2px;
border-radius: 4px;
}
/* ── Buttons ───────────────────────── */
.btn {
display: inline-flex; align-items: center; justify-content: center;
font-weight: 800; font-size: 0.95rem;
padding: 13px 22px; border-radius: 8px; border: 2px solid transparent;
cursor: pointer; transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease), background 0.15s;
text-transform: uppercase; letter-spacing: 0.02em;
}
.btn:active { transform: translateY(1px); }
.btn-hv {
background: var(--hv); color: var(--steel-d);
box-shadow: 0 6px 0 #c79e09;
}
.btn-hv:hover { transform: translateY(-2px); box-shadow: 0 8px 0 #c79e09; }
.btn-hv:active { transform: translateY(2px); box-shadow: 0 2px 0 #c79e09; }
.btn-ghost {
background: transparent; color: var(--surface); border-color: rgba(255,255,255,0.5);
}
.btn-ghost:hover { background: rgba(255,255,255,0.12); border-color: var(--surface); }
/* ── 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: var(--surface); font-weight: 900; }
.brand-mark { color: var(--hv); font-size: 1.3rem; }
.brand-name { font-size: 1.15rem; letter-spacing: -0.02em; }
.brand-name em { color: var(--hv); font-style: normal; font-weight: 600; font-size: 0.7em; display: block; letter-spacing: 0.08em; text-transform: uppercase; }
.main-nav { margin-left: auto; display: flex; gap: 26px; }
.main-nav a {
color: #c9cdd3; font-weight: 600; font-size: 0.92rem;
padding: 6px 2px; border-bottom: 2px solid transparent; transition: color 0.15s, border-color 0.15s;
}
.main-nav a:hover, .main-nav a.active { color: var(--hv); border-color: var(--hv); }
.nav-cta { padding: 9px 16px; }
/* ── Hero ──────────────────────────── */
.hero {
position: relative; overflow: hidden;
background: linear-gradient(135deg, var(--steel) 0%, var(--steel-d) 100%);
color: var(--surface);
padding: 70px 0 64px;
}
.hero-hazard {
position: absolute; inset: 0; pointer-events: none; opacity: 0.06;
background: repeating-linear-gradient(45deg, var(--hv) 0 22px, transparent 22px 44px);
}
.hero-inner {
position: relative; display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 48px; align-items: center;
}
.eyebrow {
display: inline-block; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--hv);
border: 1px solid rgba(245,197,24,0.4); padding: 6px 12px; border-radius: 999px; margin-bottom: 20px;
}
.hero h1 { font-size: clamp(2.6rem, 6vw, 4.4rem); text-transform: uppercase; }
.hero h1 .hl { color: var(--hv); }
.lead { color: #c9cdd3; font-size: 1.12rem; max-width: 46ch; margin: 22px 0 28px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 38px; }
.hero-stats { display: flex; gap: 34px; flex-wrap: wrap; }
.hero-stats div { display: flex; flex-direction: column; }
.hero-stats dt { font-size: 2.2rem; font-weight: 900; color: var(--hv); line-height: 1; }
.hero-stats dd { font-size: 0.82rem; color: #aeb3ba; text-transform: uppercase; letter-spacing: 0.06em; margin-top: 6px; }
/* teaser */
.hero-teaser { display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 130px; gap: 14px; }
.teaser-card {
position: relative; border-radius: var(--radius); overflow: hidden;
border: 3px solid rgba(255,255,255,0.08); box-shadow: var(--shadow);
}
.teaser-lg { grid-column: 1 / -1; grid-row: span 1; }
.teaser-img { width: 100%; height: 100%; }
.teaser-card figcaption {
position: absolute; left: 0; right: 0; bottom: 0;
background: linear-gradient(transparent, rgba(20,24,30,0.85));
color: #fff; font-size: 0.82rem; font-weight: 700; padding: 26px 12px 10px;
}
/* shared image fills */
.teaser-img, .proj-img {
background-size: cover; background-position: center;
}
[data-img="kitchen"] { background: linear-gradient(135deg,#b07b4a,#6c4a2c); }
[data-img="kitchen2"] { background: linear-gradient(135deg,#c89b5f,#7a5a32); }
[data-img="bath"] { background: linear-gradient(135deg,#7d97a8,#3f5566); }
[data-img="bath2"] { background: linear-gradient(135deg,#92a7b3,#4d6675); }
[data-img="addition"] { background: linear-gradient(135deg,#9aa17e,#5c624a); }
[data-img="addition2"]{ background: linear-gradient(135deg,#a8ad8c,#666c52); }
[data-img="whole"] { background: linear-gradient(135deg,#b98c5e,#5d4730); }
[data-img="whole2"] { background: linear-gradient(135deg,#c5a079,#6f573c); }
/* ── Trust strip ───────────────────── */
.trust { background: var(--hv); color: var(--steel-d); }
.trust-inner {
display: flex; flex-wrap: wrap; gap: 8px 34px; justify-content: center;
padding: 14px 0; font-weight: 800; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.04em;
}
.trust-inner span { position: relative; }
.trust-inner span + span::before {
content: "·"; position: absolute; left: -19px; opacity: 0.5;
}
/* ── Sections ──────────────────────── */
.section { padding: 76px 0; }
.section-steel { background: var(--steel-d); color: var(--surface); }
.section-concrete { background: #e2dfd9; }
.section-head { max-width: 620px; margin: 0 auto 44px; text-align: center; }
.section-head .kicker {
display: inline-block; color: var(--orange); font-weight: 800; letter-spacing: 0.14em;
text-transform: uppercase; font-size: 0.78rem; margin-bottom: 12px;
}
.section-head h2 { font-size: clamp(2rem, 4vw, 2.9rem); text-transform: uppercase; }
.section-head p { color: var(--muted); margin-top: 14px; font-size: 1.05rem; }
.section-head-light .kicker { color: var(--hv); }
.section-head-light p { color: #b7bcc3; }
.cards { display: grid; gap: 22px; }
.services-grid { grid-template-columns: repeat(4, 1fr); }
/* service card */
.svc-card {
background: var(--surface); border: 1px solid var(--line);
border-top: 5px solid var(--steel); border-radius: var(--radius);
padding: 26px 22px; transition: transform 0.18s var(--ease), border-color 0.18s, box-shadow 0.18s;
}
.svc-card:hover {
transform: translateY(-5px); border-top-color: var(--orange);
box-shadow: var(--shadow);
}
.svc-icon { font-size: 2rem; display: block; margin-bottom: 14px; }
.svc-card h3 { font-size: 1.25rem; text-transform: uppercase; margin-bottom: 8px; }
.svc-card p { color: var(--muted); font-size: 0.95rem; }
.svc-from {
display: inline-block; margin-top: 16px; font-weight: 800; color: var(--steel-d);
background: var(--hv); padding: 5px 12px; border-radius: 6px; font-size: 0.85rem;
}
/* ── Process steps ─────────────────── */
.steps {
list-style: none; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; counter-reset: step;
}
.step {
position: relative; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1);
border-radius: var(--radius); padding: 28px 22px 24px; transition: background 0.18s, transform 0.18s var(--ease);
}
.step:hover { background: rgba(255,255,255,0.08); transform: translateY(-4px); }
.step-num {
display: inline-block; font-size: 2.4rem; font-weight: 900; color: var(--hv);
-webkit-text-stroke: 1px var(--hv); line-height: 1; margin-bottom: 12px;
}
.step h3 { font-size: 1.15rem; text-transform: uppercase; margin-bottom: 8px; }
.step p { color: #b7bcc3; font-size: 0.92rem; }
/* ── Gallery ───────────────────────── */
.filters { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-bottom: 30px; }
.filter {
font-family: inherit; font-weight: 700; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.04em;
background: var(--surface); color: var(--steel); border: 2px solid var(--line);
padding: 9px 18px; border-radius: 999px; cursor: pointer; transition: all 0.15s var(--ease);
}
.filter:hover { border-color: var(--steel); }
.filter.is-active { background: var(--steel-d); color: var(--hv); border-color: var(--steel-d); }
.gallery-grid { grid-template-columns: repeat(4, 1fr); }
.proj {
border-radius: var(--radius); overflow: hidden; background: var(--surface);
border: 1px solid var(--line); box-shadow: 0 4px 14px rgba(27,34,43,0.07);
transition: transform 0.18s var(--ease), box-shadow 0.18s;
}
.proj:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.proj.hide { display: none; }
.proj-img { height: 150px; }
.proj figcaption { padding: 14px 16px; display: flex; flex-direction: column; gap: 2px; }
.proj figcaption strong { font-size: 0.98rem; }
.proj figcaption span { color: var(--orange); font-weight: 700; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.03em; }
.gallery-empty { text-align: center; color: var(--muted); padding: 30px 0; font-weight: 600; }
/* ── Reviews ───────────────────────── */
.reviews-grid { grid-template-columns: repeat(3, 1fr); }
.review {
background: var(--surface); border: 1px solid var(--line); border-left: 5px solid var(--orange);
border-radius: var(--radius); padding: 26px 24px; box-shadow: 0 4px 14px rgba(27,34,43,0.06);
}
.review .stars { color: var(--hv); font-size: 1.1rem; letter-spacing: 2px; margin-bottom: 12px; }
.review p { font-size: 1rem; }
.review footer { margin-top: 18px; }
.review footer strong { display: block; }
.review footer span { color: var(--muted); font-size: 0.85rem; }
/* ── Consult CTA ───────────────────── */
.consult { position: relative; overflow: hidden; background: var(--orange); color: #fff; padding: 70px 0; }
.consult-hazard {
position: absolute; inset: 0; pointer-events: none; opacity: 0.12;
background: repeating-linear-gradient(-45deg, #000 0 24px, transparent 24px 48px);
}
.consult-inner { position: relative; display: grid; grid-template-columns: 1fr 1.1fr; gap: 48px; align-items: center; }
.consult-copy h2 { font-size: clamp(1.9rem, 4vw, 2.8rem); text-transform: uppercase; }
.consult-copy p { font-size: 1.1rem; margin-top: 12px; max-width: 40ch; }
.consult-form {
background: var(--surface); color: var(--ink); border-radius: var(--radius);
padding: 28px; display: grid; gap: 16px; box-shadow: var(--shadow); border: 3px solid var(--steel-d);
}
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-weight: 700; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.03em; }
.field input, .field select {
font-family: inherit; font-size: 1rem; padding: 12px 14px; border: 2px solid var(--line);
border-radius: 8px; background: #fafafa; transition: border-color 0.15s;
}
.field input:focus, .field select:focus { border-color: var(--orange); outline: none; background: #fff; }
.field.invalid input, .field.invalid select { border-color: #d23b1f; background: #fff4f1; }
.consult-submit { width: 100%; margin-top: 4px; }
.form-msg { min-height: 1.2em; font-weight: 700; font-size: 0.9rem; }
.form-msg.ok { color: #1f7a3d; }
.form-msg.err { color: #d23b1f; }
/* ── Footer ────────────────────────── */
.site-footer { background: var(--steel-d); color: #aeb3ba; padding: 40px 0; }
.footer-inner { display: flex; flex-wrap: wrap; gap: 16px; justify-content: space-between; align-items: center; }
.footer-brand .brand-name { color: #fff; }
.footer-brand p { font-size: 0.9rem; margin-top: 6px; }
.footer-fine { font-size: 0.82rem; }
/* ── Reveal animation ──────────────── */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.6s var(--ease), transform 0.6s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
* { scroll-behavior: auto !important; }
.reveal { opacity: 1 !important; transform: none !important; transition: none; }
}
/* ── Responsive ────────────────────── */
@media (max-width: 980px) {
.hero-inner { grid-template-columns: 1fr; gap: 36px; }
.services-grid { grid-template-columns: repeat(2, 1fr); }
.steps { grid-template-columns: repeat(2, 1fr); }
.gallery-grid { grid-template-columns: repeat(2, 1fr); }
.reviews-grid { grid-template-columns: 1fr; }
.consult-inner { grid-template-columns: 1fr; gap: 30px; }
}
@media (max-width: 520px) {
.main-nav { display: none; }
.header-inner { gap: 12px; }
.hero { padding: 48px 0 44px; }
.hero-stats { gap: 22px; }
.hero-stats dt { font-size: 1.7rem; }
.hero-teaser { grid-auto-rows: 110px; }
.section { padding: 54px 0; }
.services-grid,
.steps,
.gallery-grid { grid-template-columns: 1fr; }
.btn { width: 100%; }
.hero-actions { flex-direction: column; }
.nav-cta { width: auto; }
.trust-inner span + span::before { display: none; }
}// Ironbar Design-Build landing — vanilla JS, no libraries.
(function () {
'use strict';
/* ── Gallery filter ─────────────────────────── */
const filters = document.querySelectorAll('.filter');
const projects = document.querySelectorAll('.proj');
const emptyMsg = document.getElementById('galleryEmpty');
function applyFilter(cat) {
let visible = 0;
projects.forEach((p) => {
const match = cat === 'all' || p.dataset.cat === cat;
p.classList.toggle('hide', !match);
if (match) visible++;
});
if (emptyMsg) emptyMsg.hidden = visible !== 0;
}
filters.forEach((btn) => {
btn.addEventListener('click', () => {
filters.forEach((b) => {
b.classList.remove('is-active');
b.setAttribute('aria-pressed', 'false');
});
btn.classList.add('is-active');
btn.setAttribute('aria-pressed', 'true');
applyFilter(btn.dataset.filter);
});
});
/* ── Animated stat counters ─────────────────── */
const counters = document.querySelectorAll('.hero-stats dt[data-count]');
function runCounter(el) {
const target = parseInt(el.dataset.count, 10) || 0;
const suffix = el.dataset.suffix || '';
const duration = 1400;
const start = performance.now();
function tick(now) {
const t = Math.min((now - start) / duration, 1);
const eased = 1 - Math.pow(1 - t, 3); // easeOutCubic
el.textContent = Math.round(target * eased) + suffix;
if (t < 1) requestAnimationFrame(tick);
else el.textContent = target + suffix;
}
requestAnimationFrame(tick);
}
/* ── Scroll reveal + counter trigger ────────── */
const revealEls = document.querySelectorAll(
'.section-head, .svc-card, .step, .proj, .review, .consult-inner'
);
revealEls.forEach((el) => el.classList.add('reveal'));
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if ('IntersectionObserver' in window && !prefersReduced) {
const io = new IntersectionObserver(
(entries, obs) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('in');
obs.unobserve(entry.target);
}
});
},
{ threshold: 0.15 }
);
revealEls.forEach((el) => io.observe(el));
const statObs = new IntersectionObserver(
(entries, obs) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
counters.forEach(runCounter);
obs.disconnect();
}
});
},
{ threshold: 0.4 }
);
if (counters.length) statObs.observe(counters[0]);
} else {
revealEls.forEach((el) => el.classList.add('in'));
counters.forEach((el) => {
el.textContent = el.dataset.count + (el.dataset.suffix || '');
});
}
/* ── Scroll-spy nav highlight ───────────────── */
const navLinks = document.querySelectorAll('.main-nav a');
const sections = Array.from(navLinks)
.map((a) => document.querySelector(a.getAttribute('href')))
.filter(Boolean);
if ('IntersectionObserver' in window && sections.length) {
const spy = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const id = entry.target.id;
navLinks.forEach((a) =>
a.classList.toggle('active', a.getAttribute('href') === '#' + id)
);
}
});
},
{ rootMargin: '-45% 0px -50% 0px' }
);
sections.forEach((s) => spy.observe(s));
}
/* ── Consult form validation ────────────────── */
const form = document.getElementById('consultForm');
const msg = document.getElementById('formMsg');
if (form) {
form.addEventListener('submit', (e) => {
e.preventDefault();
let valid = true;
const fields = form.querySelectorAll('input[required], select[required]');
fields.forEach((f) => {
const wrap = f.closest('.field');
const ok = f.checkValidity() && f.value.trim() !== '';
if (wrap) wrap.classList.toggle('invalid', !ok);
if (!ok) valid = false;
});
if (!valid) {
msg.textContent = 'Please fill in every field with a valid value.';
msg.className = 'form-msg err';
return;
}
const name = form.querySelector('#name').value.trim().split(' ')[0];
msg.textContent = `Thanks${name ? ', ' + name : ''}! We'll send a ballpark range within 2 business days.`;
msg.className = 'form-msg ok';
form.reset();
});
// clear invalid state as the user fixes a field
form.addEventListener('input', (e) => {
const wrap = e.target.closest('.field');
if (wrap && wrap.classList.contains('invalid') && e.target.value.trim() !== '') {
wrap.classList.remove('invalid');
}
});
}
})();<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ironbar Design-Build — Home Remodeling</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<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">Ironbar<em>Design-Build</em></span>
</a>
<nav class="main-nav" aria-label="Primary">
<a href="#services">Services</a>
<a href="#process">Process</a>
<a href="#gallery">Gallery</a>
<a href="#reviews">Reviews</a>
</nav>
<a class="btn btn-hv nav-cta" href="#consult">Free Consult</a>
</div>
</header>
<main id="main">
<!-- HERO -->
<section class="hero" id="top">
<div class="hero-hazard" aria-hidden="true"></div>
<div class="wrap hero-inner">
<div class="hero-copy">
<span class="eyebrow">Licensed · Insured · Award-winning</span>
<h1>Remodels that<br /><span class="hl">build value,</span><br />not headaches.</h1>
<p class="lead">
We design, draw and build kitchens, baths, additions and whole-home renovations across
the Greater Portland area — one accountable crew, fixed-price contracts, on time.
</p>
<div class="hero-actions">
<a class="btn btn-hv" href="#consult">Book a free consult</a>
<a class="btn btn-ghost" href="#gallery">See our work</a>
</div>
<dl class="hero-stats">
<div><dt data-count="640">0</dt><dd>Projects built</dd></div>
<div><dt data-count="27">0</dt><dd>Years in trade</dd></div>
<div><dt data-count="98" data-suffix="%">0</dt><dd>On-time finish</dd></div>
</dl>
</div>
<aside class="hero-teaser" aria-label="Recent project teaser">
<figure class="teaser-card teaser-lg">
<div class="teaser-img" data-img="kitchen"></div>
<figcaption>Alameda Ridge — Chef's Kitchen</figcaption>
</figure>
<figure class="teaser-card">
<div class="teaser-img" data-img="bath"></div>
<figcaption>Sellwood Spa Bath</figcaption>
</figure>
<figure class="teaser-card">
<div class="teaser-img" data-img="addition"></div>
<figcaption>Laurelhurst Addition</figcaption>
</figure>
</aside>
</div>
</section>
<!-- TRUST STRIP -->
<section class="trust" aria-label="Credentials">
<div class="wrap trust-inner">
<span>OR CCB #214-887</span>
<span>EPA Lead-Safe Certified</span>
<span>NARI Member</span>
<span>5.0★ on 312 reviews</span>
<span>10-Year Workmanship Warranty</span>
</div>
</section>
<!-- SERVICES -->
<section class="section" id="services">
<div class="wrap">
<header class="section-head">
<span class="kicker">What we build</span>
<h2>Four ways to remodel</h2>
<p>Fixed-price scopes, real timelines, and a single project lead from drawing to punch list.</p>
</header>
<div class="cards services-grid">
<article class="svc-card">
<span class="svc-icon" aria-hidden="true">🍳</span>
<h3>Kitchen Remodels</h3>
<p>Custom cabinetry, stone counters, smart layouts and structural openings.</p>
<span class="svc-from">From $48,000</span>
</article>
<article class="svc-card">
<span class="svc-icon" aria-hidden="true">🛁</span>
<h3>Bath Remodels</h3>
<p>Curbless showers, heated floors, waterproofing done right, spa finishes.</p>
<span class="svc-from">From $26,000</span>
</article>
<article class="svc-card">
<span class="svc-icon" aria-hidden="true">🏗️</span>
<h3>Additions</h3>
<p>Bump-outs, second stories and ADUs — permits, engineering and framing.</p>
<span class="svc-from">From $135,000</span>
</article>
<article class="svc-card">
<span class="svc-icon" aria-hidden="true">🏠</span>
<h3>Whole-Home</h3>
<p>Down-to-the-studs renovations that modernize systems and open the plan.</p>
<span class="svc-from">From $310,000</span>
</article>
</div>
</div>
</section>
<!-- PROCESS -->
<section class="section section-steel" id="process">
<div class="wrap">
<header class="section-head section-head-light">
<span class="kicker">How it works</span>
<h2>The design-build process</h2>
<p>One contract, one team — no finger-pointing between architect and builder.</p>
</header>
<ol class="steps">
<li class="step">
<span class="step-num">01</span>
<h3>Discovery call</h3>
<p>A 30-minute walkthrough to scope goals, budget range and timeline.</p>
</li>
<li class="step">
<span class="step-num">02</span>
<h3>Design & estimate</h3>
<p>Drawings, 3D renders and a transparent fixed-price proposal.</p>
</li>
<li class="step">
<span class="step-num">03</span>
<h3>Build phase</h3>
<p>Dedicated lead, daily clean-up and a live schedule in your portal.</p>
</li>
<li class="step">
<span class="step-num">04</span>
<h3>Walkthrough & warranty</h3>
<p>Punch list, final walk and a 10-year workmanship warranty.</p>
</li>
</ol>
</div>
</section>
<!-- GALLERY -->
<section class="section" id="gallery">
<div class="wrap">
<header class="section-head">
<span class="kicker">Recent work</span>
<h2>Project gallery</h2>
<p>A few builds we wrapped this year — filter by room.</p>
</header>
<div class="filters" role="group" aria-label="Filter gallery by category">
<button class="filter is-active" data-filter="all" aria-pressed="true">All</button>
<button class="filter" data-filter="kitchen" aria-pressed="false">Kitchen</button>
<button class="filter" data-filter="bath" aria-pressed="false">Bath</button>
<button class="filter" data-filter="addition" aria-pressed="false">Addition</button>
<button class="filter" data-filter="whole" aria-pressed="false">Whole-Home</button>
</div>
<div class="cards gallery-grid" id="galleryGrid">
<figure class="proj" data-cat="kitchen">
<div class="proj-img" data-img="kitchen"></div>
<figcaption><strong>Alameda Ridge Kitchen</strong><span>Kitchen · $62k</span></figcaption>
</figure>
<figure class="proj" data-cat="bath">
<div class="proj-img" data-img="bath"></div>
<figcaption><strong>Sellwood Spa Bath</strong><span>Bath · $34k</span></figcaption>
</figure>
<figure class="proj" data-cat="addition">
<div class="proj-img" data-img="addition"></div>
<figcaption><strong>Laurelhurst Sunroom Addition</strong><span>Addition · $148k</span></figcaption>
</figure>
<figure class="proj" data-cat="whole">
<div class="proj-img" data-img="whole"></div>
<figcaption><strong>Irvington Whole-Home</strong><span>Whole-Home · $355k</span></figcaption>
</figure>
<figure class="proj" data-cat="kitchen">
<div class="proj-img" data-img="kitchen2"></div>
<figcaption><strong>Beaumont Galley Reno</strong><span>Kitchen · $51k</span></figcaption>
</figure>
<figure class="proj" data-cat="bath">
<div class="proj-img" data-img="bath2"></div>
<figcaption><strong>Hawthorne Primary Bath</strong><span>Bath · $29k</span></figcaption>
</figure>
<figure class="proj" data-cat="addition">
<div class="proj-img" data-img="addition2"></div>
<figcaption><strong>Mount Tabor ADU</strong><span>Addition · $186k</span></figcaption>
</figure>
<figure class="proj" data-cat="whole">
<div class="proj-img" data-img="whole2"></div>
<figcaption><strong>Eastmoreland Craftsman</strong><span>Whole-Home · $412k</span></figcaption>
</figure>
</div>
<p class="gallery-empty" id="galleryEmpty" hidden>No projects in this category yet.</p>
</div>
</section>
<!-- TESTIMONIALS -->
<section class="section section-concrete" id="reviews">
<div class="wrap">
<header class="section-head">
<span class="kicker">Homeowner reviews</span>
<h2>What our clients say</h2>
</header>
<div class="cards reviews-grid">
<blockquote class="review">
<p class="stars" aria-label="5 out of 5 stars">★★★★★</p>
<p>“They held the price and the schedule. Our kitchen demo to final walk was 41 days — exactly what the contract said.”</p>
<footer><strong>Dana & Marcus Hill</strong><span>Alameda · Kitchen</span></footer>
</blockquote>
<blockquote class="review">
<p class="stars" aria-label="5 out of 5 stars">★★★★★</p>
<p>“The daily clean-up and the client portal made living through a remodel actually bearable. Crew was respectful every day.”</p>
<footer><strong>Priya Nair</strong><span>Sellwood · Bath</span></footer>
</blockquote>
<blockquote class="review">
<p class="stars" aria-label="5 out of 5 stars">★★★★★</p>
<p>“One contract for design and build saved us months. No fighting between an architect and a builder — just one team that owned it.”</p>
<footer><strong>Greg Olsen</strong><span>Irvington · Whole-Home</span></footer>
</blockquote>
</div>
</div>
</section>
<!-- CTA -->
<section class="consult" id="consult">
<div class="consult-hazard" aria-hidden="true"></div>
<div class="wrap consult-inner">
<div class="consult-copy">
<h2>Get a free, no-pressure consult</h2>
<p>Tell us about your project and we'll send a ballpark range within two business days.</p>
</div>
<form class="consult-form" id="consultForm" novalidate>
<div class="field">
<label for="name">Name</label>
<input id="name" name="name" type="text" autocomplete="name" required placeholder="Jordan Pierce" />
</div>
<div class="field">
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required placeholder="[email protected]" />
</div>
<div class="field">
<label for="project">Project type</label>
<select id="project" name="project" required>
<option value="" disabled selected>Choose one…</option>
<option>Kitchen</option>
<option>Bath</option>
<option>Addition</option>
<option>Whole-Home</option>
</select>
</div>
<button class="btn btn-hv consult-submit" type="submit">Request my estimate</button>
<p class="form-msg" id="formMsg" 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">Ironbar<em>Design-Build</em></span>
<p>2140 SE Powell Blvd, Portland, OR 97202 · (503) 555-0148</p>
</div>
<p class="footer-fine">© 2026 Ironbar Design-Build · OR CCB #214-887 · Illustrative demo only.</p>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>Home Remodel Landing
A warm, rugged landing page for a residential design-build remodeler. The hero pairs a chunky condensed headline with a hi-vis call-to-action and a portfolio teaser strip of completed projects. Below it, four sturdy service cards cover Kitchen, Bath, Additions and Whole-Home, followed by a numbered design-build process so prospects know exactly what to expect.
A filterable gallery groups recent jobs by room type with smooth toggle buttons, real-sounding project names and dollar ranges. Testimonials add social proof, and a closing free-consultation section anchors the page with a sticky-feeling CTA. Everything is vanilla HTML, CSS and JS — the gallery filter, scroll-spy nav highlight and animated stat counters all run without libraries.
The palette leans on steel and concrete neutrals with safety-orange and hi-vis-yellow accents used sparingly, plus diagonal hazard accents and chunky borders for a trades-built feel.
Illustrative UI only — not a real contractor; do not use for actual bids or licensing.