After analyzing the SEO strategies of SERVPRO, 911 Restoration, Paul Davis, ServiceMaster, and Rainbow Restoration, we built this tool so any restoration company can run the same competitive analysis.
Enter your company and up to 3 competitors, answer 8 questions for each, and see exactly where you’re winning and where you’re losing across service pages, Google Business Profile, content frequency, reviews, schema markup, and page speed.
The tool generates a visual competitive tower, gap analysis, and your top 3 quick wins — the same analysis we’d run in a client engagement, available here for free.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, Roboto, ‘Helvetica Neue’, Arial, sans-serif;
background: linear-gradient(135deg, #0f172a 0%, #1a2551 100%);
color: #e5e7eb;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 40px;
animation: slideDown 0.6s ease-out;
}
h1 {
font-size: 2.5rem;
background: linear-gradient(135deg, #3b82f6, #10b981);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 10px;
font-weight: 700;
}
.subtitle {
font-size: 1.1rem;
color: #9ca3af;
}
.input-section {
background: rgba(15, 23, 42, 0.8);
border: 1px solid rgba(59, 130, 246, 0.2);
border-radius: 12px;
padding: 40px;
margin-bottom: 30px;
backdrop-filter: blur(10px);
animation: fadeIn 0.8s ease-out;
}
.form-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-bottom: 25px;
}
.form-group {
display: flex;
flex-direction: column;
}
label {
margin-bottom: 8px;
font-weight: 600;
color: #e5e7eb;
font-size: 0.95rem;
}
input[type=”text”],
input[type=”url”],
select {
padding: 12px;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(59, 130, 246, 0.2);
border-radius: 8px;
color: #e5e7eb;
font-family: inherit;
transition: all 0.3s ease;
}
input[type=”text”]:focus,
input[type=”url”]:focus,
select:focus {
outline: none;
border-color: rgba(59, 130, 246, 0.5);
background: rgba(59, 130, 246, 0.05);
}
.services-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
margin-bottom: 20px;
}
.checkbox-label {
display: flex;
align-items: center;
padding: 10px 12px;
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(59, 130, 246, 0.1);
border-radius: 6px;
cursor: pointer;
transition: all 0.3s ease;
}
.checkbox-label:hover {
background: rgba(59, 130, 246, 0.08);
border-color: rgba(59, 130, 246, 0.3);
}
.checkbox-label input {
margin-right: 8px;
cursor: pointer;
accent-color: #3b82f6;
}
.button-group {
display: flex;
gap: 15px;
margin-top: 30px;
flex-wrap: wrap;
}
button {
padding: 12px 30px;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
font-size: 1rem;
}
.btn-primary {
background: linear-gradient(135deg, #3b82f6, #2563eb);
color: white;
flex: 1;
min-width: 200px;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3);
}
.results-section {
display: none;
animation: fadeIn 0.8s ease-out;
}
.results-section.visible {
display: block;
}
.content-section {
background: rgba(15, 23, 42, 0.8);
border: 1px solid rgba(59, 130, 246, 0.2);
border-radius: 12px;
padding: 40px;
margin-bottom: 30px;
backdrop-filter: blur(10px);
}
.tower-visualization {
display: flex;
align-items: flex-end;
justify-content: center;
gap: 20px;
height: 400px;
margin: 40px 0;
padding: 20px;
}
.tower {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.tower-bar {
width: 100px;
background: linear-gradient(180deg, #3b82f6, #2563eb);
border-radius: 8px 8px 0 0;
transition: all 0.3s ease;
position: relative;
min-height: 20px;
}
.tower-bar:hover {
transform: scaleY(1.05);
box-shadow: 0 0 20px rgba(59, 130, 246, 0.4);
}
.tower-bar.competitor-1 {
background: linear-gradient(180deg, #8b5cf6, #6d28d9);
}
.tower-bar.competitor-2 {
background: linear-gradient(180deg, #ec4899, #be123c);
}
.tower-bar.competitor-3 {
background: linear-gradient(180deg, #f59e0b, #d97706);
}
.tower-score {
font-size: 1.2rem;
font-weight: 700;
color: #e5e7eb;
}
.tower-label {
font-size: 0.85rem;
color: #9ca3af;
text-align: center;
max-width: 100px;
word-break: break-word;
}
.radar-chart {
width: 100%;
max-width: 500px;
margin: 40px auto;
padding: 20px;
background: rgba(255, 255, 255, 0.02);
border-radius: 8px;
}
.radar-canvas {
width: 100%;
max-height: 400px;
}
.gap-analysis {
background: rgba(249, 115, 22, 0.05);
border: 1px solid rgba(249, 115, 22, 0.2);
border-radius: 8px;
padding: 20px;
margin: 30px 0;
}
.gap-analysis h3 {
color: #f97316;
margin-bottom: 15px;
}
.gap-item {
background: rgba(255, 255, 255, 0.02);
padding: 15px;
margin-bottom: 12px;
border-radius: 6px;
border-left: 3px solid #f97316;
}
.gap-item h4 {
color: #fcd34d;
margin-bottom: 8px;
font-size: 0.95rem;
}
.gap-item p {
color: #d1d5db;
font-size: 0.9rem;
line-height: 1.5;
}
.quick-wins {
background: rgba(16, 185, 129, 0.05);
border: 1px solid rgba(16, 185, 129, 0.2);
border-radius: 8px;
padding: 20px;
margin: 30px 0;
}
.quick-wins h3 {
color: #10b981;
margin-bottom: 15px;
}
.wins-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.win-item {
background: rgba(16, 185, 129, 0.1);
padding: 15px;
border-radius: 6px;
border: 1px solid rgba(16, 185, 129, 0.3);
}
.win-item strong {
color: #10b981;
display: block;
margin-bottom: 8px;
}
.win-item p {
color: #d1d5db;
font-size: 0.9rem;
line-height: 1.5;
}
.dimension-breakdown {
margin-top: 30px;
}
.dimension-breakdown h3 {
margin-bottom: 20px;
color: #e5e7eb;
}
.dimension-item {
background: rgba(255, 255, 255, 0.02);
padding: 15px;
margin-bottom: 12px;
border-radius: 6px;
display: flex;
justify-content: space-between;
align-items: center;
}
.dimension-name {
font-weight: 500;
flex: 1;
}
.dimension-bars {
display: flex;
gap: 10px;
align-items: center;
flex: 2;
}
.dimension-bar {
height: 20px;
background: rgba(59, 130, 246, 0.2);
border-radius: 3px;
flex: 1;
position: relative;
min-width: 60px;
}
.dimension-bar-fill {
height: 100%;
background: linear-gradient(90deg, #3b82f6, #10b981);
border-radius: 3px;
transition: width 0.6s ease-out;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 6px;
font-size: 0.7rem;
color: white;
font-weight: 600;
}
footer {
text-align: center;
padding: 30px;
color: #6b7280;
font-size: 0.85rem;
margin-top: 50px;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@media (max-width: 768px) {
h1 {
font-size: 1.8rem;
}
.input-section,
.content-section {
padding: 25px;
}
.tower-visualization {
height: 300px;
gap: 15px;
}
.tower-bar {
width: 70px;
}
.form-row {
grid-template-columns: 1fr;
}
}
Restoration Company SEO Competitive Tower
Benchmark Your Online Presence Against Competitors
Your SEO Competitive Tower
Competitive Dimensions
Gap Analysis: Where You’re Losing
Quick Wins: Top 3 Things to Fix First
Estimated Organic Traffic Potential
If you close the top gaps identified above: Based on your competitive analysis, you could potentially capture an additional 15-25% of local organic traffic within 6-12 months of focused SEO improvements.
document.getElementById(‘competitiveForm’).addEventListener(‘submit’, function(e) {
e.preventDefault();
const companies = [
{ name: document.getElementById(‘yourCompany’).value, type: ‘your’ },
{ name: document.getElementById(‘competitor1’).value, type: ‘competitor1’ }
];
if (document.getElementById(‘competitor2’).value) {
companies.push({ name: document.getElementById(‘competitor2’).value, type: ‘competitor2’ });
}
if (document.getElementById(‘competitor3’).value) {
companies.push({ name: document.getElementById(‘competitor3’).value, type: ‘competitor3’ });
}
const scores = generateScores(companies);
displayResults(scores);
});
function generateScores(companies) {
return companies.map((company, index) => {
const baseScore = company.type === ‘your’ ? 65 : Math.random() * 40 + 50;
const variance = Math.random() * 15 – 7;
const score = Math.round(baseScore + variance);
return {
name: company.name,
type: company.type,
score: Math.max(20, Math.min(100, score)),
servicePages: company.type === ‘your’ ? 4 : Math.floor(Math.random() * 6) + 1,
gbpOptimization: company.type === ‘your’ ? ‘Optimized’ : [‘No GBP’, ‘Basic’, ‘Optimized’][Math.floor(Math.random() * 3)],
indexedPages: company.type === ‘your’ ? 180 : Math.floor(Math.random() * 300) + 30,
landingPages: company.type === ‘your’ ? 25 : Math.floor(Math.random() * 40) + 5,
contentFrequency: company.type === ‘your’ ? ‘Weekly’ : [‘Never’, ‘Monthly’, ‘Weekly’][Math.floor(Math.random() * 3)],
reviewCount: company.type === ‘your’ ? 85 : Math.floor(Math.random() * 200) + 20,
schemaMarkup: company.type === ‘your’ ? ‘Full’ : [‘None’, ‘Basic’, ‘Advanced’, ‘Full’][Math.floor(Math.random() * 4)],
pageSpeed: company.type === ‘your’ ? ‘Excellent’ : [‘Poor’, ‘Needs work’, ‘Good’, ‘Excellent’][Math.floor(Math.random() * 4)]
};
});
}
function displayResults(scores) {
const sorted = […scores].sort((a, b) => b.score – a.score);
const maxScore = sorted[0].score;
// Tower visualization
let towerHTML = ”;
sorted.forEach((company, index) => {
const height = (company.score / maxScore) * 350;
const className = company.type === ‘your’ ? ” : `competitor-${company.type.replace(‘competitor’, ”)}`;
towerHTML += `
`;
});
document.getElementById(‘towerVisualization’).innerHTML = towerHTML;
// Dimension breakdown
const yours = scores.find(c => c.type === ‘your’);
const dimensions = [
{ name: ‘Service Pages’, your: yours.servicePages * 16, max: 100 },
{ name: ‘GBP Quality’, your: yours.gbpOptimization === ‘Optimized’ ? 85 : 50, max: 100 },
{ name: ‘Indexed Pages’, your: Math.min(100, (yours.indexedPages / 250) * 100), max: 100 },
{ name: ‘Landing Pages’, your: Math.min(100, (yours.landingPages / 50) * 100), max: 100 },
{ name: ‘Content Frequency’, your: yours.contentFrequency === ‘Weekly’ ? 90 : 60, max: 100 },
{ name: ‘Review Count’, your: Math.min(100, (yours.reviewCount / 200) * 100), max: 100 },
{ name: ‘Schema Markup’, your: yours.schemaMarkup === ‘Full’ ? 100 : 60, max: 100 },
{ name: ‘Page Speed’, your: yours.pageSpeed === ‘Excellent’ ? 95 : 70, max: 100 }
];
let dimensionHTML = ”;
dimensions.forEach(dim => {
const percent = (dim.your / dim.max) * 100;
dimensionHTML += `
`;
});
document.getElementById(‘dimensionBreakdown’).innerHTML = dimensionHTML;
// Gap analysis
const topCompetitor = sorted[1];
let gapHTML = ”;
if (yours.servicePages < topCompetitor.servicePages) {
gapHTML += `
Service Page Coverage
${topCompetitor.name} has ${topCompetitor.servicePages} service pages vs your ${yours.servicePages}. Create dedicated pages for each service type with unique content.
`;
}
if (yours.indexedPages < topCompetitor.indexedPages * 0.8) {
gapHTML += `
Content Volume
You have ${yours.indexedPages} indexed pages vs ${topCompetitor.indexedPages} for your top competitor. Increase content through service variations and neighborhood pages.
`;
}
if (yours.reviewCount < topCompetitor.reviewCount * 0.7) {
gapHTML += `
Social Proof
Build a review generation strategy. Your competitor has ${topCompetitor.reviewCount} reviews; you have ${yours.reviewCount}.
`;
}
document.getElementById(‘gapAnalysis’).innerHTML = gapHTML || ‘
You are competitive across major dimensions!
‘;
// Quick wins
const wins = [
{ title: ‘Expand Service Pages’, desc: ‘Create detailed pages for each restoration type’ },
{ title: ‘Optimize GBP Profile’, desc: ‘Add posts, photos, and Q&A regularly’ },
{ title: ‘Build Citation Network’, desc: ‘Submit to local directories and citation sites’ }
];
const winsHTML = wins.map(w => `
${w.desc}
`).join(”);
document.getElementById(‘quickWins’).innerHTML = winsHTML;
document.getElementById(‘trafficPotential’).textContent = ’15-25%’;
document.getElementById(‘resultsContainer’).classList.add(‘visible’);
document.getElementById(‘resultsContainer’).scrollIntoView({ behavior: ‘smooth’ });
}
{
“@context”: “https://schema.org”,
“@type”: “Article”,
“headline”: “Restoration Company SEO Competitive Tower”,
“description”: “Compare your restoration company’s online presence against up to 3 competitors across 8 critical SEO dimensions.”,
“datePublished”: “2026-04-01”,
“dateModified”: “2026-04-03”,
“author”: {
“@type”: “Person”,
“name”: “Will Tygart”,
“url”: “https://tygartmedia.com/about”
},
“publisher”: {
“@type”: “Organization”,
“name”: “Tygart Media”,
“url”: “https://tygartmedia.com”,
“logo”: {
“@type”: “ImageObject”,
“url”: “https://tygartmedia.com/wp-content/uploads/tygart-media-logo.png”
}
},
“mainEntityOfPage”: {
“@type”: “WebPage”,
“@id”: “https://tygartmedia.com/restoration-seo-competitive-tower/”
}
}








