Instant Cleaning Estimate
Adjust the sliders and options below to get a real-time price estimate for your home.
Your Estimated Price
Estimated Hours:
~3.5 hrs
Subtotal:
$245.00
Bi-Weekly Discount (10%):
-$24.50
Total Estimate:
$220.50
This is an estimate only. Price may vary based on the actual condition of the home.
/* Flawless LLC Calculator Styles */
:root {
–hot-pink: #FF007F; /* A vibrant, modern hot pink */
–black: #1a1a1a;
–white: #ffffff;
–light-grey: #f7f7f7;
–medium-grey: #e9e9e9;
–text-grey: #555555;
}
#flawless-calculator-container {
font-family: -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, Helvetica, Arial, sans-serif;
background-color: var(–white);
padding: 20px;
max-width: 700px;
margin: 20px auto;
border: 1px solid var(–medium-grey);
border-radius: 12px;
box-shadow: 0 8px 25px rgba(0,0,0,0.1);
}
#flawless-calculator h2, #flawless-calculator h3, #flawless-calculator h4 {
color: var(–black);
text-align: center;
margin-top: 0;
}
#flawless-calculator h4 {
text-align: left;
border-bottom: 2px solid var(–hot-pink);
padding-bottom: 8px;
margin-top: 25px;
margin-bottom: 20px;
}
#flawless-calculator p {
color: var(–text-grey);
text-align: center;
margin-bottom: 25px;
line-height: 1.5;
}
.form-group {
margin-bottom: 20px;
}
.form-group.inline {
display: flex;
justify-content: space-between;
gap: 20px;
}
.form-group.inline > div, .form-group.inline > label {
flex: 1;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: var(–black);
}
input[type=”number”], select {
width: 100%;
padding: 12px;
border: 1px solid var(–medium-grey);
border-radius: 8px;
font-size: 16px;
box-sizing: border-box; /* Important for consistent sizing */
}
input[type=”range”] {
width: 100%;
cursor: pointer;
}
/* Custom Checkbox and Radio Styles */
input[type=”checkbox”], input[type=”radio”] {
accent-color: var(–hot-pink);
transform: scale(1.2);
margin-right: 8px;
}
.radio-group label {
display: inline-block;
margin-right: 20px;
font-weight: normal;
}
.form-group.addon label {
display: flex;
align-items: center;
font-weight: normal;
}
.slider-labels {
display: flex;
justify-content: space-between;
font-size: 12px;
color: var(–text-grey);
margin-top: 5px;
}
#calculator-result {
background-color: var(–light-grey);
padding: 25px;
margin-top: 30px;
border-radius: 8px;
border-top: 4px solid var(–hot-pink);
}
.result-line, .final-price {
display: flex;
justify-content: space-between;
font-size: 16px;
margin-bottom: 12px;
}
.final-price {
font-size: 24px;
font-weight: bold;
color: var(–black);
}
#estimated-price {
color: var(–hot-pink);
}
#discount-line {
color: #008a00; /* Green for discount */
}
#calculator-result hr {
border: 0;
border-top: 1px solid var(–medium-grey);
margin: 15px 0;
}
.disclaimer {
font-size: 12px;
text-align: center;
color: #777;
margin-top: 20px;
margin-bottom: 0;
}
document.addEventListener(‘DOMContentLoaded’, function() {
// — CONFIGURATION —
// You can easily adjust your business logic here
const config = {
hourlyRate: 70, // Your average hourly rate ($65-75)
// Time calculation factors (in hours)
timePerSqFt: 0.0008, // Base hours per square foot
timePerBed: 0.25, // Extra 15 mins per bedroom
timePerBath: 0.40, // Extra 24 mins per bathroom
timeUpgraded: 0.25, // Extra 15 mins for upgraded homes
timePerLinenChange: 0.125, // Extra 7.5 mins per bed for linens
// Price for fixed-cost add-ons
addOns: {
oven: 35,
fridge: 40,
petHair: 50,
windowsPerPiece: 10,
},
// Modifiers for cleaning type
typeModifiers: {
‘deep-clean’: 1.6, // Deep cleans take 60% longer than a standard clean
‘weekly’: 1.0,
‘biweekly’: 1.0,
‘monthly’: 1.1, // Monthly cleans take a bit longer than bi-weekly
},
// Frequency discounts
discounts: {
‘weekly’: 0.15, // 15%
‘biweekly’: 0.10, // 10%
‘monthly’: 0.05, // 5%
‘deep-clean’: 0,
}
};
// — ELEMENT SELECTORS —
const form = document.getElementById(‘cleaning-form’);
// Inputs
const sqftSlider = document.getElementById(‘sqft’);
const bedroomsInput = document.getElementById(‘bedrooms’);
const bathroomsInput = document.getElementById(‘bathrooms’);
const flooringInputs = document.getElementsByName(‘flooring’);
const isUpgradedCheckbox = document.getElementById(‘home-upgraded’);
const cleaningTypeSelect = document.getElementById(‘cleaning-type’);
const conditionSlider = document.getElementById(‘condition’);
// Add-ons
const addOvenCheckbox = document.getElementById(‘add-oven’);
const addFridgeCheckbox = document.getElementById(‘add-fridge’);
const addLinensCheckbox = document.getElementById(‘add-linens’);
const addPetHairCheckbox = document.getElementById(‘add-pet-hair’);
const addWindowsInput = document.getElementById(‘add-windows’);
// Outputs
const sqftValueSpan = document.getElementById(‘sqft-value’);
const conditionTextSpan = document.getElementById(‘condition-text’);
const estimatedHoursSpan = document.getElementById(‘estimated-hours’);
const subtotalPriceSpan = document.getElementById(‘subtotal-price’);
const discountLine = document.getElementById(‘discount-line’);
const discountLabelSpan = document.getElementById(‘discount-label’);
const discountAmountSpan = document.getElementById(‘discount-amount’);
const estimatedPriceSpan = document.getElementById(‘estimated-price’);
// — CALCULATION FUNCTION —
function calculatePrice() {
// 1. Get all current values from the form
const sqft = parseInt(sqftSlider.value);
const bedrooms = parseInt(bedroomsInput.value);
const bathrooms = parseInt(bathroomsInput.value);
const cleaningType = cleaningTypeSelect.value;
const conditionMultiplier = parseFloat(conditionSlider.value);
let selectedFlooring = document.querySelector(‘input[name=”flooring”]:checked’).value;
// 2. Calculate BASE cleaning hours
let baseHours = (sqft * config.timePerSqFt) + (bedrooms * config.timePerBed) + (bathrooms * config.timePerBath);
// 3. Apply MODIFIERS to the hours
// Cleaning Type Modifier
baseHours *= config.typeModifiers[cleaningType];
// Home Condition Modifier
baseHours *= conditionMultiplier;
// Flooring Modifier (e.g., carpet takes 5% longer)
if (selectedFlooring === ‘carpet’) {
baseHours *= 1.05;
}
// Upgraded Home Modifier
if (isUpgradedCheckbox.checked) {
baseHours += config.timeUpgraded;
}
// Linen change modifier
if (addLinensCheckbox.checked) {
baseHours += bedrooms * config.timePerLinenChange;
}
// 4. Calculate cost of ADD-ONS
let addOnsCost = 0;
if (addOvenCheckbox.checked) addOnsCost += config.addOns.oven;
if (addFridgeCheckbox.checked) addOnsCost += config.addOns.fridge;
if (addPetHairCheckbox.checked) addOnsCost += config.addOns.petHair;
addOnsCost += parseInt(addWindowsInput.value) * config.addOns.windowsPerPiece;
// 5. Calculate SUBTOTAL
const cleaningCost = baseHours * config.hourlyRate;
const subtotal = cleaningCost + addOnsCost;
// 6. Calculate DISCOUNT
const discountPercentage = config.discounts[cleaningType];
const discountAmount = subtotal * discountPercentage;
// 7. Calculate FINAL price
const finalPrice = subtotal – discountAmount;
// 8. UPDATE the display
sqftValueSpan.textContent = sqft;
updateConditionText(conditionMultiplier);
estimatedHoursSpan.textContent = `~${baseHours.toFixed(1)} hrs`;
subtotalPriceSpan.textContent = `$${subtotal.toFixed(2)}`;
if (discountAmount > 0) {
discountLine.style.display = ‘flex’;
discountLabelSpan.textContent = `${cleaningType.charAt(0).toUpperCase() + cleaningType.slice(1)} Discount (${discountPercentage * 100}%):`;
discountAmountSpan.textContent = `-$${discountAmount.toFixed(2)}`;
} else {
discountLine.style.display = ‘none’;
}
estimatedPriceSpan.textContent = `$${finalPrice.toFixed(2)}`;
}
function updateConditionText(value) {
if (value < 1.2) conditionTextSpan.textContent = 'Average';
else if (value {
input.addEventListener(‘input’, calculatePrice);
});
// Initial calculation on page load
calculatePrice();
});