Files
HOALedgerIQ_Website/v2.js
olsch01 86a80deaf8 V2 site: Apple-inspired redesign with SEO, native pricing, FAQ, and mobile nav
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>
2026-06-09 20:08:59 -04:00

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'
});
}
});
});
})();