# 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: 1. H1 on homepage: "Knoxville & Surrounding Areas" 2. H2 on HVAC page: "HVAC Repair in Knoxville, Powell, Halls & Beyond" 3. Body bullets on HVAC page with fake "response times" per city (makes it useful, not spammy) 4. Footer on every page: "📍 Proudly serving: Knoxville · Powell · Halls · Corryton · Fountain City · Karns" 5. 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:** ```js 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 `` - Touch targets minimum 44px ### Implementation Phases 1. Global shell (header, footer, CSS, JS, mobile nav, callbar) 2. Emergency HVAC landing page 3. Contact/quote page 4. Homepage (all 7 sections) 5. HVAC service page 6. Handyman service page 7. Polish (schema, meta, images, performance)