From ba9ddee99d63513290fa173ce0283390f87c5cb0 Mon Sep 17 00:00:00 2001 From: olsch01 Date: Wed, 11 Mar 2026 09:49:18 -0400 Subject: [PATCH] Add interest income benefit calculator widget to hero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New "✦ Calculate Your Interest Income Potential" button between hero CTAs with gradient border styling distinct from primary/ghost buttons - Modal overlay collects: homesites, property type, annual dues + frequency, reserve fund balance, and 2025 actual interest income - Conservative calculation model: 4.0% HYSA for operating cash, 4.25% CD ladder for 65% of investable reserves; operating multiplier varies by payment frequency (monthly 10%, quarterly 20%, annual 35%) - Results screen shows animated dollar counter, operating vs reserve breakdown, AI-style narrative recommendation, and direct CTA to signup - Modal closes on backdrop click or Escape key; CTA closes modal and scrolls to early access signup form Co-Authored-By: Claude Sonnet 4.6 --- app.js | 118 +++++++++++++++++++++++++++++ index.html | 101 +++++++++++++++++++++++++ styles.css | 217 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 436 insertions(+) diff --git a/app.js b/app.js index 2c60ebe..eea282d 100644 --- a/app.js +++ b/app.js @@ -20,6 +20,124 @@ if (signupEl) signupEl.textContent = text; })(); +// ── Benefit Calculator ─────────────────────────────────── +(function initCalculator() { + const overlay = document.getElementById('calcOverlay'); + const openBtn = document.getElementById('openCalc'); + const closeBtn = document.getElementById('calcClose'); + const submitBtn = document.getElementById('calcSubmit'); + const recalcBtn = document.getElementById('calcRecalc'); + const calcForm = document.getElementById('calcForm'); + const calcRes = document.getElementById('calcResults'); + const calcErr = document.getElementById('calcError'); + const ctaBtn = document.getElementById('calcCTABtn'); + + if (!overlay) return; + + function open() { overlay.classList.add('open'); document.body.style.overflow = 'hidden'; } + function close() { overlay.classList.remove('open'); document.body.style.overflow = ''; } + + openBtn?.addEventListener('click', open); + closeBtn?.addEventListener('click', close); + overlay.addEventListener('click', e => { if (e.target === overlay) close(); }); + document.addEventListener('keydown', e => { if (e.key === 'Escape') close(); }); + + recalcBtn?.addEventListener('click', () => { + calcRes.classList.add('hidden'); + calcForm.classList.remove('hidden'); + }); + + // Close modal and scroll to signup when CTA clicked + ctaBtn?.addEventListener('click', () => { + close(); + }); + + submitBtn?.addEventListener('click', () => { + const homesites = parseFloat(document.getElementById('calcHomesites').value) || 0; + const propertyType = document.getElementById('calcPropertyType').value; + const annualIncome = parseFloat(document.getElementById('calcAnnualIncome').value) || 0; + const paymentFreq = document.getElementById('calcPaymentFreq').value; + const reserveFunds = parseFloat(document.getElementById('calcReserveFunds').value) || 0; + const interest2025 = parseFloat(document.getElementById('calcInterest2025').value) || 0; + + if (!homesites || !annualIncome) { + calcErr.classList.remove('hidden'); + return; + } + calcErr.classList.add('hidden'); + + // ── Conservative investment assumptions ── + // Operating cash: depending on payment frequency, portion investable in high-yield savings + const opMultiplier = { monthly: 0.10, quarterly: 0.20, annually: 0.35 }[paymentFreq] || 0.10; + const opRate = 0.040; // 4.0% money market / HYSA + const resRatio = 0.65; // 65% of reserves investable (keep 35% liquid) + const resRate = 0.0425; // 4.25% CD ladder / short-term treasuries + + const investableOp = annualIncome * opMultiplier; + const investableRes = reserveFunds * resRatio; + const opInterest = Math.round(investableOp * opRate); + const resInterest = Math.round(investableRes * resRate); + const totalPotential = opInterest + resInterest; + const increase = totalPotential - interest2025; + const pctIncrease = interest2025 > 0 + ? Math.round((increase / interest2025) * 100) + : (totalPotential > 0 ? 100 : 0); + + // ── Populate results ── + const fmt = n => '$' + Math.round(n).toLocaleString(); + + document.getElementById('resultAmount').textContent = fmt(totalPotential); + document.getElementById('resultCurrent').textContent = fmt(interest2025); + document.getElementById('resultOperating').textContent = fmt(opInterest); + document.getElementById('resultReserve').textContent = fmt(resInterest); + + const badge = document.getElementById('resultBadge'); + if (increase > 0) { + badge.textContent = `+${fmt(increase)} · +${pctIncrease}%`; + badge.style.display = 'inline-block'; + } else { + badge.style.display = 'none'; + } + + // ── AI-style suggestion text ── + const typeLabels = { sfh:'single-family home', townhomes:'townhome', condos:'condo', mixed:'mixed-use', '':'' }; + const typeLabel = typeLabels[propertyType] || ''; + const freqLabel = { monthly:'monthly', quarterly:'quarterly', annually:'annual' }[paymentFreq]; + const communityDesc = [homesites && `${homesites}-unit`, typeLabel, 'community'].filter(Boolean).join(' '); + + let ai = `Based on your ${communityDesc} collecting ${fmt(annualIncome)} in ${freqLabel} dues`; + if (reserveFunds > 0) ai += ` and ${fmt(reserveFunds)} in reserve funds`; + ai += `, a conservative investment strategy could generate approximately ${fmt(totalPotential)} in annual interest income. `; + if (resInterest > 0) ai += `Deploying ${fmt(investableRes)} of your reserve funds into a short-term CD ladder at ~4.25% yields ${fmt(resInterest)} annually. `; + if (opInterest > 0) ai += `Keeping a ${fmt(investableOp)} operating cash buffer in a high-yield money market at ~4.0% adds another ${fmt(opInterest)}. `; + if (interest2025 > 0 && increase > 0) { + ai += `That's a ${fmt(increase)} improvement (+${pctIncrease}%) over your 2025 interest income of ${fmt(interest2025)} — with no additional risk.`; + } else if (interest2025 === 0) { + ai += `This would represent entirely new interest income for your community at no additional risk.`; + } + + document.getElementById('calcAiText').textContent = ai; + + // ── Animate the main number ── + animateValue(document.getElementById('resultAmount'), 0, totalPotential); + + calcForm.classList.add('hidden'); + calcRes.classList.remove('hidden'); + }); + + function animateValue(el, from, to) { + const duration = 900; + const start = performance.now(); + function step(now) { + const progress = Math.min((now - start) / duration, 1); + const ease = 1 - Math.pow(1 - progress, 3); + el.textContent = '$' + Math.round(from + (to - from) * ease).toLocaleString(); + if (progress < 1) requestAnimationFrame(step); + } + requestAnimationFrame(step); + } +})(); + // ── Screenshot Carousel ────────────────────────────────── (function initCarousel() { const carousel = document.getElementById('screenshotCarousel'); diff --git a/index.html b/index.html index 4375105..c23efcb 100644 --- a/index.html +++ b/index.html @@ -63,6 +63,7 @@

