Free Roofing Calculator Widget — Add a Roof Cost Estimator to Any Website
Three Free Roofing Calculators Included
Free Roofing Calculator Widget — Add a Roof Cost Estimator to Any Website
Three Free Roofing Calculators Included
Why Use an AI TXT File Generator?
As AI-powered search engines evolve, optimizing your site for AI crawlers is just as important as traditional local SEO
Our AI TXT File Generator helps you manage robots.txt and LLMs.txt files, giving you full control over how AI models interact with your content.
✅ Allow or block AI bots based on your SEO strategy
✅ Optimize for AI search engines while protecting proprietary data
✅ Prevent unauthorized content scraping by AI training models
Take charge of AI-driven SEO and safeguard your website’s visibility today!
Generate optimized robots.txt and LLMs.txt files for better AI crawling control.
Shingle Replacement Calculator
Optimized configuration to allow beneficial AI crawlers while blocking unwanted training bots.
Copy & Paste HTML Code
<!-- Enhanced Roofing Calculator for WordPress -->
<div id="roofing-calculator">
<div class="calculator-container">
<!-- Header Section -->
<div class="calculator-header">
<h2>Professional Roofing Cost Calculator</h2>
<p class="subtitle">Get an accurate estimate for your roofing project in 60 seconds</p>
<div class="trust-badges">
<span class="badge">✓ Licensed & Insured</span>
<span class="badge">✓ Free Estimates</span>
<span class="badge">✓ 25+ Years Experience</span>
</div>
</div>
<!-- Main Calculator Form -->
<form id="roofingForm" class="calculator-form">
<div class="form-section">
<h3 class="section-title">Project Details</h3>
<div class="form-row">
<div class="form-group">
<label for="roofArea">
<span class="label-text">Roof Area (sq ft)</span>
<span class="label-hint">Typical home: 1,500-3,000 sq ft</span>
</label>
<input type="number" id="roofArea" placeholder="e.g., 2000" required min="100" step="50">
</div>
<div class="form-group">
<label for="materialType">
<span class="label-text">Shingle Type</span>
</label>
<select id="materialType" required>
<option value="">Select shingle type...</option>
<option value="245">Iko Dynasty Class 3 Shingle (Premium)</option>
<option value="180">Standard Architectural Shingle</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="roofPitch">
<span class="label-text">Roof Pitch</span>
</label>
<select id="roofPitch" required>
<option value="">Select pitch...</option>
<option value="250">Flat or Low Pitch (0-4/12)</option>
<option value="280">Medium Pitch (5-8/12)</option>
<option value="350">Steep Pitch (9/12+)</option>
</select>
</div>
<div class="form-group">
<label for="tearOffLayers">
<span class="label-text">Tear-Off Required</span>
</label>
<select id="tearOffLayers" required>
<option value="">Select option...</option>
<option value="0">No Tear-Off (New Construction)</option>
<option value="60">1 Layer Removal</option>
<option value="120">2 Layers Removal</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="location">
<span class="label-text">Location Type</span>
</label>
<select id="location" required>
<option value="">Select location...</option>
<option value="urban">Urban Area</option>
<option value="suburban">Suburban Area</option>
<option value="rural">Rural Area</option>
</select>
</div>
<div class="form-group">
<label for="complexity">
<span class="label-text">Roof Complexity</span>
</label>
<select id="complexity" required>
<option value="">Select complexity...</option>
<option value="simple">Simple (Few peaks/valleys)</option>
<option value="moderate">Moderate (Multiple angles)</option>
<option value="complex">Complex (Many features)</option>
</select>
</div>
</div>
</div>
<button type="submit" class="calculate-button">
<span class="button-text">Calculate My Estimate</span>
<span class="button-icon">→</span>
</button>
<p class="privacy-note">🔒 Your information is secure and will never be shared</p>
</form>
<!-- Lead Capture Modal -->
<div id="leadModal" class="modal">
<div class="modal-content lead-modal">
<span class="close-button" data-modal="lead">×</span>
<div class="modal-header">
<h3>Get Your Detailed Estimate</h3>
<p>Enter your details below to see your personalized roofing cost breakdown</p>
</div>
<form id="leadForm" class="lead-form">
<div class="form-group">
<label for="leadName">Full Name *</label>
<input type="text" id="leadName" placeholder="John Smith" required>
</div>
<div class="form-group">
<label for="leadEmail">Email Address *</label>
<input type="email" id="leadEmail" placeholder="john@example.com" required>
</div>
<div class="form-group">
<label for="leadPhone">Phone Number *</label>
<input type="tel" id="leadPhone" placeholder="(555) 123-4567" required>
</div>
<div class="form-group">
<label for="leadAddress">Property Address (Optional)</label>
<input type="text" id="leadAddress" placeholder="123 Main St, City, State">
</div>
<button type="submit" class="submit-button">View My Estimate</button>
<p class="form-note">By submitting, you agree to receive follow-up communications about your project</p>
</form>
</div>
</div>
<!-- Results Modal -->
<div id="resultModal" class="modal">
<div class="modal-content result-modal">
<span class="close-button" data-modal="result">×</span>
<div class="modal-header">
<h3>Your Roofing Estimate</h3>
<p class="estimate-disclaimer">This is an estimated cost. Final quote may vary based on inspection.</p>
</div>
<div class="result-highlight">
<div class="highlight-box primary">
<p class="highlight-label">Estimated Total Cost</p>
<p id="totalCost" class="highlight-value">$0.00</p>
<p class="highlight-subtext">Professional installation included</p>
</div>
<div class="highlight-box secondary">
<p class="highlight-label">Cost per Square Foot</p>
<p id="costPerSquare" class="highlight-value">$0.00</p>
<p class="highlight-subtext">Industry competitive pricing</p>
</div>
</div>
<div class="breakdown-section">
<h4 class="breakdown-title">Cost Breakdown</h4>
<div class="breakdown-items">
<div class="breakdown-item">
<span class="breakdown-label">Premium Materials</span>
<span id="materialCost" class="breakdown-value">$0.00</span>
</div>
<div class="breakdown-item">
<span class="breakdown-label">Professional Labor</span>
<span id="laborCost" class="breakdown-value">$0.00</span>
</div>
<div class="breakdown-item">
<span class="breakdown-label">Old Roof Removal</span>
<span id="tearOffCost" class="breakdown-value">$0.00</span>
</div>
<div class="breakdown-item">
<span class="breakdown-label">Debris Disposal</span>
<span id="disposalCost" class="breakdown-value">$0.00</span>
</div>
</div>
</div>
<div class="included-section">
<h4 class="included-title">What's Included</h4>
<ul class="included-list">
<li>✓ High-quality materials with warranty</li>
<li>✓ Professional installation by licensed contractors</li>
<li>✓ Complete tear-off and disposal</li>
<li>✓ Clean-up and site restoration</li>
<li>✓ Manufacturer warranty registration</li>
</ul>
</div>
<div class="cta-section">
<h4 class="cta-title">Ready to Get Started?</h4>
<p class="cta-subtitle">Schedule your free on-site inspection today</p>
<div class="cta-buttons">
<a href="tel:+1234567890" class="cta-button primary">
<span class="cta-icon">📞</span>
<span class="cta-text">Call Now</span>
</a>
<a href="mailto:info@example.com" class="cta-button secondary">
<span class="cta-icon">✉️</span>
<span class="cta-text">Email Us</span>
</a>
</div>
<p class="urgency-text">⏰ Limited slots available this month - Book now to secure your spot!</p>
</div>
</div>
</div>
</div>
</div>
<style>
/* Base Styles */
* {
box-sizing: border-box;
}
#roofing-calculator {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
}
.calculator-container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
background: #ffffff;
border-radius: 16px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}
/* Header Styles */
.calculator-header {
text-align: center;
margin-bottom: 40px;
padding-bottom: 30px;
border-bottom: 2px solid #f0f0f0;
}
.calculator-header h2 {
color: #1a1a1a;
font-size: 32px;
font-weight: 700;
margin: 0 0 12px 0;
letter-spacing: -0.5px;
}
.subtitle {
color: #666;
font-size: 18px;
margin: 0 0 20px 0;
font-weight: 400;
}
.trust-badges {
display: flex;
justify-content: center;
gap: 16px;
flex-wrap: wrap;
margin-top: 20px;
}
.badge {
background: #f0f7ff;
color: #1260cc;
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
font-weight: 600;
border: 1px solid #d0e7ff;
}
/* Form Styles */
.calculator-form {
background: #fafafa;
padding: 32px;
border-radius: 12px;
margin-bottom: 20px;
}
.form-section {
margin-bottom: 24px;
}
.section-title {
color: #1a1a1a;
font-size: 20px;
font-weight: 600;
margin: 0 0 20px 0;
padding-bottom: 12px;
border-bottom: 2px solid #e0e0e0;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
@media (max-width: 768px) {
.form-row {
grid-template-columns: 1fr;
}
.calculator-header h2 {
font-size: 24px;
}
.calculator-form {
padding: 20px;
}
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
display: flex;
flex-direction: column;
gap: 4px;
}
.label-text {
font-weight: 600;
color: #1a1a1a;
font-size: 15px;
}
.label-hint {
font-size: 13px;
color: #888;
font-weight: 400;
}
.form-group input,
.form-group select {
padding: 12px 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
background: white;
transition: all 0.2s;
font-family: inherit;
}
.form-group input:focus,
.form-group select:focus {
border-color: #1260cc;
outline: none;
box-shadow: 0 0 0 3px rgba(18, 96, 204, 0.1);
}
.form-group select {
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1L6 6L11 1' stroke='%23666' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 16px center;
padding-right: 40px;
}
/* Button Styles */
.calculate-button {
width: 100%;
background: linear-gradient(135deg, #1260cc 0%, #0d4ba3 100%);
color: white;
padding: 16px 32px;
border: none;
border-radius: 8px;
font-size: 18px;
font-weight: 700;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
margin-top: 8px;
box-shadow: 0 4px 12px rgba(18, 96, 204, 0.3);
}
.calculate-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(18, 96, 204, 0.4);
}
.calculate-button:active {
transform: translateY(0);
}
.button-icon {
font-size: 24px;
transition: transform 0.3s;
}
.calculate-button:hover .button-icon {
transform: translateX(4px);
}
.privacy-note {
text-align: center;
color: #888;
font-size: 13px;
margin-top: 16px;
margin-bottom: 0;
}
/* Modal Styles */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75);
justify-content: center;
align-items: center;
z-index: 10000;
padding: 20px;
backdrop-filter: blur(4px);
overflow-y: auto;
}
.modal-content {
background: white;
padding: 40px;
border-radius: 16px;
max-width: 600px;
width: 100%;
position: relative;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
margin: auto;
max-height: 90vh;
overflow-y: auto;
}
@media (max-width: 768px) {
.modal-content {
padding: 24px;
max-width: 100%;
}
}
.close-button {
position: absolute;
top: 16px;
right: 16px;
font-size: 32px;
cursor: pointer;
color: #666;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.2s;
line-height: 1;
}
.close-button:hover {
background: #f0f0f0;
color: #1260cc;
}
.modal-header {
text-align: center;
margin-bottom: 32px;
}
.modal-header h3 {
color: #1a1a1a;
font-size: 28px;
font-weight: 700;
margin: 0 0 12px 0;
}
.modal-header p {
color: #666;
font-size: 16px;
margin: 0;
}
/* Lead Form Styles */
.lead-form .form-group {
margin-bottom: 20px;
}
.lead-form label {
font-weight: 600;
color: #1a1a1a;
margin-bottom: 8px;
display: block;
}
.lead-form input {
width: 100%;
padding: 12px 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
transition: all 0.2s;
}
.lead-form input:focus {
border-color: #1260cc;
outline: none;
box-shadow: 0 0 0 3px rgba(18, 96, 204, 0.1);
}
.submit-button {
width: 100%;
background: linear-gradient(135deg, #1260cc 0%, #0d4ba3 100%);
color: white;
padding: 14px 32px;
border: none;
border-radius: 8px;
font-size: 18px;
font-weight: 700;
cursor: pointer;
transition: all 0.3s;
margin-top: 8px;
}
.submit-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(18, 96, 204, 0.4);
}
.form-note {
text-align: center;
font-size: 12px;
color: #888;
margin-top: 12px;
margin-bottom: 0;
}
/* Results Styles */
.estimate-disclaimer {
background: #fff3cd;
color: #856404;
padding: 12px 16px;
border-radius: 8px;
font-size: 14px;
margin-top: 16px;
border-left: 4px solid #ffc107;
}
.result-highlight {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin: 32px 0;
}
@media (max-width: 640px) {
.result-highlight {
grid-template-columns: 1fr;
}
}
.highlight-box {
padding: 24px;
border-radius: 12px;
text-align: center;
}
.highlight-box.primary {
background: linear-gradient(135deg, #1260cc 0%, #0d4ba3 100%);
color: white;
}
.highlight-box.secondary {
background: #f0f7ff;
border: 2px solid #1260cc;
color: #1260cc;
}
.highlight-label {
font-size: 14px;
font-weight: 600;
margin: 0 0 8px 0;
opacity: 0.9;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.highlight-value {
font-size: 36px;
font-weight: 800;
margin: 0 0 8px 0;
line-height: 1;
}
.highlight-subtext {
font-size: 13px;
margin: 0;
opacity: 0.85;
}
/* Breakdown Section */
.breakdown-section {
background: #fafafa;
padding: 24px;
border-radius: 12px;
margin: 32px 0;
}
.breakdown-title {
color: #1a1a1a;
font-size: 18px;
font-weight: 700;
margin: 0 0 20px 0;
}
.breakdown-items {
display: flex;
flex-direction: column;
gap: 16px;
}
.breakdown-item {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 16px;
border-bottom: 1px solid #e0e0e0;
}
.breakdown-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
.breakdown-label {
color: #666;
font-size: 15px;
font-weight: 500;
}
.breakdown-value {
color: #1260cc;
font-size: 18px;
font-weight: 700;
}
/* Included Section */
.included-section {
margin: 32px 0;
}
.included-title {
color: #1a1a1a;
font-size: 18px;
font-weight: 700;
margin: 0 0 16px 0;
}
.included-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.included-list li {
color: #333;
font-size: 15px;
padding-left: 8px;
}
/* CTA Section */
.cta-section {
background: linear-gradient(135deg, #f0f7ff 0%, #e6f2ff 100%);
padding: 32px;
border-radius: 12px;
text-align: center;
margin-top: 32px;
}
.cta-title {
color: #1a1a1a;
font-size: 22px;
font-weight: 700;
margin: 0 0 8px 0;
}
.cta-subtitle {
color: #666;
font-size: 16px;
margin: 0 0 24px 0;
}
.cta-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 20px;
}
@media (max-width: 480px) {
.cta-buttons {
grid-template-columns: 1fr;
}
}
.cta-button {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
padding: 14px 24px;
border-radius: 8px;
text-decoration: none;
font-weight: 700;
font-size: 16px;
transition: all 0.3s;
}
.cta-button.primary {
background: #1260cc;
color: white;
border: 2px solid #1260cc;
}
.cta-button.primary:hover {
background: #0d4ba3;
border-color: #0d4ba3;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(18, 96, 204, 0.3);
}
.cta-button.secondary {
background: white;
color: #1260cc;
border: 2px solid #1260cc;
}
.cta-button.secondary:hover {
background: #1260cc;
color: white;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(18, 96, 204, 0.2);
}
.cta-icon {
font-size: 20px;
}
.urgency-text {
color: #d97706;
font-size: 14px;
font-weight: 600;
margin: 0;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('roofingForm');
const leadModal = document.getElementById('leadModal');
const resultModal = document.getElementById('resultModal');
const leadForm = document.getElementById('leadForm');
const closeButtons = document.querySelectorAll('.close-button');
let calculatedResults = null;
// Form submission - shows lead capture modal
form.addEventListener('submit', function(e) {
e.preventDefault();
const roofArea = parseFloat(document.getElementById('roofArea').value);
const materialCost = parseFloat(document.getElementById('materialType').value);
const laborCost = parseFloat(document.getElementById('roofPitch').value);
const tearOffCost = parseFloat(document.getElementById('tearOffLayers').value);
const location = document.getElementById('location').value;
const complexity = document.getElementById('complexity').value;
// Validate inputs
if (isNaN(roofArea) || roofArea <= 0) {
alert("Please enter a valid roof area.");
return;
}
if (!materialCost || !laborCost || tearOffCost === '' || !location || !complexity) {
alert("Please fill in all fields.");
return;
}
// Calculate costs
const squares = roofArea / 100;
const complexityMultiplier = complexity === 'simple' ? 1 :
complexity === 'moderate' ? 1.2 : 1.4;
const locationMultiplier = location === 'urban' ? 1.1 :
location === 'suburban' ? 1 : 0.9;
const materialTotal = squares * materialCost * locationMultiplier;
const laborTotal = squares * laborCost * complexityMultiplier * locationMultiplier;
const tearOffTotal = squares * tearOffCost;
const disposalFee = squares * 25;
const totalCost = materialTotal + laborTotal + tearOffTotal + disposalFee;
const costPerSquare = totalCost / squares;
// Store results
calculatedResults = {
totalCost: totalCost,
costPerSquare: costPerSquare,
materialTotal: materialTotal,
laborTotal: laborTotal,
tearOffTotal: tearOffTotal,
disposalFee: disposalFee
};
// Show lead capture modal
leadModal.style.display = 'flex';
});
// Lead form submission - shows results
leadForm.addEventListener('submit', function(e) {
e.preventDefault();
const name = document.getElementById('leadName').value;
const email = document.getElementById('leadEmail').value;
const phone = document.getElementById('leadPhone').value;
const address = document.getElementById('leadAddress').value;
// Here you would normally send this data to your server/CRM
// For now, we'll just log it to console
console.log('Lead captured:', {
name: name,
email: email,
phone: phone,
address: address,
estimate: calculatedResults
});
// You can add AJAX call here to send data to your backend
// Example:
// fetch('your-endpoint-url', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ name, email, phone, address, ...calculatedResults })
// });
// Hide lead modal
leadModal.style.display = 'none';
// Show results
if (calculatedResults) {
document.getElementById('totalCost').textContent = `$${calculatedResults.totalCost.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('costPerSquare').textContent = `$${calculatedResults.costPerSquare.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('materialCost').textContent = `$${calculatedResults.materialTotal.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('laborCost').textContent = `$${calculatedResults.laborTotal.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('tearOffCost').textContent = `$${calculatedResults.tearOffTotal.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('disposalCost').textContent = `$${calculatedResults.disposalFee.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
resultModal.style.display = 'flex';
}
// Reset lead form
leadForm.reset();
});
// Close button handlers
closeButtons.forEach(button => {
button.addEventListener('click', function() {
const modalType = this.getAttribute('data-modal');
if (modalType === 'lead') {
leadModal.style.display = 'none';
} else if (modalType === 'result') {
resultModal.style.display = 'none';
}
});
});
// Click outside to close
window.addEventListener('click', function(e) {
if (e.target === leadModal) {
leadModal.style.display = 'none';
}
if (e.target === resultModal) {
resultModal.style.display = 'none';
}
});
// Prevent modal content clicks from closing modal
document.querySelectorAll('.modal-content').forEach(content => {
content.addEventListener('click', function(e) {
e.stopPropagation();
});
});
});
</script>
Roofing Type Selector Calculator
Copy & Paste HTML Code
<!-- Enhanced Roofing Calculator - Flexible Material Options -->
<div id="roofing-calculator">
<div class="calculator-container">
<!-- Header Section -->
<div class="calculator-header">
<h2>Professional Roofing Cost Calculator</h2>
<p class="subtitle">Get an accurate estimate for your roofing project in 60 seconds</p>
<div class="trust-badges">
<span class="badge">✓ Licensed & Insured</span>
<span class="badge">✓ Free Estimates</span>
<span class="badge">✓ 25+ Years Experience</span>
</div>
</div>
<!-- Main Calculator Form -->
<form id="roofingForm" class="calculator-form">
<div class="form-section">
<h3 class="section-title">Project Details</h3>
<div class="form-row">
<div class="form-group">
<label for="roofArea">
<span class="label-text">Roof Area (sq ft)</span>
<span class="label-hint">Typical home: 1,500-3,000 sq ft</span>
</label>
<input type="number" id="roofArea" placeholder="e.g., 2000" required min="100" step="50">
</div>
<div class="form-group">
<label for="materialType">
<span class="label-text">Roof Material</span>
</label>
<select id="materialType" required>
<option value="">Select material type...</option>
<!-- ASPHALT SHINGLES -->
<optgroup label="Asphalt Shingles">
<option value="180">3-Tab Asphalt Shingles ($180/sq)</option>
<option value="220">Architectural Shingles ($220/sq)</option>
<option value="280">Premium Architectural ($280/sq)</option>
<option value="350">Designer/Luxury Shingles ($350/sq)</option>
</optgroup>
<!-- METAL ROOFING -->
<optgroup label="Metal Roofing">
<option value="400">Standing Seam Metal ($400/sq)</option>
<option value="350">Metal Shingles ($350/sq)</option>
<option value="300">Corrugated Metal ($300/sq)</option>
<option value="500">Copper/Premium Metal ($500/sq)</option>
</optgroup>
<!-- TILE ROOFING -->
<optgroup label="Tile Roofing">
<option value="450">Concrete Tile ($450/sq)</option>
<option value="600">Clay Tile ($600/sq)</option>
<option value="550">Slate Tile ($550/sq)</option>
</optgroup>
<!-- SPECIALTY OPTIONS -->
<optgroup label="Other Materials">
<option value="320">Wood Shakes/Shingles ($320/sq)</option>
<option value="280">Synthetic Slate ($280/sq)</option>
<option value="250">TPO/Single-Ply ($250/sq)</option>
<option value="300">EPDM Rubber ($300/sq)</option>
</optgroup>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="roofPitch">
<span class="label-text">Roof Pitch</span>
</label>
<select id="roofPitch" required>
<option value="">Select pitch...</option>
<option value="200">Flat or Low Pitch (0-4/12) - $200/sq labor</option>
<option value="250">Medium Pitch (5-8/12) - $250/sq labor</option>
<option value="350">Steep Pitch (9-12/12) - $350/sq labor</option>
<option value="450">Very Steep (12+/12) - $450/sq labor</option>
</select>
</div>
<div class="form-group">
<label for="tearOffLayers">
<span class="label-text">Tear-Off Required</span>
</label>
<select id="tearOffLayers" required>
<option value="">Select option...</option>
<option value="0">No Tear-Off (New Construction)</option>
<option value="50">1 Layer Removal ($50/sq)</option>
<option value="100">2 Layers Removal ($100/sq)</option>
<option value="150">3+ Layers Removal ($150/sq)</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="location">
<span class="label-text">Location Type</span>
</label>
<select id="location" required>
<option value="">Select location...</option>
<option value="urban">Urban Area (+15% cost)</option>
<option value="suburban">Suburban Area (base cost)</option>
<option value="rural">Rural Area (-10% cost)</option>
</select>
</div>
<div class="form-group">
<label for="complexity">
<span class="label-text">Roof Complexity</span>
</label>
<select id="complexity" required>
<option value="">Select complexity...</option>
<option value="simple">Simple - Few peaks (base labor)</option>
<option value="moderate">Moderate - Multiple angles (+15% labor)</option>
<option value="complex">Complex - Many features (+30% labor)</option>
<option value="verycomplex">Very Complex - Turrets/dormers (+50% labor)</option>
</select>
</div>
</div>
<!-- Optional: Additional Features -->
<div class="form-section optional-features">
<h4 class="subsection-title">Additional Options (Optional)</h4>
<div class="form-row">
<div class="form-group">
<label for="underlayment">
<span class="label-text">Underlayment Type</span>
</label>
<select id="underlayment">
<option value="0">Standard Felt (included)</option>
<option value="50">Synthetic Underlayment (+$50/sq)</option>
<option value="100">Ice & Water Shield (+$100/sq)</option>
</select>
</div>
<div class="form-group">
<label for="warranty">
<span class="label-text">Warranty Package</span>
</label>
<select id="warranty">
<option value="0">Standard Warranty (included)</option>
<option value="150">Extended Warranty (+$150/sq)</option>
<option value="250">Lifetime Warranty (+$250/sq)</option>
</select>
</div>
</div>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" id="gutters" value="800">
<span>Include Gutter Replacement (+$800-$1,500)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" id="skylights" value="500">
<span>Skylight Installation/Replacement (+$500-$1,000 each)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" id="ventilation" value="300">
<span>Enhanced Ventilation System (+$300-$600)</span>
</label>
</div>
</div>
</div>
<button type="submit" class="calculate-button">
<span class="button-text">Calculate My Estimate</span>
<span class="button-icon">→</span>
</button>
<p class="privacy-note">🔒 Your information is secure and will never be shared</p>
</form>
<!-- Lead Capture Modal -->
<div id="leadModal" class="modal">
<div class="modal-content lead-modal">
<span class="close-button" data-modal="lead">×</span>
<div class="modal-header">
<h3>Get Your Detailed Estimate</h3>
<p>Enter your details below to see your personalized roofing cost breakdown</p>
</div>
<form id="leadForm" class="lead-form">
<div class="form-group">
<label for="leadName">Full Name *</label>
<input type="text" id="leadName" name="name" placeholder="John Smith" required>
</div>
<div class="form-group">
<label for="leadEmail">Email Address *</label>
<input type="email" id="leadEmail" name="email" placeholder="john@example.com" required>
</div>
<div class="form-group">
<label for="leadPhone">Phone Number *</label>
<input type="tel" id="leadPhone" name="phone" placeholder="(555) 123-4567" required>
</div>
<div class="form-group">
<label for="leadAddress">Property Address (Optional)</label>
<input type="text" id="leadAddress" name="address" placeholder="123 Main St, City, State">
</div>
<button type="submit" class="submit-button">
<span id="submitButtonText">View My Estimate</span>
<span id="submitButtonLoader" style="display: none;">Sending...</span>
</button>
<p class="form-note">By submitting, you agree to receive follow-up communications about your project</p>
</form>
</div>
</div>
<!-- Results Modal -->
<div id="resultModal" class="modal">
<div class="modal-content result-modal">
<span class="close-button" data-modal="result">×</span>
<div class="modal-header">
<h3>Your Roofing Estimate</h3>
<p class="estimate-disclaimer">This is an estimated cost. Final quote may vary based on inspection.</p>
</div>
<div class="result-highlight">
<div class="highlight-box primary">
<p class="highlight-label">Estimated Total Cost</p>
<p id="totalCost" class="highlight-value">$0.00</p>
<p class="highlight-subtext">Professional installation included</p>
</div>
<div class="highlight-box secondary">
<p class="highlight-label">Cost per Square</p>
<p id="costPerSquare" class="highlight-value">$0.00</p>
<p class="highlight-subtext">Industry competitive pricing</p>
</div>
</div>
<div class="breakdown-section">
<h4 class="breakdown-title">Cost Breakdown</h4>
<div class="breakdown-items">
<div class="breakdown-item">
<span class="breakdown-label">Roofing Materials</span>
<span id="materialCost" class="breakdown-value">$0.00</span>
</div>
<div class="breakdown-item">
<span class="breakdown-label">Professional Labor</span>
<span id="laborCost" class="breakdown-value">$0.00</span>
</div>
<div class="breakdown-item">
<span class="breakdown-label">Old Roof Removal</span>
<span id="tearOffCost" class="breakdown-value">$0.00</span>
</div>
<div class="breakdown-item">
<span class="breakdown-label">Debris Disposal</span>
<span id="disposalCost" class="breakdown-value">$0.00</span>
</div>
<div class="breakdown-item" id="additionalCostsItem" style="display: none;">
<span class="breakdown-label">Additional Features</span>
<span id="additionalCosts" class="breakdown-value">$0.00</span>
</div>
</div>
</div>
<div class="project-summary">
<h4 class="summary-title">Project Summary</h4>
<div class="summary-grid">
<div class="summary-item">
<span class="summary-label">Material:</span>
<span id="summaryMaterial" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label">Roof Area:</span>
<span id="summaryArea" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label">Pitch:</span>
<span id="summaryPitch" class="summary-value">-</span>
</div>
<div class="summary-item">
<span class="summary-label">Complexity:</span>
<span id="summaryComplexity" class="summary-value">-</span>
</div>
</div>
</div>
<div class="included-section">
<h4 class="included-title">What's Included</h4>
<ul class="included-list">
<li>✓ High-quality materials with manufacturer warranty</li>
<li>✓ Professional installation by licensed contractors</li>
<li>✓ Complete tear-off and disposal (if selected)</li>
<li>✓ Clean-up and site restoration</li>
<li>✓ Building permits and inspections</li>
<li>✓ Workmanship warranty</li>
</ul>
</div>
<div class="cta-section">
<h4 class="cta-title">Ready to Get Started?</h4>
<p class="cta-subtitle">Schedule your free on-site inspection today</p>
<div class="cta-buttons">
<a href="tel:+1234567890" class="cta-button primary">
<span class="cta-icon">📞</span>
<span class="cta-text">Call Now</span>
</a>
<a href="mailto:info@example.com" class="cta-button secondary">
<span class="cta-icon">✉️</span>
<span class="cta-text">Email Us</span>
</a>
</div>
<p class="urgency-text">⏰ Limited slots available this month - Book now to secure your spot!</p>
</div>
</div>
</div>
</div>
</div>
<style>
/* Base Styles */
* {
box-sizing: border-box;
}
#roofing-calculator {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
}
.calculator-container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
background: #ffffff;
border-radius: 16px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}
/* Header Styles */
.calculator-header {
text-align: center;
margin-bottom: 40px;
padding-bottom: 30px;
border-bottom: 2px solid #f0f0f0;
}
.calculator-header h2 {
color: #1a1a1a;
font-size: 32px;
font-weight: 700;
margin: 0 0 12px 0;
letter-spacing: -0.5px;
}
.subtitle {
color: #666;
font-size: 18px;
margin: 0 0 20px 0;
font-weight: 400;
}
.trust-badges {
display: flex;
justify-content: center;
gap: 16px;
flex-wrap: wrap;
margin-top: 20px;
}
.badge {
background: #f0f7ff;
color: #1260cc;
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
font-weight: 600;
border: 1px solid #d0e7ff;
}
/* Form Styles */
.calculator-form {
background: #fafafa;
padding: 32px;
border-radius: 12px;
margin-bottom: 20px;
}
.form-section {
margin-bottom: 24px;
}
.section-title {
color: #1a1a1a;
font-size: 20px;
font-weight: 600;
margin: 0 0 20px 0;
padding-bottom: 12px;
border-bottom: 2px solid #e0e0e0;
}
.subsection-title {
color: #1a1a1a;
font-size: 17px;
font-weight: 600;
margin: 24px 0 16px 0;
}
.optional-features {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
margin-top: 24px;
border: 1px dashed #d0d0d0;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
@media (max-width: 768px) {
.form-row {
grid-template-columns: 1fr;
}
.calculator-header h2 {
font-size: 24px;
}
.calculator-form {
padding: 20px;
}
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
display: flex;
flex-direction: column;
gap: 4px;
}
.label-text {
font-weight: 600;
color: #1a1a1a;
font-size: 15px;
}
.label-hint {
font-size: 13px;
color: #888;
font-weight: 400;
}
.form-group input,
.form-group select {
padding: 12px 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
background: white;
transition: all 0.2s;
font-family: inherit;
}
.form-group input:focus,
.form-group select:focus {
border-color: #1260cc;
outline: none;
box-shadow: 0 0 0 3px rgba(18, 96, 204, 0.1);
}
.form-group select {
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' viewBox='0 0 12 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1L6 6L11 1' stroke='%23666' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 16px center;
padding-right: 40px;
}
.form-group optgroup {
font-weight: 700;
font-size: 15px;
color: #1260cc;
}
.form-group option {
font-weight: 400;
color: #333;
padding: 8px;
}
/* Checkbox Group */
.checkbox-group {
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 16px;
}
.checkbox-label {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
padding: 10px;
border-radius: 6px;
transition: background 0.2s;
}
.checkbox-label:hover {
background: #ebebeb;
}
.checkbox-label input[type="checkbox"] {
width: 20px;
height: 20px;
cursor: pointer;
accent-color: #1260cc;
}
.checkbox-label span {
color: #333;
font-size: 15px;
}
/* Button Styles */
.calculate-button {
width: 100%;
background: linear-gradient(135deg, #1260cc 0%, #0d4ba3 100%);
color: white;
padding: 16px 32px;
border: none;
border-radius: 8px;
font-size: 18px;
font-weight: 700;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
margin-top: 8px;
box-shadow: 0 4px 12px rgba(18, 96, 204, 0.3);
}
.calculate-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(18, 96, 204, 0.4);
}
.calculate-button:active {
transform: translateY(0);
}
.button-icon {
font-size: 24px;
transition: transform 0.3s;
}
.calculate-button:hover .button-icon {
transform: translateX(4px);
}
.privacy-note {
text-align: center;
color: #888;
font-size: 13px;
margin-top: 16px;
margin-bottom: 0;
}
/* Modal Styles */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75);
justify-content: center;
align-items: center;
z-index: 10000;
padding: 20px;
backdrop-filter: blur(4px);
overflow-y: auto;
}
.modal-content {
background: white;
padding: 40px;
border-radius: 16px;
max-width: 600px;
width: 100%;
position: relative;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
margin: auto;
max-height: 90vh;
overflow-y: auto;
}
@media (max-width: 768px) {
.modal-content {
padding: 24px;
max-width: 100%;
}
}
.close-button {
position: absolute;
top: 16px;
right: 16px;
font-size: 32px;
cursor: pointer;
color: #666;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.2s;
line-height: 1;
}
.close-button:hover {
background: #f0f0f0;
color: #1260cc;
}
.modal-header {
text-align: center;
margin-bottom: 32px;
}
.modal-header h3 {
color: #1a1a1a;
font-size: 28px;
font-weight: 700;
margin: 0 0 12px 0;
}
.modal-header p {
color: #666;
font-size: 16px;
margin: 0;
}
/* Lead Form Styles */
.lead-form .form-group {
margin-bottom: 20px;
}
.lead-form label {
font-weight: 600;
color: #1a1a1a;
margin-bottom: 8px;
display: block;
}
.lead-form input {
width: 100%;
padding: 12px 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
transition: all 0.2s;
}
.lead-form input:focus {
border-color: #1260cc;
outline: none;
box-shadow: 0 0 0 3px rgba(18, 96, 204, 0.1);
}
.submit-button {
width: 100%;
background: linear-gradient(135deg, #1260cc 0%, #0d4ba3 100%);
color: white;
padding: 14px 32px;
border: none;
border-radius: 8px;
font-size: 18px;
font-weight: 700;
cursor: pointer;
transition: all 0.3s;
margin-top: 8px;
}
.submit-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(18, 96, 204, 0.4);
}
.submit-button:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.form-note {
text-align: center;
font-size: 12px;
color: #888;
margin-top: 12px;
margin-bottom: 0;
}
/* Results Styles */
.estimate-disclaimer {
background: #fff3cd;
color: #856404;
padding: 12px 16px;
border-radius: 8px;
font-size: 14px;
margin-top: 16px;
border-left: 4px solid #ffc107;
}
.result-highlight {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin: 32px 0;
}
@media (max-width: 640px) {
.result-highlight {
grid-template-columns: 1fr;
}
}
.highlight-box {
padding: 24px;
border-radius: 12px;
text-align: center;
}
.highlight-box.primary {
background: linear-gradient(135deg, #1260cc 0%, #0d4ba3 100%);
color: white;
}
.highlight-box.secondary {
background: #f0f7ff;
border: 2px solid #1260cc;
color: #1260cc;
}
.highlight-label {
font-size: 14px;
font-weight: 600;
margin: 0 0 8px 0;
opacity: 0.9;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.highlight-value {
font-size: 36px;
font-weight: 800;
margin: 0 0 8px 0;
line-height: 1;
}
.highlight-subtext {
font-size: 13px;
margin: 0;
opacity: 0.85;
}
/* Breakdown Section */
.breakdown-section {
background: #fafafa;
padding: 24px;
border-radius: 12px;
margin: 32px 0;
}
.breakdown-title {
color: #1a1a1a;
font-size: 18px;
font-weight: 700;
margin: 0 0 20px 0;
}
.breakdown-items {
display: flex;
flex-direction: column;
gap: 16px;
}
.breakdown-item {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 16px;
border-bottom: 1px solid #e0e0e0;
}
.breakdown-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
.breakdown-label {
color: #666;
font-size: 15px;
font-weight: 500;
}
.breakdown-value {
color: #1260cc;
font-size: 18px;
font-weight: 700;
}
/* Project Summary */
.project-summary {
background: #f0f7ff;
padding: 24px;
border-radius: 12px;
margin: 32px 0;
border: 2px solid #d0e7ff;
}
.summary-title {
color: #1a1a1a;
font-size: 18px;
font-weight: 700;
margin: 0 0 16px 0;
}
.summary-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
@media (max-width: 640px) {
.summary-grid {
grid-template-columns: 1fr;
}
}
.summary-item {
display: flex;
justify-content: space-between;
padding: 8px 0;
}
.summary-label {
color: #666;
font-size: 14px;
font-weight: 600;
}
.summary-value {
color: #1260cc;
font-size: 14px;
font-weight: 600;
}
/* Included Section */
.included-section {
margin: 32px 0;
}
.included-title {
color: #1a1a1a;
font-size: 18px;
font-weight: 700;
margin: 0 0 16px 0;
}
.included-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.included-list li {
color: #333;
font-size: 15px;
padding-left: 8px;
}
/* CTA Section */
.cta-section {
background: linear-gradient(135deg, #f0f7ff 0%, #e6f2ff 100%);
padding: 32px;
border-radius: 12px;
text-align: center;
margin-top: 32px;
}
.cta-title {
color: #1a1a1a;
font-size: 22px;
font-weight: 700;
margin: 0 0 8px 0;
}
.cta-subtitle {
color: #666;
font-size: 16px;
margin: 0 0 24px 0;
}
.cta-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 20px;
}
@media (max-width: 480px) {
.cta-buttons {
grid-template-columns: 1fr;
}
}
.cta-button {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
padding: 14px 24px;
border-radius: 8px;
text-decoration: none;
font-weight: 700;
font-size: 16px;
transition: all 0.3s;
}
.cta-button.primary {
background: #1260cc;
color: white;
border: 2px solid #1260cc;
}
.cta-button.primary:hover {
background: #0d4ba3;
border-color: #0d4ba3;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(18, 96, 204, 0.3);
}
.cta-button.secondary {
background: white;
color: #1260cc;
border: 2px solid #1260cc;
}
.cta-button.secondary:hover {
background: #1260cc;
color: white;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(18, 96, 204, 0.2);
}
.cta-icon {
font-size: 20px;
}
.urgency-text {
color: #d97706;
font-size: 14px;
font-weight: 600;
margin: 0;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('roofingForm');
const leadModal = document.getElementById('leadModal');
const resultModal = document.getElementById('resultModal');
const leadForm = document.getElementById('leadForm');
const closeButtons = document.querySelectorAll('.close-button');
let calculatedResults = null;
// ============================================
// CONFIGURATION - UPDATE THESE VALUES
// ============================================
// Formspree endpoint - replace with your actual form ID
const FORMSPREE_ENDPOINT = 'https://formspree.io/f/YOUR_FORM_ID';
// ============================================
// Form submission - shows lead capture modal
form.addEventListener('submit', function(e) {
e.preventDefault();
const roofArea = parseFloat(document.getElementById('roofArea').value);
const materialCost = parseFloat(document.getElementById('materialType').value);
const laborCost = parseFloat(document.getElementById('roofPitch').value);
const tearOffCost = parseFloat(document.getElementById('tearOffLayers').value);
const location = document.getElementById('location').value;
const complexity = document.getElementById('complexity').value;
// Optional features
const underlayment = parseFloat(document.getElementById('underlayment').value) || 0;
const warranty = parseFloat(document.getElementById('warranty').value) || 0;
// Checkboxes
const gutters = document.getElementById('gutters').checked ? parseFloat(document.getElementById('gutters').value) : 0;
const skylights = document.getElementById('skylights').checked ? parseFloat(document.getElementById('skylights').value) : 0;
const ventilation = document.getElementById('ventilation').checked ? parseFloat(document.getElementById('ventilation').value) : 0;
// Validate inputs
if (isNaN(roofArea) || roofArea <= 0) {
alert("Please enter a valid roof area.");
return;
}
if (!materialCost || !laborCost || tearOffCost === '' || !location || !complexity) {
alert("Please fill in all required fields.");
return;
}
// Calculate costs
const squares = roofArea / 100;
// Complexity multipliers
const complexityMultiplier =
complexity === 'simple' ? 1 :
complexity === 'moderate' ? 1.15 :
complexity === 'complex' ? 1.30 : 1.50;
// Location multipliers
const locationMultiplier =
location === 'urban' ? 1.15 :
location === 'suburban' ? 1 : 0.90;
// Base costs
const materialTotal = (squares * materialCost * locationMultiplier) + (squares * underlayment) + (squares * warranty);
const laborTotal = squares * laborCost * complexityMultiplier * locationMultiplier;
const tearOffTotal = squares * tearOffCost;
const disposalFee = squares * 25;
// Additional features
const additionalFeatures = gutters + skylights + ventilation;
// Total
const totalCost = materialTotal + laborTotal + tearOffTotal + disposalFee + additionalFeatures;
const costPerSquare = totalCost / squares;
// Get selected text values for summary
const materialText = document.getElementById('materialType').selectedOptions[0].text;
const pitchText = document.getElementById('roofPitch').selectedOptions[0].text;
const complexityText = document.getElementById('complexity').selectedOptions[0].text;
// Store results
calculatedResults = {
roofArea: roofArea,
squares: squares,
materialType: materialText,
roofPitch: pitchText,
tearOffLayers: document.getElementById('tearOffLayers').selectedOptions[0].text,
location: location,
complexity: complexityText,
totalCost: totalCost,
costPerSquare: costPerSquare,
materialTotal: materialTotal,
laborTotal: laborTotal,
tearOffTotal: tearOffTotal,
disposalFee: disposalFee,
additionalFeatures: additionalFeatures,
underlayment: document.getElementById('underlayment').selectedOptions[0].text,
warranty: document.getElementById('warranty').selectedOptions[0].text,
hasGutters: gutters > 0,
hasSkylights: skylights > 0,
hasVentilation: ventilation > 0
};
// Show lead capture modal
leadModal.style.display = 'flex';
});
// Lead form submission - sends email and shows results
leadForm.addEventListener('submit', async function(e) {
e.preventDefault();
const submitButton = leadForm.querySelector('.submit-button');
const buttonText = document.getElementById('submitButtonText');
const buttonLoader = document.getElementById('submitButtonLoader');
// Disable button and show loading
submitButton.disabled = true;
buttonText.style.display = 'none';
buttonLoader.style.display = 'inline';
const formData = {
name: document.getElementById('leadName').value,
email: document.getElementById('leadEmail').value,
phone: document.getElementById('leadPhone').value,
address: document.getElementById('leadAddress').value,
roofArea: `${calculatedResults.roofArea} sq ft`,
materialType: calculatedResults.materialType,
roofPitch: calculatedResults.roofPitch,
tearOffLayers: calculatedResults.tearOffLayers,
location: calculatedResults.location,
complexity: calculatedResults.complexity,
underlayment: calculatedResults.underlayment,
warranty: calculatedResults.warranty,
gutters: calculatedResults.hasGutters ? 'Yes' : 'No',
skylights: calculatedResults.hasSkylights ? 'Yes' : 'No',
ventilation: calculatedResults.hasVentilation ? 'Yes' : 'No',
estimatedCost: `$${calculatedResults.totalCost.toFixed(2)}`,
costPerSquare: `$${calculatedResults.costPerSquare.toFixed(2)}`,
materialCost: `$${calculatedResults.materialTotal.toFixed(2)}`,
laborCost: `$${calculatedResults.laborTotal.toFixed(2)}`,
tearOffCost: `$${calculatedResults.tearOffTotal.toFixed(2)}`,
disposalCost: `$${calculatedResults.disposalFee.toFixed(2)}`,
additionalFeatures: `$${calculatedResults.additionalFeatures.toFixed(2)}`,
timestamp: new Date().toISOString()
};
try {
// Send to Formspree (or your chosen service)
const response = await fetch(FORMSPREE_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
if (response.ok) {
console.log('Lead captured successfully:', formData);
// Hide lead modal
leadModal.style.display = 'none';
// Show results
displayResults();
// Reset lead form
leadForm.reset();
} else {
throw new Error('Failed to submit form');
}
} catch (error) {
console.error('Error submitting form:', error);
alert('There was an error submitting your information. Please try calling us directly.');
} finally {
// Re-enable button
submitButton.disabled = false;
buttonText.style.display = 'inline';
buttonLoader.style.display = 'none';
}
});
function displayResults() {
if (calculatedResults) {
// Update cost displays
document.getElementById('totalCost').textContent = `$${calculatedResults.totalCost.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('costPerSquare').textContent = `$${calculatedResults.costPerSquare.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('materialCost').textContent = `$${calculatedResults.materialTotal.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('laborCost').textContent = `$${calculatedResults.laborTotal.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('tearOffCost').textContent = `$${calculatedResults.tearOffTotal.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
document.getElementById('disposalCost').textContent = `$${calculatedResults.disposalFee.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
// Show additional costs if any
if (calculatedResults.additionalFeatures > 0) {
document.getElementById('additionalCostsItem').style.display = 'flex';
document.getElementById('additionalCosts').textContent = `$${calculatedResults.additionalFeatures.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}`;
}
// Update project summary
document.getElementById('summaryMaterial').textContent = calculatedResults.materialType;
document.getElementById('summaryArea').textContent = `${calculatedResults.roofArea} sq ft (${calculatedResults.squares.toFixed(1)} squares)`;
document.getElementById('summaryPitch').textContent = calculatedResults.roofPitch;
document.getElementById('summaryComplexity').textContent = calculatedResults.complexity;
resultModal.style.display = 'flex';
}
}
// Close button handlers
closeButtons.forEach(button => {
button.addEventListener('click', function() {
const modalType = this.getAttribute('data-modal');
if (modalType === 'lead') {
leadModal.style.display = 'none';
} else if (modalType === 'result') {
resultModal.style.display = 'none';
}
});
});
// Click outside to close
window.addEventListener('click', function(e) {
if (e.target === leadModal) {
leadModal.style.display = 'none';
}
if (e.target === resultModal) {
resultModal.style.display = 'none';
}
});
// Prevent modal content clicks from closing modal
document.querySelectorAll('.modal-content').forEach(content => {
content.addEventListener('click', function(e) {
e.stopPropagation();
});
});
});
</script>
Complete AI Search Optimization Guide
Content Structure
- Use clear hierarchical headings (H1-H6)
- Include structured data (Schema.org)
- Write descriptive meta descriptions
- Optimize image alt texts for AI understanding
AI-Friendly Content
Technical Optimization
AI Crawler Management
Control which AI and search engine crawlers can access your site.
- Block AI data scrapers while allowing search engines like Googlebot.
- Prevent AI-generated content theft and unauthorized indexing.
- Optimize for AI-driven search while maintaining SEO best practices.
Define how AI models interact with your website’s content.
- Set clear boundaries for LLMs (Large Language Models) like OpenAI and Google Gemini.
- Specify content usage rules to prevent unauthorized AI training.
- Ensure compliance with emerging AI search indexing standards.
- Select which AI bots to allow or block
- Configure custom crawl rules for search engines & AI models
- Click “Generate TXT File” and download your ready-to-use file
- Upload it to your website’s root directory (example.com/robots.txt)
No coding required. No manual editing. Just simple AI search optimization.
AI search engines and content crawlers are here to stay. Don’t leave your content unprotected.
Take control of AI crawling today with our free AI TXT File Generator.
Helping Local Companies Grow
Proven Results
Chaz's Local SEO Framework creates market domination in every major metro area.
And helps companies get found locally, everywhere in their city, when potential customers are searching for their services.




