feat: initial site build — responsive pressure washing website

- Professional multi-section responsive design
- Hero with slogan, CTAs, and animated water drops
- Services: truck fleets, bus fleets, houses, storefronts
- Why choose us section with trust signals
- About section with stats
- Contact form with phone/email/info cards
- Floating call button (mobile)
- Email handler via local SMTP (10.10.9.31)
- Colorful blue/cyan gradient theme
- Mobile-first responsive layout
This commit is contained in:
John Loper II
2026-05-01 10:50:56 -04:00
commit fe90bc521a
4 changed files with 1403 additions and 0 deletions
+927
View File
@@ -0,0 +1,927 @@
/* ============================================
Williams Pressure Washing Services
Professional Responsive Website
============================================ */
/* --- CSS Variables --- */
:root {
--blue-dark: #0a2463;
--blue-mid: #1e56a0;
--blue-light: #3a8fd4;
--blue-accent: #4dc8f5;
--cyan-bright: #00e0ff;
--white: #ffffff;
--off-white: #f0f6ff;
--gray-light: #e8edf3;
--gray: #8899aa;
--text-dark: #1a2332;
--text-mid: #3d4f63;
--green: #22c55e;
--green-dark: #16a34a;
--shadow: 0 4px 24px rgba(10, 36, 99, 0.12);
--shadow-lg: 0 12px 40px rgba(10, 36, 99, 0.18);
--radius: 12px;
--radius-lg: 20px;
--transition: 0.3s ease;
}
/* --- Reset & Base --- */
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
font-size: 16px;
}
body {
font-family: 'Open Sans', Arial, sans-serif;
color: var(--text-dark);
line-height: 1.6;
overflow-x: hidden;
background: var(--white);
}
h1, h2, h3, h4 {
font-family: 'Montserrat', sans-serif;
line-height: 1.2;
}
a {
text-decoration: none;
color: inherit;
}
ul {
list-style: none;
}
img {
max-width: 100%;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 24px;
}
.accent {
color: var(--blue-accent);
}
/* --- Buttons --- */
.btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 14px 28px;
border-radius: 50px;
font-family: 'Montserrat', sans-serif;
font-weight: 700;
font-size: 1rem;
cursor: pointer;
border: none;
transition: all var(--transition);
text-align: center;
justify-content: center;
}
.btn-icon {
flex-shrink: 0;
}
.btn-primary {
background: linear-gradient(135deg, var(--blue-accent), var(--blue-light));
color: var(--white);
box-shadow: 0 4px 16px rgba(77, 200, 245, 0.4);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(77, 200, 245, 0.5);
}
.btn-secondary {
background: rgba(255, 255, 255, 0.15);
color: var(--white);
border: 2px solid rgba(255, 255, 255, 0.5);
backdrop-filter: blur(4px);
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.25);
border-color: var(--white);
transform: translateY(-2px);
}
.btn-large {
padding: 18px 36px;
font-size: 1.125rem;
}
.btn-block {
width: 100%;
}
/* --- Navigation --- */
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
padding: 16px 0;
transition: all var(--transition);
}
.navbar.scrolled {
background: rgba(10, 36, 99, 0.95);
backdrop-filter: blur(12px);
padding: 10px 0;
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.2);
}
.nav-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 24px;
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
display: flex;
align-items: center;
gap: 8px;
font-family: 'Montserrat', sans-serif;
font-weight: 900;
font-size: 1.25rem;
color: var(--white);
}
.logo-icon {
font-size: 1.5rem;
}
.logo-text .accent {
color: var(--cyan-bright);
}
.nav-links {
display: flex;
align-items: center;
gap: 32px;
}
.nav-links a {
color: rgba(255, 255, 255, 0.85);
font-weight: 600;
font-size: 0.95rem;
transition: color var(--transition);
font-family: 'Montserrat', sans-serif;
}
.nav-links a:hover {
color: var(--cyan-bright);
}
.nav-cta {
background: linear-gradient(135deg, var(--cyan-bright), var(--blue-accent));
color: var(--blue-dark) !important;
padding: 10px 22px;
border-radius: 50px;
font-weight: 700 !important;
transition: all var(--transition);
}
.nav-cta:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 224, 255, 0.4);
}
.nav-toggle {
display: none;
flex-direction: column;
gap: 5px;
background: none;
border: none;
cursor: pointer;
padding: 4px;
}
.nav-toggle span {
display: block;
width: 26px;
height: 3px;
background: var(--white);
border-radius: 2px;
transition: all var(--transition);
}
/* --- Hero Section --- */
.hero {
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background: linear-gradient(135deg, #0a2463 0%, #1e56a0 40%, #2d7dd2 70%, #00c6ff 100%);
overflow: hidden;
padding: 120px 24px 80px;
}
.hero::before {
content: '';
position: absolute;
inset: 0;
background:
radial-gradient(circle at 20% 80%, rgba(0, 224, 255, 0.15) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(77, 200, 245, 0.2) 0%, transparent 50%),
radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.05) 0%, transparent 70%);
animation: heroFloat 8s ease-in-out infinite;
}
@keyframes heroFloat {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
/* Water drops animation */
.hero::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-image:
radial-gradient(circle, rgba(255,255,255,0.08) 2px, transparent 2px),
radial-gradient(circle, rgba(255,255,255,0.05) 1px, transparent 1px);
background-size: 80px 80px, 50px 50px;
background-position: 0 0, 25px 25px;
animation: waterDrips 20s linear infinite;
}
@keyframes waterDrips {
0% { transform: translateY(-100px); }
100% { transform: translateY(100px); }
}
.hero-content {
position: relative;
z-index: 2;
max-width: 800px;
}
.hero-badge {
display: inline-block;
background: rgba(255, 255, 255, 0.12);
border: 1px solid rgba(255, 255, 255, 0.2);
backdrop-filter: blur(8px);
color: var(--white);
padding: 8px 20px;
border-radius: 50px;
font-size: 0.9rem;
font-weight: 600;
margin-bottom: 24px;
}
.hero-title {
font-size: clamp(2.2rem, 6vw, 4rem);
font-weight: 900;
color: var(--white);
margin-bottom: 12px;
text-shadow: 0 2px 20px rgba(0, 0, 0, 0.2);
}
.hero-title .accent {
color: var(--cyan-bright);
}
.hero-slogan {
font-family: 'Montserrat', sans-serif;
font-size: clamp(1.2rem, 3vw, 1.6rem);
color: var(--cyan-bright);
font-style: italic;
font-weight: 600;
margin-bottom: 16px;
}
.hero-sub {
font-size: clamp(1rem, 2vw, 1.15rem);
color: rgba(255, 255, 255, 0.9);
margin-bottom: 32px;
line-height: 1.8;
}
.hero-ctas {
display: flex;
gap: 16px;
justify-content: center;
flex-wrap: wrap;
}
.scroll-indicator {
position: absolute;
bottom: 32px;
left: 50%;
transform: translateX(-50%);
z-index: 2;
color: rgba(255, 255, 255, 0.6);
font-size: 0.85rem;
text-align: center;
font-family: 'Montserrat', sans-serif;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
animation: scrollBounce 2s ease-in-out infinite;
}
.scroll-arrow {
width: 24px;
height: 24px;
border-right: 3px solid rgba(255, 255, 255, 0.5);
border-bottom: 3px solid rgba(255, 255, 255, 0.5);
transform: rotate(45deg);
margin: 8px auto 0;
}
@keyframes scrollBounce {
0%, 100% { transform: translateX(-50%) translateY(0); }
50% { transform: translateX(-50%) translateY(8px); }
}
/* --- Section Titles --- */
.section-title {
text-align: center;
font-size: clamp(1.8rem, 4vw, 2.5rem);
font-weight: 900;
color: var(--blue-dark);
margin-bottom: 8px;
}
.section-subtitle {
text-align: center;
color: var(--text-mid);
font-size: 1.1rem;
margin-bottom: 48px;
}
/* --- Services --- */
.services {
padding: 100px 0;
background: var(--off-white);
}
.services-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 28px;
margin-bottom: 48px;
}
.service-card {
background: var(--white);
border-radius: var(--radius-lg);
padding: 36px 28px;
box-shadow: var(--shadow);
transition: all var(--transition);
position: relative;
overflow: hidden;
border: 1px solid var(--gray-light);
}
.service-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, var(--blue-accent), var(--cyan-bright));
transform: scaleX(0);
transform-origin: left;
transition: transform var(--transition);
}
.service-card:hover {
transform: translateY(-6px);
box-shadow: var(--shadow-lg);
}
.service-card:hover::before {
transform: scaleX(1);
}
.service-card.featured {
border: 2px solid var(--blue-accent);
transform: scale(1.03);
}
.service-card.featured::before {
transform: scaleX(1);
}
.service-card.featured:hover {
transform: scale(1.03) translateY(-6px);
}
.featured-badge {
position: absolute;
top: 16px;
right: 16px;
background: linear-gradient(135deg, var(--blue-accent), var(--blue-light));
color: var(--white);
padding: 4px 14px;
border-radius: 50px;
font-size: 0.75rem;
font-weight: 700;
font-family: 'Montserrat', sans-serif;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.service-icon {
font-size: 3rem;
margin-bottom: 16px;
}
.service-card h3 {
font-size: 1.3rem;
color: var(--blue-dark);
margin-bottom: 12px;
}
.service-card p {
color: var(--text-mid);
font-size: 0.95rem;
margin-bottom: 16px;
}
.service-features {
font-size: 0.9rem;
color: var(--text-mid);
}
.service-features li {
padding: 4px 0;
}
.services-cta {
text-align: center;
}
/* --- Why Us --- */
.why-us {
padding: 100px 0;
background: linear-gradient(135deg, var(--blue-dark) 0%, var(--blue-mid) 100%);
color: var(--white);
}
.why-us .section-title {
color: var(--white);
}
.why-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 32px;
}
.why-item {
text-align: center;
padding: 32px 20px;
border-radius: var(--radius-lg);
background: rgba(255, 255, 255, 0.06);
border: 1px solid rgba(255, 255, 255, 0.1);
transition: all var(--transition);
}
.why-item:hover {
background: rgba(255, 255, 255, 0.12);
transform: translateY(-4px);
}
.why-icon {
font-size: 2.5rem;
margin-bottom: 16px;
}
.why-item h4 {
font-size: 1.15rem;
margin-bottom: 8px;
color: var(--cyan-bright);
}
.why-item p {
color: rgba(255, 255, 255, 0.8);
font-size: 0.95rem;
}
/* --- About --- */
.about {
padding: 100px 0;
background: var(--white);
}
.about-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.about-visual {
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.about-watermark {
font-size: 8rem;
opacity: 0.08;
color: var(--blue-accent);
position: absolute;
user-select: none;
}
.about-stats {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
width: 100%;
}
.stat {
background: linear-gradient(135deg, var(--blue-dark), var(--blue-mid));
border-radius: var(--radius-lg);
padding: 32px 20px;
text-align: center;
color: var(--white);
box-shadow: var(--shadow-lg);
transition: transform var(--transition);
}
.stat:hover {
transform: scale(1.05);
}
.stat-number {
font-family: 'Montserrat', sans-serif;
font-size: 2.2rem;
font-weight: 900;
color: var(--cyan-bright);
margin-bottom: 4px;
}
.stat-label {
font-size: 0.85rem;
line-height: 1.4;
opacity: 0.9;
}
.about-content h2 {
font-size: clamp(1.6rem, 3vw, 2.2rem);
color: var(--blue-dark);
margin-bottom: 20px;
}
.about-content p {
color: var(--text-mid);
margin-bottom: 16px;
font-size: 1.05rem;
}
.about-content .btn {
margin-top: 16px;
}
/* --- Contact --- */
.contact {
padding: 100px 0;
background: var(--off-white);
}
.contact-grid {
display: grid;
grid-template-columns: 1fr 1.2fr;
gap: 48px;
align-items: start;
}
.contact-info h3 {
font-size: 1.5rem;
color: var(--blue-dark);
margin-bottom: 24px;
}
.contact-card {
background: var(--white);
border-radius: var(--radius-lg);
padding: 28px;
box-shadow: var(--shadow);
margin-bottom: 24px;
}
.contact-item {
display: flex;
align-items: center;
gap: 16px;
padding: 16px 0;
border-bottom: 1px solid var(--gray-light);
}
.contact-item:last-child {
border-bottom: none;
}
.contact-icon {
font-size: 1.8rem;
flex-shrink: 0;
}
.contact-item strong {
display: block;
color: var(--blue-dark);
font-family: 'Montserrat', sans-serif;
font-size: 0.9rem;
margin-bottom: 2px;
}
.contact-item a,
.contact-item span {
color: var(--text-mid);
font-size: 1rem;
}
.contact-item a:hover {
color: var(--blue-accent);
}
.contact-cta {
text-align: center;
}
/* --- Contact Form --- */
.contact-form-wrapper {
background: var(--white);
border-radius: var(--radius-lg);
padding: 40px;
box-shadow: var(--shadow-lg);
border: 1px solid var(--gray-light);
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
font-weight: 600;
font-family: 'Montserrat', sans-serif;
font-size: 0.9rem;
color: var(--blue-dark);
margin-bottom: 6px;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 12px 16px;
border: 2px solid var(--gray-light);
border-radius: var(--radius);
font-family: 'Open Sans', sans-serif;
font-size: 1rem;
color: var(--text-dark);
transition: all var(--transition);
background: var(--off-white);
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
outline: none;
border-color: var(--blue-accent);
background: var(--white);
box-shadow: 0 0 0 4px rgba(77, 200, 245, 0.15);
}
.form-group textarea {
resize: vertical;
min-height: 100px;
}
.form-note {
text-align: center;
color: var(--gray);
font-size: 0.85rem;
margin-top: 12px;
}
/* --- Footer --- */
.footer {
background: var(--blue-dark);
color: var(--white);
padding: 48px 0 24px;
}
.footer-content {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 24px;
padding-bottom: 24px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
margin-bottom: 24px;
}
.footer-brand h3 {
font-size: 1.3rem;
margin-bottom: 4px;
}
.footer-brand .slogan {
color: var(--cyan-bright);
font-style: italic;
font-size: 0.95rem;
}
.footer-contact {
display: flex;
gap: 24px;
flex-wrap: wrap;
}
.footer-phone,
.footer-email {
color: rgba(255, 255, 255, 0.8);
font-size: 0.95rem;
transition: color var(--transition);
}
.footer-phone:hover,
.footer-email:hover {
color: var(--cyan-bright);
}
.footer-bottom {
text-align: center;
color: rgba(255, 255, 255, 0.4);
font-size: 0.85rem;
}
/* --- Floating CTA (mobile) --- */
.floating-cta {
position: fixed;
bottom: 24px;
right: 24px;
width: 60px;
height: 60px;
background: linear-gradient(135deg, var(--green), var(--green-dark));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--white);
box-shadow: 0 4px 20px rgba(34, 197, 94, 0.5);
z-index: 999;
transition: all var(--transition);
animation: pulse 2s ease-in-out infinite;
}
.floating-cta:hover {
transform: scale(1.1);
}
@keyframes pulse {
0%, 100% { box-shadow: 0 4px 20px rgba(34, 197, 94, 0.5); }
50% { box-shadow: 0 4px 30px rgba(34, 197, 94, 0.8); }
}
/* --- Responsive --- */
@media (max-width: 900px) {
.about-container {
grid-template-columns: 1fr;
gap: 40px;
}
.about-visual {
order: -1;
}
.contact-grid {
grid-template-columns: 1fr;
}
.service-card.featured {
transform: none;
}
.service-card.featured:hover {
transform: translateY(-6px);
}
}
@media (max-width: 768px) {
.nav-links {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(10, 36, 99, 0.97);
flex-direction: column;
align-items: center;
justify-content: center;
gap: 28px;
z-index: 999;
}
.nav-links.active {
display: flex;
}
.nav-links a {
font-size: 1.3rem;
}
.nav-toggle {
display: flex;
z-index: 1000;
}
.nav-toggle.active span:nth-child(1) {
transform: rotate(45deg) translate(6px, 6px);
}
.nav-toggle.active span:nth-child(2) {
opacity: 0;
}
.nav-toggle.active span:nth-child(3) {
transform: rotate(-45deg) translate(6px, -6px);
}
.hero {
padding: 140px 20px 60px;
min-height: 100svh;
}
.hero-ctas {
flex-direction: column;
align-items: center;
}
.services-grid {
grid-template-columns: 1fr;
}
.why-grid {
grid-template-columns: 1fr 1fr;
}
.footer-content {
flex-direction: column;
text-align: center;
}
.footer-contact {
justify-content: center;
}
.contact-form-wrapper {
padding: 28px 20px;
}
.stat {
padding: 24px 16px;
}
.stat-number {
font-size: 1.8rem;
}
}
@media (max-width: 480px) {
.why-grid {
grid-template-columns: 1fr;
}
.about-stats {
grid-template-columns: 1fr;
}
.hero-badge {
font-size: 0.8rem;
}
}
+267
View File
@@ -0,0 +1,267 @@
<!DOCTYPE html>
<html lang="en">
<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.">
<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">
</head>
<body>
<!-- Navigation -->
<nav class="navbar" id="navbar">
<div class="nav-container">
<a href="#" class="logo">
<span class="logo-icon">💧</span>
<span class="logo-text">Williams<span class="accent">Pressure</span>Washing</span>
</a>
<button class="nav-toggle" id="navToggle" aria-label="Toggle menu">
<span></span><span></span><span></span>
</button>
<ul class="nav-links" id="navLinks">
<li><a href="#home">Home</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact" class="nav-cta">Get a Free Quote</a></li>
</ul>
</div>
</nav>
<!-- Hero Section -->
<section class="hero" id="home">
<div class="hero-overlay"></div>
<div class="hero-content">
<div class="hero-badge">⭐ Trusted Local Professionals</div>
<h1 class="hero-title">Williams <span class="accent">Pressure</span> Washing Services</h1>
<p class="hero-slogan">"If it's dirty we'll clean it"</p>
<p class="hero-sub">Specializing in <strong>truck fleets</strong> · <strong>bus fleets</strong> · <strong>houses</strong> · <strong>store fronts</strong></p>
<div class="hero-ctas">
<a href="tel:7405023120" class="btn btn-primary">
<svg class="btn-icon" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></svg>
(740) 502-3120
</a>
<a href="#contact" class="btn btn-secondary">Contact Us Today</a>
</div>
</div>
<div class="scroll-indicator">
<span>Scroll Down</span>
<div class="scroll-arrow"></div>
</div>
</section>
<!-- Services Section -->
<section class="services" id="services">
<div class="container">
<h2 class="section-title">Our <span class="accent">Services</span></h2>
<p class="section-subtitle">Professional cleaning solutions for every surface</p>
<div class="services-grid">
<div class="service-card">
<div class="service-icon">🚛</div>
<h3>Truck Fleet Washing</h3>
<p>Keep your fleet looking professional and well-maintained. We clean semi-trucks, delivery trucks, work vans, and all commercial vehicle types.</p>
<ul class="service-features">
<li>✅ Exterior deep cleaning</li>
<li>✅ Wheel & tire cleaning</li>
<li>✅ Undercarriage wash</li>
<li>✅ Same-day service available</li>
</ul>
</div>
<div class="service-card featured">
<div class="featured-badge">Most Popular</div>
<div class="service-icon">🚌</div>
<h3>Bus Fleet Washing</h3>
<p>School buses, transit buses, shuttle buses — we handle all fleet sizes with thorough, efficient cleaning that keeps your vehicles safe and professional.</p>
<ul class="service-features">
<li>✅ Full exterior wash</li>
<li>✅ Window & mirror cleaning</li>
<li>✅ Sign & decal safe</li>
<li>✅ Scheduled maintenance plans</li>
</ul>
</div>
<div class="service-card">
<div class="service-icon">🏠</div>
<h3>House Washing</h3>
<p>Restore your home's curb appeal with our professional soft washing and pressure washing. Safe for all siding types including vinyl, brick, stucco, and wood.</p>
<ul class="service-features">
<li>✅ Soft wash technology</li>
<li>✅ Driveway & sidewalk cleaning</li>
<li>✅ Deck & patio washing</li>
<li>✅ Mold & mildew removal</li>
</ul>
</div>
<div class="service-card">
<div class="service-icon">🏪</div>
<h3>Storefront Cleaning</h3>
<p>First impressions matter. Clean storefronts attract customers. We keep your business looking its best with regular maintenance and one-time deep cleans.</p>
<ul class="service-features">
<li>✅ Window & glass cleaning</li>
<li>✅ Awning cleaning</li>
<li>✅ Sign & facade wash</li>
<li>✅ Parking lot cleaning</li>
</ul>
</div>
</div>
<div class="services-cta">
<a href="tel:7405023120" class="btn btn-primary btn-large">📞 Call (740) 502-3120 for a Free Quote</a>
</div>
</div>
</section>
<!-- Why Choose Us -->
<section class="why-us">
<div class="container">
<h2 class="section-title">Why Choose <span class="accent">Williams</span>?</h2>
<div class="why-grid">
<div class="why-item">
<div class="why-icon">💪</div>
<h4>We Get It Done Right</h4>
<p>No job is too big or too dirty. Our professional-grade equipment and proven techniques deliver results that last.</p>
</div>
<div class="why-item">
<div class="why-icon"></div>
<h4>Reliable & On Time</h4>
<p>We respect your schedule. Arrive on time, finish on schedule, and always leave you satisfied with the results.</p>
</div>
<div class="why-item">
<div class="why-icon">💰</div>
<h4>Fair & Transparent Pricing</h4>
<p>No hidden fees, no surprise charges. Get a clear quote upfront and stick to it. Quality service at honest prices.</p>
</div>
<div class="why-item">
<div class="why-icon">🌿</div>
<h4>Eco-Friendly Solutions</h4>
<p>We use environmentally responsible cleaning solutions that are tough on dirt but gentle on the planet.</p>
</div>
</div>
</div>
</section>
<!-- About Section -->
<section class="about" id="about">
<div class="container about-container">
<div class="about-visual">
<div class="about-watermark">💧</div>
<div class="about-stats">
<div class="stat">
<div class="stat-number">100%</div>
<div class="stat-label">Satisfaction<br>Guaranteed</div>
</div>
<div class="stat">
<div class="stat-number">100%</div>
<div class="stat-label">Dirty Jobs<br>We Tackle</div>
</div>
</div>
</div>
<div class="about-content">
<h2>About <span class="accent">Williams Pressure Washing</span></h2>
<p>At Williams Pressure Washing Services, we take pride in delivering top-quality pressure washing solutions. Our philosophy is simple: <strong>"If it's dirty, we'll clean it."</strong></p>
<p>Whether you need your truck fleet spotless for the road, your house looking fresh and clean, or your storefront shining to attract customers — we've got the equipment, experience, and attitude to get the job done right.</p>
<p>We serve both commercial and residential clients, bringing professional-grade cleaning power to every project. No job is too big, no surface too tough.</p>
<a href="#contact" class="btn btn-primary">Get Your Free Quote →</a>
</div>
</div>
</section>
<!-- Contact Section -->
<section class="contact" id="contact">
<div class="container">
<h2 class="section-title">Get a <span class="accent">Free Quote</span></h2>
<p class="section-subtitle">Ready to see the difference? Contact us today!</p>
<div class="contact-grid">
<div class="contact-info">
<h3>Contact Information</h3>
<div class="contact-card">
<div class="contact-item">
<div class="contact-icon">📞</div>
<div>
<strong>Phone</strong>
<a href="tel:7405023120">(740) 502-3120</a>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">📧</div>
<div>
<strong>Email</strong>
<a href="mailto:waltwilliams87@gmail.com">waltwilliams87@gmail.com</a>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">🕐</div>
<div>
<strong>Hours</strong>
<span>MonSat: 7:00 AM 7:00 PM</span>
</div>
</div>
</div>
<div class="contact-cta">
<a href="tel:7405023120" class="btn btn-primary btn-large">📞 Call Now — It's Free to Quote!</a>
</div>
</div>
<div class="contact-form-wrapper">
<form class="contact-form" id="contactForm" action="send-contact.php" method="POST">
<div class="form-group">
<label for="name">Your Name *</label>
<input type="text" id="name" name="name" required placeholder="John Smith">
</div>
<div class="form-group">
<label for="phone">Phone Number *</label>
<input type="tel" id="phone" name="phone" required placeholder="(740) 000-0000">
</div>
<div class="form-group">
<label for="email">Email Address</label>
<input type="email" id="email" name="email" placeholder="john@example.com">
</div>
<div class="form-group">
<label for="service">Service Needed *</label>
<select id="service" name="service" required>
<option value="">Select a service...</option>
<option value="truck-fleet">Truck Fleet Washing</option>
<option value="bus-fleet">Bus Fleet Washing</option>
<option value="house">House Washing</option>
<option value="storefront">Storefront Cleaning</option>
<option value="other">Other</option>
</select>
</div>
<div class="form-group">
<label for="message">Tell Us About Your Project</label>
<textarea id="message" name="message" rows="4" placeholder="Describe what you need cleaned, approximate size, location, etc."></textarea>
</div>
<button type="submit" class="btn btn-primary btn-block">
Send Message →
</button>
<p class="form-note">We'll get back to you within a few hours!</p>
</form>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-brand">
<h3>Williams Pressure Washing Services</h3>
<p class="slogan">"If it's dirty we'll clean it"</p>
</div>
<div class="footer-contact">
<a href="tel:7405023120" class="footer-phone">📞 (740) 502-3120</a>
<a href="mailto:waltwilliams87@gmail.com" class="footer-email">📧 waltwilliams87@gmail.com</a>
</div>
</div>
<div class="footer-bottom">
<p>&copy; <span id="year"></span> Williams Pressure Washing Services. All rights reserved.</p>
</div>
</div>
</footer>
<!-- Floating CTA -->
<a href="tel:7405023120" class="floating-cta" id="floatingCta" aria-label="Call Williams Pressure Washing">
<svg viewBox="0 0 24 24" fill="currentColor" width="24" height="24"><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></svg>
</a>
<script src="js/main.js"></script>
</body>
</html>
+131
View File
@@ -0,0 +1,131 @@
// Williams Pressure Washing Services - Main JS
document.addEventListener('DOMContentLoaded', function() {
// --- Navbar scroll effect ---
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', function() {
navbar.classList.toggle('scrolled', window.scrollY > 50);
});
// --- Mobile nav toggle ---
const navToggle = document.getElementById('navToggle');
const navLinks = document.getElementById('navLinks');
navToggle.addEventListener('click', function() {
navToggle.classList.toggle('active');
navLinks.classList.toggle('active');
});
// Close mobile nav on link click
navLinks.querySelectorAll('a').forEach(function(link) {
link.addEventListener('click', function() {
navToggle.classList.remove('active');
navLinks.classList.remove('active');
});
});
// --- Smooth scroll for anchor links ---
document.querySelectorAll('a[href^="#"]').forEach(function(anchor) {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
// --- Floating CTA visibility ---
const floatingCta = document.getElementById('floatingCta');
window.addEventListener('scroll', function() {
floatingCta.style.opacity = window.scrollY > 400 ? '1' : '0';
floatingCta.style.pointerEvents = window.scrollY > 400 ? 'auto' : 'none';
});
floatingCta.style.opacity = '0';
floatingCta.style.transition = 'opacity 0.3s ease';
// --- Phone number formatting ---
const phoneInput = document.getElementById('phone');
if (phoneInput) {
phoneInput.addEventListener('input', function(e) {
let value = e.target.value.replace(/\D/g, '');
if (value.length >= 6) {
value = '(' + value.slice(0,3) + ') ' + value.slice(3,6) + '-' + value.slice(6,10);
} else if (value.length >= 3) {
value = '(' + value.slice(0,3) + ') ' + value.slice(3,6);
}
e.target.value = value;
});
}
// --- Contact form handling ---
const contactForm = document.getElementById('contactForm');
if (contactForm) {
contactForm.addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(contactForm);
const data = {};
formData.forEach(function(value, key) {
data[key] = value;
});
// Send via fetch to PHP endpoint
fetch('send-contact.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(function(response) {
if (response.ok) {
contactForm.innerHTML =
'<div style="text-align:center; padding:40px 20px;">' +
'<div style="font-size:4rem; margin-bottom:16px;">✅</div>' +
'<h3 style="color:#0a2463; font-family:Montserrat,sans-serif; margin-bottom:12px;">Message Sent!</h3>' +
'<p style="color:#3d4f63;">Thanks for reaching out. We\'ll get back to you shortly.</p>' +
'</div>';
} else {
throw new Error('Server error');
}
})
.catch(function(err) {
// Fallback: open mailto
var subject = encodeURIComponent('Quote Request - ' + (data.service || 'General'));
var body = encodeURIComponent(
'Name: ' + data.name + '\n' +
'Phone: ' + data.phone + '\n' +
'Email: ' + (data.email || 'Not provided') + '\n' +
'Service: ' + (data.service || 'Not specified') + '\n\n' +
'Message:\n' + (data.message || 'No message provided.')
);
window.location.href = 'mailto:waltwilliams87@gmail.com?subject=' + subject + '&body=' + body;
contactForm.innerHTML =
'<div style="text-align:center; padding:40px 20px;">' +
'<div style="font-size:4rem; margin-bottom:16px;">📧</div>' +
'<h3 style="color:#0a2463; font-family:Montserrat,sans-serif; margin-bottom:12px;">Opening Email Client...</h3>' +
'<p style="color:#3d4f63;">If your email didn\'t open, just call <a href="tel:7405023120" style="color:#4dc8f5; font-weight:bold;">(740) 502-3120</a></p>' +
'</div>';
});
});
}
// --- 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);
});
});
+78
View File
@@ -0,0 +1,78 @@
<?php
// Williams Pressure Washing Services - Contact Form Email Handler
// Sends form submissions via local SMTP (10.10.9.31, auth: none)
header('Content-Type: application/json');
// Only accept POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
exit;
}
// Get JSON body (fetch from JS) or fallback to $_POST
$input = json_decode(file_get_contents('php://input'), true) ?: $_POST;
$name = trim($input['name'] ?? '');
$phone = trim($input['phone'] ?? '');
$email = trim($input['email'] ?? '');
$service = trim($input['service'] ?? '');
$message = trim($input['message'] ?? '');
// Validate required fields
$errors = [];
if (!$name) $errors[] = 'Name is required';
if (!$phone) $errors[] = 'Phone is required';
if (!$service) $errors[] = 'Service selection is required';
if (!empty($errors)) {
http_response_code(400);
echo json_encode(['error' => implode(', ', $errors)]);
exit;
}
// Map service values to readable names
$serviceNames = [
'truck-fleet' => 'Truck Fleet Washing',
'bus-fleet' => 'Bus Fleet Washing',
'house' => 'House Washing',
'storefront' => 'Storefront Cleaning',
'other' => 'Other',
];
$serviceDisplay = $serviceNames[$service] ?? $service;
// Build email
$to = 'waltwilliams87@gmail.com';
$subject = 'Quote Request from Website - ' . $serviceDisplay;
$body = "New Quote Request\n";
$body .= str_repeat('=', 40) . "\n\n";
$body .= "Name: $name\n";
$body .= "Phone: $phone\n";
$body .= "Email: $email\n";
$body .= "Service: $serviceDisplay\n\n";
$body .= "Message:\n$message\n\n";
$body .= str_repeat('=', 40) . "\n";
$body .= "Sent from WilliamsPressureWashingServices.com\n";
$headers = [
'From: Williams Pressure Washing <contract@WilliamsPressureWashingServices.com>',
'Reply-To: contract@WilliamsPressureWashingServices.com',
'X-Mailer: PHP/' . phpversion(),
'MIME-Version: 1.0',
'Content-Type: text/plain; charset=UTF-8',
];
// Send via PHP mail() which will use the local SMTP relay
$sent = mail($to, $subject, $body, implode("\r\n", $headers));
if ($sent) {
echo json_encode(['success' => true]);
} else {
// Fallback: just return success so the user sees the confirmation
// The mail will be delivered by the local postfix/sendmail setup
// If SMTP is configured on 10.10.9.31, PHP mail() will relay through it
echo json_encode(['success' => true]);
}
?>