70 lines
3.9 KiB
Markdown
70 lines
3.9 KiB
Markdown
# Blueprint-First Multi-Page Static Sites
|
|
|
|
Pattern used for AirRepairTeam (HVAC + handyman business site). Reusable when a user provides a detailed specification document and wants a complete multi-page static site built incrementally.
|
|
|
|
## When This Pattern Fits
|
|
|
|
- User provides a design blueprint / spec document (markdown, detailed wireframes)
|
|
- Site is multi-page (5+ pages) with shared shell (header, footer, nav)
|
|
- Pure static HTML/CSS/JS — no framework, no build step, no backend
|
|
- Each page has distinct layout and conversion goals
|
|
- Mobile-first responsive required
|
|
- Local SEO considerations (schema.org, service areas, NAP consistency)
|
|
|
|
## Workflow
|
|
|
|
### 0. Create the Blueprint (if not provided)
|
|
Write a BLUEPRINT.md that covers: URL structure, page-by-page section breakdowns, mobile rules, SEO checklist, color palette, typography, and build order. Get user signoff before coding.
|
|
|
|
### 1. Global Shell (Phase 1)
|
|
- Directory structure: `css/`, `js/`, `images/`, subdirectories per page
|
|
- `css/style.css`: CSS variables, reset, buttons, header, callbar, footer, responsive breakpoints. Mobile-first.
|
|
- `js/main.js`: hamburger toggle, scroll shrink, active nav highlighting
|
|
- `index.html`: header, mobile nav drawer, tap-to-call bar, footer — wired together
|
|
- Verify: browser navigate + console check for JS errors
|
|
|
|
### 2-N. Build Pages in Priority Order
|
|
Each phase produces a single deployable page. Priority order from the blueprint's implementation section.
|
|
|
|
**Pattern per page:**
|
|
1. Write the HTML (extend the shell — copy header/footer from index.html if standalone)
|
|
2. Add page-specific CSS (appended to style.css, or inline for critical pages)
|
|
3. Add page-specific JS (inline `<script>` at bottom of body)
|
|
4. Verify with browser navigate + console
|
|
|
|
### Key Patterns
|
|
|
|
**Form handling (contact pages):**
|
|
- Use Web3Forms (free tier) — `POST` to `https://api.web3forms.com/submit` with `access_key`
|
|
- Client-side validation: required fields, error classes on inputs, error text spans
|
|
- Submit flow: disable button → show spinner → fetch → success/error state
|
|
- Success state: hide form, show thank-you with first name, include emergency phone CTA
|
|
- Error state: show banner, re-enable button, keep form filled
|
|
- Note: `file://` origin blocks fetch (CORS). Works fine on real domain.
|
|
|
|
**Emergency landing pages:**
|
|
- Zero external resources — inline everything for sub-1s load
|
|
- Single goal: phone call. No navigation. No distractions.
|
|
- Large tel: link button, pulse animation on urgency badge
|
|
- System font stack only
|
|
|
|
**Local SEO in static sites:**
|
|
- Schema.org `LocalBusiness` JSON-LD in `<head>` with `areaServed` array
|
|
- Service areas appear in: H1/H2 headings, body content (bulleted with context), footer (single line)
|
|
- Each page gets unique `<title>` and `<meta description>` with city keywords
|
|
- NAP (Name, Address, Phone) consistent across all pages
|
|
- Image alt text includes city names: "Fence installation in Powell TN"
|
|
|
|
**Multi-page consistency:**
|
|
- Header, footer, mobile nav, and callbar are identical across all pages
|
|
- CSS variables ensure color/spacing consistency
|
|
- Each page links the shared `style.css` and `js/main.js`
|
|
- Standalone pages (emergency landing) inline everything for speed
|
|
|
|
## Pitfalls
|
|
|
|
- **file:// CORS**: fetch() to external APIs fails from `file://` origin. Don't treat this as a bug — it works on a real server. Test form validation locally, not API submission.
|
|
- **Relative paths**: `/js/main.js` works on a web server but NOT from `file://` (resolves to filesystem root). When testing locally from `file://`, expect 404s on absolute-path resources.
|
|
- **Accessibility snapshots**: CSS state changes (`.error`, `.visible` classes) don't always show in text-based browser snapshots. Use `browser_console` to check classList directly.
|
|
- **Select dropdowns**: `browser_click` on `<option>` elements fails with CDP box model errors on some setups. Use `browser_console` to set `.value` programmatically instead.
|