Skip to main content
Fervor Grade™  /  The CRO Index  /  National Site Inspection
National Site Inspection — Remodeling — Canada & United States

All Things New

A Site Inspection of the highest-traffic organic pages across atnhawaii.com — measuring whether the website earns trust independent of brand equity.

Domain atnhawaii.com
Inspection Date March 19, 2026
Pages Inspected 3
72 /100 Weighted Score: Grade /
Executive Summary

The All Things New Site Inspection

All Things New is a Hawaii (Kapolei, Oahu) design-build remodeler trading on an unusually strong content-marketing stack for the category: ATN Productions YouTube channel with personality-driven episode series, dual gallery surfaces (/exteriors, /interiors, /360gallery), 27+ press-coverage detail pages, and the strongest JSON-LD stack in the trade sample (WebSite + Organization + LocalBusiness + Product with aggregateRating 4.7/47 + embedded Review). Tier B. The Fervor Grade™ National Site Inspection scored atnhawaii.com at 72/100 — Grade B, Passing.

Overall Weighted Brand Score 72
Fervor Grade™ Interpretation

72/100 · Grade B — Passing. The website is passing. Most conversion fundamentals are present; the gap to A-tier is in tightening trust signals, lead-capture variety, or mobile UX.

Homepage 74 Services Page 70 Contact 68
Homepage 74 ×0.15 · wt. 37.0
Services Page 70 ×0.20 · wt. 21.0
Contact 68 ×0.30 · wt. 13.6

Methodology note. This Site Inspection applies the Fervor Grade™ 2.5 National Site Inspection framework to five key conversion pages on atnhawaii.com. Scoring categories: First Impression (/20), Trust & Credibility (/22), Lead Capture (/20), Mobile Experience (/15), Content & SEO (/15), Accessibility (/8). Pages are weighted by conversion funnel role: Homepage ×0.15, Location Finder ×0.20, Location Page ×0.30, Service Page ×0.20, Lead Capture ×0.15. Fervor Grade™ scores conversion potential independent of brand equity.

Page 1 of 5 — Homepage

Homepage

Homepage
https://atnhawaii.com
74 /100 B — Green Band
First Impression
17/20
Trust & Credibility
17/22
Lead Capture
13/20
Mobile Experience
10/15
Content & SEO
8/15
Accessibility
6/8
Page Total
74/100
✓ Pass — First Impression

First Impression scored 17/20 on the Homepage Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

✓ Pass — Trust & Credibility

Trust & Credibility scored 17/22 on the Homepage Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Lead Capture

Lead Capture scored 13/20 on the Homepage Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Mobile Experience

Mobile Experience scored 10/15 on the Homepage Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Content & SEO

Content & SEO scored 8/15 on the Homepage Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

✓ Pass — Accessibility

Accessibility scored 6/8 on the Homepage Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

Page 2 of 5 — Location Finder

Services Page

Services Page
https://atnhawaii.com/services/
70 /100 B — Amber Band
First Impression
16/20
Trust & Credibility
16/22
Lead Capture
12/20
Mobile Experience
9/15
Content & SEO
8/15
Accessibility
6/8
Page Total
70/100
✓ Pass — First Impression

First Impression scored 17/20 on the Services Page Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

✓ Pass — Trust & Credibility

Trust & Credibility scored 17/22 on the Services Page Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Lead Capture

Lead Capture scored 13/20 on the Services Page Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Mobile Experience

Mobile Experience scored 10/15 on the Services Page Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Content & SEO

Content & SEO scored 8/15 on the Services Page Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

✓ Pass — Accessibility

Accessibility scored 6/8 on the Services Page Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

Page 3 of 5 — Location Page

Contact

Contact
https://atnhawaii.com/contact/
68 /100 C — Amber Band
First Impression
16/20
Trust & Credibility
16/22
Lead Capture
12/20
Mobile Experience
9/15
Content & SEO
7/15
Accessibility
6/8
Page Total
68/100
✓ Pass — First Impression

First Impression scored 17/20 on the Contact Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

✓ Pass — Trust & Credibility

Trust & Credibility scored 17/22 on the Contact Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Lead Capture

Lead Capture scored 13/20 on the Contact Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Mobile Experience

Mobile Experience scored 10/15 on the Contact Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

⚠ Warn — Content & SEO

Content & SEO scored 8/15 on the Contact Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

✓ Pass — Accessibility

Accessibility scored 6/8 on the Contact Site Inspection. See the rubric components in the Scoring Summary section for category-level breakdowns.

Strengths Identified

What's Done Well

Fervor Grade™ — Top Strengths

