Implements the revised website enhancement requirements: - Light, clean Apple-style layout (system font stack, pill buttons, generous whitespace) with a dark AI showcase section - SEO foundation: meta description, Open Graph, Twitter Card, and JSON-LD (SoftwareApplication, Organization, FAQPage) - Native HTML pricing tiers (Starter $29 / Professional $79 / Enterprise custom) with monthly-annual toggle, replacing the uncrawlable iframe; pulled from app.hoaledgeriq.com/pricing - New sections: How It Works (3 steps), trust bar, FAQ accordion, spreadsheet comparison table, closing CTA - Mobile hamburger menu (nav previously disappeared under 640px) - Pillar pages surfaced in footer (investment, reserve studies, assessment calculator) - Performance: deferred Chatwoot load, image dimensions, preload hints, no blocking webfont - Accessibility: skip link, aria states, prefers-reduced-motion - ROI calculator preserved (same IDs/handlers in app.js); new v2.js for hamburger, billing toggle, section highlighting, GA4 events - Legacy article styles retained so Insights pages keep working Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
134 lines
5.0 KiB
JavaScript
134 lines
5.0 KiB
JavaScript
/* HOA LedgerIQ — V2 site behaviors
|
|
Mobile nav, billing toggle, secondary calc trigger,
|
|
active-section nav highlighting, GA4 events. */
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
// ── Mobile hamburger nav ────────────────────────────────
|
|
var toggle = document.getElementById('navToggle');
|
|
var links = document.getElementById('navLinks');
|
|
|
|
if (toggle && links) {
|
|
toggle.addEventListener('click', function () {
|
|
var open = links.classList.toggle('open');
|
|
toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
toggle.setAttribute('aria-label', open ? 'Close navigation menu' : 'Open navigation menu');
|
|
});
|
|
|
|
// Close the panel when a link is chosen
|
|
links.addEventListener('click', function (e) {
|
|
if (e.target.tagName === 'A') {
|
|
links.classList.remove('open');
|
|
toggle.setAttribute('aria-expanded', 'false');
|
|
}
|
|
});
|
|
|
|
// Close on Escape
|
|
document.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape' && links.classList.contains('open')) {
|
|
links.classList.remove('open');
|
|
toggle.setAttribute('aria-expanded', 'false');
|
|
toggle.focus();
|
|
}
|
|
});
|
|
}
|
|
|
|
// ── Second calculator trigger (footer CTA) ─────────────
|
|
var calc2 = document.getElementById('openCalc2');
|
|
var overlay = document.getElementById('calcOverlay');
|
|
if (calc2 && overlay) {
|
|
calc2.addEventListener('click', function () {
|
|
overlay.classList.add('open');
|
|
document.body.style.overflow = 'hidden';
|
|
if (window.gtag) {
|
|
gtag('event', 'calculator_open', { event_category: 'engagement', event_label: 'CTA section' });
|
|
}
|
|
});
|
|
}
|
|
|
|
// ── Billing interval toggle ─────────────────────────────
|
|
var billingOpts = document.querySelectorAll('.billing-opt');
|
|
billingOpts.forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
var interval = btn.dataset.billing; // 'month' | 'year'
|
|
|
|
billingOpts.forEach(function (b) {
|
|
b.classList.toggle('is-active', b === btn);
|
|
b.setAttribute('aria-selected', b === btn ? 'true' : 'false');
|
|
});
|
|
|
|
document.querySelectorAll('.price-num[data-monthly]').forEach(function (el) {
|
|
var val = interval === 'year' ? el.dataset.annual : el.dataset.monthly;
|
|
el.textContent = '$' + val;
|
|
});
|
|
document.querySelectorAll('.price-per[data-monthly]').forEach(function (el) {
|
|
el.textContent = interval === 'year' ? el.dataset.annual : el.dataset.monthly;
|
|
});
|
|
|
|
if (window.gtag) {
|
|
gtag('event', 'billing_toggle', { event_category: 'engagement', event_label: interval });
|
|
}
|
|
});
|
|
});
|
|
|
|
// ── Active-section nav highlighting ─────────────────────
|
|
if ('IntersectionObserver' in window && links) {
|
|
var sectionIds = ['features', 'how', 'ai', 'pricing', 'faq'];
|
|
var navAnchors = {};
|
|
sectionIds.forEach(function (id) {
|
|
var a = links.querySelector('a[href="#' + id + '"]');
|
|
if (a) navAnchors[id] = a;
|
|
});
|
|
|
|
var observer = new IntersectionObserver(function (entries) {
|
|
entries.forEach(function (entry) {
|
|
var a = navAnchors[entry.target.id];
|
|
if (!a) return;
|
|
if (entry.isIntersecting) {
|
|
Object.keys(navAnchors).forEach(function (k) { navAnchors[k].classList.remove('is-active'); });
|
|
a.classList.add('is-active');
|
|
}
|
|
});
|
|
}, { rootMargin: '-40% 0px -55% 0px' });
|
|
|
|
sectionIds.forEach(function (id) {
|
|
var el = document.getElementById(id);
|
|
if (el) observer.observe(el);
|
|
});
|
|
}
|
|
|
|
// ── GA4: scroll depth + CTA clicks (lightweight) ───────
|
|
var fired = {};
|
|
window.addEventListener('scroll', function () {
|
|
var pct = Math.round((window.scrollY + window.innerHeight) / document.body.scrollHeight * 100);
|
|
[25, 50, 75].forEach(function (mark) {
|
|
if (pct >= mark && !fired[mark]) {
|
|
fired[mark] = true;
|
|
if (window.gtag) gtag('event', 'scroll_' + mark, { event_category: 'engagement' });
|
|
}
|
|
});
|
|
}, { passive: true });
|
|
|
|
document.querySelectorAll('a.btn-primary, #openCalc, #openCalc2, #calcSubmit').forEach(function (el) {
|
|
el.addEventListener('click', function () {
|
|
if (!window.gtag) return;
|
|
var label = (el.textContent || '').trim().substring(0, 50) || el.id;
|
|
gtag('event', 'cta_click', { event_category: 'conversion', event_label: label });
|
|
});
|
|
});
|
|
|
|
// ── GA4: FAQ engagement ─────────────────────────────────
|
|
document.querySelectorAll('.faq-item').forEach(function (item) {
|
|
item.addEventListener('toggle', function () {
|
|
if (item.open && window.gtag) {
|
|
var q = item.querySelector('summary');
|
|
gtag('event', 'faq_open', {
|
|
event_category: 'engagement',
|
|
event_label: q ? q.textContent.trim().substring(0, 60) : 'unknown'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
})();
|