From 484428d71f5b3ecb37811bcc493797c11c1e44af Mon Sep 17 00:00:00 2001 From: Deeman Date: Sat, 14 Feb 2026 02:36:33 +0100 Subject: [PATCH] redesign landing page: better teaser calc, value-focused CTAs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace toy-like sliders (rent/m², exit multiple) with more intuitive inputs (build cost per court, equity %). Replace outputs (annual revenue, equity IRR) with payback period and cash-on-cash return. Show model assumptions inline. Remove "free" messaging from all CTAs and meta tags, focus on the plan→suppliers→financing value chain instead. Co-Authored-By: Claude Opus 4.6 --- .../padelnomics/public/templates/landing.html | 159 +++++++----------- 1 file changed, 65 insertions(+), 94 deletions(-) diff --git a/padelnomics/src/padelnomics/public/templates/landing.html b/padelnomics/src/padelnomics/public/templates/landing.html index 730d016..a367c7b 100644 --- a/padelnomics/src/padelnomics/public/templates/landing.html +++ b/padelnomics/src/padelnomics/public/templates/landing.html @@ -3,9 +3,9 @@ {% block title %}Padelnomics - Padel Court Business Plan & ROI Calculator{% endblock %} {% block head %} - + - + @@ -122,7 +122,7 @@

Plan Your Padel Business
in Minutes, Not Months

- Model your padel court investment with 60+ variables, sensitivity analysis, and professional-grade projections. 100% free. + Model your padel court investment with 60+ variables, sensitivity analysis, and professional-grade projections.

@@ -147,16 +147,18 @@ 40%
- - - €4/m² + + + €30K
- - - 6.0x + + + 25%
+

Assumes €8/m² rent, 5% interest, 10-year loan, 300 m² per court

+
Total Investment
@@ -169,23 +171,23 @@
After debt service
-
Annual Revenue
-
-
Net of booking fees
+
Payback Period
+
+
Years to recover equity
-
Equity IRR
-
-
5-year hold
+
Cash-on-Cash
+
+
Annual return on equity
-

This is a simplified estimate. The full planner models 60+ variables with monthly cash flows, sensitivity analysis, and more.

+

Want the full picture? The planner models 60+ variables with monthly projections, sensitivity analysis, and connects you with court suppliers.

{% if user %} - Open Full Planner + Start Planning {% else %} - Unlock the Full Planner — Free + Create Your Plan {% endif %}
@@ -197,7 +199,7 @@
Plan
-

Model your padel hall investment with our free financial planner. CAPEX, operating costs, cash flow, returns, sensitivity analysis.

+

Model your padel hall investment with our financial planner. CAPEX, operating costs, cash flow, returns, sensitivity analysis.

Finance
@@ -261,11 +263,11 @@

Start Planning Today

-

No credit card. No paywall. Full access to every feature.

+

Start with your plan. Then get quotes from verified court suppliers and connect with financing partners.