All Things New is a Hawaii (Kapolei, Oahu) design-build remodeler trading on an unusually strong...

  • All Things New is a Hawaii (Kapolei, Oahu) design-build remodeler trading on an unusually strong content-marketing stack for the category: ATN Productions YouTube channel with personality-driven episode series, dual gallery surfaces (/exteriors, /interiors, /360gallery), 27+ press-coverage detail pages, and the strongest JSON-LD stack in the trade sample (WebSite + Organization + LocalBusiness + Product with aggregateRating 4.7/47 + embedded Review). Tier B.
  • Three concrete drags on the score: (1) homepage and services-page tags are 200+ characters of stuffed local-commercial keywords that Google will truncate and devalue; (2) the contact page form is modal-gated behind an 'OPEN FORM' button, which both adds friction and breaks DOM-level form detection (forms[] = 0 on every capture); (3) homepage has white-on-white text contrast failure (#ffffff on #fcfcfc) in the 'Customer Service is everything' and 'WE GUARANTEE OUR WORK' blocks, a serious-tier axe violation that repeats on mobile.</li> </ul> </div> </section> <section class="section"> <span class="section-eyebrow">Critical Conversion Failures</span> <h2 class="section-title" id="conversion-killers">Conversion Killers</h2> <div class="killer-box"> <span class="section-eyebrow">Fervor Grade™ — Most Damaging Findings</span> <h2 class="killer-title">Conversion Machinery Below Industry Bar</h2> <ul class="killer-list"> <li class="killer-item"><span class="killer-item-label">✗ Below Industry Bar</span><p>No single conversion-blocker surfaced in the Site Inspection, but category-level rubric scores below the 80% bar across multiple pages limit the ceiling on visitor-to-lead conversion regardless of traffic volume.</p></li> </ul> <div class="killer-stat">22% of users abandon forms because the process is too long or complicated (Baymard Institute, 2024). 62.45% of users browse on mobile (Statcounter, 2025).</div> </div> </section> <section class="section"> <span class="section-eyebrow">Revenue Projection</span> <h2 class="section-title" id="revenue-impact">Revenue Impact</h2> <h3>Conversion Gap Calculation</h3> <p><strong>Step 1 — Traffic Baseline (estimated):</strong> All Things New draws an estimated 3,000–10,000 monthly organic visitors from search and direct traffic. Estimate from third-party tools; actual variance ±30–50%.</p> <p><strong>Step 2 — Conversion Benchmarks (published):</strong> The average paid search conversion rate for home remodeling is 7.0–10.0% (LocaliQ 2025, 3,200+ campaigns). The average CPC is $6–$12. Average project value for this brand: $15,000–$60,000 (mid: $37,500) (trade-segment benchmark fallback (no brand-specific data)).</p> <p><strong>Step 3 — Conversion Gap Argument (observed):</strong> The Site Inspection did not surface any single conversion-blocker. Improvements are distributed across rubric categories scoring below 80%.</p> <p><strong>Step 4 — Financial Range:</strong></p> <div class="revenue-panel"> <h3>Assumptions</h3> <table class="Site Inspection-table"> <thead> <tr><th>Variable</th><th>Value</th><th>Source / Rationale</th></tr> </thead> <tbody> <tr><td>Monthly organic visitors (estimated)</td><td><strong>3,000 – 10,000</strong></td><td>Third-party traffic estimates ±30–50%</td></tr> <tr><td>Industry CVR for home remodeling</td><td><strong>7.0% – 10.0%</strong></td><td>LocaliQ 2025 (3,200+ campaigns)</td></tr> <tr><td>Estimated current site CVR</td><td><strong>5.0% – 7.2%</strong></td><td>Scaled by current Fervor Grade weighted score</td></tr> <tr><td>Estimated CVR after fixes</td><td><strong>7.0% – 10.0%</strong></td><td>Industry benchmark for category</td></tr> <tr><td>Avg project value</td><td><strong>$15,000 – $60,000 (mid: $37,500)</strong></td><td>[BRAND] from per-brand pricing research, confidence: low</td></tr> <tr><td>Close rate (industry)</td><td><strong>30% – 40%</strong></td><td>Standard residential-services close rate</td></tr> </tbody> </table> <div class="revenue-row"> <div class="revenue-cell"> <span class="revenue-cell-label">Monthly revenue left on the table</span> <span class="revenue-cell-val" style="color:var(--green)">$0 – $6.5M/month</span> </div> <div class="revenue-cell"> <span class="revenue-cell-label">Annual cost of inaction</span> <span class="revenue-cell-val" style="color:var(--accent)">$0 – $78.1M/year</span> </div> </div> </div> <p><strong>Step 5 — Paid Traffic Argument:</strong> At the industry CPC of $6–$12 for home remodeling and a brand avg-project-value of $37,500, every paid click hits the site's current conversion potential. Improving the lowest-scoring rubric category lifts ROI on every advertising dollar already being spent.</p> <p class="revenue-note">Revenue projections are estimates based on published industry benchmarks and third-party traffic estimates. They should not be interpreted as guarantees.</p> </section> <section class="section"> <span class="section-eyebrow">Immediate Opportunities</span> <h2 class="section-title" id="quick-wins">Quick Wins</h2> <p class="section-intro">Four high-impact, low-effort improvements ranked by expected conversion lift.</p> <div class="quickwin-list"> <div class="quickwin"><span class="quickwin-num">1</span><div><p class="quickwin-title">Strengthen weakest category</p><p class="quickwin-detail">Address the lowest-scoring rubric area across the inspected pages with focused conversion-machinery upgrades.</p><span class="quickwin-impact">Expected lift: 8–15% on page-level conversion</span></div></div> </div> </section> <section class="section"> <span class="section-eyebrow">Competitive Context</span> <h2 class="section-title" id="competitive-position">Strengths, Vulnerabilities, and Competitive Position</h2> <h3>National Brand vs. Local Competitors</h3> <p><strong>Strengths:</strong></p> <ul><li>All Things New is a Hawaii (Kapolei, Oahu) design-build remodeler trading on an unusually strong content-marketing stack for the category: ATN Productions YouTube channel with personality-driven episode series, dual gallery surfaces (/exteriors, /interiors, /360gallery), 27+ press-coverage detail pages, and the strongest JSON-LD stack in the trade sample (WebSite + Organization + LocalBusiness + Product with aggregateRating 4.7/47 + embedded Review). Tier B.</li> <li>Three concrete drags on the score: (1) homepage and services-page <title> tags are 200+ characters of stuffed local-commercial keywords that Google will truncate and devalue; (2) the contact page form is modal-gated behind an 'OPEN FORM' button, which both adds friction and breaks DOM-level form detection (forms[] = 0 on every capture); (3) homepage has white-on-white text contrast failure (#ffffff on #fcfcfc) in the 'Customer Service is everything' and 'WE GUARANTEE OUR WORK' blocks, a serious-tier axe violation that repeats on mobile.</li></ul> <p><strong>Vulnerabilities:</strong></p> <ul><li>No critical vulnerabilities surfaced in the Site Inspection; tier-level gaps are tracked in the Quick Wins section.</li></ul> </section> <section class="section"> <span class="section-eyebrow">Verdict</span> <h2 class="section-title" id="the-summary">The Summary</h2> <div class="verdict-box"> <span class="section-eyebrow">Inspection Verdict — All Things New</span> <p class="verdict-p1">All Things New scores 72/100 on the Fervor Grade™ National Framework — Grade B, Passing. The website is passing. Most conversion fundamentals are present; the gap to A-tier is in tightening trust signals, lead-capture variety, or mobile UX. All Things New is a Hawaii (Kapolei, Oahu) design-build remodeler trading on an unusually strong content-marketing stack for the category: ATN Productions YouTube channel with personality-driven episode series, dual gallery surfaces (/exteriors, /interiors, /360gallery), 27+ press-coverage detail pages, and the strongest JSON-LD stack in the trade sample (WebSite + Organization + LocalBusiness + Product with aggregateRating 4.7/47 + embedded Review).</p> <p class="verdict-p2">The Site Inspection observed All Things New's framework pages and applied the standard Fervor Grade™ rubric. The lowest-scoring category was Content & SEO at 8/15; category-level breakdowns and per-page observations follow.</p> <div class="verdict-primary"> PRIMARY ISSUE <strong>Content & SEO scores below the 70% bar across the inspected pages. The category-level rubric components and supporting evidence are detailed in the per-page Site Inspections above.</strong> </div> <div class="verdict-primary" style="margin-top:1rem;"> RECOMMENDED FIRST ACTION <strong>Site Inspection each page against the rubric components above; the highest-ROI fixes are typically in lead-capture form length, trust-signal embedding, and mobile click-to-call/click-to-form conversion mechanics.</strong> </div> </div> </section> <section class="section"> <span class="section-eyebrow">Scoring Summary</span> <h2 class="section-title" id="weighted-brand-score-calculation">Weighted Brand Score Calculation</h2> <table class="Site Inspection-table"> <thead> <tr><th>Page</th><th>Raw Score</th><th>Weight</th><th>Weighted</th></tr> </thead> <tbody> <tr> <td><strong>Homepage</strong></td> <td><strong style="color:var(--Site Inspection-green)">74</strong>/100</td> <td>×0.15</td> <td><strong>37.0</strong></td> </tr> <tr> <td><strong>Services Page</strong></td> <td><strong style="color:var(--Site Inspection-green)">70</strong>/100</td> <td>×0.20</td> <td><strong>21.0</strong></td> </tr> <tr> <td><strong>Contact</strong></td> <td><strong style="color:var(--Site Inspection-amber)">68</strong>/100</td> <td>×0.30</td> <td><strong>13.6</strong></td> </tr> <tr style="background:var(--paper-2);"> <td colspan="3"><strong>Overall Weighted Brand Score</strong></td> <td><strong style="font-size:1.1rem;">72 / 100</strong></td> </tr> </tbody> </table> </section> <section class="section"> <span class="section-eyebrow">Site Inspection Framework</span> <h2 class="section-title" id="modifiers-applied">Modifiers Applied</h2> <div class="method-box"> <table class="Site Inspection-table"> <thead> <tr><th>Modifier</th><th>Trigger</th><th>Score Impact</th></tr> </thead> <tbody> <tr><td colspan="3">No score-adjusting modifiers triggered.</td></tr> </tbody> </table> </div> </section> <section class="section"> <span class="section-eyebrow">Data Integrity</span> <h2 class="section-title" id="data-confidence">Data Confidence Statement</h2> <div class="method-box"> <p><strong>Observed with certainty:</strong> First Impression: Homepage hero on desktop and mobile shows 'DREAM . DESIGN . BUILD' positioning over kitchen interior imagery; 'REQUEST A CONSULTATION' button visible at hero center; 808.230.3385 phone link directly below CTA; ATN ALL THINGS NEW logo top-left; below-fold 'ATN PRODUCTIONS | YOUTUBE' section with 'Modern Renovation Luxury Home' and 'Coffee and Carpentry Surfers Episode 2' video tiles.. Trust Credibility: Homepage JSON-LD Product schema carries aggregateRating ratingValue 4.7, reviewCount 47, bestRating 5, plus an embedded Review (Susie V., 5 stars, 2023-04-28); homepage body HTML contains 'Licensed & Insured #BC-35190' and 'WE GUARANTEE OUR WORK' headline; Yelp reviews widget (elfsight yelpReviews.js v3.41.0) loaded on homepage; 27+ press-coverage detail URLs in sitemap including 'Reader's Choice Awards 2021: Builder', 'Reader's Choice Awards 2021: Interior Design', 'KBB People of the Year 2021', and 'ATN named Top Builder 2019'.. Lead Capture: Primary CTA 'Request a Consultation' resolves to /consult per cta_clickthrough.json captures[0].cta_href; 6 successful CTA clicks across home, services, and about (desktop + mobile); contact page itself returns error 'no_ctas_found' because the form is modal-gated behind an 'OPEN FORM' button visible in contact__desktop__1_load.png; DOM forms[] empty on all 6 captures; phone (2 tel: links), email (2 mailto: links including subject=Website%20Inquiry), and 5 social platforms confirmed across every page.. Mobile Experience: Mobile hero (home__mobile__1_load.png) shows REQUEST A CONSULTATION button at 287x52 geometry, 808.230.3385 tel-link directly below, social row beneath (instagram, facebook, youtube, email, yelp), hamburger menu top-right; mobile contact page replicates the desktop 'OPEN FORM' modal pattern without a streamlined inline mobile form; mobile a11y axe runs match desktop fingerprint (5 contact violations, 4 home, 3 services) indicating no mobile-specific accessibility polish.. Content Seo: Homepage <title> is 220 characters of stuffed local-commercial keywords; services-page <title> is similarly bloated; only contact-page title is well-formed; JSON-LD stack across captured pages includes WebSite, Organization, LocalBusiness, and Product (with aggregateRating) schemas; page_role_coverage 0.60 (3 of 5 canonical roles per manifest.json); 123 URLs in sitemap including /blog, /blog-2 with 14+ articles, /atn-in-the-news with 27+ detail pages, /faq, /testimonials, /clients, /360gallery, /atn-luxury sub-brand surface.. Accessibility: axe-core 4.10.2 run across 6 contexts (home/services/contact x desktop/mobile) yields 5 unique violation IDs: color-contrast (serious, repeats on every page including white-on-white Customer Service text block at homepage), heading-order (moderate, home + contact), landmark-unique (moderate, all 3 pages), region (moderate, all 3 pages), empty-heading (minor, contact only). Zero critical violations. WCAG 2.1 AA + best-practice tags applied.. Architecture: architecture.json detector classifies the brand as 'standard' with high confidence ('no_non_standard_pattern_matched'); manifest.json captures 123 total URLs from sitemap (79) + homepage_nav (44); framework_page_roles fills 3 of 5 canonical slots (homepage, service_page, lead_capture); location_finder and location_page slots null despite Hawaii multi-island opportunity..</p> <p><strong>Estimated with published benchmarks:</strong> Monthly organic traffic estimated via third-party tools (±30–50%). Industry CPC, CVR, and CPL drawn from LocaliQ 2025 (3,200+ campaigns). Average project values from remodeling industry sources. Actual conversion rate, ad spend, lead volume, and close rate are unknown in non-client Site Inspections.</p> </div> </section> <section class="section"> <span class="section-eyebrow">Sources</span> <h2 class="section-title" id="citations">Citations</h2> <div class="citation">[1] BrightLocal (2025). "97% of consumers read reviews before hiring a local business." <a href="https://www.brightlocal.com/research/local-consumer-review-survey/">brightlocal.com</a></div> <div class="citation">[2] Baymard Institute (2024). "22% of users abandon forms because the process is too long or complicated." <a href="https://baymard.com/lists/cart-abandonment-rate">baymard.com</a></div> <div class="citation">[3] Statcounter (2025). "62.45% of users browse the web on mobile." <a href="https://gs.statcounter.com/platform-market-share/desktop-mobile-tablet">gs.statcounter.com</a></div> <div class="citation">[4] LocaliQ (2025). "Industry CPC + CVR benchmarks across 3,200+ campaigns." <a href="https://localiq.com/blog/search-advertising-benchmarks/">localiq.com</a></div> <div class="citation">[5] Nielsen Norman Group (2024). "Trust signals (reviews, credentials, named team) are the strongest predictors of B2C service-page conversion." <a href="https://www.nngroup.com/articles/trust-signals/">nngroup.com</a></div> </section><nav style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--audit-rule);"> <a href="/contractor/cro-index/" style="font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); text-decoration: none;"> ← Back to Contractor CRO Index </a> </nav> </article> <div class="td-sidebar-rail" data-astro-cid-xzg2zzut> <!-- Desktop sidebar --><aside class="guides-sidebar" aria-label="Related Inspections" data-astro-cid-7o3n3qur> <p class="guides-sidebar__title" data-astro-cid-7o3n3qur>Related Inspections</p> <nav class="guides-sidebar__list" data-astro-cid-7o3n3qur> <div class="guides-sidebar__group" data-astro-cid-7o3n3qur> <div class="guides-sidebar__header" data-astro-cid-7o3n3qur> <a href="/contractor/residential-construction/remodeling/" class="guides-sidebar__heading" data-astro-cid-7o3n3qur>Remodeling Guides</a> <button class="guides-sidebar__toggle" aria-expanded="false" aria-label="Toggle Remodeling Guides" data-guides-toggle data-astro-cid-7o3n3qur> <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" data-astro-cid-7o3n3qur> <path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-7o3n3qur></path> </svg> </button> </div> <ul class="guides-sidebar__links" data-guides-links hidden data-astro-cid-7o3n3qur> <li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/state-of-the-industry/remodeling/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Remodeling State of the Industry 2026</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/residential-construction/remodeling/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Remodeling Contractor Guide</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/residential-construction/remodeling/honolulu-remodeling-seo/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Honolulu remodeling SEO</a> </li> </ul> </div><div class="guides-sidebar__group" data-astro-cid-7o3n3qur> <div class="guides-sidebar__header" data-astro-cid-7o3n3qur> <span class="guides-sidebar__heading" data-astro-cid-7o3n3qur>More Remodeling Inspections</span> <button class="guides-sidebar__toggle" aria-expanded="false" aria-label="Toggle More Remodeling Inspections" data-guides-toggle data-astro-cid-7o3n3qur> <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" data-astro-cid-7o3n3qur> <path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-7o3n3qur></path> </svg> </button> </div> <ul class="guides-sidebar__links" data-guides-links hidden data-astro-cid-7o3n3qur> <li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/mr-sandless-sir-grout/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Mr. Sandless / Sir Grout (73/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/thompson-contractors-llc/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Thompson Contractors LLC (73/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/total-living-concepts/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Total Living Concepts (73/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/trace-ventures/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Trace Ventures (73/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/ec-construction/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>EC Construction (72/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/espalux-renovation-inc/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Espalux Renovation Inc. (72/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/hurst-design-build-remodeling/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Hurst Design-Build Remodeling (72/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/j-i-home-improvements/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>J&I Home Improvements (72/100)</a> </li> </ul> </div> </nav> </aside> <!-- Mobile: inline section --> <div class="guides-sidebar-mobile" aria-label="Related Inspections" data-astro-cid-7o3n3qur> <h2 class="guides-sidebar-mobile__title" data-astro-cid-7o3n3qur>Related Inspections</h2> <div class="guides-sidebar-mobile__grid" data-astro-cid-7o3n3qur> <div class="guides-sidebar-mobile__card" data-astro-cid-7o3n3qur> <h3 data-astro-cid-7o3n3qur> <a href="/contractor/residential-construction/remodeling/" data-astro-cid-7o3n3qur>Remodeling Guides</a> </h3> <ul data-astro-cid-7o3n3qur> <li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/state-of-the-industry/remodeling/" data-astro-cid-7o3n3qur>Remodeling State of the Industry 2026</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/residential-construction/remodeling/" data-astro-cid-7o3n3qur>Remodeling Contractor Guide</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/residential-construction/remodeling/honolulu-remodeling-seo/" data-astro-cid-7o3n3qur>Honolulu remodeling SEO</a></li> </ul> </div><div class="guides-sidebar-mobile__card" data-astro-cid-7o3n3qur> <h3 data-astro-cid-7o3n3qur> <span data-astro-cid-7o3n3qur>More Remodeling Inspections</span> </h3> <ul data-astro-cid-7o3n3qur> <li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/mr-sandless-sir-grout/" data-astro-cid-7o3n3qur>Mr. Sandless / Sir Grout (73/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/thompson-contractors-llc/" data-astro-cid-7o3n3qur>Thompson Contractors LLC (73/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/total-living-concepts/" data-astro-cid-7o3n3qur>Total Living Concepts (73/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/trace-ventures/" data-astro-cid-7o3n3qur>Trace Ventures (73/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/ec-construction/" data-astro-cid-7o3n3qur>EC Construction (72/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/espalux-renovation-inc/" data-astro-cid-7o3n3qur>Espalux Renovation Inc. (72/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/hurst-design-build-remodeling/" data-astro-cid-7o3n3qur>Hurst Design-Build Remodeling (72/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/j-i-home-improvements/" data-astro-cid-7o3n3qur>J&I Home Improvements (72/100)</a></li> </ul> </div> </div> </div> <script type="module">document.querySelectorAll("[data-guides-toggle]").forEach(e=>{e.addEventListener("click",()=>{const d=e.getAttribute("aria-expanded")==="true",t=e.closest(".guides-sidebar__group")?.querySelector("[data-guides-links]");t&&(d?(t.setAttribute("hidden",""),e.setAttribute("aria-expanded","false")):(t.removeAttribute("hidden"),e.setAttribute("aria-expanded","true")))})});</script> </div> </div> </main> <footer class="ft" role="contentinfo" data-astro-cid-sz7xmlte> <div class="ft__inner" data-astro-cid-sz7xmlte> <!-- ═══ TOP: 4-column grid ═══ --> <div class="ft__grid" data-astro-cid-sz7xmlte> <!-- Column 1: Brand + Newsletter --> <div class="ft__brand" data-astro-cid-sz7xmlte> <a href="/" class="ft__logo" aria-label="Fervor Studio, Home" data-astro-cid-sz7xmlte>FERVOR</a> <p class="ft__tagline" data-astro-cid-sz7xmlte> Conversion first websites and local SEO for home service contractors. </p> <div class="ft__newsletter" data-astro-cid-sz7xmlte> <p class="ft__col-label" data-astro-cid-sz7xmlte>Join Booked Solid</p> <p class="ft__newsletter-desc" data-astro-cid-sz7xmlte> Clear emails about what's actually working for contractors. CRO plays, site fixes, the occasional teardown. </p> <form class="ft__form footer-newsletter-js" data-endpoint="/api/contact" novalidate data-astro-cid-sz7xmlte> <input type="text" name="firstName" placeholder="Your first name" class="ft__input ft__input--name" autocomplete="given-name" required aria-label="Your first name" data-astro-cid-sz7xmlte> <div class="ft__form-row" data-astro-cid-sz7xmlte> <input type="email" name="email" placeholder="your@email.com" class="ft__input" autocomplete="email" required aria-label="Email address" data-astro-cid-sz7xmlte> <button type="submit" class="ft__submit" data-astro-cid-sz7xmlte> <span class="nl-btn-text" data-astro-cid-sz7xmlte>Subscribe</span> <span class="nl-btn-loading" style="display:none;" data-astro-cid-sz7xmlte>...</span> </button> </div> <div style="position:absolute;left:-9999px;" aria-hidden="true" data-astro-cid-sz7xmlte> <input type="text" name="website_url" tabindex="-1" autocomplete="off" data-astro-cid-sz7xmlte> </div> <label class="ft__consent" data-astro-cid-sz7xmlte> <input type="checkbox" name="consent" required data-astro-cid-sz7xmlte> <span data-astro-cid-sz7xmlte>Yes, send me The Crew newsletter. I can unsubscribe at any time.</span> </label> <span class="nl-error" data-astro-cid-sz7xmlte></span> <span class="nl-success" style="display:none;" data-astro-cid-sz7xmlte>You're in. Welcome to The Crew.</span> <p class="ft__legal-note" data-astro-cid-sz7xmlte>Sent by Fervor Group Inc., Cochrane, AB. <a href="/privacy/" data-astro-cid-sz7xmlte>Privacy Policy</a></p> </form> </div> </div> <!-- Column 2: Services --> <nav class="ft__col" aria-label="Services" data-astro-cid-sz7xmlte> <p class="ft__col-label" data-astro-cid-sz7xmlte>Services</p> <ul class="ft__links" data-astro-cid-sz7xmlte> <li data-astro-cid-sz7xmlte> <a href="/services/booked-by-design/" class data-astro-cid-sz7xmlte> Booked by Design™ </a> </li><li data-astro-cid-sz7xmlte> <a href="/services/leak-plug-sprint/" class data-astro-cid-sz7xmlte> Leak Plug Sprint </a> </li><li data-astro-cid-sz7xmlte> <a href="/services/the-local-pick/" class data-astro-cid-sz7xmlte> The Local Pick </a> </li><li data-astro-cid-sz7xmlte> <a href="/services/referral-closer/" class data-astro-cid-sz7xmlte> Referral Closer </a> </li><li data-astro-cid-sz7xmlte> <a href="/services/performance-partner/" class data-astro-cid-sz7xmlte> Performance Partner™ </a> </li><li data-astro-cid-sz7xmlte> <a href="/site-inspection/" class="ft__link--highlight" data-astro-cid-sz7xmlte> The Site Inspection </a> </li> </ul> </nav> <!-- Column 3: Contractor Guides --> <nav class="ft__col" aria-label="Contractor Guides" data-astro-cid-sz7xmlte> <p class="ft__col-label" data-astro-cid-sz7xmlte>Contractor Guides</p> <ul class="ft__links" data-astro-cid-sz7xmlte> <li data-astro-cid-sz7xmlte> <a href="/contractor/building-envelope/roofing/" class data-astro-cid-sz7xmlte> Roofing </a> </li><li data-astro-cid-sz7xmlte> <a href="/contractor/building-systems/hvac/" class data-astro-cid-sz7xmlte> HVAC </a> </li><li data-astro-cid-sz7xmlte> <a href="/contractor/building-systems/plumbing/" class data-astro-cid-sz7xmlte> Plumbing </a> </li><li data-astro-cid-sz7xmlte> <a href="/contractor/building-systems/electrician/" class data-astro-cid-sz7xmlte> Electrician </a> </li><li data-astro-cid-sz7xmlte> <a href="/contractor/residential-construction/remodeling/" class data-astro-cid-sz7xmlte> Remodeling </a> </li><li data-astro-cid-sz7xmlte> <a href="/contractor/residential-construction/kitchen-bath/" class data-astro-cid-sz7xmlte> Kitchen & Bath </a> </li><li data-astro-cid-sz7xmlte> <a href="/contractor/building-systems/solar/" class data-astro-cid-sz7xmlte> Solar </a> </li><li data-astro-cid-sz7xmlte> <a href="/contractor/" class="ft__link--highlight" data-astro-cid-sz7xmlte> All Trades </a> </li> </ul> </nav> <!-- Column 4: Company --> <nav class="ft__col" aria-label="Company" data-astro-cid-sz7xmlte> <p class="ft__col-label" data-astro-cid-sz7xmlte>Company</p> <ul class="ft__links" data-astro-cid-sz7xmlte> <li data-astro-cid-sz7xmlte><a href="/about-fervor-studio/" data-astro-cid-sz7xmlte>About</a></li><li data-astro-cid-sz7xmlte><a href="/contractor/cro-index/" data-astro-cid-sz7xmlte>The CRO Index</a></li><li data-astro-cid-sz7xmlte><a href="/contractor/cro-index/page-breakdowns/" data-astro-cid-sz7xmlte>Page Breakdowns</a></li><li data-astro-cid-sz7xmlte><a href="/compare/" data-astro-cid-sz7xmlte>Agency Comparison</a></li><li data-astro-cid-sz7xmlte><a href="/news/" data-astro-cid-sz7xmlte>News</a></li> </ul> </nav> <!-- Column 5: Tools --> <nav class="ft__col" aria-label="Tools" data-astro-cid-sz7xmlte> <p class="ft__col-label" data-astro-cid-sz7xmlte>Tools</p> <ul class="ft__links" data-astro-cid-sz7xmlte> <li data-astro-cid-sz7xmlte><a href="/revenue-loss-calculator/" data-astro-cid-sz7xmlte>Lead Leak Calculator</a></li> </ul> </nav> </div> <!-- ═══ BOTTOM BAR ═══ --> <div class="ft__bottom" data-astro-cid-sz7xmlte> <div class="ft__bottom-left" data-astro-cid-sz7xmlte> <span class="ft__copyright" data-astro-cid-sz7xmlte>© 2026 Fervor Studio</span> <a href="/privacy/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Privacy Policy</a><a href="/terms/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Terms of Service</a><a href="/cookies/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Cookie Policy</a><a href="/accessibility/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Accessibility</a><a href="/affiliate-disclosure/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Affiliate Disclosure</a> <a href="/cookies/" class="ft__bottom-link" data-manage-cookies data-astro-cid-sz7xmlte>Manage Cookies</a> </div> <a href="https://fervorstudio.ca" class="ft__sig" target="_blank" rel="noopener noreferrer" data-astro-cid-sz7xmlte>Designed with Fervor</a> </div> </div> </footer> <script> document.addEventListener('DOMContentLoaded', () => { document.querySelectorAll('.footer-newsletter-js').forEach(form => { form.addEventListener('submit', async (e) => { e.preventDefault(); const f = e.target; const endpoint = f.dataset.endpoint; const errorEl = f.querySelector('.nl-error'); const successEl = f.querySelector('.nl-success'); const btnText = f.querySelector('.nl-btn-text'); const btnLoading = f.querySelector('.nl-btn-loading'); const submitBtn = f.querySelector('button[type="submit"]'); if (errorEl) errorEl.textContent = ''; const fd = new FormData(f); const data = { email: fd.get('email')?.toString().trim() || '', firstName: fd.get('firstName')?.toString().trim() || '', service: 'newsletter', sourcePage: window.location.pathname, website_url: fd.get('website_url')?.toString() || '', }; if (!data.firstName) { if (errorEl) errorEl.textContent = 'Please enter your name.'; return; } if (!data.email) { if (errorEl) errorEl.textContent = 'Please enter your email.'; return; } if (!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(data.email)) { if (errorEl) errorEl.textContent = 'Please enter a valid email address.'; return; } var consentBox = f.querySelector('input[name="consent"]'); if (consentBox && !consentBox.checked) { if (errorEl) errorEl.textContent = 'Please confirm you want to receive our newsletter.'; return; } submitBtn.disabled = true; if (btnText) btnText.style.display = 'none'; if (btnLoading) btnLoading.style.display = 'inline'; try { const res = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); const result = await res.json(); if (res.ok && result.success) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'newsletter_signup', newsletter_name: 'the_crew', signup_location: 'footer', page_path: window.location.pathname }); Array.from(f.querySelectorAll('input, button, label')).forEach(el => el.style.display = 'none'); const legal = f.querySelector('.ft__legal-note'); if (legal) legal.style.display = 'none'; if (successEl) successEl.style.display = 'block'; } else { if (errorEl) errorEl.textContent = result.errors?.email || result.message || 'Something went wrong.'; } } catch { if (errorEl) errorEl.textContent = 'Network error. Please try again.'; } finally { submitBtn.disabled = false; if (btnText) btnText.style.display = 'inline'; if (btnLoading) btnLoading.style.display = 'none'; } }); }); }); </script> <!-- ── Sticky Mobile CTA (canonical .btn-rose: rose gradient + white text, matches homepage .fgx-sticky-cta) ── --> <a href="/site-inspection/" class="sticky-mobile-cta btn-rose" aria-label="Get My Site Inspection"> Get My Site Inspection </a> <!-- Consent Banner, fixed bottom, PIPEDA compliant --> <div id="fervor-consent-banner" class="consent-banner" role="dialog" aria-label="Cookie consent" aria-modal="false" style="display:none" data-astro-cid-2effgw6e> <div class="consent-inner" data-astro-cid-2effgw6e> <p class="consent-message" data-astro-cid-2effgw6e> We use cookies to understand how you interact with our site and improve your experience. You can accept or reject non-essential cookies. <a href="/cookies/" class="consent-link" data-astro-cid-2effgw6e>Cookie Policy</a> </p> <div class="consent-actions" data-astro-cid-2effgw6e> <button type="button" class="consent-btn consent-btn--reject" id="consent-reject" data-astro-cid-2effgw6e> Reject </button> <button type="button" class="consent-btn consent-btn--accept" id="consent-accept" data-astro-cid-2effgw6e> Accept </button> </div> </div> </div> <script> // ── Consent Banner Logic ── // Runs inline to avoid Astro bundling. Must execute before GTM. (function() { var COOKIE_NAME = 'fervor_consent'; var COOKIE_MAX_AGE = 31536000; // 12 months function getCookie(name) { var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); return match ? decodeURIComponent(match[2]) : null; } function setCookie(name, value, maxAge) { document.cookie = name + '=' + encodeURIComponent(value) + '; path=/; max-age=' + maxAge + '; SameSite=Lax; Secure'; } function updateConsent(analytics, marketing) { if (typeof gtag === 'function') { gtag('consent', 'update', { 'analytics_storage': analytics ? 'granted' : 'denied', 'ad_storage': marketing ? 'granted' : 'denied', 'ad_user_data': marketing ? 'granted' : 'denied', 'ad_personalization': marketing ? 'granted' : 'denied' }); } // Store in cookie with timestamp and version for PIPEDA audit trail var consent = JSON.stringify({ analytics: analytics, marketing: marketing, timestamp: new Date().toISOString(), version: '1' }); setCookie(COOKIE_NAME, consent, COOKIE_MAX_AGE); // Push consent event for GTM window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'consent_update', 'consent_analytics': analytics, 'consent_marketing': marketing }); // Notify other scripts (e.g. Clarity gating) of consent change window.dispatchEvent(new CustomEvent('fervor:consent-updated', { detail: { analytics: analytics, marketing: marketing } })); } var banner = document.getElementById('fervor-consent-banner'); function showBanner() { if (!banner) return; banner.style.display = ''; requestAnimationFrame(function() { requestAnimationFrame(function() { banner.setAttribute('data-visible', ''); }); }); } function hideBanner() { if (!banner) return; banner.removeAttribute('data-visible'); setTimeout(function() { banner.style.display = 'none'; }, 350); } // Always wire the buttons so the banner works whether it auto-shows or is // re-opened later via the "Manage Cookies" control. // Accept: grant analytics, deny marketing (no ads yet). var acceptBtn = document.getElementById('consent-accept'); if (acceptBtn) acceptBtn.addEventListener('click', function() { updateConsent(true, false); hideBanner(); }); // Reject: deny everything. var rejectBtn = document.getElementById('consent-reject'); if (rejectBtn) rejectBtn.addEventListener('click', function() { updateConsent(false, false); hideBanner(); }); // Expose a manual opener for the always-available "Manage Cookies" footer // link. This is how US (granted-by-default) visitors opt OUT, and how any // visitor revisits their choice. window.fervorOpenConsent = showBanner; document.addEventListener('click', function(e) { var t = e.target && e.target.closest ? e.target.closest('[data-manage-cookies]') : null; if (t) { e.preventDefault(); showBanner(); } }); // Check for existing consent var existing = getCookie(COOKIE_NAME); if (existing) { try { var parsed = JSON.parse(existing); // Restore consent state from cookie if (typeof gtag === 'function') { gtag('consent', 'update', { 'analytics_storage': parsed.analytics ? 'granted' : 'denied', 'ad_storage': parsed.marketing ? 'granted' : 'denied', 'ad_user_data': parsed.marketing ? 'granted' : 'denied', 'ad_personalization': parsed.marketing ? 'granted' : 'denied' }); } } catch(e) {} // User already chose — never auto-show (still reachable via Manage Cookies). return; } // No explicit choice yet. Auto-show ONLY when the geo-resolved Consent Mode // default is 'denied' (GDPR/UK/CH/PIPEDA+Law 25/LGPD, or GPC set). In // non-restrictive opt-out jurisdictions (e.g. US) the default is 'granted' // and the banner stays hidden — those visitors opt out via Manage Cookies. if (window.__fervorConsentResolved !== 'granted') { showBanner(); } })(); </script> <!-- Scroll Progress Bar --> <div id="scroll-progress" aria-hidden="true"></div> <!-- Site entrance + page transition doors --> <!-- Runs once per hard page load. SPA navigation handled by the persistent listeners. --> <script> (function() { // Guard: only run this initialization ONCE per browser session (not per SPA nav) if (window.__fervorEntranceInit) return; window.__fervorEntranceInit = true; var el = document.querySelector('.site-entrance'); if (!el) return; // ── Initial page load (hard load, not SPA) ── var isHomepage = location.pathname === '/' || location.pathname === '/index.html'; var hasSeenLogo = sessionStorage.getItem('entrance-logo-shown'); if (isHomepage && !hasSeenLogo) { sessionStorage.setItem('entrance-logo-shown', '1'); el.classList.add('entrance--show-logo'); setTimeout(function() { el.classList.remove('entrance--show-logo'); }, 600); setTimeout(function() { el.classList.add('entrance--open'); }, 800); setTimeout(function() { el.classList.add('entrance-done'); }, 1200); } else { setTimeout(function() { el.classList.add('entrance--open'); }, 50); setTimeout(function() { el.classList.add('entrance-done'); }, 180); } // ── Page transition handlers, registered ONCE, persist across SPA nav ── document.addEventListener('astro:before-preparation', function(e) { if (!e.loader) return; var originalLoader = e.loader; var fetchPromise = originalLoader(); e.loader = function() { return new Promise(function(resolve) { var persistedEl = document.querySelector('.site-entrance'); if (!persistedEl) { fetchPromise.then(resolve); return; } // Start in OPEN state (doors off-screen, element visible) persistedEl.classList.add('entrance--no-transition'); persistedEl.classList.add('entrance--open'); persistedEl.classList.remove('entrance-done'); // Wait TWO frames: one for display change to commit, one for transform snap requestAnimationFrame(function() { requestAnimationFrame(function() { // Re-enable transitions and trigger close persistedEl.classList.remove('entrance--no-transition'); persistedEl.classList.remove('entrance--open'); // Wait for close animation (180ms) AND fetch to resolve var closeDone = new Promise(function(r) { setTimeout(r, 190); }); Promise.all([fetchPromise, closeDone]).then(resolve); }); }); }); }; }); document.addEventListener('astro:before-swap', function() { window.scrollTo(0, 0); }); document.addEventListener('astro:after-swap', function() { var persistedEl = document.querySelector('.site-entrance'); if (!persistedEl) return; // Ensure classes are reset to "closed" state (strip any stale classes) persistedEl.classList.remove('entrance--open', 'entrance-done', 'entrance--show-logo'); // Force reflow so the browser commits the "closed" state before we transition to open void persistedEl.offsetHeight; // Now open persistedEl.classList.add('entrance--open'); setTimeout(function() { persistedEl.classList.add('entrance-done'); }, 130); }); })(); </script> <!-- Animation Engine, scroll-triggered WAAPI reveals --> <script type="module" src="/_astro/BaseLayout.astro_astro_type_script_index_0_lang.9ykzOiuK.js"></script> <!-- Header shrink on scroll --> <script type="module">(function(){function t(){var e=document.querySelector(".site-header");if(!e)return;e.classList.remove("header--hidden");var n=!1,a=!1;function s(){var r=window.scrollY;r>80&&!n?(e.classList.add("header--shrunk"),n=!0):r<=40&&n&&(e.classList.remove("header--shrunk"),n=!1),a=!1}window.addEventListener("scroll",function(){a||(requestAnimationFrame(s),a=!0)},{passive:!0})}document.addEventListener("astro:page-load",t),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t):t()})();</script> <!-- Number counter animation for CRO index stats, teardown scores --> <script type="module">(function(){if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;function c(){var n=[];if(document.querySelectorAll(".idx-stat__num, .idx-stats__callout-num").forEach(function(t){n.push(t)}),document.querySelectorAll(".td-cover__score-num").forEach(function(t){n.push(t)}),document.querySelectorAll("[data-counter]").forEach(function(t){n.push(t)}),document.querySelectorAll(".counter-number").forEach(function(t){n.push(t)}),!n.length)return;n.forEach(function(t){t.hasAttribute("data-counter-raw")||t.setAttribute("data-counter-raw",(t.textContent||"").trim())});var s=new Set;function w(t){var e=t.getAttribute("data-counter-raw"),r=e??(t.textContent||""),a=r.match(/^([^0-9.-]*)(-?[\d,.]+)(.*)$/);if(!a)return{value:0,prefix:"",suffix:"",decimals:0};var o=a[1]||"",i=a[2].replace(/,/g,""),f=a[3]||"",u=parseFloat(i),m=i.includes(".")?i.split(".")[1].length:0;return{value:u,prefix:o,suffix:f,decimals:m}}function l(t,e){var r=t.toFixed(e).split(".");return r[0]=r[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),r.join(".")}function x(t){return 1-Math.pow(1-t,3)}function A(t){if(s.has(t)||t.dataset.counted==="1")return;s.add(t),t.dataset.counted="1";var e=w(t);if(e.value===0)return;var r=800,a=performance.now();function o(i){var f=i-a,u=Math.min(f/r,1),m=x(u),E=e.value*m;t.textContent=e.prefix+l(E,e.decimals)+e.suffix,u<1?requestAnimationFrame(o):t.textContent=e.prefix+l(e.value,e.decimals)+e.suffix}requestAnimationFrame(o)}var v=window.innerHeight,d=!1,h=n.length;function p(){v=window.innerHeight;for(var t=0;t<n.length;t++){var e=n[t];if(!s.has(e)){var r=e.getBoundingClientRect();r.top<v*.85&&r.bottom>0&&(A(e),h--)}}h<=0&&window.removeEventListener("scroll",g),d=!1}function g(){d||(requestAnimationFrame(p),d=!0)}window.addEventListener("scroll",g,{passive:!0}),requestAnimationFrame(function(){requestAnimationFrame(p)})}document.addEventListener("astro:page-load",c),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",c):c()})();</script> <!-- Ripple Effect, subtle click feedback on [data-ripple] elements --> <script type="module">function c(t,e,n){const i=t.getBoundingClientRect(),d=e-i.left,s=n-i.top,o=Math.max(i.width,i.height)*2,r=document.createElement("span");r.style.cssText=` position: absolute; border-radius: 50%; background: currentColor; opacity: 0.1; width: ${o}px; height: ${o}px; left: ${d-o/2}px; top: ${s-o/2}px; transform: scale(0); pointer-events: none; z-index: 10; `,t.appendChild(r);const p=r.animate([{transform:"scale(0)",opacity:"0.1"},{transform:"scale(1)",opacity:"0"}],{duration:400,easing:"cubic-bezier(0.16, 1, 0.3, 1)",fill:"forwards"});p.onfinish=()=>r.remove()}function a(){document.addEventListener("click",t=>{const e=t.target.closest("[data-ripple]");e&&(window.matchMedia("(prefers-reduced-motion: reduce)").matches||c(e,t.clientX,t.clientY))}),document.addEventListener("touchstart",t=>{const e=t.touches[0];if(!e)return;const n=e.target.closest("[data-ripple]");n&&(window.matchMedia("(prefers-reduced-motion: reduce)").matches||c(n,e.clientX,e.clientY))},{passive:!0})}typeof document<"u"&&(document.addEventListener("astro:page-load",a),document.readyState==="complete"||document.readyState==="interactive"?a():document.addEventListener("DOMContentLoaded",a));</script> <!-- Scroll Progress Bar, shows reading position on long pages --> <script type="module">function n(){const e=document.getElementById("scroll-progress");if(!e)return;if(window.matchMedia("(prefers-reduced-motion: reduce)").matches){e.style.display="none";return}const s=document.documentElement.scrollHeight,d=window.innerHeight;if(s<d*1.5){e.style.display="none";return}e.style.display="block";let t=!1;function o(){const i=window.scrollY||document.documentElement.scrollTop,r=document.documentElement.scrollHeight-window.innerHeight,c=r>0?i/r*100:0;e.style.width=`${c}%`,e.style.opacity=i>50?"1":"0",t=!1}window.addEventListener("scroll",()=>{t||(requestAnimationFrame(o),t=!0)},{passive:!0}),o()}typeof document<"u"&&(document.addEventListener("astro:page-load",n),document.readyState==="complete"||document.readyState==="interactive"?n():document.addEventListener("DOMContentLoaded",n));</script> <!-- ── Custom Scroll Depth Tracking ── Replaces GA4 Enhanced Measurement scroll (which only fires at 90%). Fires at 25%, 50%, 75%, 100% with time-on-page context. --> <script> (function() { var milestones = [25, 50, 75, 100]; var fired = {}; var pageLoadTime = Date.now(); function getScrollPercent() { var h = document.documentElement; var b = document.body; var st = h.scrollTop || b.scrollTop; var sh = h.scrollHeight || b.scrollHeight; var ch = h.clientHeight; if (sh <= ch) return 100; return Math.round((st / (sh - ch)) * 100); } function checkScroll() { var pct = getScrollPercent(); for (var i = 0; i < milestones.length; i++) { var m = milestones[i]; if (pct >= m && !fired[m]) { fired[m] = true; window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'scroll_milestone', 'percent_scrolled': m, 'time_on_page_seconds': Math.round((Date.now() - pageLoadTime) / 1000) }); } } } // Throttled scroll listener var ticking = false; window.addEventListener('scroll', function() { if (!ticking) { window.requestAnimationFrame(function() { checkScroll(); ticking = false; }); ticking = true; } }, { passive: true }); // Handle View Transitions, reset scroll tracking on client-side nav document.addEventListener('astro:page-load', function() { fired = {}; pageLoadTime = Date.now(); }); })(); </script> <!-- ── View Transitions: Virtual Pageview ── Astro ClientRouter makes navigation SPA-like. Push a virtual pageview event on each client-side navigation so GA4 captures all page views, not just the initial load. --> <script> document.addEventListener('astro:page-load', function() { window.dataLayer = window.dataLayer || []; // Don't fire on initial page load (GTM handles that via page_view) if (window.__fervor_initial_load) { window.dataLayer.push({ 'event': 'virtual_pageview', 'page_path': window.location.pathname, 'page_title': document.title }); } window.__fervor_initial_load = true; }); </script> <!-- ── Interaction events + click-ID persistence ── One delegated capture-phase listener for booking_initiated / affiliate_click / spoke_navigation (Simo Ahava: action purity, one event per push). Click identifiers (gclid, fbclid, ttclid, msclkid, ScCid) persist to a first-party cookie so paid-traffic attribution survives past the landing session. Identifier names and values are case-sensitive: never normalize them. --> <script> (function() { var CLICK_IDS = ['gclid', 'fbclid', 'ttclid', 'msclkid', 'ScCid']; try { var params = new URLSearchParams(window.location.search); var found = {}; var any = false; for (var i = 0; i < CLICK_IDS.length; i++) { var v = params.get(CLICK_IDS[i]); if (v) { found[CLICK_IDS[i]] = v; any = true; } } if (any) { var existing = {}; var m = document.cookie.match(/(^| )fervor_click_ids=([^;]+)/); if (m) { try { existing = JSON.parse(decodeURIComponent(m[2])); } catch (e) {} } for (var k in found) { existing[k] = found[k]; } existing._ts = new Date().toISOString(); document.cookie = 'fervor_click_ids=' + encodeURIComponent(JSON.stringify(existing)) + '; path=/; max-age=7776000; SameSite=Lax; Secure'; } } catch (e) {} function push(ev) { window.dataLayer = window.dataLayer || []; window.dataLayer.push(ev); } document.addEventListener('click', function(e) { var el = e.target; if (!el || !el.closest) return; // booking_initiated — Cal.com embed triggers AND plain cal.com links // (the homepage books via a plain href, not the embed) var cal = el.closest('[data-cal-link]'); var calLink = cal ? null : el.closest('a[href*="cal.com/"]'); if (cal || calLink) { var serviceType = ''; if (cal) { serviceType = cal.getAttribute('data-cal-link') || ''; } else { try { serviceType = new URL(calLink.href).pathname.replace(/^\//, ''); } catch (err) {} } push({ 'event': 'booking_initiated', 'service_type': serviceType, 'page_path': window.location.pathname }); return; } // affiliate_click — explicitly marked affiliate links only var aff = el.closest('a[data-affiliate], a[rel~="sponsored"]'); if (aff) { var affHost = ''; try { affHost = new URL(aff.href).hostname; } catch (err) {} push({ 'event': 'affiliate_click', 'affiliate_name': aff.getAttribute('data-affiliate') || affHost, 'link_url': aff.href || '' }); return; } // spoke_navigation — hub page → trade spoke click var page = window.__fervorPage || {}; if (page.page_type !== 'hub') return; var a = el.closest('a[href]'); if (!a) return; var href = a.getAttribute('href') || ''; var spoke = href.match(/^\/contractor\/([a-z0-9-]+)\/([a-z0-9-]+)\/$/); if (spoke) { push({ 'event': 'spoke_navigation', 'from_hub': window.location.pathname, 'to_spoke': href, 'contractor_type': spoke[2] }); } }, { capture: true, passive: true }); })(); </script> <script> if (window.innerWidth <= 768) { document.addEventListener('DOMContentLoaded', function() { function floorPass(selector, minPx) { var els = document.querySelectorAll(selector); var toBump = []; // Read phase: no writes, so getComputedStyle reuses one recalc. for (var i = 0; i < els.length; i++) { if (parseFloat(getComputedStyle(els[i]).fontSize) < minPx) toBump.push(els[i]); } // Write phase: batched after all reads. for (var j = 0; j < toBump.length; j++) { toBump[j].style.setProperty('font-size', minPx + 'px', 'important'); } } function run() { // Tier 1: citations/sources get a 16px floor. Runs first so the // general pass below reads their already-applied size and leaves them. floorPass('[class*="source"],[class*="cite"],[class*="citation"],[class*="context"]', 16); // Tier 2: everything else gets a 14px minimum. floorPass('p,span,a,li,td,th,label,input,select,textarea,button,figcaption,cite,blockquote,dt,dd,summary,small', 14); } // Push past first paint so the floor never sits on the LCP critical path. if (window.requestAnimationFrame) requestAnimationFrame(function () { requestAnimationFrame(run); }); else run(); }); } </script> </body> </html>