4.7 KiB
AirRepairTeam — Worked Blueprint Example
Full blueprint at: /mnt/seagate8tb/Websites/AirRepairTeam/BLUEPRINT.md
What This Example Demonstrates
A 6-page static website for a multi-trade contractor (HVAC + Handyman/Yardwork) serving 6 Knoxville-area cities. The blueprint covers every page section-by-section with copy psychology, CTA placement, mobile behavior, and local SEO integration.
Key Patterns Illustrated
Dual-Service Routing (Homepage Section 3)
When a business has two distinct service lines with different customer psychologies (urgent vs. comparison-shopping), the homepage hero routes traffic with two equal-weight CTAs, and Section 3 presents them as side-by-side cards with visual differentiation (cool blue for HVAC, warm green for handyman).
Emergency Landing Page (/hvac/emergency)
Stripped-down page for Google Ads traffic. No nav links. One goal: phone call. The phone number appears twice (hero + sticky bottom bar). Red/urgent accent. Must load in under 1 second — no images, no frameworks, inline CSS only if needed.
Psychology-Driven Service Pages
HVAC page (high-urgency, high-ticket):
- Hero leads with emergency language and "no after-hours fees"
- Pricing table builds trust (most HVAC companies hide pricing)
- "What to do in an HVAC emergency" section provides SEO content + conversion nudge
- Phone is always the primary CTA
Handyman page (comparison shoppers):
- Hero is a photo of completed work
- Before/after gallery is THE conversion driver — juxtoposition proves competence
- 3-step "How It Works" removes friction for first-time customers
- Lighter, friendlier tone throughout
Local SEO Integration (6 Cities)
Cities appear exactly 5 ways across the site:
- H1 on homepage: "Knoxville & Surrounding Areas"
- H2 on HVAC page: "HVAC Repair in Knoxville, Powell, Halls & Beyond"
- Body bullets on HVAC page with fake "response times" per city (makes it useful, not spammy)
- Footer on every page: "📍 Proudly serving: Knoxville · Powell · Halls · Corryton · Fountain City · Karns"
- Image alt text: "Fence installation in Powell TN"
No separate city pages. No city-page links. One consistent signal.
Quote Form Design
- 6 fields: Name*, Phone*, Email (optional), Service (dropdown), Project description, Lead source
- No calendar, no file upload, no address, no CAPTCHA (initially)
- Success state still shows phone number (for emergency callers who used the form)
- Posts to Formspree/Web3Forms — no backend
Web3Forms Form Pattern
Used on the contact page. Key implementation details:
Form handler: POST to https://api.web3forms.com/submit with an access key. The access key is configured in Web3Forms dashboard (free tier available). Form data is emailed directly to the address configured there.
Client-side validation pattern:
function validate() {
var valid = true;
function showErr(name) {
document.getElementById('field-' + name).classList.add('error');
document.getElementById('error-' + name).classList.add('visible');
}
if (!nameField.value.trim()) { showErr('name'); valid = false; }
if (!phoneField.value.trim()) { showErr('phone'); valid = false; }
if (!detailsField.value.trim()) { showErr('details'); valid = false; }
if (!serviceSelect.value) { showErr('service'); valid = false; }
return valid;
}
Error clearing on input: Each input gets an input event listener that removes .error from itself and .visible from its error span — gives instant feedback as the user types.
Loading state: Button gets disabled + .loading class. CSS swaps button text for a CSS-only spinner.
Success state: Form display: none, success div gets .visible. Message includes the customer's first name (extracted from the name field) and a prominent "if this is an emergency, call now" note with phone number.
Error state: Red banner at top of form card with "Something went wrong" message. Button re-enables for retry.
CORS note: Fetch to Web3Forms will be blocked on file:// origins (browser security). Works correctly on any real domain. Test form behavior locally by manually toggling success/error state classes.
Mobile-Specific Decisions
- Sticky tap-to-call bar below header on all pages (hidden on desktop)
- Both the nav bar AND callbar remain sticky — combined ~100px height, acceptable tradeoff
- Buttons full-width on mobile
- Phone numbers always
<a href="tel:..."> - Touch targets minimum 44px
Implementation Phases
- Global shell (header, footer, CSS, JS, mobile nav, callbar)
- Emergency HVAC landing page
- Contact/quote page
- Homepage (all 7 sections)
- HVAC service page
- Handyman service page
- Polish (schema, meta, images, performance)