Join the Preview List + See What's Inside ↓
@@ -428,6 +429,106 @@
+ + + diff --git a/styles.css b/styles.css index 08132ee..a243222 100644 --- a/styles.css +++ b/styles.css @@ -623,6 +623,223 @@ body { color: var(--gray-700); } +/* ---- Calculator CTA button ---- */ +.btn-calc { + background: linear-gradient(135deg, rgba(79,70,229,0.25), rgba(14,165,233,0.2)); + border: 1.5px solid rgba(99,102,241,0.6); + color: #c7d2fe; + position: relative; + overflow: hidden; +} +.btn-calc::before { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, rgba(79,70,229,0.4), rgba(14,165,233,0.3)); + opacity: 0; + transition: opacity 0.2s; +} +.btn-calc:hover { color: #fff; border-color: rgba(99,102,241,0.9); transform: translateY(-1px); box-shadow: 0 8px 28px rgba(79,70,229,0.3); } +.btn-calc:hover::before { opacity: 1; } +.btn-calc span, .btn-calc { position: relative; z-index: 1; } + +/* ---- Calculator Modal ---- */ +.calc-overlay { + position: fixed; + inset: 0; + background: rgba(0,0,0,0.75); + backdrop-filter: blur(6px); + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + padding: 24px; + opacity: 0; + pointer-events: none; + transition: opacity 0.25s ease; +} +.calc-overlay.open { + opacity: 1; + pointer-events: all; +} +.calc-modal { + background: var(--gray-800); + border: 1px solid rgba(99,102,241,0.35); + border-radius: var(--radius-lg); + padding: 44px 48px; + max-width: 700px; + width: 100%; + max-height: 90vh; + overflow-y: auto; + position: relative; + box-shadow: 0 0 80px rgba(79,70,229,0.25), var(--shadow-lg); + transform: translateY(16px); + transition: transform 0.25s ease; +} +.calc-overlay.open .calc-modal { transform: translateY(0); } +.calc-close { + position: absolute; + top: 16px; right: 20px; + background: none; + border: none; + color: var(--gray-500); + font-size: 26px; + cursor: pointer; + line-height: 1; + padding: 4px 8px; + border-radius: 6px; + transition: color 0.15s, background 0.15s; +} +.calc-close:hover { color: #fff; background: rgba(255,255,255,0.08); } +.calc-header { margin-bottom: 28px; } +.calc-header h2 { font-size: 26px; font-weight: 800; color: #fff; letter-spacing: -0.02em; margin-bottom: 8px; } +.calc-header p { font-size: 15px; color: var(--gray-400); } +.calc-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + margin-bottom: 8px; +} +.calc-field { display: flex; flex-direction: column; gap: 6px; } +.calc-field label { font-size: 13px; font-weight: 600; color: var(--gray-400); } +.calc-field input, +.calc-field select { + background: var(--gray-900); + border: 1px solid rgba(255,255,255,0.1); + border-radius: 8px; + padding: 11px 14px; + color: var(--gray-100); + font-size: 15px; + font-family: inherit; + width: 100%; + outline: none; + transition: border-color 0.15s; + -webkit-appearance: none; +} +.calc-field input:focus, +.calc-field select:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(37,99,235,0.2); } +.calc-field input::placeholder { color: var(--gray-700); } +.calc-field select { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2394a3b8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 14px center; + padding-right: 36px; +} +.calc-field select option { background: var(--gray-800); color: var(--gray-100); } +.input-prefix-wrap { position: relative; } +.input-prefix { + position: absolute; + left: 13px; + top: 50%; + transform: translateY(-50%); + color: var(--gray-600); + font-size: 15px; + font-weight: 600; + pointer-events: none; +} +.input-prefix-wrap input { padding-left: 28px; } +.calc-error { + color: #f87171; + font-size: 13px; + margin: 8px 0; + font-weight: 500; +} +.calc-submit-btn { width: 100%; justify-content: center; margin-top: 16px; } +.calc-fine { + font-size: 11px; + color: var(--gray-700); + text-align: center; + margin-top: 10px; + line-height: 1.5; +} + +/* ── Results ── */ +.result-highlight { + background: linear-gradient(135deg, rgba(79,70,229,0.18), rgba(14,165,233,0.12)); + border: 1px solid rgba(79,70,229,0.4); + border-radius: var(--radius); + padding: 28px; + text-align: center; + margin-bottom: 20px; +} +.result-label { + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--gray-500); + font-weight: 700; + margin-bottom: 10px; +} +.result-amount { + font-size: 52px; + font-weight: 900; + letter-spacing: -0.03em; + color: var(--green); + line-height: 1.1; + margin-bottom: 12px; +} +.result-comparison { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + flex-wrap: wrap; + font-size: 14px; + color: var(--gray-400); +} +.result-badge { + background: rgba(34,197,94,0.15); + border: 1px solid rgba(34,197,94,0.35); + color: var(--green); + padding: 3px 12px; + border-radius: 99px; + font-size: 13px; + font-weight: 700; + white-space: nowrap; +} +.result-breakdown { + background: rgba(255,255,255,0.03); + border: 1px solid rgba(255,255,255,0.07); + border-radius: var(--radius); + padding: 16px 20px; + margin-bottom: 20px; + display: flex; + flex-direction: column; + gap: 10px; +} +.result-row { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 14px; + color: var(--gray-400); +} +.result-row-val { font-weight: 700; color: var(--gray-200); } +.calc-ai-bubble { + background: rgba(79,70,229,0.12); + border: 1px solid rgba(79,70,229,0.3); + border-radius: var(--radius); + padding: 18px 20px; + margin-bottom: 24px; + font-size: 14px; + color: var(--gray-200); + line-height: 1.65; +} +.calc-ai-bubble .ai-label { + display: block; + font-size: 11px; + font-weight: 700; + color: #a5b4fc; + text-transform: uppercase; + letter-spacing: 0.06em; + margin-bottom: 8px; +} +.calc-cta { text-align: center; } +.calc-cta > p { color: var(--gray-400); font-size: 15px; margin-bottom: 16px; } +.calc-cta-btn { width: 100%; justify-content: center; margin-bottom: 12px; } +.calc-recalc { font-size: 14px; color: var(--gray-500); } +.calc-recalc:hover { color: var(--gray-200); } + /* ---- Screenshot Carousel ---- */ .screenshot-carousel { width: 100%;