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 C (Conditional)
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 infrastructure 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 infrastructure. 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 Site 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 Site 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> <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/capable-group-inc/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Capable Group Inc. (86/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/garage-living/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Garage Living (86/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/n-hance/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>N-Hance (85/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/dfw-improved/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>DFW Improved (85/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/murray-lampert/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Murray Lampert Design Build Remodel (85/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/trademark-renovations/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Trademark Renovations (85/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/floor-coverings-international/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Floor Coverings International (84/100)</a> </li><li data-astro-cid-7o3n3qur> <a href="/contractor/cro-index/eatgatherlove/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>EatGatherLove (84/100)</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>Trade Guide</span> <button class="guides-sidebar__toggle" aria-expanded="false" aria-label="Toggle Trade Guide" 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/interior/remodeling/" class="guides-sidebar__link" data-astro-cid-7o3n3qur>Remodeling Contractor Guide</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> <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/capable-group-inc/" data-astro-cid-7o3n3qur>Capable Group Inc. (86/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/garage-living/" data-astro-cid-7o3n3qur>Garage Living (86/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/n-hance/" data-astro-cid-7o3n3qur>N-Hance (85/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/dfw-improved/" data-astro-cid-7o3n3qur>DFW Improved (85/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/murray-lampert/" data-astro-cid-7o3n3qur>Murray Lampert Design Build Remodel (85/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/trademark-renovations/" data-astro-cid-7o3n3qur>Trademark Renovations (85/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/floor-coverings-international/" data-astro-cid-7o3n3qur>Floor Coverings International (84/100)</a></li><li data-astro-cid-7o3n3qur><a href="/contractor/cro-index/eatgatherlove/" data-astro-cid-7o3n3qur>EatGatherLove (84/100)</a></li> </ul> </div><div class="guides-sidebar-mobile__card" data-astro-cid-7o3n3qur> <h3 data-astro-cid-7o3n3qur> <span data-astro-cid-7o3n3qur>Trade Guide</span> </h3> <ul data-astro-cid-7o3n3qur> <li data-astro-cid-7o3n3qur><a href="/contractor/interior/remodeling/" data-astro-cid-7o3n3qur>Remodeling Contractor Guide</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 doing $500K to $5M. </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/local-dominance-setup/" class data-astro-cid-sz7xmlte> Local Dominance Setup </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="/services/contractor-growth-engine/" class data-astro-cid-sz7xmlte> Growth Engine </a> </li><li data-astro-cid-sz7xmlte> <a href="/services/content-starter-pack/" class data-astro-cid-sz7xmlte> Content Starter Pack </a> </li><li data-astro-cid-sz7xmlte> <a href="/services/review-velocity-boost/" class data-astro-cid-sz7xmlte> Review Velocity Boost </a> </li><li data-astro-cid-sz7xmlte> <a href="/services/priority-build/" class data-astro-cid-sz7xmlte> Priority Build </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/" 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> </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> <span class="ft__dot" aria-hidden="true" data-astro-cid-sz7xmlte>·</span> <a href="/privacy/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Privacy Policy</a> <span class="ft__dot" aria-hidden="true" data-astro-cid-sz7xmlte>·</span> <a href="/terms/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Terms of Service</a> <span class="ft__dot" aria-hidden="true" data-astro-cid-sz7xmlte>·</span> <a href="/cookies/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Cookie Policy</a> <span class="ft__dot" aria-hidden="true" data-astro-cid-sz7xmlte>·</span> <a href="/accessibility/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Accessibility</a> <span class="ft__dot" aria-hidden="true" data-astro-cid-sz7xmlte>·</span> <a href="/affiliate-disclosure/" class="ft__bottom-link" data-astro-cid-sz7xmlte>Affiliate Disclosure</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 ── --> <a href="/site-inspection/" class="sticky-mobile-cta" 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 } })); } // 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) {} // Don't show banner, user already chose return; } // Show banner (no existing consent) var banner = document.getElementById('fervor-consent-banner'); if (banner) { banner.style.display = ''; requestAnimationFrame(function() { requestAnimationFrame(function() { banner.setAttribute('data-visible', ''); }); }); } // Accept: grant analytics, deny marketing (no ads yet) var acceptBtn = document.getElementById('consent-accept'); if (acceptBtn) { acceptBtn.addEventListener('click', function() { updateConsent(true, false); if (banner) { banner.removeAttribute('data-visible'); setTimeout(function() { banner.style.display = 'none'; }, 350); } }); } // Reject: deny everything var rejectBtn = document.getElementById('consent-reject'); if (rejectBtn) { rejectBtn.addEventListener('click', function() { updateConsent(false, false); if (banner) { banner.removeAttribute('data-visible'); setTimeout(function() { banner.style.display = 'none'; }, 350); } }); } })(); </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.DSEUMZ1R.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 o(){var r=[];if(document.querySelectorAll(".td-cover__score-num").forEach(function(e){r.push(e)}),document.querySelectorAll("[data-counter]").forEach(function(e){r.push(e)}),document.querySelectorAll(".counter-number").forEach(function(e){r.push(e)}),!r.length)return;var u=new Set;function g(e){var t=e.textContent||"",n=t.match(/^([^0-9.-]*)(-?[\d,.]+)(.*)$/);if(!n)return{value:0,prefix:"",suffix:"",decimals:0};var s=n[1]||"",a=n[2].replace(/,/g,""),f=n[3]||"",d=parseFloat(a),i=a.includes(".")?a.split(".")[1].length:0;return{value:d,prefix:s,suffix:f,decimals:i}}function l(e,t){var n=e.toFixed(t).split(".");return n[0]=n[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),n.join(".")}function w(e){return 1-Math.pow(1-e,3)}function x(e){if(u.has(e))return;u.add(e);var t=g(e);if(t.value===0)return;var n=800,s=performance.now();function a(f){var d=f-s,i=Math.min(d/n,1),q=w(i),A=t.value*q;e.textContent=t.prefix+l(A,t.decimals)+t.suffix,i<1?requestAnimationFrame(a):e.textContent=t.prefix+l(t.value,t.decimals)+t.suffix}requestAnimationFrame(a)}var m=window.innerHeight,c=!1,v=r.length;function p(){m=window.innerHeight;for(var e=0;e<r.length;e++){var t=r[e];if(!u.has(t)){var n=t.getBoundingClientRect();n.top<m*.85&&n.bottom>0&&(x(t),v--)}}v<=0&&window.removeEventListener("scroll",h),c=!1}function h(){c||(requestAnimationFrame(p),c=!0)}window.addEventListener("scroll",h,{passive:!0}),requestAnimationFrame(function(){requestAnimationFrame(p)})}document.addEventListener("astro:page-load",o),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",o):o()})();</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> <script> if (window.innerWidth <= 768) { document.addEventListener('DOMContentLoaded', function() { // Tier: citations/sources get 16px floor var citeEls = document.querySelectorAll('[class*="source"],[class*="cite"],[class*="citation"],[class*="context"]'); for (var c = 0; c < citeEls.length; c++) { var cfs = parseFloat(getComputedStyle(citeEls[c]).fontSize); if (cfs < 16) citeEls[c].style.setProperty('font-size', '16px', 'important'); } // Floor: everything else gets 14px minimum var els = document.querySelectorAll('p,span,a,li,td,th,label,input,select,textarea,button,figcaption,cite,blockquote,dt,dd,summary,small'); for (var i = 0; i < els.length; i++) { var fs = parseFloat(getComputedStyle(els[i]).fontSize); if (fs < 14) els[i].style.setProperty('font-size', '14px', 'important'); } }); } </script> </body> </html>