Construction — Construction FAQ
A rugged contractor FAQ with a live search box, accordion questions grouped into Estimates, Permits, Timeline, Payment and Warranty, full keyboard support with arrow keys and home/end, an empty-search state, a live result count and a hi-vis contact CTA card.
MCP
Code
:root {
--hv: #f5c518;
--steel: #2b3440;
--steel-d: #1b222b;
--bg: #eceae6;
--ink: #1a1d22;
--muted: #666c75;
--orange: #e8642a;
--white: #ffffff;
--line: #d2cfc8;
--radius: 6px;
--shadow: 0 2px 0 rgba(27, 34, 43, 0.08), 0 10px 24px rgba(27, 34, 43, 0.08);
--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,
p,
dl,
dd {
margin: 0;
}
button,
input {
font-family: inherit;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
border: 0;
}
.wrap {
max-width: 760px;
margin: 0 auto;
padding: 40px 20px 64px;
}
/* ---------- Masthead ---------- */
.masthead {
margin-bottom: 28px;
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--muted);
}
.hazard {
width: 34px;
height: 12px;
border-radius: 2px;
background: repeating-linear-gradient(
-45deg,
var(--hv) 0 7px,
var(--steel-d) 7px 14px
);
}
h1 {
margin: 10px 0 8px;
font-size: clamp(2rem, 6vw, 2.9rem);
font-weight: 800;
letter-spacing: -0.02em;
line-height: 1.04;
text-transform: uppercase;
}
.lead {
max-width: 56ch;
color: var(--muted);
font-size: 1rem;
}
/* ---------- Search ---------- */
.search {
position: relative;
display: flex;
align-items: center;
margin: 22px 0 8px;
background: var(--white);
border: 2px solid var(--steel);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.search__icon {
padding-left: 14px;
font-size: 1rem;
}
.search input {
flex: 1;
border: 0;
background: transparent;
padding: 14px 12px;
font-size: 1rem;
color: var(--ink);
}
.search input:focus {
outline: none;
}
.search:focus-within {
border-color: var(--orange);
box-shadow: 0 0 0 3px rgba(232, 100, 42, 0.25);
}
.search__clear {
margin-right: 8px;
padding: 7px 12px;
border: 1px solid var(--line);
border-radius: 4px;
background: var(--bg);
color: var(--ink);
font-size: 0.8rem;
font-weight: 600;
cursor: pointer;
}
.search__clear:hover {
background: var(--steel);
color: var(--white);
border-color: var(--steel);
}
.count {
font-size: 0.8rem;
font-weight: 600;
color: var(--muted);
}
/* ---------- Groups ---------- */
.group {
margin-top: 26px;
}
.group.is-hidden {
display: none;
}
.group__title {
display: flex;
align-items: center;
gap: 12px;
font-size: 0.95rem;
font-weight: 800;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--steel-d);
padding-bottom: 10px;
border-bottom: 3px solid var(--steel);
margin-bottom: 4px;
}
.group__tag {
display: inline-grid;
place-items: center;
min-width: 30px;
height: 24px;
padding: 0 6px;
background: var(--hv);
color: var(--steel-d);
font-size: 0.78rem;
font-weight: 800;
border-radius: 3px;
}
/* ---------- Accordion ---------- */
.acc {
display: flex;
flex-direction: column;
}
.item {
border-bottom: 1px solid var(--line);
}
.item.is-hidden {
display: none;
}
.trigger {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
padding: 16px 4px;
background: transparent;
border: 0;
text-align: left;
cursor: pointer;
color: var(--ink);
}
.trigger__q {
font-size: 1rem;
font-weight: 600;
line-height: 1.4;
}
.trigger:hover .trigger__q {
color: var(--orange);
}
.trigger:focus-visible {
outline: 3px solid var(--orange);
outline-offset: 2px;
border-radius: 4px;
}
.trigger__icon {
flex: none;
position: relative;
width: 22px;
height: 22px;
border: 2px solid var(--steel);
border-radius: 4px;
}
.trigger__icon::before,
.trigger__icon::after {
content: "";
position: absolute;
background: var(--steel);
border-radius: 1px;
transition: transform 0.18s ease, opacity 0.18s ease;
}
.trigger__icon::before {
top: 50%;
left: 4px;
right: 4px;
height: 2px;
transform: translateY(-50%);
}
.trigger__icon::after {
left: 50%;
top: 4px;
bottom: 4px;
width: 2px;
transform: translateX(-50%);
}
.trigger[aria-expanded="true"] .trigger__icon {
background: var(--hv);
border-color: var(--steel-d);
}
.trigger[aria-expanded="true"] .trigger__icon::before,
.trigger[aria-expanded="true"] .trigger__icon::after {
background: var(--steel-d);
}
.trigger[aria-expanded="true"] .trigger__icon::after {
transform: translateX(-50%) scaleY(0);
opacity: 0;
}
.panel {
padding: 0 4px 18px;
}
.panel p {
color: var(--muted);
font-size: 0.95rem;
max-width: 62ch;
}
/* ---------- Search highlight ---------- */
mark {
background: var(--hv);
color: var(--steel-d);
padding: 0 2px;
border-radius: 2px;
}
/* ---------- Empty state ---------- */
.empty {
margin-top: 28px;
padding: 32px 24px;
text-align: center;
background: var(--white);
border: 2px dashed var(--line);
border-radius: var(--radius);
}
.empty__title {
font-size: 1.1rem;
font-weight: 700;
}
.empty__sub {
margin: 6px 0 16px;
color: var(--muted);
font-size: 0.92rem;
}
/* ---------- Buttons ---------- */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 12px 18px;
border-radius: var(--radius);
font-size: 0.9rem;
font-weight: 700;
text-decoration: none;
cursor: pointer;
border: 2px solid transparent;
transition: transform 0.12s ease, background 0.12s ease;
}
.btn:active {
transform: translateY(1px);
}
.btn:focus-visible {
outline: 3px solid var(--orange);
outline-offset: 2px;
}
.btn--hv {
background: var(--hv);
color: var(--steel-d);
border-color: var(--steel-d);
}
.btn--hv:hover {
background: #ffd633;
}
.btn--steel {
background: var(--steel);
color: var(--white);
}
.btn--steel:hover {
background: var(--steel-d);
}
.btn--ghost {
background: transparent;
color: var(--ink);
border-color: var(--steel);
}
.btn--ghost:hover {
background: var(--steel);
color: var(--white);
}
/* ---------- CTA ---------- */
.cta {
position: relative;
display: flex;
margin-top: 36px;
overflow: hidden;
background: var(--steel-d);
color: var(--white);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.cta__stripe {
flex: none;
width: 14px;
background: repeating-linear-gradient(
-45deg,
var(--hv) 0 10px,
var(--steel-d) 10px 20px
);
}
.cta__body {
padding: 26px 24px;
}
.cta__body h2 {
font-size: 1.3rem;
font-weight: 800;
letter-spacing: -0.01em;
}
.cta__body p {
margin: 8px 0 18px;
color: #c3c8cf;
font-size: 0.95rem;
}
.cta__actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.cta .btn--ghost {
color: var(--white);
border-color: rgba(255, 255, 255, 0.4);
}
.cta .btn--ghost:hover {
background: var(--white);
color: var(--steel-d);
border-color: var(--white);
}
/* ---------- Responsive ---------- */
@media (max-width: 520px) {
.wrap {
padding: 28px 14px 48px;
}
.trigger {
padding: 14px 2px;
}
.trigger__q {
font-size: 0.95rem;
}
.cta {
flex-direction: column;
}
.cta__stripe {
width: auto;
height: 12px;
}
.cta__actions .btn {
flex: 1 1 100%;
}
}(function () {
"use strict";
var root = document.getElementById("faq-root");
var triggers = Array.prototype.slice.call(root.querySelectorAll(".trigger"));
var items = Array.prototype.slice.call(root.querySelectorAll("[data-item]"));
var groups = Array.prototype.slice.call(root.querySelectorAll("[data-group]"));
var searchInput = document.getElementById("faq-search");
var clearBtn = document.getElementById("faq-clear");
var countEl = document.getElementById("faq-count");
var emptyEl = document.getElementById("faq-empty");
var emptyTerm = document.getElementById("empty-term");
var emptyReset = document.getElementById("empty-reset");
var total = items.length;
/* ---------- Accordion toggle ---------- */
function setOpen(trigger, open) {
var panel = document.getElementById(trigger.getAttribute("aria-controls"));
trigger.setAttribute("aria-expanded", open ? "true" : "false");
if (panel) {
if (open) panel.removeAttribute("hidden");
else panel.setAttribute("hidden", "");
}
}
triggers.forEach(function (trigger) {
trigger.addEventListener("click", function () {
var open = trigger.getAttribute("aria-expanded") === "true";
setOpen(trigger, !open);
});
});
/* ---------- Keyboard navigation ---------- */
function visibleTriggers() {
return triggers.filter(function (t) {
return !t.closest("[data-item]").classList.contains("is-hidden");
});
}
root.addEventListener("keydown", function (e) {
var current = e.target.closest(".trigger");
if (!current) return;
var list = visibleTriggers();
var i = list.indexOf(current);
if (i === -1) return;
var next = null;
switch (e.key) {
case "ArrowDown":
next = list[(i + 1) % list.length];
break;
case "ArrowUp":
next = list[(i - 1 + list.length) % list.length];
break;
case "Home":
next = list[0];
break;
case "End":
next = list[list.length - 1];
break;
default:
return;
}
if (next) {
e.preventDefault();
next.focus();
}
});
/* ---------- Search / filter ---------- */
function escapeRegExp(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function clearHighlights(el) {
var marks = el.querySelectorAll("mark");
marks.forEach(function (m) {
var parent = m.parentNode;
parent.replaceChild(document.createTextNode(m.textContent), m);
parent.normalize();
});
}
function highlight(el, term) {
if (!term) return;
var re = new RegExp("(" + escapeRegExp(term) + ")", "ig");
var walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null);
var nodes = [];
var node;
while ((node = walker.nextNode())) {
if (re.test(node.nodeValue)) nodes.push(node);
}
nodes.forEach(function (textNode) {
var span = document.createElement("span");
span.innerHTML = textNode.nodeValue.replace(re, "<mark>$1</mark>");
textNode.parentNode.replaceChild(span, textNode);
while (span.firstChild) span.parentNode.insertBefore(span.firstChild, span);
span.parentNode.removeChild(span);
});
}
function applySearch(raw) {
var term = raw.trim().toLowerCase();
var matches = 0;
items.forEach(function (item) {
clearHighlights(item);
var text = item.textContent.toLowerCase();
var hit = term === "" || text.indexOf(term) !== -1;
item.classList.toggle("is-hidden", !hit);
if (hit) {
matches++;
if (term) highlight(item, term);
}
});
// Hide group headers that have no visible items
groups.forEach(function (group) {
var anyVisible = group.querySelector("[data-item]:not(.is-hidden)");
group.classList.toggle("is-hidden", !anyVisible);
});
// Empty state + counts
var hasTerm = term !== "";
clearBtn.hidden = !hasTerm;
if (matches === 0) {
emptyTerm.textContent = raw.trim();
emptyEl.hidden = false;
countEl.textContent = "No questions match your search";
} else {
emptyEl.hidden = true;
countEl.textContent = hasTerm
? matches + " of " + total + " questions match"
: total + " questions";
}
}
searchInput.addEventListener("input", function () {
applySearch(searchInput.value);
});
function resetSearch() {
searchInput.value = "";
applySearch("");
searchInput.focus();
}
clearBtn.addEventListener("click", resetSearch);
emptyReset.addEventListener("click", resetSearch);
// Init
applySearch("");
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Construction FAQ — Ironridge Builders</title>
<link
rel="preconnect"
href="https://fonts.googleapis.com"
/>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="wrap">
<header class="masthead">
<p class="eyebrow"><span class="hazard"></span> Ironridge Builders · Help Center</p>
<h1>Construction FAQ</h1>
<p class="lead">
Answers on estimates, permits, schedules, payment and warranties for residential and
light-commercial projects. Search below or browse by topic.
</p>
<div class="search">
<label class="visually-hidden" for="faq-search">Search the FAQ</label>
<span class="search__icon" aria-hidden="true">🔎</span>
<input
id="faq-search"
type="search"
placeholder="Search questions… e.g. permit, deposit, warranty"
autocomplete="off"
aria-describedby="faq-count"
/>
<button id="faq-clear" class="search__clear" type="button" hidden>Clear</button>
</div>
<p id="faq-count" class="count" role="status" aria-live="polite">18 questions</p>
</header>
<div id="faq-root" class="faq">
<!-- ESTIMATES -->
<section class="group" data-group>
<h2 class="group__title"><span class="group__tag">01</span> Estimates</h2>
<dl class="acc">
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-e1"
id="t-e1"
>
<span class="trigger__q">Is the initial estimate free?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-e1" role="region" aria-labelledby="t-e1" hidden>
<p>
Yes. The first on-site walkthrough and written estimate are free for projects
within 30 miles of our Hayward yard. Detailed design-build proposals with
architectural drawings carry a refundable $450 fee credited toward your contract.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-e2"
id="t-e2"
>
<span class="trigger__q">How long is a quote valid?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-e2" role="region" aria-labelledby="t-e2" hidden>
<p>
Quotes are firm for 30 days. After that, material pricing — especially lumber,
steel and concrete — may be re-checked. We lock final numbers the day you sign and
pay the deposit.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-e3"
id="t-e3"
>
<span class="trigger__q">Why do bids vary so much between contractors?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-e3" role="region" aria-labelledby="t-e3" hidden>
<p>
Low bids often omit allowances for permits, demolition, dump fees or finish-grade
materials. Our estimates itemize labor, materials, subcontractors and a clearly
marked contingency so you can compare line by line.
</p>
</dd>
</div>
</dl>
</section>
<!-- PERMITS -->
<section class="group" data-group>
<h2 class="group__title"><span class="group__tag">02</span> Permits</h2>
<dl class="acc">
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-pm1"
id="t-pm1"
>
<span class="trigger__q">Do you handle the building permits?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-pm1" role="region" aria-labelledby="t-pm1" hidden>
<p>
Yes. As the licensed general contractor (CSLB #1042887) we pull and manage all
building, electrical, plumbing and mechanical permits, and we coordinate every
inspection through final sign-off.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-pm2"
id="t-pm2"
>
<span class="trigger__q">How long does permitting usually take?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-pm2" role="region" aria-labelledby="t-pm2" hidden>
<p>
Over-the-counter permits (a water heater, a deck) often clear same-day. Plan-check
for additions or ADUs typically runs 4–8 weeks depending on the jurisdiction. We
build that review window into your project schedule.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-pm3"
id="t-pm3"
>
<span class="trigger__q">What if my project needs HOA or coastal approval?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-pm3" role="region" aria-labelledby="t-pm3" hidden>
<p>
We prepare the submittal packages and attend HOA architectural reviews or coastal
hearings with you. These approvals are outside our control on timing, so they are
tracked as separate schedule milestones.
</p>
</dd>
</div>
</dl>
</section>
<!-- TIMELINE -->
<section class="group" data-group>
<h2 class="group__title"><span class="group__tag">03</span> Timeline</h2>
<dl class="acc">
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-tl1"
id="t-tl1"
>
<span class="trigger__q">How soon can you start?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-tl1" role="region" aria-labelledby="t-tl1" hidden>
<p>
Once permits are issued and the deposit clears, most kitchen and bath remodels
start within 2–3 weeks. Larger additions are scheduled at signing so we can order
long-lead items like windows and cabinetry early.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-tl2"
id="t-tl2"
>
<span class="trigger__q">What can delay a project?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-tl2" role="region" aria-labelledby="t-tl2" hidden>
<p>
The usual culprits are change orders, hidden conditions found during demolition
(dry rot, outdated wiring), special-order backorders and weather on exterior work.
We flag risks at our weekly Monday site meeting.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-tl3"
id="t-tl3"
>
<span class="trigger__q">Will I have one point of contact?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-tl3" role="region" aria-labelledby="t-tl3" hidden>
<p>
Yes — a dedicated project manager runs your job day to day, posts photo updates to
the client portal and answers questions within one business day. The owner,
Marcus Delgado, reviews every project weekly.
</p>
</dd>
</div>
</dl>
</section>
<!-- PAYMENT -->
<section class="group" data-group>
<h2 class="group__title"><span class="group__tag">04</span> Payment</h2>
<dl class="acc">
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-pa1"
id="t-pa1"
>
<span class="trigger__q">How is the payment schedule structured?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-pa1" role="region" aria-labelledby="t-pa1" hidden>
<p>
We follow California's progress-payment rules: a 10% or $1,000 deposit (whichever
is less), then draws tied to completed milestones — rough-in, drywall, finishes —
with a final payment due only after your walkthrough and punch list are signed off.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-pa2"
id="t-pa2"
>
<span class="trigger__q">What payment methods do you accept?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-pa2" role="region" aria-labelledby="t-pa2" hidden>
<p>
ACH bank transfer and check are preferred and carry no fee. Cards are accepted up
to $5,000 per draw with a 2.9% processing surcharge. Financing is available
through our lending partner with terms from 12 to 84 months.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-pa3"
id="t-pa3"
>
<span class="trigger__q">How are change orders billed?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-pa3" role="region" aria-labelledby="t-pa3" hidden>
<p>
Every change order is written, priced and approved by you before work proceeds. No
surprise charges appear on your final invoice — if it is not on a signed change
order, you do not pay for it.
</p>
</dd>
</div>
</dl>
</section>
<!-- WARRANTY -->
<section class="group" data-group>
<h2 class="group__title"><span class="group__tag">05</span> Warranty</h2>
<dl class="acc">
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-w1"
id="t-w1"
>
<span class="trigger__q">What warranty comes with the work?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-w1" role="region" aria-labelledby="t-w1" hidden>
<p>
All workmanship is covered by a 2-year Ironridge warranty, and structural framing
carries a 10-year guarantee. Manufacturer warranties on materials such as roofing,
appliances and windows are registered in your name and passed straight to you.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-w2"
id="t-w2"
>
<span class="trigger__q">How do I file a warranty claim?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-w2" role="region" aria-labelledby="t-w2" hidden>
<p>
Email [email protected] or open a ticket in the client portal with
photos. We respond within 2 business days and schedule a service visit, usually
within the same week for anything affecting safety or weather-tightness.
</p>
</dd>
</div>
<div class="item" data-item>
<dt>
<button
type="button"
class="trigger"
aria-expanded="false"
aria-controls="p-w3"
id="t-w3"
>
<span class="trigger__q">Are you licensed, bonded and insured?</span>
<span class="trigger__icon" aria-hidden="true"></span>
</button>
</dt>
<dd class="panel" id="p-w3" role="region" aria-labelledby="t-w3" hidden>
<p>
Yes — CSLB license #1042887, a $25,000 contractor's bond and $2M general liability
plus full workers' compensation coverage. We provide certificates of insurance to
any homeowner or HOA on request.
</p>
</dd>
</div>
</dl>
</section>
</div>
<!-- EMPTY STATE -->
<div id="faq-empty" class="empty" hidden>
<p class="empty__title">No matches for “<span id="empty-term"></span>”</p>
<p class="empty__sub">Try a different word, or reach out below and we'll answer directly.</p>
<button type="button" class="btn btn--ghost" id="empty-reset">Reset search</button>
</div>
<!-- CONTACT CTA -->
<aside class="cta" aria-labelledby="cta-title">
<span class="cta__stripe" aria-hidden="true"></span>
<div class="cta__body">
<h2 id="cta-title">Still got a question on the punch list?</h2>
<p>
Talk to a real estimator — no call centers, no bots. We answer Monday to Saturday,
7am–6pm.
</p>
<div class="cta__actions">
<a class="btn btn--hv" href="tel:+15105550148">Call (510) 555-0148</a>
<a class="btn btn--steel" href="mailto:[email protected]">Email us</a>
<a class="btn btn--ghost" href="#">Request an estimate</a>
</div>
</div>
</aside>
</main>
<script src="script.js"></script>
</body>
</html>Construction FAQ
A sturdy, job-site-flavoured help section for a general contractor. Questions are grouped into five
labelled sections — Estimates, Permits, Timeline, Payment and Warranty — each
rendered as an accessible disclosure accordion built on real <button> triggers with
aria-expanded and aria-controls.
A live search filters questions and answers as you type, highlights the matched section headings, keeps a running result count and shows a friendly empty state with a one-tap clear button. The accordion is fully keyboard operable: Up/Down move between questions, Home/End jump to the first or last, and Enter/Space toggle the panel.
The hi-vis contact CTA card at the bottom routes anyone whose question is not covered to call, email or request an estimate. Everything is vanilla JS with no libraries.
Illustrative UI only — not for real construction, permitting or contractual use.