initial commit
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
---
|
||||
name: local-business-website
|
||||
description: Build production static websites for local service businesses — blueprint-first workflow, mobile-first CSS patterns, local SEO integration, phased implementation. Absorbed small-business-website (directory structure, CSS architecture, gallery/pricing table patterns).
|
||||
---
|
||||
|
||||
## Trigger
|
||||
|
||||
Use this skill when the user asks to build, design, or architect a static website for a local service business (HVAC, handyman, plumbing, landscaping, roofing, electrical, etc.). Also load it when the user references a website blueprint or a multi-page brochure site for a local business.
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Gather Requirements
|
||||
|
||||
Before any code, collect:
|
||||
- Business name and owner
|
||||
- Service lines (primary and secondary)
|
||||
- Service areas (cities/neighborhoods — critical for local SEO)
|
||||
- USPs (24/7 emergency, family-owned, flat-rate pricing, etc.)
|
||||
- Phone number and email
|
||||
- Any specific pages needed beyond the standard set
|
||||
|
||||
If the user is terse (common for this user), ask directly rather than guessing business type or features.
|
||||
|
||||
### 2. Produce a BLUEPRINT.md
|
||||
|
||||
Write a comprehensive blueprint document saved to the project directory BEFORE writing any code. Cover:
|
||||
- URL structure for every page
|
||||
- Technology choices (static HTML/CSS/JS, no frameworks, no build step — keep it fast and portable)
|
||||
- Global header and footer design (desktop + mobile behavior)
|
||||
- Every page: section-by-section layout with copy guidance, CTA placement, and psychology notes
|
||||
- Mobile-specific rules (touch targets, sticky bars, typography)
|
||||
- Local SEO checklist: where each service area city appears (H1, H2, footer, image alt text)
|
||||
- Color palette and typography spec
|
||||
- Implementation phases: each phase produces a deployable increment
|
||||
|
||||
The blueprint is the source of truth. All implementation decisions trace back to it.
|
||||
|
||||
### 3. Build in Phases
|
||||
|
||||
Standard phase order for local business sites:
|
||||
|
||||
| Phase | Deliverable | Priority |
|
||||
|-------|------------|----------|
|
||||
| 1 | Global shell: base HTML, CSS custom properties, header, footer, mobile nav, tap-to-call bar, shared JS | Foundation |
|
||||
| 2 | Emergency/urgent landing page (if applicable) | Highest conversion |
|
||||
| 3 | Contact/quote form page | Lead capture |
|
||||
| 4 | Homepage (all sections) | Main entry point |
|
||||
| 5+ | Secondary service pages | Supporting pages |
|
||||
| Final | Polish: schema.org, meta tags, image optimization, performance | SEO finish |
|
||||
|
||||
Each phase produces a working, self-contained increment. Never deliver a half-built page.
|
||||
|
||||
## CSS Architecture (Mobile-First)
|
||||
|
||||
### Custom Properties
|
||||
|
||||
Always use CSS custom properties on `:root`. Standard palette for local business sites:
|
||||
|
||||
```css
|
||||
:root {
|
||||
--color-primary: #1E40AF; /* Blue — trust */
|
||||
--color-secondary: #15803D; /* Green — growth/outdoors */
|
||||
--color-emergency: #DC2626; /* Red — urgency only */
|
||||
--color-dark: #111827; /* Near-black body text */
|
||||
--color-medium: #6B7280; /* Secondary text */
|
||||
--color-light: #F9FAFB; /* Page background */
|
||||
--color-white: #FFFFFF;
|
||||
--color-border: #E5E7EB;
|
||||
|
||||
--font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
--max-width: 72rem;
|
||||
--header-height: 64px;
|
||||
--callbar-height: 48px;
|
||||
}
|
||||
```
|
||||
|
||||
Use system font stack — no Google Fonts. Zero FOUT, fastest load.
|
||||
|
||||
### Mobile-First Rules
|
||||
|
||||
- Body text: 16px minimum (prevents iOS zoom on input focus)
|
||||
- All tappable elements: minimum 44×44px
|
||||
- Buttons: full-width on mobile
|
||||
- Phone numbers: ALWAYS `<a href="tel:...">` — never plain text
|
||||
- Section padding: 48px top/bottom on mobile
|
||||
|
||||
### Header (Sticky)
|
||||
|
||||
Three zones:
|
||||
1. **Desktop (≥768px):** Logo left, nav center, phone + CTA button right. Sticky, shrinks on scroll.
|
||||
2. **Mobile (<768px):** Logo left, hamburger right. Hamburger opens slide-down drawer with all links + emergency call button.
|
||||
3. **Mobile nav drawer:** Full-viewport overlay below header. Links at 18px, bold, with rounded tap targets. Close on link tap.
|
||||
|
||||
Pattern:
|
||||
```html
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a href="/" class="logo">...</a>
|
||||
<nav class="main-nav">...</nav>
|
||||
<div class="header-right">...</div>
|
||||
<button class="hamburger">...</button>
|
||||
</div>
|
||||
</header>
|
||||
<nav class="mobile-nav">...</nav>
|
||||
```
|
||||
|
||||
### Tap-to-Call Bar (Mobile Only)
|
||||
|
||||
CRITICAL for service businesses. A sticky bar below the header on mobile (<768px) with phone icon + "Call Now: (XXX) XXX-XXXX — 24/7" that dials on tap. Hidden on desktop via CSS media query.
|
||||
|
||||
```html
|
||||
<a href="tel:+1XXXXXXXXXX" class="callbar">
|
||||
<svg><!-- phone icon --></svg>
|
||||
Call Now: (XXX) XXX-XXXX — 24/7
|
||||
</a>
|
||||
```
|
||||
|
||||
CSS: `position: fixed; top: var(--header-height);` — sits between header and content. Use accent/emergency background color.
|
||||
|
||||
The body gets `padding-top: calc(var(--header-height) + var(--callbar-height))` on mobile, `padding-top: var(--header-height)` on desktop.
|
||||
|
||||
### Footer
|
||||
|
||||
Three-section grid on desktop (brand, nav, contact), stacked on mobile. Must include service area cities in natural language: "📍 Proudly serving: City1 · City2 · City3"
|
||||
|
||||
## Local SEO Patterns
|
||||
|
||||
### Where to Place Service Areas
|
||||
|
||||
| Element | Location | Format |
|
||||
|---------|----------|--------|
|
||||
| H1 | Homepage hero | "Service in City1 & Surrounding Areas" |
|
||||
| H2 | Service area section | "Serving City1, City2 & Beyond" |
|
||||
| Body list | Dedicated section on main service page | Bullet points with context ("City1 — 30-min response") |
|
||||
| Footer | Global footer | Single line, all pages |
|
||||
| Image alt text | Gallery/service photos | "Fence installation in City1 TN" |
|
||||
| Meta description | `<head>` per page | Include primary city |
|
||||
| Schema.org | JSON-LD `LocalBusiness` | `areaServed` array |
|
||||
|
||||
### Schema.org Template
|
||||
|
||||
```json
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "LocalBusiness",
|
||||
"name": "Business Name",
|
||||
"telephone": "(XXX) XXX-XXXX",
|
||||
"areaServed": ["City1", "City2", "City3"],
|
||||
"hasOfferCatalog": {
|
||||
"@type": "OfferCatalog",
|
||||
"name": "Service Category",
|
||||
"itemListElement": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Include on every page.
|
||||
|
||||
### Anti-Patterns
|
||||
|
||||
- Do NOT create separate pages for each service area city — spammy, adds no value
|
||||
- Do NOT link city names to dedicated city pages
|
||||
- Do NOT keyword-stuff city names into every heading
|
||||
- One well-optimized service area mention beats six low-quality city pages
|
||||
|
||||
## JavaScript (Vanilla, No Dependencies)
|
||||
|
||||
Three pieces of shared JS:
|
||||
|
||||
1. **Mobile nav toggle:** hamburger click → open/close drawer, animate hamburger icon, set `body overflow: hidden` when open, close on link tap
|
||||
2. **Header shrink on scroll:** add `.scrolled` class when `scrollY > 80`
|
||||
3. **Active nav highlighting:** match `window.location.pathname` against nav links
|
||||
|
||||
Keep it simple. No frameworks. `DOMContentLoaded` wrapper. All vanilla.
|
||||
|
||||
## Quote/Contact Form Pattern
|
||||
|
||||
Use Web3Forms (free tier, simple API) for form-to-email on static sites. No backend needed.
|
||||
|
||||
### Form Fields (6-field standard)
|
||||
- Name* (text, required)
|
||||
- Phone* (tel, required) — phone is THE critical field for local businesses
|
||||
- Email (email, optional) — don't require; some local customers don't use email
|
||||
- Service Needed* (select, required) — routes the lead mentally, helps owner prioritize
|
||||
- Project Description* (textarea, required) — gives context before callback
|
||||
- Lead Source (select, optional) — helps track which marketing works
|
||||
|
||||
### Validation Pattern
|
||||
Client-side only. On submit: check required fields, add `.error` class to empty inputs (red border), add `.visible` to error spans. On input: remove error classes — instant feedback.
|
||||
|
||||
### States
|
||||
- **Loading:** button disabled + CSS spinner (swaps button text for animated spinner via `display` toggle)
|
||||
- **Success:** form hidden, success card shown. Includes customer's first name + emergency phone CTA
|
||||
- **Error:** red banner displayed, button re-enabled for retry
|
||||
|
||||
### Web3Forms Setup
|
||||
1. Create free account at https://web3forms.com/
|
||||
2. Replace `YOUR_ACCESS_KEY` in the form script
|
||||
3. Form POSTs to `https://api.web3forms.com/submit`
|
||||
4. Emails go to the address configured in dashboard
|
||||
|
||||
Full implementation reference at `references/airrepairteam-blueprint.md`.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **Don't use Google Fonts** — system font stack is faster and looks native on every device
|
||||
- **Don't use iframe Google Maps** — they kill page speed. Use a static image or CSS map
|
||||
- **Don't add a calendar/scheduler to forms** — adds complexity, needs backend, breaks when not maintained. Simple POST-to-email via Formspree or Web3Forms is enough
|
||||
- **Don't require email on quote forms** — some local customers don't use email. Phone is the required field
|
||||
- **Don't build landing pages with nav links** — emergency landing pages should have ONE exit: the phone number
|
||||
- **Don't use frameworks for simple brochure sites** — Tailwind or raw CSS is fine, but React/Vue/Next.js is overkill and adds hosting complexity the owner can't maintain
|
||||
|
||||
## Support Files
|
||||
|
||||
- `references/airrepairteam-blueprint.md` — Full blueprint example: 6-page HVAC/handyman site with section-by-section layout, mobile rules, and SEO checklist
|
||||
- `references/blueprint-template.md` — Empty website blueprint template (absorbed from small-business-website)
|
||||
- `references/contact-form.md` — Complete Web3Forms contact form pattern with HTML, CSS, and JS (absorbed from small-business-website)
|
||||
- `templates/style.css` — Copyable base CSS: custom properties, reset, header, callbar, footer, responsive breakpoints
|
||||
- `templates/main.js` — Copyable base JS: mobile nav toggle, header shrink, active link detection, smooth scroll
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```text
|
||||
BusinessName/
|
||||
├── BLUEPRINT.md
|
||||
├── index.html
|
||||
├── css/style.css
|
||||
├── js/main.js
|
||||
├── contact/index.html
|
||||
├── service-pages/...
|
||||
├── images/
|
||||
```
|
||||
|
||||
## Global CSS Architecture (Section Order)
|
||||
|
||||
All styles go in `css/style.css`. Structure:
|
||||
|
||||
```text
|
||||
1. CSS custom properties (colors, typography, spacing, layout vars)
|
||||
2. Reset
|
||||
3. Utility classes
|
||||
4. Buttons (btn, btn-primary, btn-emergency, btn-outline, btn-large, btn-full)
|
||||
5. Phone link (.phone-link)
|
||||
6. Header (.site-header, .logo, .main-nav, .header-right, .hamburger)
|
||||
7. Mobile nav drawer (.mobile-nav)
|
||||
8. Tap-to-call bar (.callbar — mobile only, hidden on desktop)
|
||||
9. Page sections (.page-section, .section-heading, .section-subheading)
|
||||
10. Footer (.site-footer, .footer-grid, .footer-service-areas)
|
||||
11. Page-specific section styles
|
||||
12. Responsive: Tablet (768px) — grid layouts, header changes, hide mobile elements
|
||||
13. Responsive: Desktop (1024px) — larger type, wider grids
|
||||
```
|
||||
|
||||
## Emergency Landing Page (if applicable)
|
||||
|
||||
For service businesses with 24/7 emergency offerings, create a standalone stripped-down page:
|
||||
- Zero external resources — all CSS inline, no JS files, no images, no fonts
|
||||
- ~7KB total page weight, sub-1s cold load
|
||||
- ONE goal: phone call. Phone number is the only prominent interactive element
|
||||
- Red/urgent accent, pulsing emergency badge
|
||||
- No navigation links (people click them and bounce)
|
||||
- "No after-hours fees" prominently addressed
|
||||
|
||||
## Before/After Gallery (if applicable)
|
||||
|
||||
For service businesses where visual proof drives conversions:
|
||||
- 2×2 or 4-col grid of before/after pairs side-by-side
|
||||
- Filter bar by service category (All, Fences, Lawns, etc.)
|
||||
- Filter JS: `data-category` attributes, toggles `display:none`
|
||||
- Place gallery filter script BEFORE main.js in the HTML
|
||||
- "Before"/"After" labels on each image
|
||||
|
||||
## Pricing Table (if applicable)
|
||||
|
||||
- Responsive table: collapses to label-value rows on mobile using `data-label` attributes
|
||||
- Use "Flat Rate" or "Starting at $XX" language — don't lock in exact numbers
|
||||
- Disclaimer: "Final price confirmed before any work begins"
|
||||
- Wrap in a card with border and shadow for visual weight
|
||||
|
||||
## After Build Checklist
|
||||
|
||||
1. Search all files for `XXX-XXXX` and replace with real phone number
|
||||
2. Replace placeholder email
|
||||
3. Get Web3Forms access key, update contact page
|
||||
4. Replace emoji/placeholder images with real photos
|
||||
5. Fill in actual pricing if applicable
|
||||
6. Serve via nginx
|
||||
Reference in New Issue
Block a user