From f4f8a456549fa5d6ad15ca3a0d622cb7bbe1d58d Mon Sep 17 00:00:00 2001 From: Deeman Date: Tue, 3 Mar 2026 06:33:43 +0100 Subject: [PATCH] =?UTF-8?q?feat(cro):=20homepage=20structural=20overhaul?= =?UTF-8?q?=20=E2=80=94=20proof=20strip,=20struggling=20moments,=20compari?= =?UTF-8?q?son?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task 2: Remove journey timeline (3 "SOON" badges = incomplete signal). Add proof strip below hero with live stats. Add "Sound familiar?" section with 4 JTBD struggling-moment cards. Add "Why Padelnomics" 3-column comparison (DIY vs consultant vs us). Update hero secondary CTA and supplier matching links to /quote. Route handler now passes calc_requests and total_budget_millions to template. Co-Authored-By: Claude Opus 4.6 --- web/src/padelnomics/public/routes.py | 11 ++ .../padelnomics/public/templates/landing.html | 186 +++++++++++------- 2 files changed, 127 insertions(+), 70 deletions(-) diff --git a/web/src/padelnomics/public/routes.py b/web/src/padelnomics/public/routes.py index 43d945f..99aeb1c 100644 --- a/web/src/padelnomics/public/routes.py +++ b/web/src/padelnomics/public/routes.py @@ -26,10 +26,21 @@ async def _supplier_counts(): @bp.route("/") async def landing(): total_suppliers, total_countries = await _supplier_counts() + calc_requests = await count_where("scenarios WHERE deleted_at IS NULL") + budget_row = await fetch_one( + "SELECT COALESCE(SUM(budget_estimate), 0) AS total" + " FROM lead_requests WHERE budget_estimate > 0 AND lead_type = 'quote'" + ) + total_budget_millions = round((budget_row["total"] if budget_row else 0) / 1_000_000, 1) + # Floor to nearest whole number if > 1, show one decimal if < 1 + if total_budget_millions >= 1: + total_budget_millions = int(total_budget_millions) return await render_template( "landing.html", total_suppliers=total_suppliers, total_countries=total_countries, + calc_requests=calc_requests, + total_budget_millions=total_budget_millions, ) diff --git a/web/src/padelnomics/public/templates/landing.html b/web/src/padelnomics/public/templates/landing.html index fb03060..9fa68ee 100644 --- a/web/src/padelnomics/public/templates/landing.html +++ b/web/src/padelnomics/public/templates/landing.html @@ -118,48 +118,64 @@ } .roi-calc__cta:hover { background: #1E40AF; color: #fff; } - /* Journey timeline */ - .journey-section { padding: 5rem 0 4rem; } - .journey-section h2 { text-align: center; font-size: 1.75rem; margin-bottom: 3.5rem; } - .journey-track { - display: grid; grid-template-columns: repeat(5, 1fr); - position: relative; padding: 0 1rem; + /* Proof strip */ + .proof-strip { + display: flex; align-items: center; justify-content: center; gap: 8px; + padding: 1rem 1.5rem; font-size: 0.8125rem; color: #64748B; + border-bottom: 1px solid #E2E8F0; flex-wrap: wrap; } - .journey-track::after { - content: ''; position: absolute; top: 23px; left: 12%; right: 12%; - height: 2px; background: #E2E8F0; z-index: 0; + .proof-strip__dot { color: #CBD5E1; } + + /* "Sound familiar?" cards */ + .familiar-grid { + display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; + max-width: 800px; margin: 0 auto; } - .journey-step { - display: flex; flex-direction: column; align-items: center; - text-align: center; position: relative; z-index: 1; + .familiar-card { + background: #F8FAFC; border: 1px solid #E2E8F0; border-radius: 14px; + padding: 1.5rem; position: relative; } - .journey-step__num { - width: 48px; height: 48px; border-radius: 50%; - display: flex; align-items: center; justify-content: center; - font-family: var(--font-display, 'Bricolage Grotesque', sans-serif); - font-weight: 800; font-size: 0.875rem; - background: #fff; border: 2px solid #E2E8F0; color: #CBD5E1; - margin-bottom: 1rem; transition: all 0.2s; + .familiar-card blockquote { + font-size: 0.9375rem; color: #334155; font-style: italic; + line-height: 1.6; margin: 0 0 0.75rem; padding: 0; } - .journey-step--active .journey-step__num { - background: #1D4ED8; border-color: #1D4ED8; color: #fff; - box-shadow: 0 4px 16px rgba(29,78,216,0.3); + .familiar-card p { + font-size: 0.8125rem; color: #64748B; margin: 0; line-height: 1.5; } - .journey-step__title { - font-family: var(--font-display, 'Bricolage Grotesque', sans-serif); - font-size: 0.9375rem; font-weight: 700; color: #0F172A; margin-bottom: 0.375rem; + + /* "Why Padelnomics" comparison */ + .vs-grid { + display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; + max-width: 900px; margin: 0 auto; } - .journey-step__desc { - font-size: 0.8125rem; color: #64748B; max-width: 170px; line-height: 1.5; + .vs-card { + border: 1px solid #E2E8F0; border-radius: 14px; padding: 1.5rem; + display: flex; flex-direction: column; } - .journey-step--upcoming { opacity: 0.45; } - .journey-step--upcoming .journey-step__title { color: #64748B; } - .badge-soon { - display: inline-block; background: rgba(29,78,216,0.08); color: #1D4ED8; - font-size: 0.625rem; font-weight: 700; padding: 2px 8px; border-radius: 999px; - margin-left: 4px; text-transform: uppercase; letter-spacing: 0.04em; - vertical-align: middle; + .vs-card h3 { + font-size: 1rem; margin-bottom: 1rem; text-align: center; } + .vs-card dl { flex-grow: 1; } + .vs-card dt { + font-size: 0.6875rem; color: #94A3B8; text-transform: uppercase; + letter-spacing: 0.04em; margin-top: 0.75rem; + } + .vs-card dt:first-of-type { margin-top: 0; } + .vs-card dd { font-size: 0.875rem; color: #475569; margin: 0.25rem 0 0; } + .vs-card--muted { background: #F8FAFC; } + .vs-card--highlight { + border-color: #1D4ED8; border-width: 2px; + box-shadow: 0 4px 16px rgba(29,78,216,0.08); + } + .vs-card__bottom { + font-size: 0.8125rem; color: #94A3B8; font-style: italic; + text-align: center; margin-top: auto; padding-top: 1rem; + } + .vs-card__cta { + display: block; text-align: center; margin-top: auto; padding-top: 1rem; + color: #1D4ED8; font-weight: 600; font-size: 0.875rem; text-decoration: none; + } + .vs-card__cta:hover { text-decoration: underline; } /* Supplier matching */ .match-grid { @@ -225,14 +241,8 @@ .hero-title { font-size: clamp(32px, 8vw, 44px); } .hero-bullets { flex-wrap: wrap; gap: 12px; } .roi-metrics { grid-template-columns: 1fr 1fr; } - .journey-track { grid-template-columns: 1fr; gap: 2rem; padding: 0; } - .journey-track::after { display: none; } - .journey-step { - display: grid; grid-template-columns: 48px 1fr; - column-gap: 1rem; text-align: left; align-items: start; - } - .journey-step__num { grid-row: 1 / 3; margin-bottom: 0; } - .journey-step__desc { max-width: none; } + .familiar-grid { grid-template-columns: 1fr; } + .vs-grid { grid-template-columns: 1fr; } .match-grid { grid-template-columns: 1fr; } } @@ -253,7 +263,7 @@

