diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..078861f
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "phpmailer/phpmailer": "^7.0"
+ }
+}
diff --git a/convert-webp.sh b/convert-webp.sh
new file mode 100644
index 0000000..52abd88
--- /dev/null
+++ b/convert-webp.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Convert all JPG/PNG images to WebP and update HTML with srcset fallbacks
+set -e
+
+IMG_DIR="img"
+INDEX_FILE="index.html"
+
+echo "Converting images to WebP..."
+
+# Convert all JPG and PNG files to WebP
+for f in "$IMG_DIR"/*.jpg "$IMG_DIR"/*.png; do
+ [ -f "$f" ] || continue
+ base="${f%.*}"
+ webp="${base}.webp"
+ if [ ! -f "$webp" ]; then
+ convert "$f" -quality 82 "$webp"
+ echo " Converted: $(basename "$f") -> $(basename "$webp")"
+ fi
+done
+
+echo ""
+echo "Updating index.html with srcset attributes..."
+
+# Update each img tag in index.html with srcset
+# We need to update: gallery images, work images, and og-banner in meta tags
+sed -i 's|img/og-banner.jpg|img/og-banner.jpg, img/og-banner.webp|g' "$INDEX_FILE"
+
+# Gallery images - update each img tag with srcset
+for f in "$IMG_DIR"/*.jpg "$IMG_DIR"/*.png; do
+ [ -f "$f" ] || continue
+ basename="${f#$IMG_DIR/}"
+ basename="${basename%.*}"
+ # Update JPG references
+ if [[ "$basename" == *".jpg" ]]; then
+ webp="${basename%.jpg}.webp"
+ sed -i "s|\"$basename\"|\"$basename\", \"$webp\" type=\"image/webp\"|g" "$INDEX_FILE"
+ fi
+ # Update PNG references
+ if [[ "$basename" == *".png" ]]; then
+ webp="${basename%.png}.webp"
+ sed -i "s|\"$basename\"|\"$basename\", \"$webp\" type=\"image/webp\"|g" "$INDEX_FILE"
+ fi
+done
+
+echo ""
+echo "Done! Generated WebP files and updated index.html with srcset fallbacks."
+echo ""
+echo "Size comparison:"
+echo "Original: $(du -sh "$IMG_DIR" | cut -f1)"
+echo "With WebP: $(du -sh "$IMG_DIR" | cut -f1)"
+du -sh "$IMG_DIR"/*.webp 2>/dev/null | awk '{printf " %-35s %s\n", $2, $1}' | sort
diff --git a/css/style.css b/css/style.css
index 4fa70b3..04bfef3 100644
--- a/css/style.css
+++ b/css/style.css
@@ -1075,6 +1075,22 @@ img {
}
@media (max-width: 768px) {
+ .nav-container {
+ padding: 0 12px;
+ }
+
+ .logo-text {
+ font-size: 1rem;
+ }
+
+ .logo-icon {
+ font-size: 1.2rem;
+ }
+
+ .nav-toggle span {
+ width: 22px;
+ }
+
.nav-links {
display: none;
position: fixed;
@@ -1156,6 +1172,20 @@ img {
}
@media (max-width: 480px) {
+ .logo-text {
+ font-size: 0.85rem;
+ }
+
+ .logo {
+ gap: 4px;
+ max-width: 60%;
+ }
+
+ .logo-text .accent {
+ display: inline;
+ }
+
+
.why-grid {
grid-template-columns: 1fr;
}
@@ -1168,3 +1198,12 @@ img {
font-size: 0.8rem;
}
}
+@media (max-width: 360px) {
+ .logo-text {
+ font-size: 0.75rem;
+ }
+
+ .logo {
+ max-width: 55%;
+ }
+}
diff --git a/index.html b/index.html
index d52c250..9b7665b 100644
--- a/index.html
+++ b/index.html
@@ -42,13 +42,6 @@
"url": "https://WilliamsPressureWashingServices.com",
"telephone": "+1-740-502-3120",
"email": "waltwilliams87@gmail.com",
- "address": {
- "@type": "PostalAddress",
- "streetAddress": "26096 State Route 93",
- "addressLocality": "Fresno",
- "addressRegion": "OH",
- "postalCode": "43824"
- },
"areaServed": {
"@type": "Place",
"name": "Coshocton, Ohio and surrounding areas"
@@ -64,7 +57,7 @@
-
+
@@ -159,13 +152,13 @@
Most Popular
π
Bus Fleet Washing
-
School buses, transit buses, shuttle buses β we handle all fleet sizes with thorough, efficient cleaning. Every job includes exterior wash, window & mirror cleaning, and undercarriage inspection and cleaning.
+
School buses, transit buses, shuttle buses β we handle all fleet sizes with thorough, efficient cleaning that keeps your vehicles safe and professional.
';
+ contactForm.style.pointerEvents = 'none';
+ });
+ });
+ }
+
+ // --- Dynamic year ---
+ document.getElementById('year').textContent = new Date().getFullYear();
+
+ // --- Intersection Observer for animations ---
+ var observer = new IntersectionObserver(function(entries) {
+ entries.forEach(function(entry) {
+ if (entry.isIntersecting) {
+ entry.target.style.opacity = '1';
+ entry.target.style.transform = 'translateY(0)';
+ }
+ });
+ }, { threshold: 0.1 });
+
+ document.querySelectorAll('.service-card, .why-item, .stat').forEach(function(el) {
+ el.style.opacity = '0';
+ el.style.transform = 'translateY(30px)';
+ el.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
+ observer.observe(el);
+ });
+});
diff --git a/progress.md b/progress.md
index b68c3f4..43e95c2 100644
--- a/progress.md
+++ b/progress.md
@@ -22,25 +22,24 @@
## Pending
### π¨ SEO (HIGH PRIORITY β must be done before going live)
-- [x] **Real favicon** β created π§ water droplet favicon matching site header icon (`favicon.png` 32x32 + `apple-touch-icon.png` 180x180)
- [ ] **Real OG banner image** β replace placeholder `img/og-banner.jpg` with a proper 1200Γ630 branded image
-- [ ] **Google Search Console verification** β add meta tag or HTML file (domain purchased, DNS configured)
-- [ ] **Google Business Profile** β set up (domain now live with SSL)
-- [x] **Real photos in gallery** β replaced placeholder before/after slider with 'Our Work' section (5 real photos from Walter)
-- [ ] **Alt text review** β ensure all real images have descriptive, keyword-rich alt text (Walter's input preferred)
+- [ ] **Real favicon** β generate a proper `.ico` / `.png` favicon from a pressure washing logo (currently using inline SVG emoji)
+- [ ] **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, minify CSS/JS
- [ ] **Content review** β Walter to review all copy for accuracy before going live
### Contact Form / Email
-- [x] **SMTP relay configuration** β PHPMailer connected to hMailserver on 10.10.9.31:25 (no auth, no TLS)
+- [x] **SMTP relay configuration** β PHPMailer connected to hMailserver on 10.10.9.31:25 (no auth, no TLS) β relay handled by hMailserver/Mailjet
- [x] **Test form end-to-end** β verified working (POST returns `{"success":true}`)
-- [x] **Email delivery** β confirmed emails arrive at waltwilliams87@gmail.com
-- [x] **Form spam protection** β honeypot field (`website_url`) β bots fill it, returns success silently
+- [ ] **Test email delivery** β confirm message actually arrives at waltwilliams87@gmail.com (need real email to verify)
+- [ ] **Form spam protection** β add honeypot field or privacy-respecting alternative to reCAPTCHA
### Hosting & Domain
-- [x] **Purchase domain** β WilliamsPressureWashingServices.com
-- [x] **DNS setup** β domain points to public IP, resolves correctly
-- [x] **SSL certificate** β Let's Encrypt via Nginx Proxy Manager, valid through July 31 2026
+- [ ] **Purchase domain** β WilliamsPressureWashingServices.com (John to purchase)
+- [ ] **DNS setup** β point domain to 10.10.9.230 (John to configure)
+- [ ] **SSL certificate** β configure via Nginx Proxy Manager or Let's Encrypt on 10.10.9.230
- [ ] **PHP `mail()` config** β verify Postfix on 10.10.9.31 can relay for this server (10.10.9.230)
### Content & Branding
@@ -58,13 +57,8 @@
## Open Questions
- Does Walter have hosting, or are we providing it? β WE ARE PROVIDING (10.10.9.230)
-- Domain purchased? β WilliamsPressureWashingServices.com
-- DNS configured? β Points to public IP, SSL active
-- SSL? β Let's Encrypt via NPM, valid until July 31
-- Contact form spam protection? β Honeypot field active
-- Email delivery? β Confirmed at waltwilliams87@gmail.com
-- Favicon? β π§ water droplet icon created and deployed
-- Specific images/branding from Walter? β³ Still collecting
+- 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)