diff --git a/assets/Group-433.png b/assets/Group-433.png new file mode 100644 index 0000000..52abe0a Binary files /dev/null and b/assets/Group-433.png differ diff --git a/assets/boat-work-min-scaled.jpg b/assets/boat-work-min-scaled.jpg new file mode 100644 index 0000000..9ad8b18 Binary files /dev/null and b/assets/boat-work-min-scaled.jpg differ diff --git a/assets/electrical-1-min.jpg b/assets/electrical-1-min.jpg new file mode 100644 index 0000000..9b20714 Binary files /dev/null and b/assets/electrical-1-min.jpg differ diff --git a/assets/electrical-2-min.jpg b/assets/electrical-2-min.jpg new file mode 100644 index 0000000..63b8efa Binary files /dev/null and b/assets/electrical-2-min.jpg differ diff --git a/assets/electrical-3-min.jpg b/assets/electrical-3-min.jpg new file mode 100644 index 0000000..a5eba81 Binary files /dev/null and b/assets/electrical-3-min.jpg differ diff --git a/assets/electrical-4-min.jpg b/assets/electrical-4-min.jpg new file mode 100644 index 0000000..4b1fd89 Binary files /dev/null and b/assets/electrical-4-min.jpg differ diff --git a/assets/electrical-5-min.jpg b/assets/electrical-5-min.jpg new file mode 100644 index 0000000..a7dcd1b Binary files /dev/null and b/assets/electrical-5-min.jpg differ diff --git a/assets/electrical-6-min-1.jpg b/assets/electrical-6-min-1.jpg new file mode 100644 index 0000000..e5455fd Binary files /dev/null and b/assets/electrical-6-min-1.jpg differ diff --git a/assets/electrical-7-min-768x1165.jpg b/assets/electrical-7-min-768x1165.jpg new file mode 100644 index 0000000..85b4f11 Binary files /dev/null and b/assets/electrical-7-min-768x1165.jpg differ diff --git a/assets/electrical-7-min.jpg b/assets/electrical-7-min.jpg new file mode 100644 index 0000000..ac6be7a Binary files /dev/null and b/assets/electrical-7-min.jpg differ diff --git a/assets/electrical-8-min.jpg b/assets/electrical-8-min.jpg new file mode 100644 index 0000000..242aa3d Binary files /dev/null and b/assets/electrical-8-min.jpg differ diff --git a/assets/grab-bar-min.png b/assets/grab-bar-min.png new file mode 100644 index 0000000..dde013e Binary files /dev/null and b/assets/grab-bar-min.png differ diff --git a/assets/painting-1-min-1429x1536.png b/assets/painting-1-min-1429x1536.png new file mode 100644 index 0000000..9d0a891 Binary files /dev/null and b/assets/painting-1-min-1429x1536.png differ diff --git a/assets/painting-1-min.png b/assets/painting-1-min.png new file mode 100644 index 0000000..52bc440 Binary files /dev/null and b/assets/painting-1-min.png differ diff --git a/assets/painting-2-min.png b/assets/painting-2-min.png new file mode 100644 index 0000000..6b0ae20 Binary files /dev/null and b/assets/painting-2-min.png differ diff --git a/assets/painting-3-min.jpg b/assets/painting-3-min.jpg new file mode 100644 index 0000000..fb8c11e Binary files /dev/null and b/assets/painting-3-min.jpg differ diff --git a/assets/painting-4-min.jpg b/assets/painting-4-min.jpg new file mode 100644 index 0000000..aff9ca6 Binary files /dev/null and b/assets/painting-4-min.jpg differ diff --git a/assets/painting-5-min.jpg b/assets/painting-5-min.jpg new file mode 100644 index 0000000..548958d Binary files /dev/null and b/assets/painting-5-min.jpg differ diff --git a/assets/painting-6-min.jpg b/assets/painting-6-min.jpg new file mode 100644 index 0000000..6bb721d Binary files /dev/null and b/assets/painting-6-min.jpg differ diff --git a/assets/painting-7-min.jpg b/assets/painting-7-min.jpg new file mode 100644 index 0000000..e5d1b62 Binary files /dev/null and b/assets/painting-7-min.jpg differ diff --git a/assets/painting-8-min.jpg b/assets/painting-8-min.jpg new file mode 100644 index 0000000..edee1d3 Binary files /dev/null and b/assets/painting-8-min.jpg differ diff --git a/assets/plumbing-2-min.png b/assets/plumbing-2-min.png new file mode 100644 index 0000000..901f1c8 Binary files /dev/null and b/assets/plumbing-2-min.png differ diff --git a/assets/plumbing-3-min.png b/assets/plumbing-3-min.png new file mode 100644 index 0000000..a6171ac Binary files /dev/null and b/assets/plumbing-3-min.png differ diff --git a/assets/plumbing-4-min.png b/assets/plumbing-4-min.png new file mode 100644 index 0000000..ebc1e44 Binary files /dev/null and b/assets/plumbing-4-min.png differ diff --git a/assets/plumbing-5-min.png b/assets/plumbing-5-min.png new file mode 100644 index 0000000..f71a81f Binary files /dev/null and b/assets/plumbing-5-min.png differ diff --git a/assets/plumbing-6-min.png b/assets/plumbing-6-min.png new file mode 100644 index 0000000..a2eab5c Binary files /dev/null and b/assets/plumbing-6-min.png differ diff --git a/assets/plumbing-7-min.png b/assets/plumbing-7-min.png new file mode 100644 index 0000000..f0775df Binary files /dev/null and b/assets/plumbing-7-min.png differ diff --git a/assets/plumbing-8-min.png b/assets/plumbing-8-min.png new file mode 100644 index 0000000..80092c1 Binary files /dev/null and b/assets/plumbing-8-min.png differ diff --git a/assets/security-garage-door-min.png b/assets/security-garage-door-min.png new file mode 100644 index 0000000..0f4c2fc Binary files /dev/null and b/assets/security-garage-door-min.png differ diff --git a/assets/sheetrocking-1-min.png b/assets/sheetrocking-1-min.png new file mode 100644 index 0000000..7d95cfa Binary files /dev/null and b/assets/sheetrocking-1-min.png differ diff --git a/assets/sheetrocking-2-min.png b/assets/sheetrocking-2-min.png new file mode 100644 index 0000000..823ac36 Binary files /dev/null and b/assets/sheetrocking-2-min.png differ diff --git a/assets/sheetrocking-3-min.png b/assets/sheetrocking-3-min.png new file mode 100644 index 0000000..a01e90a Binary files /dev/null and b/assets/sheetrocking-3-min.png differ diff --git a/assets/sheetrocking-4-min.jpg b/assets/sheetrocking-4-min.jpg new file mode 100644 index 0000000..73911ec Binary files /dev/null and b/assets/sheetrocking-4-min.jpg differ diff --git a/assets/sheetrocking-5-min.png b/assets/sheetrocking-5-min.png new file mode 100644 index 0000000..01f7d75 Binary files /dev/null and b/assets/sheetrocking-5-min.png differ diff --git a/assets/tile-setting-1-min.png b/assets/tile-setting-1-min.png new file mode 100644 index 0000000..8428734 Binary files /dev/null and b/assets/tile-setting-1-min.png differ diff --git a/assets/tile-setting-2-min.png b/assets/tile-setting-2-min.png new file mode 100644 index 0000000..8d83ed6 Binary files /dev/null and b/assets/tile-setting-2-min.png differ diff --git a/assets/tile-setting-3-min.png b/assets/tile-setting-3-min.png new file mode 100644 index 0000000..1ad7339 Binary files /dev/null and b/assets/tile-setting-3-min.png differ diff --git a/assets/tile-setting-4-min.png b/assets/tile-setting-4-min.png new file mode 100644 index 0000000..e809754 Binary files /dev/null and b/assets/tile-setting-4-min.png differ diff --git a/assets/tile-setting-5-min.png b/assets/tile-setting-5-min.png new file mode 100644 index 0000000..a7e1877 Binary files /dev/null and b/assets/tile-setting-5-min.png differ diff --git a/assets/tile-setting-6-min.png b/assets/tile-setting-6-min.png new file mode 100644 index 0000000..373ea47 Binary files /dev/null and b/assets/tile-setting-6-min.png differ diff --git a/assets/tile-setting-7-min.png b/assets/tile-setting-7-min.png new file mode 100644 index 0000000..5d80423 Binary files /dev/null and b/assets/tile-setting-7-min.png differ diff --git a/assets/tile-setting-8-min.png b/assets/tile-setting-8-min.png new file mode 100644 index 0000000..6470b08 Binary files /dev/null and b/assets/tile-setting-8-min.png differ diff --git a/assets/wood-refinishing-1-min.png b/assets/wood-refinishing-1-min.png new file mode 100644 index 0000000..63d3b6b Binary files /dev/null and b/assets/wood-refinishing-1-min.png differ diff --git a/assets/wood-refinishing-2-min.png b/assets/wood-refinishing-2-min.png new file mode 100644 index 0000000..91a17b3 Binary files /dev/null and b/assets/wood-refinishing-2-min.png differ diff --git a/assets/wood-refinishing-3-min.png b/assets/wood-refinishing-3-min.png new file mode 100644 index 0000000..5c198bf Binary files /dev/null and b/assets/wood-refinishing-3-min.png differ diff --git a/assets/wood-refinishing-4-min.png b/assets/wood-refinishing-4-min.png new file mode 100644 index 0000000..a2d1903 Binary files /dev/null and b/assets/wood-refinishing-4-min.png differ diff --git a/assets/wood-refinishing-5-min.png b/assets/wood-refinishing-5-min.png new file mode 100644 index 0000000..eff43ac Binary files /dev/null and b/assets/wood-refinishing-5-min.png differ diff --git a/assets/wood-refinishing-6-min.png b/assets/wood-refinishing-6-min.png new file mode 100644 index 0000000..a0a3ff0 Binary files /dev/null and b/assets/wood-refinishing-6-min.png differ diff --git a/assets/wood-refinishing-7-min.png b/assets/wood-refinishing-7-min.png new file mode 100644 index 0000000..00198c6 Binary files /dev/null and b/assets/wood-refinishing-7-min.png differ diff --git a/assets/wood-refinishing-8-min.png b/assets/wood-refinishing-8-min.png new file mode 100644 index 0000000..69bb1a0 Binary files /dev/null and b/assets/wood-refinishing-8-min.png differ diff --git a/assets/wood-refinishing-9-min.png b/assets/wood-refinishing-9-min.png new file mode 100644 index 0000000..2895bef Binary files /dev/null and b/assets/wood-refinishing-9-min.png differ diff --git a/specification/00-overview.md b/specification/00-overview.md new file mode 100644 index 0000000..f000841 --- /dev/null +++ b/specification/00-overview.md @@ -0,0 +1,51 @@ +# Diana Website — Specification Overview (v1) + +## Purpose +Build a **mobile-first, SEO-friendly, static website** for Diana (handywoman) that primarily **converts visitors into qualified quote requests**. + +This document is the navigation map for the specification set. + +## Goals +1. **Generate qualified leads** via a lightweight quote/contact form. +2. Communicate Diana’s differentiation: **trustworthy, easy to work with, female handyman/handywoman**, strong **project coordination/mediation** skills. +3. **SEO-first information architecture**: separate service pages with clear local relevance (San Francisco + 50-mile radius). +4. **Fast, mobile-first UX** (Core Web Vitals friendly, readable, tap-target safe). + +## Non-goals / Out of scope (v1) +- Blog +- Booking / calendar scheduling +- Payments +- Deployment/infrastructure work beyond “static site served behind Caddy reverse proxy” + +## Key constraints +- Language: **English**. +- Site type: **static website**. +- Content updates expected to be infrequent (maintained by owner/you). +- Form should be **lightweight** (no file uploads in v1). + +## Primary user flows +1. Visitor lands on Home page → scans credibility/services → taps **Request a Quote** → submits form. +2. Visitor lands on a Service page (SEO) → sees what’s included + service area + CTA → submits form. +3. Visitor checks About / Testimonials for trust → CTA → submits form. + +## Intended information architecture (high level) +- Home +- Services (hub) +- Service detail pages (one per service) +- About Diana +- Testimonials +- Contact / Request a Quote + +## Specification documents +### Core specs (Phase 2) +- `00-overview.md` (this file) +- `01-requirements.md` +- `02-architecture-decisions.md` +- `99-open-questions.md` + +### Themed specs (Phase 3 — planned) +- `33-frontend-spec.md` — pages, components, UX, mobile-first design, conversion flow +- `37-seo-content-spec.md` — page structure, metadata, schema.org, sitemap/robots, content requirements per page +- `38-lead-capture-spec.md` — form fields, validation, spam protection, delivery/routing, confirmation UX + +(If a themed spec requires an architectural decision, it will be captured in `02-architecture-decisions.md`. If uncertainty remains, it will be captured in `99-open-questions.md`.) diff --git a/specification/01-requirements.md b/specification/01-requirements.md new file mode 100644 index 0000000..2cdbf13 --- /dev/null +++ b/specification/01-requirements.md @@ -0,0 +1,74 @@ +# Requirements — Diana Website (v1) + +## Stakeholders +- **S1 — Prospective customers**: homeowners/property managers seeking repair/maintenance/renovation work. +- **S2 — Diana**: needs qualified inquiries, wants accurate representation, wants credibility and differentiation. +- **S3 — Search engines**: require indexable content, clear structure, performance, metadata. + +## Functional requirements + +### Lead capture (primary) +- **FR-1**: The site must provide a **Request a Quote / Contact** form accessible within 1–2 taps from any page (persistent CTA). +- **FR-2**: The form must be **lightweight** (no file upload requirement in v1). +- **FR-3**: The form must collect enough info to support **qualified leads**. + - Minimum fields TBD in `38-lead-capture-spec.md`. +- **FR-4**: After submission, the user must see a **clear confirmation** (and guidance on next steps). + +### Content & pages +- **FR-5**: The site must be **English-only**. +- **FR-6**: The site must clearly state the **service area: San Francisco + 50 mile radius**. +- **FR-7**: The site must include a **Services hub page**. +- **FR-8**: The site must include **one page per service** (SEO-driven). + - Services list (current): + - Security & Safety Equipment + - Tile Setting + - Drywall / Sheetrocking + - Painting + - Minor Plumbing + - Minor Electrical + - Carpentry + - Mounting + - Flooring touch-ups + - Boat work +- **FR-9**: The site must include an **About Diana** page highlighting credibility, experience, and project coordination. +- **FR-10**: The site must include a **Testimonials** page using existing testimonial content as a base (source: https://spotlighthis.com/testimonials/). +- **FR-11**: The site must include a **Contact** page (may be the same as Request a Quote). + +### Differentiation / brand messaging +- **FR-12**: The site must explicitly lean into “**female handyman/handywoman**” positioning. +- **FR-13**: The site must highlight Diana as **trustworthy, easy to work with**, and skilled at **project coordination/mediation**. +- **FR-14**: The site must incorporate proof points (e.g., **years of experience**, project coordination background). + +## Non-functional requirements + +### Mobile-first UX +- **NFR-1**: The site must be designed **mobile-first**, with readable typography and touch-friendly controls. +- **NFR-2**: The quote/contact CTA must be prominent and accessible on mobile. + +### SEO +- **NFR-3**: The site must be **indexable** (server-rendered/static HTML; no content hidden behind client-only rendering). +- **NFR-4**: Each service page must have unique, descriptive metadata (title/description) and content targeting that service. +- **NFR-5**: The site must have sitemap and robots configuration (details in `37-seo-content-spec.md`). + +### Performance +- **NFR-6**: Pages must load quickly on mobile networks; images must be optimized and appropriately sized. + +### Maintainability +- **NFR-7**: The solution should be low-maintenance and suitable for infrequent updates by you. + +## Constraints / scope boundaries +- **C-1**: Site must be a **static website**. +- **C-2**: Deployment/infrastructure is **out of scope** for v1 beyond the assumption it will be served behind **Caddy reverse proxy**. +- **C-3**: No blog, booking/calendar, or payments in v1. + +## Acceptance criteria (v1) +- **AC-1**: A visitor can reach a quote request form from any page in 1–2 taps. +- **AC-2**: Service pages exist for each service in FR-8, and each has a clear CTA. +- **AC-3**: The site clearly states service area and core positioning. +- **AC-4**: The site is usable on mobile (no horizontal scroll, readable text, accessible tap targets). +- **AC-5**: The site is SEO-ready: indexable pages, unique metadata per service page, sitemap/robots present. + +## Traceability notes +- Lead capture specs → `38-lead-capture-spec.md` +- Frontend UX and page layout → `33-frontend-spec.md` +- SEO structure and metadata/schema → `37-seo-content-spec.md` diff --git a/specification/02-architecture-decisions.md b/specification/02-architecture-decisions.md new file mode 100644 index 0000000..8494438 --- /dev/null +++ b/specification/02-architecture-decisions.md @@ -0,0 +1,54 @@ +# Architecture Decisions (ADRs) — Diana Website (v1) + +This file records stable architectural decisions and their rationale. Items here should remain valid even as implementation details evolve. + +## ADR-001 — Static website (SSG or plain static HTML) as the delivery model +- **Status**: Accepted +- **Context**: Site is primarily informational/lead-capture, needs strong SEO, and is expected to change infrequently. +- **Decision**: Build as a **static website** (pre-rendered HTML) suitable for hosting behind a reverse proxy. +- **Rationale**: + - SEO-friendly (indexable content) + - Fast and reliable on mobile + - Low maintenance +- **Alternatives considered**: + - WordPress/CMS: easier editing but higher maintenance/security surface + - SPA-only: SEO/performance risks and complexity +- **Consequences**: + - Contact form delivery must be handled via a static-compatible approach (see ADR-002, TBD) + +## ADR-002 — Quote request form submission mechanism +- **Status**: Proposed (blocked) +- **Context**: Form is required (FR-1..FR-4), but the mechanism (email service, server endpoint, third-party form backend) is not yet selected. +- **Decision**: TBD. +- **Options to evaluate** (non-exhaustive): + 1. Static form backend service (e.g., Netlify Forms / Formspree / Basin) + 2. Self-hosted lightweight endpoint behind Caddy (out-of-scope per C-2 unless already existing) + 3. Email link fallback (mailto) — likely insufficient for qualified leads +- **Drivers**: + - Qualified lead capture + - Spam protection + - GDPR/cookie implications + - Operational simplicity +- **Next step**: Resolve in `99-open-questions.md` and specify in `38-lead-capture-spec.md`. + +## ADR-003 — Mobile-first, performance-first design +- **Status**: Accepted +- **Context**: Most traffic is expected on mobile; SEO and conversion depend on usability and speed. +- **Decision**: Adopt a **mobile-first** layout and performance budget mindset. +- **Rationale**: + - Improves conversion + - Supports SEO (Core Web Vitals) +- **Consequences**: + - Images must be optimized; avoid heavy JS + - Ensure accessible typography and tap targets + +## ADR-004 — SEO information architecture: one page per service +- **Status**: Accepted +- **Context**: SEO is important and services are distinct. +- **Decision**: Create **separate service pages** for each service category listed in FR-8. +- **Rationale**: + - Supports service-intent keywords + - Improves internal linking and topical relevance +- **Consequences**: + - Requires unique content per page (avoid duplicate/thin pages) + - Requires a services hub and internal navigation diff --git a/specification/99-open-questions.md b/specification/99-open-questions.md new file mode 100644 index 0000000..ab2ba60 --- /dev/null +++ b/specification/99-open-questions.md @@ -0,0 +1,42 @@ +# Open Questions — Diana Website (v1) + +This log tracks uncertainties and deferred decisions. Each item should be resolved before implementation in Phase 4. + +## OQ-1 — Preferred contact method(s) beyond the contact form +- **Status**: Open +- **Context**: Contact form is a given, but preferred secondary channel(s) are not finalized. +- **Why it matters**: Influences CTA design, header/footer, and “next steps” after form submission. +- **Candidates**: phone, SMS/text, email. +- **Proposed resolution**: Decide primary + secondary channel(s) and when to encourage each. + +## OQ-2 — GDPR/cookie consent and tracking requirements +- **Status**: Open +- **Context**: Need to know whether we will run analytics/ads pixels and whether consent banners are required. +- **Why it matters**: Affects scripts, cookie banner, privacy policy content, and SEO. +- **Proposed resolution**: + - Decide whether to use analytics (and which) + - If analytics, decide consent model and privacy policy needs + +## OQ-3 — Form backend + spam protection approach (ADR-002) +- **Status**: Open +- **Context**: Static site requires an external or existing backend mechanism. +- **Why it matters**: Reliability, spam filtering, and operational workflow. +- **Proposed resolution**: Choose a form delivery method and specify validation + anti-spam. + +## OQ-4 — Minimum quote form fields for “qualified leads” +- **Status**: Open +- **Context**: Goal is “more qualified leads”, but minimum qualifying information is not fully specified. +- **Why it matters**: Balances friction vs. lead quality. +- **Proposed resolution**: Define required vs optional fields in `38-lead-capture-spec.md`. + +## OQ-5 — Service taxonomy: separate pages vs grouping for carpentry/mounting/flooring +- **Status**: Open +- **Context**: Requirement says separate page per service, but some services overlap. +- **Why it matters**: SEO clarity and content uniqueness. +- **Proposed resolution**: Confirm final service list and page slugs. + +## OQ-6 — Brand naming and domain +- **Status**: Open +- **Context**: Current site uses “Spotlight Home Improvement Services”; new site may keep or adjust branding. +- **Why it matters**: Title tags, logo, copy, and SEO continuity. +- **Proposed resolution**: Confirm public-facing brand name for v1.