Serving
Fairfield Vacaville Benicia Napa Solano County
Free Estimate · No Commitment

Find Out What Your
Clean Will Cost

Honest pricing, calculated live. Built on 15 years of Solano County rates. Final price confirmed on-site after a quick walkthrough — no surprises.

★★★★★ 4.9 on Google · 500+ clients · Licensed, Bonded & Insured
Step 1 of 4
1 What kind of clean do you need?
2 How big is your space?
sq ft
1,000
3 Want to go the extra mile? (optional)
Oven Cleaning
Full interior scrub & degrease
+$75
Refrigerator Cleaning
Interior wipe, sanitize & deodorize
+$75
Window Cleaning
From $12 / window
0
windows
4 How often? More visits, more savings
Your estimate is seconds away
Enter your square footage above to reveal pricing
Lock In This Quote

Send me this estimate & book my walkthrough.

We'll confirm the price on-site, then schedule your first clean. No commitment until you say yes.

Or call directly: (707) 430-6372
Licensed & Bonded
Eco-Friendly
Green Clean Certified
OSHA 10 Trained
15+ Years Local
Prefer to Just Talk?
Call us directly or fill out the form above — we'll confirm your quote in under 24 hours.
(707) 430-6372
grcleaningservices.com · Fairfield, CA
Contact Us
Call Text Quote
+ roundTo5(Math.round(n)).toLocaleString(); const fmtR = (a,b) => fmt(a) + ' – ' + fmt(b); let wins = 0, scrs = 0, bLo = 0, bHi = 0, firstRun = true; const slider = $('sqft-slider'); const sqftInp = $('sqft'); function updateSliderBg(val) { const pct = ((val - 100) / (5000 - 100)) * 100; slider.style.background = `linear-gradient(to right, #2d6a45 ${pct}%, #e7e2d8 ${pct}%)`; $('slider-label').textContent = Number(val).toLocaleString(); } slider.addEventListener('input', () => { const v = parseInt(slider.value); sqftInp.value = v; sqftInp.classList.add('has-val'); document.querySelectorAll('.qbtn').forEach(b => b.classList.remove('selected')); updateSliderBg(v); calcNow(); }); sqftInp.addEventListener('input', () => { const v = parseInt(sqftInp.value) || 0; if (v >= 100 && v <= 10000) { slider.value = v; updateSliderBg(v); } if (v >= 100) sqftInp.classList.add('has-val'); else sqftInp.classList.remove('has-val'); document.querySelectorAll('.qbtn').forEach(b => b.classList.remove('selected')); calcNow(); }); updateSliderBg(1000); // Quick sqft preset buttons document.querySelectorAll('.qbtn').forEach(btn => { btn.addEventListener('click', () => { const v = parseInt(btn.dataset.sqft, 10); sqftInp.value = v; sqftInp.classList.add('has-val'); if (v <= 5000) { slider.value = v; updateSliderBg(v); } document.querySelectorAll('.qbtn').forEach(b => b.classList.remove('selected')); btn.classList.add('selected'); calcNow(); toastMsg('✓ ' + v.toLocaleString() + ' sq ft selected'); }); }); // Add-ons (oven + fridge row click toggles checkbox) document.getElementById('row-oven').addEventListener('click', () => { const cb = $('oven-cb'); cb.checked = !cb.checked; calcNow(); if (cb.checked) toastMsg('Oven cleaning added'); }); document.getElementById('row-fridge').addEventListener('click', () => { const cb = $('fridge-cb'); cb.checked = !cb.checked; calcNow(); if (cb.checked) toastMsg('Refrigerator cleaning added'); }); // Windows stepper — click + touchend for reliable mobile support function winHandler(dir, e) { e.preventDefault(); e.stopPropagation(); if (dir === -1 && wins <= 0) return; wins += dir; $('win-val').textContent = wins; const screenRow = $('screen-row'); if (wins > 0) { screenRow.classList.remove('hidden'); setTimeout(() => screenRow.classList.add('show'), 10); } else { screenRow.classList.remove('show'); scrs = 0; $('scr-val').textContent = 0; } calcNow(); } function scrHandler(dir, e) { e.preventDefault(); e.stopPropagation(); if (dir === -1 && scrs <= 0) return; scrs += dir; $('scr-val').textContent = scrs; calcNow(); } ['click','touchend'].forEach(evt => { $('win-minus').addEventListener(evt, (e) => winHandler(-1, e), { passive: false }); $('win-plus').addEventListener(evt, (e) => winHandler(1, e), { passive: false }); $('scr-minus').addEventListener(evt, (e) => scrHandler(-1, e), { passive: false }); $('scr-plus').addEventListener(evt, (e) => scrHandler(1, e), { passive: false }); }); // ============ Core calculation ============ function calcNow() { const sqft = parseInt(sqftInp.value) || 0; if (sqft < 100) { $('result-empty').classList.remove('hidden'); $('result-content').classList.add('hidden'); updateStepChecks(); updateHiddenFields(); return; } const svc = document.querySelector('input[name="svc"]:checked')?.value || 'commercial'; const freq = parseFloat(document.querySelector('input[name="freq"]:checked')?.value || 1); const oven = $('oven-cb').checked; const fridge= $('fridge-cb').checked; const R = RATES[svc]; let baseLo = Math.max(sqft * R.lo, R.min); let baseHi = Math.max(sqft * R.hi, R.min); const addons = (oven ? 75 : 0) + (fridge ? 75 : 0) + (wins * 13) + (scrs * 6); const rawLo = baseLo + addons; const rawHi = baseHi + addons; bLo = Math.round(rawLo * freq); bHi = Math.round(rawHi * freq); $('result-empty').classList.add('hidden'); $('result-content').classList.remove('hidden'); const discShow = freq < 1; $('savings-badge').classList.toggle('hidden', !discShow); if (discShow) { const dLo = Math.round(rawLo - bLo); const dHi = Math.round(rawHi - bHi); const lblMap = { '0.95':'Monthly (5% off)', '0.90':'Bi-Weekly (10% off)', '0.85':'Weekly (15% off)' }; $('bv-disc-lbl').textContent = lblMap[String(freq)] || 'Recurring discount'; $('bv-disc-val').textContent = '−' + fmtR(dLo, dHi); $('savings-amt').textContent = fmtR(dLo, dHi); } $('brow-oven').classList.toggle('hidden', !oven); $('brow-fridge').classList.toggle('hidden', !fridge); $('brow-windows').classList.toggle('hidden', wins === 0 && scrs === 0); $('brow-disc').classList.toggle('hidden', !discShow); if (wins > 0) { $('bv-win-lbl').textContent = '+ ' + wins + ' window' + (wins > 1 ? 's' : ''); $('bv-win-val').textContent = '+' + fmt(wins * 13 + scrs * 6); $('bv-win-lbl').textContent = '+ ' + wins + ' window' + (wins > 1 ? 's' : '') + (scrs > 0 ? ' + ' + scrs + ' screen' + (scrs > 1 ? 's' : '') : ''); } $('bv-base').textContent = fmtR(Math.round(baseLo), Math.round(baseHi)); $('bv-total').textContent = fmtR(bLo, bHi); if (!firstRun) { animNum('plo', undefined, bLo); animNum('phi', undefined, bHi); } else { $('plo').textContent = fmt(bLo); $('phi').textContent = fmt(bHi); firstRun = false; } updateStepChecks(); updateHiddenFields(); } function updateStepChecks() { const sqft = parseInt(sqftInp.value) || 0; const freq = parseFloat(document.querySelector('input[name="freq"]:checked')?.value || 1); $('ps1').classList.add('active'); $('ps2').classList.toggle('active', sqft >= 100); $('ps3').classList.toggle('active', true); $('ps4').classList.toggle('active', freq !== 1 || sqft >= 100); $('chk2').classList.toggle('show', sqft >= 100); $('chk4').classList.toggle('show', true); const step = sqft < 100 ? 2 : 4; $('prog-label').textContent = 'Step ' + step + ' of 4'; } function updateHiddenFields() { const sqft = parseInt(sqftInp.value) || 0; const svc = document.querySelector('input[name="svc"]:checked')?.value || ''; const freq = document.querySelector('input[name="freq"]:checked')?.value || '1'; const oven = $('oven-cb').checked; const fridge= $('fridge-cb').checked; const freqLbl = { '1':'One-Time', '0.95':'Monthly (5% off)', '0.90':'Bi-Weekly (10% off)', '0.85':'Weekly (15% off)' }; const addonList = []; if (oven) addonList.push('Oven cleaning'); if (fridge) addonList.push('Refrigerator cleaning'); if (wins > 0) addonList.push(wins + ' window' + (wins > 1 ? 's' : '') + ' (+' + fmt(wins * 13) + ')'); if (scrs > 0) addonList.push(scrs + ' screen' + (scrs > 1 ? 's' : '') + ' (+' + fmt(scrs * 6) + ')'); $('hf-service').value = RATES[svc]?.label || svc; $('hf-sqft').value = sqft; $('hf-addons').value = addonList.length ? addonList.join(', ') : 'None'; $('hf-freq').value = freqLbl[freq] || freq; $('hf-lo').value = Math.round(bLo); $('hf-hi').value = Math.round(bHi); $('hf-summary').value = `${RATES[svc]?.label || svc} | ${sqft.toLocaleString()} sqft | ${freqLbl[freq]} | Add-ons: ${addonList.length ? addonList.join(', ') : 'None'} | Estimate: ${fmtR(bLo, bHi)}`; const arName = (document.getElementById('lf-name')?.value || '').trim().split(' ')[0] || 'there'; const arEl = document.getElementById('hf-autoresponse'); if (arEl) arEl.value = 'Hi ' + arName + '! Thanks for requesting your instant estimate from Green Rose Cleaning Services.\n\n' + 'YOUR ESTIMATE: $' + $('hf-lo').value + ' - $' + $('hf-hi').value + ' (' + $('hf-service').value + ', ' + $('hf-sqft').value + ' sq ft, ' + $('hf-freq').value + ')\n\n' + 'Your estimate is locked in. We will call you within 24 hours to confirm the details and schedule your free walkthrough. Want to talk sooner? Call or text us at (707) 430-6372.\n\n' + '- The Green Rose team\nLicensed - Bonded - Insured\nwww.grcleaningservices.com'; } function animNum(id, from, to) { const el = $(id); const steps = 18, dur = 380; let s = 0; const start = from || to; const iv = setInterval(() => { s++; const t = 1 - Math.pow(1 - s/steps, 3); el.textContent = fmt(Math.round(start + (to - start) * t)); el.classList.remove('num-in'); void el.offsetWidth; el.classList.add('num-in'); if (s >= steps) { clearInterval(iv); el.textContent = fmt(to); } }, dur/steps); } let toastT; function toastMsg(msg) { const t = $('toast'); t.textContent = msg; t.classList.add('show'); clearTimeout(toastT); toastT = setTimeout(() => t.classList.remove('show'), 2000); } document.getElementById('quote-form').addEventListener('submit', async (e) => { if (e.defaultPrevented) return; e.preventDefault(); updateHiddenFields(); const form = e.target; const btn = $('lf-submit'); const lfsuccess = $('lf-success'); calcNow(); btn.textContent = 'Sending…'; btn.disabled = true; btn.classList.add('opacity-70'); try { const res = await fetch(form.action, { method: 'POST', body: (function(){ const fd = new FormData(form); fd.delete('cf-turnstile-response'); return fd; })(), headers: { 'Accept': 'application/json' } }); if (res.ok) { const arEmail = document.getElementById('lf-email'); if (lfsuccess && arEmail && arEmail.value) lfsuccess.textContent = 'Got it — your estimate is locked in and a confirmation email is on its way. We’ll reach out within 24 hours.'; lfsuccess.classList.remove('hidden'); btn.textContent = 'Quote Locked In ✓'; btn.classList.remove('bg-gold-500', 'hover:bg-gold-400', 'text-forest-950'); btn.classList.add('bg-forest-700', 'text-white'); btn.classList.remove('opacity-70'); form.reset(); window.location.href = '/cleaning-quote/'; } else { btn.textContent = 'Error — Please Call Us'; btn.classList.add('bg-red-600', 'text-white'); btn.disabled = false; } } catch (err) { btn.textContent = 'Error — Please Call Us'; btn.classList.add('bg-red-600', 'text-white'); btn.disabled = false; } }); calcNow(); document.querySelectorAll('input[name="svc"]').forEach(r => r.addEventListener('change', calcNow)); document.querySelectorAll('input[name="freq"]').forEach(r => r.addEventListener('change', calcNow));
Call Text Quote