{% if user %} - Open Planner + Start Planning {% else %} - Create Free Account + Create Your Plan {% endif %}
@@ -277,72 +279,53 @@ function tCalc() { var courts = +document.getElementById('tc-courts').value; var rate = +document.getElementById('tc-rate').value; var util = +document.getElementById('tc-util').value; - var rentSqm = +document.getElementById('tc-rent').value; - var exitMult = +document.getElementById('tc-exit').value; + var buildCost = +document.getElementById('tc-buildcost').value; + var equityPct = +document.getElementById('tc-equity').value; // Display slider values document.getElementById('tv-courts').textContent = courts; document.getElementById('tv-rate').innerHTML = '€' + rate + '/hr'; document.getElementById('tv-util').textContent = util + '%'; - document.getElementById('tv-rent').innerHTML = '€' + rentSqm + '/m\u00B2'; - document.getElementById('tv-exit').textContent = exitMult.toFixed(1) + 'x'; + document.getElementById('tv-buildcost').innerHTML = '€' + Math.round(buildCost / 1000) + 'K'; + document.getElementById('tv-equity').textContent = equityPct + '%'; - // Simplified model (rent model, indoor, all double courts) - var sqmPerCourt = 300; // court + shared space - var totalSqm = courts * sqmPerCourt; - var courtCost = courts * 25000; - var capex = courtCost + 60000 + 80000 + 40000 + 100000 + 50000; // elec + sanitary + fitout + planning + parking + // CAPEX: build cost per court is the main driver + var capex = courts * buildCost; + + // Financing: equity % from slider, remainder is debt + // Assumes 5% interest, 10-year amortizing loan + var iRate = 0.05, term = 10; + var equity = capex * (equityPct / 100); + var debt = capex - equity; + var mRate = iRate / 12; + var nPay = term * 12; + var pmt = debt > 0 ? debt * mRate / (1 - Math.pow(1 + mRate, -nPay)) : 0; // Revenue + // Assumes 16 bookable hours/day, 29 days/month, off-peak rate = 65% of peak var hoursDay = 16, daysMonth = 29; var availHours = courts * hoursDay * daysMonth; var bookedHours = availHours * (util / 100); - var offPeakRate = rate * 0.65; - var wRate = rate * 0.4 + offPeakRate * 0.6; - var courtRev = bookedHours * wRate; - var netRev = courtRev * 0.9; // 10% booking fee + var peakShare = 0.4; + var wRate = rate * peakShare + rate * 0.65 * (1 - peakShare); + var grossRev = bookedHours * wRate; + var netRev = grossRev * 0.9; // 10% booking platform fee // Operating costs - var rent = totalSqm * rentSqm; - var opex = rent + courts * 400 + 350; // utilities/maint per court + marketing + // Assumes €8/m² rent (300 m² per court), €400/court utilities, €350 marketing + var rent = courts * 300 * 8; + var opex = rent + courts * 400 + 350; - // EBITDA + // Monthly cash flow after debt service var ebitda = netRev - opex; - - // Financing (85% LTV, 5%, 10yr) - var loanPct = 0.85, iRate = 0.05, term = 10; - var debt = capex * loanPct; - var equity = capex - debt; - var mRate = iRate / 12; - var nPay = term * 12; - var pmt = debt * mRate / (1 - Math.pow(1 + mRate, -nPay)); var netCF = ebitda - pmt; - // Annual figures - var annualRev = netRev * 12; + // Payback period: years to recover equity from annual net cash flow var annualCF = netCF * 12; + var payback = annualCF > 0 ? equity / annualCF : Infinity; - // IRR approximation (Newton's method, 5yr hold) - var hold = 5; - var y3ebitda = ebitda * 12; - var exitVal = y3ebitda * exitMult; - var cfs = [-equity]; - for (var y = 1; y <= hold; y++) { - var cf = annualCF; - if (y === hold) cf += exitVal - debt * Math.pow((1 + mRate), 12 * hold - 12 * hold); // simplified: remaining debt ~ original for short holds - // Simplified: remaining debt after Y years - var remDebt = 0; - if (y === hold) { - // Outstanding balance after hold*12 payments - var paid = hold * 12; - remDebt = debt * Math.pow(1 + mRate, paid) - pmt * (Math.pow(1 + mRate, paid) - 1) / mRate; - if (remDebt < 0) remDebt = 0; - cf = annualCF + exitVal - remDebt; - } - cfs.push(cf); - } - - var irr = calcIRR(cfs); + // Cash-on-cash return: annual net CF / equity invested + var coc = equity > 0 ? annualCF / equity : 0; // Format outputs var fmt = function(n) { return (n >= 0 ? '' : '-') + '\u20AC' + Math.abs(Math.round(n)).toLocaleString('de-DE'); }; @@ -353,35 +336,23 @@ function tCalc() { cfEl.innerHTML = fmt(netCF); cfEl.className = 'tm-value ' + (netCF >= 0 ? 'tm-green' : 'tm-red'); - document.getElementById('tr-rev').innerHTML = fmt(annualRev); - - var irrEl = document.getElementById('tr-irr'); - if (irr !== null && isFinite(irr)) { - irrEl.textContent = (irr * 100).toFixed(1) + '%'; - irrEl.className = 'tm-value ' + (irr >= 0 ? 'tm-green' : 'tm-red'); + var pbEl = document.getElementById('tr-payback'); + if (payback > 0 && payback <= 30) { + pbEl.textContent = payback.toFixed(1) + 'yr'; + pbEl.className = 'tm-value ' + (payback <= 5 ? 'tm-blue' : 'tm-navy'); } else { - irrEl.innerHTML = '—'; - irrEl.className = 'tm-value tm-navy'; + pbEl.innerHTML = '—'; + pbEl.className = 'tm-value tm-red'; } -} -function calcIRR(cfs) { - // Newton-Raphson IRR solver - var guess = 0.15; - for (var i = 0; i < 100; i++) { - var npv = 0, dnpv = 0; - for (var t = 0; t < cfs.length; t++) { - var f = Math.pow(1 + guess, t); - npv += cfs[t] / f; - if (t > 0) dnpv -= t * cfs[t] / (f * (1 + guess)); - } - if (Math.abs(dnpv) < 1e-10) break; - var next = guess - npv / dnpv; - if (Math.abs(next - guess) < 1e-7) return next; - guess = next; - if (guess < -0.99 || guess > 10) return null; + var cocEl = document.getElementById('tr-coc'); + if (isFinite(coc)) { + cocEl.textContent = (coc * 100).toFixed(1) + '%'; + cocEl.className = 'tm-value ' + (coc >= 0 ? 'tm-green' : 'tm-red'); + } else { + cocEl.innerHTML = '—'; + cocEl.className = 'tm-value tm-navy'; } - return guess; } // Run on load