merge: opportunity-score-integration — expose Marktpotenzial score in city + country articles
This commit is contained in:
@@ -7,6 +7,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- **Opportunity Score integration** — second scoring dimension (`Marktpotenzial`) now visible in city and country articles:
|
||||||
|
- **SQL chain**: `dim_cities` now carries `geoname_id` (from the existing GeoNames LEFT JOIN); threaded through `city_market_profile` → `pseo_city_costs_de` which LEFT JOINs `location_opportunity_profile` on `(country_code, geoname_id)`; `pseo_country_overview` gains `avg_opportunity_score`, `top_opportunity_score`, `top_opportunity_slugs`, `top_opportunity_names`
|
||||||
|
- **71.4% match rate** — 3,350 of 4,693 cities matched to a GeoNames `geoname_id`; unmatched cities gracefully show no Opportunity Score
|
||||||
|
- **City articles** (`city-cost-de.md.jinja`) — `{% if opportunity_score %}` guard adds: 5th stats-strip item with green/amber/red color coding (≥65/≥40/<40), contextual intro sentence explaining the score interplay, table row in Market Overview, score explainer FAQ (DE + EN)
|
||||||
|
- **Country overview articles** (`country-overview.md.jinja`) — adds: `avg_opportunity_score` as 5th stats-strip item, opportunity interplay paragraph in market landscape section, "Top Locations by Investment Potential" table (distinct from top Market Score cities), score explainer FAQ (DE + EN)
|
||||||
|
- **CSS**: stats-strip changed from `repeat(4, 1fr)` to `repeat(auto-fit, minmax(140px, 1fr))` — supports 4-item country and 5-item city strips without layout breakage
|
||||||
|
|
||||||
- **Pipeline Console admin section** — full operational visibility into the data engineering pipeline at `/admin/pipeline/`:
|
- **Pipeline Console admin section** — full operational visibility into the data engineering pipeline at `/admin/pipeline/`:
|
||||||
- **Overview tab** — extraction status grid (one card per workflow with status dot, schedule, last-run timestamp, error preview), serving table row counts from `_serving_meta.json`, landing zone file stats (per-source file count + total size)
|
- **Overview tab** — extraction status grid (one card per workflow with status dot, schedule, last-run timestamp, error preview), serving table row counts from `_serving_meta.json`, landing zone file stats (per-source file count + total size)
|
||||||
- **Extractions tab** — filterable, paginated run history table from `.state.sqlite` (extractor + status dropdowns, HTMX live filter); stale "running" row detection (amber highlight) with "Mark Failed" button; "Run All Extractors" button enqueues `run_extraction` task
|
- **Extractions tab** — filterable, paginated run history table from `.state.sqlite` (extractor + status dropdowns, HTMX live filter); stale "running" row detection (amber highlight) with "Mark Failed" button; "Run All Extractors" button enqueues `run_extraction` task
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
- [x] URL prefix fix: articles stored without lang prefix (was causing `/en/en/markets/...`), all consumers updated
|
- [x] URL prefix fix: articles stored without lang prefix (was causing `/en/en/markets/...`), all consumers updated
|
||||||
- [x] Markets hub (`/<lang>/markets`) — article listing with FTS + country/region filters
|
- [x] Markets hub (`/<lang>/markets`) — article listing with FTS + country/region filters
|
||||||
- [x] DuckDB refresh script (`refresh_from_daas.py`)
|
- [x] DuckDB refresh script (`refresh_from_daas.py`)
|
||||||
|
- [x] **Opportunity Score integration** — `opportunity_score` (Marktpotenzial) wired into city + country templates; `geoname_id` threaded through SQL chain (dim_cities → city_market_profile → pseo_city_costs_de); 71.4% city match rate; stats strip, intro paragraphs, market tables, and FAQ updated in both DE + EN
|
||||||
|
|
||||||
### Data Pipeline (DaaS)
|
### Data Pipeline (DaaS)
|
||||||
- [x] Overpass API extractor (OSM padel courts)
|
- [x] Overpass API extractor (OSM padel courts)
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ uk_pop AS (
|
|||||||
),
|
),
|
||||||
-- GeoNames global fallback (all cities ≥50K)
|
-- GeoNames global fallback (all cities ≥50K)
|
||||||
geonames_pop AS (
|
geonames_pop AS (
|
||||||
SELECT city_name, country_code, population, ref_year
|
SELECT geoname_id, city_name, country_code, population, ref_year
|
||||||
FROM staging.stg_population_geonames
|
FROM staging.stg_population_geonames
|
||||||
QUALIFY ROW_NUMBER() OVER (PARTITION BY geoname_id ORDER BY ref_year DESC) = 1
|
QUALIFY ROW_NUMBER() OVER (PARTITION BY geoname_id ORDER BY ref_year DESC) = 1
|
||||||
)
|
)
|
||||||
@@ -153,7 +153,10 @@ SELECT
|
|||||||
)::INTEGER AS population_year,
|
)::INTEGER AS population_year,
|
||||||
vc.padel_venue_count,
|
vc.padel_venue_count,
|
||||||
ci.median_income_pps,
|
ci.median_income_pps,
|
||||||
ci.income_year
|
ci.income_year,
|
||||||
|
-- GeoNames ID: FK to dim_locations / location_opportunity_profile.
|
||||||
|
-- NULL when city name doesn't match any GeoNames entry.
|
||||||
|
gn.geoname_id
|
||||||
FROM venue_cities vc
|
FROM venue_cities vc
|
||||||
LEFT JOIN country_income ci ON vc.country_code = ci.country_code
|
LEFT JOIN country_income ci ON vc.country_code = ci.country_code
|
||||||
-- Eurostat EU population (via city code→name lookup)
|
-- Eurostat EU population (via city code→name lookup)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ WITH base AS (
|
|||||||
c.padel_venue_count,
|
c.padel_venue_count,
|
||||||
c.median_income_pps,
|
c.median_income_pps,
|
||||||
c.income_year,
|
c.income_year,
|
||||||
|
c.geoname_id,
|
||||||
-- Venue density: padel venues per 100K residents
|
-- Venue density: padel venues per 100K residents
|
||||||
CASE WHEN c.population > 0
|
CASE WHEN c.population > 0
|
||||||
THEN ROUND(c.padel_venue_count::DOUBLE / c.population * 100000, 2)
|
THEN ROUND(c.padel_venue_count::DOUBLE / c.population * 100000, 2)
|
||||||
@@ -107,6 +108,7 @@ SELECT
|
|||||||
s.median_occupancy_rate,
|
s.median_occupancy_rate,
|
||||||
s.median_daily_revenue_per_venue,
|
s.median_daily_revenue_per_venue,
|
||||||
s.price_currency,
|
s.price_currency,
|
||||||
|
s.geoname_id,
|
||||||
CURRENT_DATE AS refreshed_date
|
CURRENT_DATE AS refreshed_date
|
||||||
FROM scored s
|
FROM scored s
|
||||||
ORDER BY s.market_score DESC
|
ORDER BY s.market_score DESC
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ SELECT
|
|||||||
c.padel_venue_count,
|
c.padel_venue_count,
|
||||||
c.venues_per_100k,
|
c.venues_per_100k,
|
||||||
c.market_score,
|
c.market_score,
|
||||||
|
lop.opportunity_score,
|
||||||
c.data_confidence,
|
c.data_confidence,
|
||||||
-- Pricing (from Playtomic, NULL when no coverage)
|
-- Pricing (from Playtomic, NULL when no coverage)
|
||||||
c.median_hourly_rate,
|
c.median_hourly_rate,
|
||||||
@@ -48,6 +49,9 @@ FROM serving.city_market_profile c
|
|||||||
LEFT JOIN serving.planner_defaults p
|
LEFT JOIN serving.planner_defaults p
|
||||||
ON c.country_code = p.country_code
|
ON c.country_code = p.country_code
|
||||||
AND c.city_slug = p.city_slug
|
AND c.city_slug = p.city_slug
|
||||||
|
LEFT JOIN serving.location_opportunity_profile lop
|
||||||
|
ON c.country_code = lop.country_code
|
||||||
|
AND c.geoname_id = lop.geoname_id
|
||||||
-- Only cities with actual padel presence and at least some rate data
|
-- Only cities with actual padel presence and at least some rate data
|
||||||
WHERE c.padel_venue_count > 0
|
WHERE c.padel_venue_count > 0
|
||||||
AND (p.rate_peak IS NOT NULL OR c.median_peak_rate IS NOT NULL)
|
AND (p.rate_peak IS NOT NULL OR c.median_peak_rate IS NOT NULL)
|
||||||
|
|||||||
@@ -23,6 +23,12 @@ SELECT
|
|||||||
-- Top 5 cities by market score for internal linking (DuckDB list slice syntax)
|
-- Top 5 cities by market score for internal linking (DuckDB list slice syntax)
|
||||||
LIST(city_slug ORDER BY market_score DESC NULLS LAST)[1:5] AS top_city_slugs,
|
LIST(city_slug ORDER BY market_score DESC NULLS LAST)[1:5] AS top_city_slugs,
|
||||||
LIST(city_name ORDER BY market_score DESC NULLS LAST)[1:5] AS top_city_names,
|
LIST(city_name ORDER BY market_score DESC NULLS LAST)[1:5] AS top_city_names,
|
||||||
|
-- Opportunity score aggregates (NULL-safe: cities without geoname_id match excluded from AVG)
|
||||||
|
ROUND(AVG(opportunity_score), 1) AS avg_opportunity_score,
|
||||||
|
MAX(opportunity_score) AS top_opportunity_score,
|
||||||
|
-- Top 5 cities by opportunity score (may differ from top market score cities)
|
||||||
|
LIST(city_slug ORDER BY opportunity_score DESC NULLS LAST)[1:5] AS top_opportunity_slugs,
|
||||||
|
LIST(city_name ORDER BY opportunity_score DESC NULLS LAST)[1:5] AS top_opportunity_names,
|
||||||
-- Pricing medians across cities (NULL when no Playtomic coverage in country)
|
-- Pricing medians across cities (NULL when no Playtomic coverage in country)
|
||||||
ROUND(MEDIAN(median_hourly_rate), 0) AS median_hourly_rate,
|
ROUND(MEDIAN(median_hourly_rate), 0) AS median_hourly_rate,
|
||||||
ROUND(MEDIAN(median_peak_rate), 0) AS median_peak_rate,
|
ROUND(MEDIAN(median_peak_rate), 0) AS median_peak_rate,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ url_pattern: "/markets/{{ country_slug }}/{{ city_slug }}"
|
|||||||
title_pattern: "{% if language == 'de' %}Padel in {{ city_name }} — Investitionskosten & Marktanalyse {{ 'now' | datetimeformat('%Y') }}{% else %}Padel in {{ city_name }} — Investment Costs & Market Analysis {{ 'now' | datetimeformat('%Y') }}{% endif %}"
|
title_pattern: "{% if language == 'de' %}Padel in {{ city_name }} — Investitionskosten & Marktanalyse {{ 'now' | datetimeformat('%Y') }}{% else %}Padel in {{ city_name }} — Investment Costs & Market Analysis {{ 'now' | datetimeformat('%Y') }}{% endif %}"
|
||||||
meta_description_pattern: "{% if language == 'de' %}Lohnt sich eine Padelhalle in {{ city_name }}? {{ padel_venue_count }} Anlagen, <span style=\"font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em\">padelnomics</span> Market Score {{ market_score | round(1) }}/100 und ein vollständiges Finanzmodell. Stand {{ 'now' | datetimeformat('%B %Y') }}.{% else %}Is {{ city_name }} worth building a padel center in? {{ padel_venue_count }} venues, <span style=\"font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em\">padelnomics</span> Market Score {{ market_score | round(1) }}/100, and a full financial model. Updated {{ 'now' | datetimeformat('%B %Y') }}.{% endif %}"
|
meta_description_pattern: "{% if language == 'de' %}Lohnt sich eine Padelhalle in {{ city_name }}? {{ padel_venue_count }} Anlagen, <span style=\"font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em\">padelnomics</span> Market Score {{ market_score | round(1) }}/100 und ein vollständiges Finanzmodell. Stand {{ 'now' | datetimeformat('%B %Y') }}.{% else %}Is {{ city_name }} worth building a padel center in? {{ padel_venue_count }} venues, <span style=\"font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em\">padelnomics</span> Market Score {{ market_score | round(1) }}/100, and a full financial model. Updated {{ 'now' | datetimeformat('%B %Y') }}.{% endif %}"
|
||||||
schema_type: [Article, FAQPage]
|
schema_type: [Article, FAQPage]
|
||||||
priority_column: padel_venue_count
|
priority_column: population
|
||||||
---
|
---
|
||||||
{% if language == "de" %}
|
{% if language == "de" %}
|
||||||
# Lohnt sich eine Padelhalle in {{ city_name }}?
|
# Lohnt sich eine Padelhalle in {{ city_name }}?
|
||||||
@@ -23,6 +23,12 @@ priority_column: padel_venue_count
|
|||||||
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
||||||
<div class="stats-strip__value" style="color:{% if market_score >= 65 %}#16A34A{% elif market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ market_score | round(1) }}<span class="stats-strip__unit">/100</span></div>
|
<div class="stats-strip__value" style="color:{% if market_score >= 65 %}#16A34A{% elif market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ market_score | round(1) }}<span class="stats-strip__unit">/100</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if opportunity_score %}
|
||||||
|
<div class="stats-strip__item">
|
||||||
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</div>
|
||||||
|
<div class="stats-strip__value" style="color:{% if opportunity_score >= 65 %}#16A34A{% elif opportunity_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ opportunity_score | round(1) }}<span class="stats-strip__unit">/100</span></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="stats-strip__item">
|
<div class="stats-strip__item">
|
||||||
<div class="stats-strip__label">Spitzenpreis</div>
|
<div class="stats-strip__label">Spitzenpreis</div>
|
||||||
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | round(0) | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate %}{{ price_currency }}/Std{% endif %}</span></div>
|
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | round(0) | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate %}{{ price_currency }}/Std{% endif %}</span></div>
|
||||||
@@ -33,7 +39,7 @@ priority_column: padel_venue_count
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ city_name }} erreicht einen **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</a> von {{ market_score | round(1) }}/100** — damit liegt die Stadt{% if market_score >= 70 %} unter den stärksten Padel-Märkten in {{ country_name_en }}{% elif market_score >= 45 %} im soliden Mittelfeld der Padel-Märkte in {{ country_name_en }}{% else %} in einem frühen Padel-Markt mit Wachstumspotenzial{% endif %}. Aktuell gibt es **{{ padel_venue_count }} Padelanlagen** für {% if population >= 1000000 %}{{ (population / 1000000) | round(1) }}M{% else %}{{ (population / 1000) | round(0) | int }}K{% endif %} Einwohner — das entspricht {{ venues_per_100k | round(1) }} Anlagen pro 100.000 Einwohner.
|
{{ city_name }} erreicht einen **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</a> von {{ market_score | round(1) }}/100** — damit liegt die Stadt{% if market_score >= 70 %} unter den stärksten Padel-Märkten in {{ country_name_en }}{% elif market_score >= 45 %} im soliden Mittelfeld der Padel-Märkte in {{ country_name_en }}{% else %} in einem frühen Padel-Markt mit Wachstumspotenzial{% endif %}. Aktuell gibt es **{{ padel_venue_count }} Padelanlagen** für {% if population >= 1000000 %}{{ (population / 1000000) | round(1) }}M{% else %}{{ (population / 1000) | round(0) | int }}K{% endif %} Einwohner — das entspricht {{ venues_per_100k | round(1) }} Anlagen pro 100.000 Einwohner.{% if opportunity_score %} Der **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</a> von {{ opportunity_score | round(1) }}/100** bewertet das Investitionspotenzial — Versorgungslücken, Einzugsgebiet und Sportaffinität der Region:{% if opportunity_score >= 65 and market_score < 50 %} überschaubare Konkurrenz trifft auf starkes Standortpotenzial{% elif opportunity_score >= 65 %} hohes Potenzial trotz bereits aktivem Marktumfeld{% elif opportunity_score >= 40 %} solides Potenzial, der Markt beginnt sich zu verdichten{% else %} der Standort ist vergleichsweise gut versorgt, Differenzierung wird zum Schlüssel{% endif %}.{% endif %}
|
||||||
|
|
||||||
Die entscheidende Frage für Investoren: Was bringt ein Padel-Investment bei den aktuellen Preisen, Auslastungsraten und Baukosten tatsächlich? Das Finanzmodell unten rechnet mit echten Marktdaten aus {{ city_name }}.
|
Die entscheidende Frage für Investoren: Was bringt ein Padel-Investment bei den aktuellen Preisen, Auslastungsraten und Baukosten tatsächlich? Das Finanzmodell unten rechnet mit echten Marktdaten aus {{ city_name }}.
|
||||||
|
|
||||||
@@ -88,7 +94,8 @@ Eine detaillierte Preisanalyse mit Preisspannen und Vergleichsdaten findest Du a
|
|||||||
| Anlagen | {{ padel_venue_count }} |
|
| Anlagen | {{ padel_venue_count }} |
|
||||||
| Anlagen pro 100K Einwohner | {{ venues_per_100k | round(1) }} |
|
| Anlagen pro 100K Einwohner | {{ venues_per_100k | round(1) }} |
|
||||||
| <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score | {{ market_score | round(1) }}/100 |
|
| <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score | {{ market_score | round(1) }}/100 |
|
||||||
| Datenqualität | {{ (data_confidence * 100) | round(0) | int }}% |
|
{% if opportunity_score %}| <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score | {{ opportunity_score | round(1) }}/100 |
|
||||||
|
{% endif %}| Datenqualität | {{ (data_confidence * 100) | round(0) | int }}% |
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
@@ -128,6 +135,14 @@ Das Gesamtinvestment hängt vom Hallentyp (Indoor vs. Outdoor), Grundstückskost
|
|||||||
Der <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score von {{ market_score | round(1) }}/100 zeigt {{ city_name }}s Position unter den erfassten Städten in {{ country_name_en }}. In der [Marktübersicht für {{ country_name_en }}](/{{ language }}/markets/{{ country_slug }}) findest Du den Vergleich aller Städte.
|
Der <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score von {{ market_score | round(1) }}/100 zeigt {{ city_name }}s Position unter den erfassten Städten in {{ country_name_en }}. In der [Marktübersicht für {{ country_name_en }}](/{{ language }}/markets/{{ country_slug }}) findest Du den Vergleich aller Städte.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
{% if opportunity_score %}
|
||||||
|
<details>
|
||||||
|
<summary>Was ist der Unterschied zwischen Market Score und Opportunity Score?</summary>
|
||||||
|
|
||||||
|
Der **Market Score ({{ market_score | round(1) }}/100)** misst die *Marktreife*: Bevölkerungsgröße, bestehende Anlagendichte und Datenqualität. Ein hoher Wert steht für einen etablierten Markt mit belastbaren Preisdaten — und oft auch für mehr Wettbewerb. Der **Opportunity Score ({{ opportunity_score | round(1) }}/100)** dreht die Logik um: Er bewertet *Investitionspotenzial* anhand von Versorgungslücken, Entfernung zur nächsten Anlage und der Tennisinfrastruktur als Proxy für Racket-Sport-Affinität. Hoher Opportunity Score bei niedrigem Market Score — das ist das klassische White-Space-Signal. Hoher Wert in beiden — bewiesene Nachfrage mit noch offenen Standorten.
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
||||||
Bereit für Deine eigene Kalkulation? →
|
Bereit für Deine eigene Kalkulation? →
|
||||||
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Businessplan erstellen</a>
|
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Businessplan erstellen</a>
|
||||||
@@ -148,6 +163,12 @@ Der <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;co
|
|||||||
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
||||||
<div class="stats-strip__value" style="color:{% if market_score >= 65 %}#16A34A{% elif market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ market_score | round(1) }}<span class="stats-strip__unit">/100</span></div>
|
<div class="stats-strip__value" style="color:{% if market_score >= 65 %}#16A34A{% elif market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ market_score | round(1) }}<span class="stats-strip__unit">/100</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if opportunity_score %}
|
||||||
|
<div class="stats-strip__item">
|
||||||
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</div>
|
||||||
|
<div class="stats-strip__value" style="color:{% if opportunity_score >= 65 %}#16A34A{% elif opportunity_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ opportunity_score | round(1) }}<span class="stats-strip__unit">/100</span></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="stats-strip__item">
|
<div class="stats-strip__item">
|
||||||
<div class="stats-strip__label">Peak Rate</div>
|
<div class="stats-strip__label">Peak Rate</div>
|
||||||
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | round(0) | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate %}{{ price_currency }}/hr{% endif %}</span></div>
|
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | round(0) | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate %}{{ price_currency }}/hr{% endif %}</span></div>
|
||||||
@@ -158,7 +179,7 @@ Der <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;co
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ city_name }} has a **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</a> of {{ market_score | round(1) }}/100** — placing it{% if market_score >= 70 %} among the strongest padel markets in {{ country_name_en }}{% elif market_score >= 45 %} in the mid-tier of {{ country_name_en }}'s padel markets{% else %} in an early-stage padel market with room for growth{% endif %}. The city currently has **{{ padel_venue_count }} padel venues** serving a population of {% if population >= 1000000 %}{{ (population / 1000000) | round(1) }}M{% else %}{{ (population / 1000) | round(0) | int }}K{% endif %} residents — a density of {{ venues_per_100k | round(1) }} venues per 100,000 people.
|
{{ city_name }} has a **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</a> of {{ market_score | round(1) }}/100** — placing it{% if market_score >= 70 %} among the strongest padel markets in {{ country_name_en }}{% elif market_score >= 45 %} in the mid-tier of {{ country_name_en }}'s padel markets{% else %} in an early-stage padel market with room for growth{% endif %}. The city currently has **{{ padel_venue_count }} padel venues** serving a population of {% if population >= 1000000 %}{{ (population / 1000000) | round(1) }}M{% else %}{{ (population / 1000) | round(0) | int }}K{% endif %} residents — a density of {{ venues_per_100k | round(1) }} venues per 100,000 people.{% if opportunity_score %} The **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</a> of {{ opportunity_score | round(1) }}/100** scores investment potential — supply gaps, catchment reach, and sports culture as a demand proxy:{% if opportunity_score >= 65 and market_score < 50 %} limited competition meets strong location fundamentals{% elif opportunity_score >= 65 %} strong potential despite an already active market{% elif opportunity_score >= 40 %} solid potential as the market starts to fill in{% else %} the area is comparatively well-served; differentiation is the key lever{% endif %}.{% endif %}
|
||||||
|
|
||||||
The question investors actually need answered is: given current pricing, occupancy, and build costs, what does the return look like? The financial model below uses real {{ city_name }} market data to give you that answer.
|
The question investors actually need answered is: given current pricing, occupancy, and build costs, what does the return look like? The financial model below uses real {{ city_name }} market data to give you that answer.
|
||||||
|
|
||||||
@@ -213,7 +234,8 @@ For a detailed pricing breakdown with price ranges and venue comparisons, see th
|
|||||||
| Venues | {{ padel_venue_count }} |
|
| Venues | {{ padel_venue_count }} |
|
||||||
| Venues per 100K residents | {{ venues_per_100k | round(1) }} |
|
| Venues per 100K residents | {{ venues_per_100k | round(1) }} |
|
||||||
| <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score | {{ market_score | round(1) }}/100 |
|
| <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score | {{ market_score | round(1) }}/100 |
|
||||||
| Data Confidence | {{ (data_confidence * 100) | round(0) | int }}% |
|
{% if opportunity_score %}| <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score | {{ opportunity_score | round(1) }}/100 |
|
||||||
|
{% endif %}| Data Confidence | {{ (data_confidence * 100) | round(0) | int }}% |
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
@@ -253,6 +275,14 @@ Total investment depends on venue type (indoor vs outdoor), land costs, and loca
|
|||||||
{{ city_name }}'s <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score of {{ market_score | round(1) }}/100 reflects its ranking among tracked {{ country_name_en }} cities. See the [{{ country_name_en }} market overview](/{{ language }}/markets/{{ country_slug }}) for a full comparison across cities.
|
{{ city_name }}'s <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score of {{ market_score | round(1) }}/100 reflects its ranking among tracked {{ country_name_en }} cities. See the [{{ country_name_en }} market overview](/{{ language }}/markets/{{ country_slug }}) for a full comparison across cities.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
{% if opportunity_score %}
|
||||||
|
<details>
|
||||||
|
<summary>What is the difference between Market Score and Opportunity Score?</summary>
|
||||||
|
|
||||||
|
The **Market Score ({{ market_score | round(1) }}/100)** measures *market maturity*: population size, existing venue density, and data quality. A high score signals an established market with reliable pricing data — and typically more competition. The **Opportunity Score ({{ opportunity_score | round(1) }}/100)** inverts that logic: it scores *investment potential* based on supply gaps, distance to the nearest facility, and tennis infrastructure as a proxy for racket sport demand. High Opportunity Score with a low Market Score is the classic white-space signal. High on both means proven demand with open locations still available.
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
||||||
Ready to run the numbers for {{ city_name }}? →
|
Ready to run the numbers for {{ city_name }}? →
|
||||||
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Build your business plan</a>
|
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Build your business plan</a>
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ priority_column: total_venues
|
|||||||
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
||||||
<div class="stats-strip__value" style="color:{% if avg_market_score >= 65 %}#16A34A{% elif avg_market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ avg_market_score }}<span class="stats-strip__unit">/100</span></div>
|
<div class="stats-strip__value" style="color:{% if avg_market_score >= 65 %}#16A34A{% elif avg_market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ avg_market_score }}<span class="stats-strip__unit">/100</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if avg_opportunity_score %}
|
||||||
|
<div class="stats-strip__item">
|
||||||
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</div>
|
||||||
|
<div class="stats-strip__value" style="color:{% if avg_opportunity_score >= 65 %}#16A34A{% elif avg_opportunity_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ avg_opportunity_score }}<span class="stats-strip__unit">/100</span></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="stats-strip__item">
|
<div class="stats-strip__item">
|
||||||
<div class="stats-strip__label">Median Spitzenpreis</div>
|
<div class="stats-strip__label">Median Spitzenpreis</div>
|
||||||
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate and price_currency %}{{ price_currency }}/Std{% endif %}</span></div>
|
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate and price_currency %}{{ price_currency }}/Std{% endif %}</span></div>
|
||||||
@@ -42,6 +48,8 @@ Padel wächst in {{ country_name_en }} mit bemerkenswertem Tempo. Unsere Daten z
|
|||||||
|
|
||||||
{% if avg_market_score >= 65 %}Märkte mit Scores über 65 weisen in der Regel eine etablierte Spielerbasis, belastbare Preisdaten und berechenbare Nachfragemuster auf — entscheidend für eine solide Finanzplanung. Dennoch bleiben viele Städte unterversorgt: Selbst in reifen Märkten variiert die Anlagendichte pro 100.000 Einwohner erheblich.{% elif avg_market_score >= 40 %}Ein Score im mittleren Bereich deutet auf eine Wachstumsphase hin: Die Nachfrage ist nachweisbar, die Anlageninfrastruktur baut sich auf, und Preise haben sich noch nicht vollständig auf Wettbewerbsniveau eingependelt. Das eröffnet Chancen für gut positionierte Neueintritte.{% else %}Aufstrebende Märkte bieten First-Mover-Vorteile — weniger direkte Konkurrenz, potenziell attraktivere Mietkonditionen und die Möglichkeit, eine loyale Spielerbasis aufzubauen, bevor sich der Markt verdichtet.{% endif %}
|
{% if avg_market_score >= 65 %}Märkte mit Scores über 65 weisen in der Regel eine etablierte Spielerbasis, belastbare Preisdaten und berechenbare Nachfragemuster auf — entscheidend für eine solide Finanzplanung. Dennoch bleiben viele Städte unterversorgt: Selbst in reifen Märkten variiert die Anlagendichte pro 100.000 Einwohner erheblich.{% elif avg_market_score >= 40 %}Ein Score im mittleren Bereich deutet auf eine Wachstumsphase hin: Die Nachfrage ist nachweisbar, die Anlageninfrastruktur baut sich auf, und Preise haben sich noch nicht vollständig auf Wettbewerbsniveau eingependelt. Das eröffnet Chancen für gut positionierte Neueintritte.{% else %}Aufstrebende Märkte bieten First-Mover-Vorteile — weniger direkte Konkurrenz, potenziell attraktivere Mietkonditionen und die Möglichkeit, eine loyale Spielerbasis aufzubauen, bevor sich der Markt verdichtet.{% endif %}
|
||||||
|
|
||||||
|
{% if avg_opportunity_score %}Der durchschnittliche **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</a> von {{ avg_opportunity_score }}/100** zeigt, wie viel Investitionspotenzial in {{ country_name_en }} noch unerschlossen ist. {% if avg_opportunity_score >= 60 and avg_market_score < 50 %}Die Kombination aus hohem Opportunity Score und moderatem Market Score macht {{ country_name_en }} besonders interessant: Nachfragepotenzial und Sportaffinität sind vorhanden, die Infrastruktur noch im Aufbau — First-Mover-Konditionen für gut gewählte Standorte.{% elif avg_opportunity_score >= 60 %}Trotz eines bereits aktiven Markts gibt es noch Standorte mit erheblichem Potenzial — vor allem in mittelgroßen Städten und an der Peripherie großer Ballungsräume.{% else %}Viele Standorte in {{ country_name_en }} sind bereits gut versorgt. Neue Projekte brauchen eine sorgfältige Standortanalyse und ein klares Differenzierungsprofil.{% endif %}{% endif %}
|
||||||
|
|
||||||
## Top-Städte in {{ country_name_en }}
|
## Top-Städte in {{ country_name_en }}
|
||||||
|
|
||||||
Die Rangfolge basiert auf dem <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score — einem Komposit aus Bevölkerungsgröße, Anlagendichte und Datenqualität. Städte mit höherem Score bieten in der Regel größere adressierbare Märkte und belastbarere Benchmarks für die Finanzplanung.
|
Die Rangfolge basiert auf dem <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score — einem Komposit aus Bevölkerungsgröße, Anlagendichte und Datenqualität. Städte mit höherem Score bieten in der Regel größere adressierbare Märkte und belastbarere Benchmarks für die Finanzplanung.
|
||||||
@@ -53,6 +61,17 @@ Die Rangfolge basiert auf dem <span style="font-family:'Bricolage Grotesque',san
|
|||||||
|
|
||||||
Jede Stadtseite enthält detaillierte Preisdaten, eine Kosten-Nutzen-Analyse und einen vorkonfigurierten Finanzplaner mit lokalen Marktdaten als Ausgangswerte.
|
Jede Stadtseite enthält detaillierte Preisdaten, eine Kosten-Nutzen-Analyse und einen vorkonfigurierten Finanzplaner mit lokalen Marktdaten als Ausgangswerte.
|
||||||
|
|
||||||
|
{% if top_opportunity_names and top_opportunity_names | length > 0 %}
|
||||||
|
## Top-Standorte nach Investitionspotenzial
|
||||||
|
|
||||||
|
Diese Städte erzielen die höchsten Opportunity Scores in {{ country_name_en }} — dort treffen adressierbare Nachfrage auf Versorgungslücken und starke Standortfaktoren. Sie können sich von den Top-Städten nach Market Score unterscheiden: Der Market Score belohnt bestehende Märkte, der Opportunity Score unerschlossenes Potenzial.
|
||||||
|
|
||||||
|
| Stadt | Investmentanalyse |
|
||||||
|
|-------|-------------------|
|
||||||
|
{% for i in range(top_opportunity_names | length) %}| [{{ top_opportunity_names[i] }}](/{{ language }}/markets/{{ country_slug }}/{{ top_opportunity_slugs[i] }}) | [Marktanalyse ansehen →](/{{ language }}/markets/{{ country_slug }}/{{ top_opportunity_slugs[i] }}) |
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
## Preisüberblick
|
## Preisüberblick
|
||||||
|
|
||||||
{% if median_peak_rate %}
|
{% if median_peak_rate %}
|
||||||
@@ -112,6 +131,14 @@ Padel gehört zu den am schnellsten wachsenden Racketsportarten in Europa. Mit {
|
|||||||
Städte mit höherem <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score (wie {{ top_city_names[0] }}) haben in der Regel die umfassendsten Preisdaten, weil dort mehr Anlagen auf Playtomic gelistet sind. In unserem <a href="/{{ language }}/markets/{{ country_slug }}">{{ country_name_en }}-Marktüberblick</a> findest Du alle Städte nach Market Score sortiert.
|
Städte mit höherem <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score (wie {{ top_city_names[0] }}) haben in der Regel die umfassendsten Preisdaten, weil dort mehr Anlagen auf Playtomic gelistet sind. In unserem <a href="/{{ language }}/markets/{{ country_slug }}">{{ country_name_en }}-Marktüberblick</a> findest Du alle Städte nach Market Score sortiert.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
{% if avg_opportunity_score %}
|
||||||
|
<details>
|
||||||
|
<summary>Was ist der Unterschied zwischen Market Score und Opportunity Score?</summary>
|
||||||
|
|
||||||
|
Der **Market Score (Ø {{ avg_market_score }}/100)** bewertet die Marktreife: Bevölkerungsgröße, bestehende Anlagendichte und Datenqualität. Der **Opportunity Score (Ø {{ avg_opportunity_score }}/100)** dreht die Logik um: Er misst Investitionspotenzial — Versorgungslücken, Einzugsgebiet und Tennisinfrastruktur als Proxy für Racket-Sport-Affinität. Für Standortentscheidungen ist die Kombination beider Scores am aussagekräftigsten: Hoher Opportunity Score bei niedrigem Market Score signalisiert White-Space-Chancen. Hoher Wert in beiden zeigt Märkte, in denen Nachfrage belegt ist und trotzdem noch offene Standorte existieren.
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
||||||
Du überlegst, eine Padelhalle in {{ country_name_en }} zu eröffnen? Rechne Dein Vorhaben mit echten Marktdaten durch →
|
Du überlegst, eine Padelhalle in {{ country_name_en }} zu eröffnen? Rechne Dein Vorhaben mit echten Marktdaten durch →
|
||||||
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Zum Finanzplaner</a>
|
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Zum Finanzplaner</a>
|
||||||
@@ -133,6 +160,12 @@ Städte mit höherem <span style="font-family:'Bricolage Grotesque',sans-serif;f
|
|||||||
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score</div>
|
||||||
<div class="stats-strip__value" style="color:{% if avg_market_score >= 65 %}#16A34A{% elif avg_market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ avg_market_score }}<span class="stats-strip__unit">/100</span></div>
|
<div class="stats-strip__value" style="color:{% if avg_market_score >= 65 %}#16A34A{% elif avg_market_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ avg_market_score }}<span class="stats-strip__unit">/100</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if avg_opportunity_score %}
|
||||||
|
<div class="stats-strip__item">
|
||||||
|
<div class="stats-strip__label"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</div>
|
||||||
|
<div class="stats-strip__value" style="color:{% if avg_opportunity_score >= 65 %}#16A34A{% elif avg_opportunity_score >= 40 %}#D97706{% else %}#DC2626{% endif %}">{{ avg_opportunity_score }}<span class="stats-strip__unit">/100</span></div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="stats-strip__item">
|
<div class="stats-strip__item">
|
||||||
<div class="stats-strip__label">Median Peak Rate</div>
|
<div class="stats-strip__label">Median Peak Rate</div>
|
||||||
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate and price_currency %}{{ price_currency }}/hr{% endif %}</span></div>
|
<div class="stats-strip__value">{% if median_peak_rate %}{{ median_peak_rate | int }}{% else %}—{% endif %}<span class="stats-strip__unit">{% if median_peak_rate and price_currency %}{{ price_currency }}/hr{% endif %}</span></div>
|
||||||
@@ -147,6 +180,8 @@ Padel is growing rapidly across {{ country_name_en }}. Our data tracks {{ total_
|
|||||||
|
|
||||||
{% if avg_market_score >= 65 %}Markets scoring above 65 typically show an established player base, reliable pricing data, and predictable demand patterns — all critical for sound financial planning. Yet even in mature markets, venue density per 100,000 residents varies significantly between cities, pointing to pockets of underserved demand.{% elif avg_market_score >= 40 %}A mid-range score signals a growth phase: demand is proven, venue infrastructure is building, and pricing hasn't fully settled to competitive levels. This creates opportunities for well-positioned new entrants who can secure good locations before the market matures.{% else %}Emerging markets offer first-mover advantages — less direct competition, potentially better lease terms, and the opportunity to build a loyal player base before the market fills out. The trade-off is less pricing data and more uncertainty in demand projections.{% endif %}
|
{% if avg_market_score >= 65 %}Markets scoring above 65 typically show an established player base, reliable pricing data, and predictable demand patterns — all critical for sound financial planning. Yet even in mature markets, venue density per 100,000 residents varies significantly between cities, pointing to pockets of underserved demand.{% elif avg_market_score >= 40 %}A mid-range score signals a growth phase: demand is proven, venue infrastructure is building, and pricing hasn't fully settled to competitive levels. This creates opportunities for well-positioned new entrants who can secure good locations before the market matures.{% else %}Emerging markets offer first-mover advantages — less direct competition, potentially better lease terms, and the opportunity to build a loyal player base before the market fills out. The trade-off is less pricing data and more uncertainty in demand projections.{% endif %}
|
||||||
|
|
||||||
|
{% if avg_opportunity_score %}The average **<a href="/{{ language }}/market-score" style="text-decoration:none"><span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Opportunity Score</a> of {{ avg_opportunity_score }}/100** shows how much investment potential remains untapped in {{ country_name_en }}. {% if avg_opportunity_score >= 60 and avg_market_score < 50 %}The combination of a high Opportunity Score and a moderate Market Score makes {{ country_name_en }} particularly attractive for new entrants: demand potential and sports culture are there, infrastructure is still building — first-mover conditions for well-chosen locations.{% elif avg_opportunity_score >= 60 %}Despite an already active market, locations with significant potential remain — particularly in mid-size cities and at the periphery of major metro areas.{% else %}Many locations in {{ country_name_en }} are already well-served. New projects need careful site selection and a clear differentiation strategy to compete.{% endif %}{% endif %}
|
||||||
|
|
||||||
## Top Cities in {{ country_name_en }}
|
## Top Cities in {{ country_name_en }}
|
||||||
|
|
||||||
Cities are ranked by <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score — a composite of population size, venue density, and data quality. Higher-scoring cities generally offer larger addressable markets and more reliable benchmarks for financial planning.
|
Cities are ranked by <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score — a composite of population size, venue density, and data quality. Higher-scoring cities generally offer larger addressable markets and more reliable benchmarks for financial planning.
|
||||||
@@ -158,6 +193,17 @@ Cities are ranked by <span style="font-family:'Bricolage Grotesque',sans-serif;f
|
|||||||
|
|
||||||
Each city page includes detailed pricing data, a cost-benefit analysis, and a pre-configured financial planner seeded with local market data.
|
Each city page includes detailed pricing data, a cost-benefit analysis, and a pre-configured financial planner seeded with local market data.
|
||||||
|
|
||||||
|
{% if top_opportunity_names and top_opportunity_names | length > 0 %}
|
||||||
|
## Top Locations by Investment Potential
|
||||||
|
|
||||||
|
These cities score highest on the Opportunity Score in {{ country_name_en }} — where addressable demand meets supply gaps and strong location fundamentals. They may differ from the top Market Score cities: the Market Score rewards established markets, the Opportunity Score rewards untapped potential.
|
||||||
|
|
||||||
|
| City | Market Analysis |
|
||||||
|
|------|----------------|
|
||||||
|
{% for i in range(top_opportunity_names | length) %}| [{{ top_opportunity_names[i] }}](/{{ language }}/markets/{{ country_slug }}/{{ top_opportunity_slugs[i] }}) | [View investment analysis →](/{{ language }}/markets/{{ country_slug }}/{{ top_opportunity_slugs[i] }}) |
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
## Pricing Overview
|
## Pricing Overview
|
||||||
|
|
||||||
{% if median_peak_rate %}
|
{% if median_peak_rate %}
|
||||||
@@ -217,6 +263,14 @@ Padel is one of the fastest-growing racquet sports in Europe. With {{ total_venu
|
|||||||
Cities with higher <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Scores (like {{ top_city_names[0] }}) typically have the most comprehensive pricing data, because more venues are listed on Playtomic. Browse our <a href="/{{ language }}/markets/{{ country_slug }}">{{ country_name_en }} market overview</a> to see all cities ranked by <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score.
|
Cities with higher <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Scores (like {{ top_city_names[0] }}) typically have the most comprehensive pricing data, because more venues are listed on Playtomic. Browse our <a href="/{{ language }}/markets/{{ country_slug }}">{{ country_name_en }} market overview</a> to see all cities ranked by <span style="font-family:'Bricolage Grotesque',sans-serif;font-weight:800;color:#0F172A;letter-spacing:-0.02em">padelnomics</span> Market Score.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
{% if avg_opportunity_score %}
|
||||||
|
<details>
|
||||||
|
<summary>What is the difference between Market Score and Opportunity Score?</summary>
|
||||||
|
|
||||||
|
The **Market Score (avg. {{ avg_market_score }}/100)** measures market maturity: population size, existing venue density, and data quality. The **Opportunity Score (avg. {{ avg_opportunity_score }}/100)** inverts that logic: it scores investment potential based on supply gaps, catchment reach, and tennis infrastructure as a proxy for racket sport demand. For site selection, the combination of both scores is the most informative signal. A high Opportunity Score with a low Market Score points to white-space locations. High on both means proven demand with open sites still available.
|
||||||
|
</details>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
<div style="background:#EFF6FF;border:1px solid #BFDBFE;border-radius:12px;padding:1rem 1.25rem;margin:1.5rem 0;">
|
||||||
Considering a padel center in {{ country_name_en }}? Model your investment with real market data →
|
Considering a padel center in {{ country_name_en }}? Model your investment with real market data →
|
||||||
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Open the Planner</a>
|
<a href="/{{ language }}/planner" style="font-weight:600;color:#1D4ED8;margin-left:0.25rem;">Open the Planner</a>
|
||||||
|
|||||||
@@ -484,7 +484,7 @@
|
|||||||
@apply grid grid-cols-2 gap-3 mb-8;
|
@apply grid grid-cols-2 gap-3 mb-8;
|
||||||
}
|
}
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
.stats-strip { grid-template-columns: repeat(4, 1fr); }
|
.stats-strip { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
|
||||||
}
|
}
|
||||||
.stats-strip__item {
|
.stats-strip__item {
|
||||||
@apply bg-soft-white border border-light-gray rounded-lg p-4;
|
@apply bg-soft-white border border-light-gray rounded-lg p-4;
|
||||||
|
|||||||
Reference in New Issue
Block a user