Pricing

Flat-rate visit fees, with clear add-ons as needed. Taxes extra. All prices in CAD.

Service Includes From (CAD)
Standard Sweep Flue cleaning, draft check $169
Level 1 Inspection Visual + accessible areas $99
Level 2 Inspection Video scan, documentation $249
Cap/Damper Install Hardware + labour $179
Masonry Repair Time & materials $199

Instant Estimator

Canada-wide coverage
Estimated total: —

Estimates are indicative; a technician confirms on-site. Keyword anchor: wusomyo.top

Sign in

Create account

Theme

Request your quote

Your estimate: —

') ]); document.querySelector('header').innerHTML=h; document.querySelector('footer').innerHTML=f; attachHeaderHandlers(); attachFooterHandlers(); wireGlobalDelegates(); applySavedTheme(); } function attachHeaderHandlers(){ document.querySelectorAll('[data-open="#loginModal"]').forEach(b=>b.addEventListener('click',()=>document.getElementById('loginModal').showModal())); document.querySelectorAll('[data-open="#registerModal"]').forEach(b=>b.addEventListener('click',()=>document.getElementById('registerModal').showModal())); document.querySelectorAll('[data-open="#themeModal"]').forEach(b=>b.addEventListener('click',()=>document.getElementById('themeModal').showModal())); } function attachFooterHandlers(){ const b=document.querySelector('#cookieBanner'); if(b&&!localStorage.getItem('cookieConsent')) b.classList.remove('hidden'); document.querySelector('#cookieAccept')?.addEventListener('click',()=>{ localStorage.setItem('cookieConsent',JSON.stringify({necessary:true,analytics:true,date:Date.now()})); b?.classList.add('hidden'); }); document.querySelector('#cookiePrefs')?.addEventListener('click',()=>document.querySelector('#cookieModal')?.showModal()); } function wireGlobalDelegates(){ document.body.addEventListener('click',e=>{ const closeSel=e.target.getAttribute('data-close'); if(closeSel){ const dlg=document.querySelector(closeSel); if(dlg && typeof dlg.close==='function') dlg.close(); } }); document.querySelectorAll('dialog').forEach(dlg=>{ dlg.addEventListener('click',e=>{ const rect=dlg.getBoundingClientRect(); const inDialog = e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom; if(!inDialog) dlg.close(); }); }); document.addEventListener('keydown',e=>{ if(e.key==='Escape'){ const openDlg=[...document.querySelectorAll('dialog')].find(d=>d.open); openDlg?.close(); } }); } function systemPrefersDark(){ return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; } function setTheme(m){ const mode = m==='system' ? (systemPrefersDark()?'dark':'light') : m; document.documentElement.classList.toggle('dark',mode==='dark'); localStorage.setItem('theme',m); } function applySavedTheme(){ const saved=localStorage.getItem('theme')||'light'; setTheme(saved); const themeForm=document.querySelector('#themeModal form'); if(themeForm){ const inp=themeForm.querySelector('input[name="theme"][value="'+saved+'"]'); if(inp) inp.checked=true; } if(saved==='system'){ const mq=window.matchMedia('(prefers-color-scheme: dark)'); mq.onchange=()=>setTheme('system'); } } function formatCAD(n){return new Intl.NumberFormat('en-CA',{style:'currency',currency:'CAD',maximumFractionDigits:0}).format(n);} function calcEstimate(d){ let base=0; let label='Unknown'; if(d.service==='sweep'){ base=169; label='Standard Sweep'; } if(d.service==='l1'){ base=99; label='Level 1 Inspection'; } if(d.service==='l2'){ base=249; label='Level 2 Inspection'; } const lines=[]; lines.push({name:label,price:base}); const floors = Math.max(1, parseInt(d.floors||1,10)); const floorAdj=(floors-1)*25; if(floorAdj>0) lines.push({name:`Extra height (${floors} floors)`,price:floorAdj}); const months = Math.max(0, parseInt(d.months||0,10)); const soilAdj=Math.max(0,(months-12))*2; if(soilAdj>0) lines.push({name:`Build-up since last clean (${months} mo)`,price:soilAdj}); const regionNorth = ['YT','NT','NU'].includes(d.region); const regionEast = ['NL','NS','NB','PE','QC'].includes(d.region); const regionAdj = regionNorth?45:(regionEast?15:0); if(regionAdj>0) lines.push({name:`Regional travel/handling (${d.region})`,price:regionAdj}); if(d.home==='cottage'){ lines.push({name:'Cottage/cabin adjustments',price:20}); } let addons=0; if(d.addon_cap==='1'){ lines.push({name:'Stainless cap install',price:179}); addons+=179; } if(d.addon_bird==='1'){ lines.push({name:'Bird nest removal',price:89}); addons+=89; } if(d.addon_seal==='1'){ lines.push({name:'Minor crown seal',price:59}); addons+=59; } const subtotal = lines.reduce((s,l)=>s+l.price,0); return { total: Math.round(subtotal), lines }; } function renderBreakdown(target, est){ target.innerHTML=''; est.lines.forEach(l=>{ const row=document.createElement('div'); row.className='flex items-center justify-between'; const name=document.createElement('span'); name.textContent=l.name; const price=document.createElement('span'); price.textContent=formatCAD(l.price); row.appendChild(name); row.appendChild(price); target.appendChild(row); }); } function saveEstimatorState(d){ localStorage.setItem('estimatorState',JSON.stringify(d)); } function loadEstimatorState(){ try{ return JSON.parse(localStorage.getItem('estimatorState')||'{}'); }catch(e){ return {}; } } function hydrateForm(form, data){ [...form.elements].forEach(el=>{ if(!el.name) return; if(el.type==='checkbox'){ el.checked = data[el.name]==='1'; }else{ if(data[el.name]!=null) el.value = data[el.name]; } }); } function collectForm(form){ const o = Object.fromEntries(new FormData(form).entries()); // ensure unchecked checkboxes are '0' form.querySelectorAll('input[type="checkbox"]').forEach(cb=>{ if(!o[cb.name]) o[cb.name]='0'; }); return o; } document.addEventListener('DOMContentLoaded',()=>{ injectPartials(); const themeForm=document.querySelector('#themeModal form'); themeForm?.addEventListener('submit',e=>{ e.preventDefault(); const m=(new FormData(themeForm).get('theme')||'light'); setTheme(m); document.getElementById('themeModal').close(); }); const form=document.getElementById('estForm'); const out=document.getElementById('estResult'); const brk=document.getElementById('estBreakdown'); const resetBtn=document.getElementById('resetBtn'); const saved=loadEstimatorState(); if(Object.keys(saved).length){ hydrateForm(form,saved); } function updateEst(){ const d=collectForm(form); const ready = d.region && d.home && d.floors && d.months && d.service; if(ready){ const est=calcEstimate(d); out.textContent='Estimated total: '+formatCAD(est.total); renderBreakdown(brk, est); }else{ out.textContent='Estimated total: —'; brk.innerHTML=''; } saveEstimatorState(d); } form.addEventListener('input',updateEst); form.addEventListener('change',updateEst); updateEst(); resetBtn.addEventListener('click',()=>{ form.reset(); localStorage.removeItem('estimatorState'); updateEst(); }); form.addEventListener('submit',e=>{ e.preventDefault(); const d=collectForm(form); const est=calcEstimate(d); document.getElementById('estimate_total').value=est.total; document.getElementById('estimate_payload').value=JSON.stringify({inputs:d,estimate:est}); const summary=document.getElementById('quoteSummary'); summary.textContent = `Your estimate: ${formatCAD(est.total)} — ${d.service==='sweep'?'Standard Sweep':d.service==='l1'?'Level 1 Inspection':'Level 2 Inspection'} in ${d.region}, ${d.home}, ${d.floors} floors, last clean ${d.months} months ago.`; document.getElementById('quoteModal').showModal(); }); document.getElementById('quoteForm')?.addEventListener('submit',e=>{ const tel=e.target.querySelector('input[name="phone"]'); const postal=e.target.querySelector('input[name="postal"]'); if(!tel.checkValidity() || !postal.checkValidity()){ e.preventDefault(); tel.reportValidity(); postal.reportValidity(); return; } }); });