{{ t.landing_hero_desc }}

{{ t.landing_hero_bullet_1 }} @@ -305,36 +315,37 @@
- -
-

{{ t.landing_journey_title }}

-
-
-
01
-

{{ t.landing_journey_01 }} {{ t.landing_journey_01_badge }}

-

{{ t.landing_journey_01_desc }}

+ +
+ {{ t.landing_proof_plans | tformat(count=calc_requests) }} + · + {{ t.landing_proof_suppliers | tformat(count=total_suppliers, countries=total_countries) }} + · + {{ t.landing_proof_projects | tformat(amount=total_budget_millions) }} +
+ + +
+

{{ t.landing_familiar_title }}

+
+
+
“{{ t.landing_familiar_1_quote }}”
+

{{ t.landing_familiar_1_desc }}

-
-
02
-

{{ t.landing_journey_02 }}

-

{{ t.landing_journey_02_desc }}

+
+
“{{ t.landing_familiar_2_quote }}”
+

{{ t.landing_familiar_2_desc }}

-
-
03
-

{{ t.landing_journey_03 }} {{ t.landing_journey_03_badge }}

-

{{ t.landing_journey_03_desc }}

+
+
“{{ t.landing_familiar_3_quote }}”
+

{{ t.landing_familiar_3_desc }}

-
-
04
-

{{ t.landing_journey_04 }}

-

{{ t.landing_journey_04_desc | tformat(total_suppliers=total_suppliers, total_countries=total_countries) }}

-
-
-
05
-

{{ t.landing_journey_05 }} {{ t.landing_journey_05_badge }}

-

{{ t.landing_journey_05_desc }}

+
+
“{{ t.landing_familiar_4_quote }}”
+

{{ t.landing_familiar_4_desc }}

+

{{ t.landing_familiar_cta }}

@@ -370,6 +381,41 @@
+ +
+

{{ t.landing_vs_title }}

+

{{ t.landing_vs_sub }}

+
+
+

{{ t.landing_vs_col_diy }}

+
+
{{ t.landing_vs_row1_label }}
{{ t.landing_vs_row1_diy }}
+
{{ t.landing_vs_row2_label }}
{{ t.landing_vs_row2_diy }}
+
{{ t.landing_vs_row3_label }}
{{ t.landing_vs_row3_diy }}
+
+

{{ t.landing_vs_diy_cta }}

+
+
+

{{ t.landing_vs_col_consultant }}

+
+
{{ t.landing_vs_row1_label }}
{{ t.landing_vs_row1_consultant }}
+
{{ t.landing_vs_row2_label }}
{{ t.landing_vs_row2_consultant }}
+
{{ t.landing_vs_row3_label }}
{{ t.landing_vs_row3_consultant }}
+
+

{{ t.landing_vs_consultant_cta }}

+
+
+

{{ t.landing_vs_col_us }}

+
+
{{ t.landing_vs_row1_label }}
{{ t.landing_vs_row1_us }}
+
{{ t.landing_vs_row2_label }}
{{ t.landing_vs_row2_us }}
+
{{ t.landing_vs_row3_label }}
{{ t.landing_vs_row3_us }}
+
+ {{ t.landing_vs_us_cta }} +
+
+
+

{{ t.landing_supplier_title }}

@@ -392,7 +438,7 @@
@@ -436,7 +482,7 @@

{{ t.landing_final_cta_h2 }}

-

{{ t.landing_final_cta_sub | tformat(total_countries=total_countries) }}

+

{{ t.landing_final_cta_sub }}

{{ t.landing_final_cta_btn }}