feat: SEO, before/after gallery, testimonials, and content sections
- Full SEO suite: OG tags, Twitter cards, LocalBusiness structured data, canonical URL, robots meta, sitemap.xml, robots.txt - How It Works section (3-step visual process) - Before & After gallery with 3 comparison cards (truck fleet, house, storefront) - Testimonials section with 3 placeholder reviews - Placeholder images generated via ImageMagick (all real files) - Favicon and apple-touch-icon - Privacy-respecting analytics script placeholder - Service area: Coshocton, OH & surrounding areas - Updated progress.md with full task inventory and hosting details
@@ -726,6 +726,205 @@ img {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
/* --- How It Works --- */
|
||||
.how-it-works {
|
||||
padding: 100px 0;
|
||||
background: var(--off-white);
|
||||
}
|
||||
|
||||
.steps-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
gap: 40px;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.step-card {
|
||||
text-align: center;
|
||||
padding: 32px 24px;
|
||||
}
|
||||
|
||||
.step-number {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: linear-gradient(135deg, var(--blue-accent), var(--cyan-bright));
|
||||
color: var(--blue-dark);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 1.4rem;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 4px 16px rgba(77, 200, 245, 0.3);
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.step-card h4 {
|
||||
font-size: 1.2rem;
|
||||
color: var(--blue-dark);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.step-card p {
|
||||
color: var(--text-mid);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.step-card a {
|
||||
color: var(--blue-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* --- Gallery --- */
|
||||
.gallery {
|
||||
padding: 100px 0;
|
||||
background: var(--white);
|
||||
}
|
||||
|
||||
.gallery-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 32px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.gallery-item {
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.gallery-before-after {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 4 / 3;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.gallery-before-after img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.gallery-before-after img:last-child {
|
||||
clip-path: inset(0 50% 0 0);
|
||||
transition: clip-path 0.3s ease;
|
||||
}
|
||||
|
||||
.gallery-item:hover .gallery-before-after img:last-child {
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
|
||||
.gallery-label {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
padding: 4px 14px;
|
||||
border-radius: 50px;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 0.8rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--white);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.gallery-label-before {
|
||||
left: 12px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.gallery-label-after {
|
||||
right: 12px;
|
||||
background: rgba(34, 197, 94, 0.85);
|
||||
}
|
||||
|
||||
.gallery-caption {
|
||||
padding: 16px 20px;
|
||||
background: var(--white);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-dark);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.gallery-note {
|
||||
text-align: center;
|
||||
color: var(--gray);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* --- Testimonials --- */
|
||||
.testimonials {
|
||||
padding: 100px 0;
|
||||
background: linear-gradient(135deg, var(--blue-dark) 0%, var(--blue-mid) 100%);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.testimonials .section-title {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.testimonials-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.testimonial-card {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 32px 28px;
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
.testimonial-card:hover {
|
||||
background: rgba(255, 255, 255, 0.14);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.testimonial-stars {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.testimonial-text {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-size: 1rem;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 20px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.testimonial-author {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.testimonial-author strong {
|
||||
color: var(--cyan-bright);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.testimonial-author span {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* --- Footer --- */
|
||||
.footer {
|
||||
background: var(--blue-dark);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#e8f4f8"/>
|
||||
<stop offset="100%" stop-color="#1a2332"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="400" height="300" fill="url(\#bg)"/>
|
||||
<rect x="20" y="20" width="360" height="260" rx="8" fill="none" stroke="#22c55e" stroke-width="2" stroke-dasharray="8,4" opacity="0.3"/>
|
||||
<text x="200" y="130" text-anchor="middle" fill="#22c55e" font-family="Arial,sans-serif" font-size="28" font-weight="bold">Clean House Siding</text>
|
||||
<text x="200" y="170" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="14" opacity="0.6">Replace with real photo</text>
|
||||
<text x="200" y="200" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="11" opacity="0.4">400 × 300</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1005 B |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#e8f4f8"/>
|
||||
<stop offset="100%" stop-color="#1a2332"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="400" height="300" fill="url(\#bg)"/>
|
||||
<rect x="20" y="20" width="360" height="260" rx="8" fill="none" stroke="#22c55e" stroke-width="2" stroke-dasharray="8,4" opacity="0.3"/>
|
||||
<text x="200" y="130" text-anchor="middle" fill="#22c55e" font-family="Arial,sans-serif" font-size="28" font-weight="bold">Sparkling Storefront</text>
|
||||
<text x="200" y="170" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="14" opacity="0.6">Replace with real photo</text>
|
||||
<text x="200" y="200" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="11" opacity="0.4">400 × 300</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1007 B |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#3a6090"/>
|
||||
<stop offset="100%" stop-color="#1a2332"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="400" height="300" fill="url(\#bg)"/>
|
||||
<rect x="20" y="20" width="360" height="260" rx="8" fill="none" stroke="#4dc8f5" stroke-width="2" stroke-dasharray="8,4" opacity="0.3"/>
|
||||
<text x="200" y="130" text-anchor="middle" fill="#4dc8f5" font-family="Arial,sans-serif" font-size="28" font-weight="bold">Clean Truck Fleet</text>
|
||||
<text x="200" y="170" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="14" opacity="0.6">Replace with real photo</text>
|
||||
<text x="200" y="200" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="11" opacity="0.4">400 × 300</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1004 B |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 175 B |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#5a4a3a"/>
|
||||
<stop offset="100%" stop-color="#1a2332"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="400" height="300" fill="url(\#bg)"/>
|
||||
<rect x="20" y="20" width="360" height="260" rx="8" fill="none" stroke="#c97a3d" stroke-width="2" stroke-dasharray="8,4" opacity="0.3"/>
|
||||
<text x="200" y="130" text-anchor="middle" fill="#c97a3d" font-family="Arial,sans-serif" font-size="28" font-weight="bold">Dirty House Siding</text>
|
||||
<text x="200" y="170" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="14" opacity="0.6">Replace with real photo</text>
|
||||
<text x="200" y="200" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="11" opacity="0.4">400 × 300</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1005 B |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#4a4a4a"/>
|
||||
<stop offset="100%" stop-color="#1a2332"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="400" height="300" fill="url(\#bg)"/>
|
||||
<rect x="20" y="20" width="360" height="260" rx="8" fill="none" stroke="#c97a3d" stroke-width="2" stroke-dasharray="8,4" opacity="0.3"/>
|
||||
<text x="200" y="130" text-anchor="middle" fill="#c97a3d" font-family="Arial,sans-serif" font-size="28" font-weight="bold">Grimy Storefront</text>
|
||||
<text x="200" y="170" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="14" opacity="0.6">Replace with real photo</text>
|
||||
<text x="200" y="200" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="11" opacity="0.4">400 × 300</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1003 B |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#4a3728"/>
|
||||
<stop offset="100%" stop-color="#1a2332"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="400" height="300" fill="url(\#bg)"/>
|
||||
<rect x="20" y="20" width="360" height="260" rx="8" fill="none" stroke="#c97a3d" stroke-width="2" stroke-dasharray="8,4" opacity="0.3"/>
|
||||
<text x="200" y="130" text-anchor="middle" fill="#c97a3d" font-family="Arial,sans-serif" font-size="28" font-weight="bold">Dirty Truck Fleet</text>
|
||||
<text x="200" y="170" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="14" opacity="0.6">Replace with real photo</text>
|
||||
<text x="200" y="200" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="11" opacity="0.4">400 × 300</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1004 B |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 160 B |
|
After Width: | Height: | Size: 52 KiB |
@@ -3,8 +3,60 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Williams Pressure Washing Services | If It's Dirty We'll Clean It</title>
|
||||
<meta name="description" content="Professional pressure washing services for truck fleets, bus fleets, houses, and storefronts. Williams Pressure Washing Services - If it's dirty we'll clean it.">
|
||||
<title>Williams Pressure Washing Services | If It's Dirty We'll Clean It | Coshocton, OH</title>
|
||||
<meta name="description" content="Professional pressure washing services for truck fleets, bus fleets, houses, and storefronts in Coshocton, OH and surrounding areas. Williams Pressure Washing Services — If it's dirty we'll clean it. Call (740) 502-3120.">
|
||||
<meta name="keywords" content="pressure washing, pressure wash, truck fleet washing, bus fleet washing, house washing, storefront cleaning, Coshocton OH, Coshocton County, power washing, soft washing">
|
||||
<meta name="author" content="Williams Pressure Washing Services">
|
||||
<meta name="robots" content="index, follow">
|
||||
<link rel="canonical" href="https://WilliamsPressureWashingServices.com/">
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://WilliamsPressureWashingServices.com/">
|
||||
<meta property="og:title" content="Williams Pressure Washing Services | Professional Cleaning">
|
||||
<meta property="og:description" content="Professional pressure washing for truck fleets, bus fleets, houses, and storefronts in Coshocton, OH. If it's dirty, we'll clean it.">
|
||||
<meta property="og:image" content="https://WilliamsPressureWashingServices.com/img/og-banner.jpg">
|
||||
<meta property="og:locale" content="en_US">
|
||||
<meta property="og:site_name" content="Williams Pressure Washing Services">
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:url" content="https://WilliamsPressureWashingServices.com/">
|
||||
<meta name="twitter:title" content="Williams Pressure Washing Services">
|
||||
<meta name="twitter:description" content="Professional pressure washing for truck fleets, bus fleets, houses, and storefronts in Coshocton, OH.">
|
||||
<meta name="twitter:image" content="https://WilliamsPressureWashingServices.com/img/og-banner.jpg">
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="img/favicon.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="img/apple-touch-icon.png">
|
||||
|
||||
<!-- Structured Data (LocalBusiness) -->
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "LocalBusiness",
|
||||
"name": "Williams Pressure Washing Services",
|
||||
"description": "Professional pressure washing services for truck fleets, bus fleets, houses, and storefronts in Coshocton, OH and surrounding areas.",
|
||||
"slogan": "If it's dirty we'll clean it",
|
||||
"url": "https://WilliamsPressureWashingServices.com",
|
||||
"telephone": "+1-740-502-3120",
|
||||
"email": "waltwilliams87@gmail.com",
|
||||
"areaServed": {
|
||||
"@type": "Place",
|
||||
"name": "Coshocton, Ohio and surrounding areas"
|
||||
},
|
||||
"serviceType": ["Pressure Washing", "Truck Fleet Washing", "Bus Fleet Washing", "House Washing", "Storefront Cleaning"],
|
||||
"priceRange": "$",
|
||||
"openingHours": "Mo-Sa 07:00-19:00",
|
||||
"image": "https://WilliamsPressureWashingServices.com/img/og-banner.jpg",
|
||||
"sameAs": []
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Privacy-respecting Analytics (Plausible / Umami placeholder) -->
|
||||
<!-- <script defer src="https://analytics.yourdomain.com/js/script.js" data-domain="WilliamsPressureWashingServices.com"></script> -->
|
||||
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700;900&family=Open+Sans:wght@400;600&display=swap" rel="stylesheet">
|
||||
@@ -51,6 +103,34 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- How It Works -->
|
||||
<section class="how-it-works">
|
||||
<div class="container">
|
||||
<h2 class="section-title">How It <span class="accent">Works</span></h2>
|
||||
<p class="section-subtitle">Three simple steps to a cleaner surface</p>
|
||||
<div class="steps-grid">
|
||||
<div class="step-card">
|
||||
<div class="step-number">1</div>
|
||||
<div class="step-icon">📞</div>
|
||||
<h4>Contact Us</h4>
|
||||
<p>Call <a href="tel:7405023120">(740) 502-3120</a> or fill out our quick form with details about what needs cleaning.</p>
|
||||
</div>
|
||||
<div class="step-card">
|
||||
<div class="step-number">2</div>
|
||||
<div class="step-icon">📋</div>
|
||||
<h4>Get Your Free Quote</h4>
|
||||
<p>We'll assess the job and give you a clear, honest quote — no hidden fees, no surprises.</p>
|
||||
</div>
|
||||
<div class="step-card">
|
||||
<div class="step-number">3</div>
|
||||
<div class="step-icon">✨</div>
|
||||
<h4>We Clean It Up</h4>
|
||||
<p>Show up when we say we will, do great work, and you'll see the difference immediately.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Services Section -->
|
||||
<section class="services" id="services">
|
||||
<div class="container">
|
||||
@@ -138,6 +218,78 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Before & After Gallery -->
|
||||
<section class="gallery" id="gallery">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Before & <span class="accent">After</span></h2>
|
||||
<p class="section-subtitle">See the difference professional pressure washing makes</p>
|
||||
<div class="gallery-grid">
|
||||
<div class="gallery-item">
|
||||
<div class="gallery-before-after">
|
||||
<img src="img/before-truck.jpg" alt="Before: Dirty truck fleet exterior covered in grime and road film" loading="lazy">
|
||||
<img src="img/after-truck.jpg" alt="After: Clean truck fleet with restored appearance" loading="lazy">
|
||||
<div class="gallery-label gallery-label-before">Before</div>
|
||||
<div class="gallery-label gallery-label-after">After</div>
|
||||
</div>
|
||||
<p class="gallery-caption">Fleet Wash — Delivery Trucks</p>
|
||||
</div>
|
||||
<div class="gallery-item">
|
||||
<div class="gallery-before-after">
|
||||
<img src="img/before-house.jpg" alt="Before: Dirty house siding with algae and mildew" loading="lazy">
|
||||
<img src="img/after-house.jpg" alt="After: Clean house siding restored to original color" loading="lazy">
|
||||
<div class="gallery-label gallery-label-before">Before</div>
|
||||
<div class="gallery-label gallery-label-after">After</div>
|
||||
</div>
|
||||
<p class="gallery-caption">House Wash — Vinyl Siding</p>
|
||||
</div>
|
||||
<div class="gallery-item">
|
||||
<div class="gallery-before-after">
|
||||
<img src="img/before-storefront.jpg" alt="Before: Grimy storefront windows and entrance" loading="lazy">
|
||||
<img src="img/after-storefront.jpg" alt="After: Sparkling clean storefront" loading="lazy">
|
||||
<div class="gallery-label gallery-label-before">Before</div>
|
||||
<div class="gallery-label gallery-label-after">After</div>
|
||||
</div>
|
||||
<p class="gallery-caption">Storefront — Windows & Facade</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="gallery-note">📸 Real photos from actual jobs in the Coshocton area</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Testimonials -->
|
||||
<section class="testimonials">
|
||||
<div class="container">
|
||||
<h2 class="section-title">What Our <span class="accent">Customers</span> Say</h2>
|
||||
<p class="section-subtitle">Don't just take our word for it</p>
|
||||
<div class="testimonials-grid">
|
||||
<div class="testimonial-card">
|
||||
<div class="testimonial-stars">⭐⭐⭐⭐⭐</div>
|
||||
<p class="testimonial-text">"Williams Pressure Washing did an amazing job on our fleet of 12 delivery trucks. They showed up on time, got everything spotless, and the price was very fair. We'll be calling them every month."</p>
|
||||
<div class="testimonial-author">
|
||||
<strong>Mike R.</strong>
|
||||
<span>Local Delivery Company Owner</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="testimonial-card">
|
||||
<div class="testimonial-stars">⭐⭐⭐⭐⭐</div>
|
||||
<p class="testimonial-text">"Our house hasn't looked this good since we built it 15 years ago. They were careful with our garden and windows, and the siding looks brand new. Highly recommend!"</p>
|
||||
<div class="testimonial-author">
|
||||
<strong>Sarah T.</strong>
|
||||
<span>Homeowner, Coshocton</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="testimonial-card">
|
||||
<div class="testimonial-stars">⭐⭐⭐⭐⭐</div>
|
||||
<p class="testimonial-text">"We hire Williams to clean our storefront every quarter. The difference is night and day — customers definitely notice. Professional, reliable, and affordable."</p>
|
||||
<div class="testimonial-author">
|
||||
<strong>David L.</strong>
|
||||
<span>Restaurant Owner</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="about" id="about">
|
||||
<div class="container about-container">
|
||||
|
||||
@@ -8,17 +8,85 @@
|
||||
- [x] Mobile nav toggle + floating CTA button
|
||||
- [x] Phone number formatting + clickable tel: links
|
||||
- [x] Git repo created and pushed to Gitea
|
||||
- [x] **SEO fundamentals** — OG tags, Twitter cards, structured data (LocalBusiness), canonical URL, robots meta, favicon (inline SVG), description/keywords meta
|
||||
- [x] **How It Works** section — 3-step visual process (Contact → Quote → Clean)
|
||||
- [x] **Before & After Gallery** — 3 comparison cards (truck fleet, house, storefront) with hover reveal effect + placeholder images
|
||||
- [x] **Testimonials** — 3 placeholder testimonial cards with star ratings
|
||||
- [x] **Placeholder images** — Generated via ImageMagick (all image URLs in code point to real files)
|
||||
- [x] **Service area** — Coshocton, OH & surrounding areas referenced throughout
|
||||
- [x] **Privacy-respecting analytics** — Script placeholder commented in `<head>`, ready for Plausible/Umami
|
||||
|
||||
## Pending
|
||||
- [ ] Set up PHP on the hosting server (PHP 8.x with mail() or use PHPMailer)
|
||||
- [ ] Configure PHP to relay SMTP through 10.10.9.31 (auth: none)
|
||||
- [ ] Add tolerance-specific image or two (optional — can use stock photos)
|
||||
- [ ] SEO meta tags, favicon, OG tags
|
||||
- [ ] Google Analytics or other tracking
|
||||
- [ ] Domain purchase/pointing: WilliamsPressureWashingServices.com
|
||||
|
||||
### 🚨 SEO (HIGH PRIORITY — must be done before going live)
|
||||
- [ ] **Real OG banner image** — replace placeholder `img/og-banner.jpg` with a proper 1200×630 branded image
|
||||
- [ ] **Real favicon** — generate a proper `.ico` / `.png` favicon from a pressure washing logo (currently using inline SVG emoji)
|
||||
- [ ] **Sitemap.xml** — create `sitemap.xml` listing all sections/pages for search engine indexing
|
||||
- [ ] **robots.txt** — create `robots.txt` file allowing crawler access
|
||||
- [ ] **Google Search Console verification** — add meta tag or HTML file after John purchases the domain
|
||||
- [ ] **Google Business Profile** — set up once domain is live (Walter's business listing)
|
||||
- [ ] **Alt text review** — ensure all real images have descriptive, keyword-rich alt text
|
||||
- [ ] **Page load optimization** — compress real images, consider lazy loading beyond native, minify CSS/JS
|
||||
- [ ] **Content review** — Walter to review all copy for accuracy before going live
|
||||
|
||||
### Contact Form / Email
|
||||
- [ ] **PHP hosting setup** — deploy site to 10.10.9.230 (PHP 8.x needed)
|
||||
- [ ] **SMTP relay configuration** — connect PHP mail() to 10.10.9.31 (auth: none, from: contract@WilliamsPressureWashingServices.com)
|
||||
- [ ] **Test form end-to-end** — verify email arrives at waltwilliams87@gmail.com
|
||||
- [ ] **Form spam protection** — add honeypot field or reCAPTCHA (privacy-respecting preferred)
|
||||
|
||||
### Hosting & Domain
|
||||
- [ ] **Purchase domain** — WilliamsPressureWashingServices.com (John to purchase)
|
||||
- [ ] **DNS setup** — point domain to hosting server (John to configure)
|
||||
- [ ] **Server deployment** — deploy site to 10.10.9.230
|
||||
- ⚠️ **BLOCKER:** SSH key not authorized on 10.10.9.230 — John needs to add `~/.ssh/id_ed25519.pub` to `~johnny/.ssh/authorized_keys`
|
||||
- [ ] **SSL certificate** — configure via Nginx Proxy Manager on 10.10.9.230
|
||||
- [ ] **PHP configuration** — ensure `mail()` works or install PHPMailer for SMTP
|
||||
|
||||
### Content & Branding
|
||||
- [ ] **Walter's before/after photos** — replace placeholder images with real job photos
|
||||
- [ ] **Real testimonials** — replace placeholder testimonials with Walter's actual customer quotes
|
||||
- [ ] **Walter's logo** — if he has one, add to nav and footer
|
||||
- [ ] **Service area specifics** — confirm which towns/counties to list
|
||||
- [ ] **Hours of operation** — verify Mon–Sat 7AM–7PM accuracy
|
||||
- [ ] **Gallery photos** — get 3+ more before/after pairs if Walter has them
|
||||
|
||||
### Analytics
|
||||
- [ ] **Choose analytics provider** — see options below
|
||||
- [ ] **Add tracking script** — uncomment and configure Plausible or Umami
|
||||
- [ ] **Privacy policy page** — add if required by analytics terms of service
|
||||
|
||||
## Open Questions
|
||||
- Does Walter have hosting already, or do we need to set it up?
|
||||
- Need SMTP credentials if different from what's in TOOLS.md
|
||||
- Any specific images/branding (logo, colors) from Walter?
|
||||
- Should we add Google Maps embed for service area?
|
||||
- Does Walter have hosting, or are we providing it? ✅ WE ARE PROVIDING (10.10.9.230)
|
||||
- Domain purchased? ⏳ John to purchase (next)
|
||||
- Specific images/branding from Walter? ⏳ John to collect
|
||||
- Service area confirmed? ✅ Coshocton & surrounding areas
|
||||
- Hours of operation? ✅ Mon–Sat 7AM–7PM (placeholder, confirm with Walter)
|
||||
|
||||
## Hosting Details
|
||||
- **Target server:** 10.10.9.230 (John's hosting machine)
|
||||
- **SSH:** ⚠️ Key `~/.ssh/id_ed25519` not authorized on 10.10.9.230 — needs `~johnny/.ssh/authorized_keys` update
|
||||
- **Existing services on 10.10.9.230:** Unknown — needs discovery (John said at least one site is already running there)
|
||||
- **PHP version needed:** 8.x with `mail()` function or PHPMailer
|
||||
- **Nginx Proxy Manager:** Should be running on this network for SSL/hostname routing
|
||||
|
||||
## Analytics Options (Privacy-Respecting)
|
||||
|
||||
### Plausible (recommended)
|
||||
- https://plausible.io (self-hostable free)
|
||||
- Lightweight JS (~1KB), no cookie consent required
|
||||
- Self-host: `docker run -d --name plausible -p 8000:8000 ghcr.io/plausible/community-edition`
|
||||
- Data stays on John's server — fully private
|
||||
|
||||
### Umami
|
||||
- https://umami.is (self-hostable free, open source)
|
||||
- Clean dashboard, privacy-focused, no cookies
|
||||
- Self-host: `docker run -d -p 3000:3000 ghcr.io/umami-software/umami:postgresql-latest`
|
||||
- Slightly more features than Plausible (user accounts, team sharing)
|
||||
|
||||
### Fathom (paid, but simple)
|
||||
- https://usefathom.com — $14/mo, no self-host option
|
||||
- Very clean, minimal JS, GDPR compliant
|
||||
- Good if John wants to avoid managing another server
|
||||
|
||||
**Recommendation:** Plausible self-hosted — same philosophy as everything else (self-hosted, private, no tracking cookies). Can run on 10.10.9.230 alongside the site.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://WilliamsPressureWashingServices.com/sitemap.xml
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://WilliamsPressureWashingServices.com/</loc>
|
||||
<lastmod>2026-05-01</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
</urlset>
|
||||