# 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 `<a href="tel:...">`
- 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)
