Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>French Property Prices</title> | |
| <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css"> | |
| <link rel="stylesheet" href="/static/style.css"> | |
| </head> | |
| <body class="dark-mode"> | |
| <div id="app"> | |
| <!-- Left control panel --> | |
| <div id="panel"> | |
| <div class="panel-header" style="display:flex;justify-content:space-between;align-items:flex-start;"> | |
| <div> | |
| <h1>Property Prices</h1> | |
| <p class="subtitle">France · €/m² · DVF 2020–2025</p> | |
| </div> | |
| <button class="theme-toggle" id="theme-toggle" title="Toggle light/dark mode">☾</button> | |
| </div> | |
| <!-- Map level (radio buttons 3x2 grid) --> | |
| <div class="panel-section"> | |
| <span class="section-label">Map Level</span> | |
| <div class="level-radios"> | |
| <label class="level-radio"><input type="radio" name="map-level" value="0" checked><span>Country</span></label> | |
| <label class="level-radio"><input type="radio" name="map-level" value="1"><span>Region</span></label> | |
| <label class="level-radio"><input type="radio" name="map-level" value="2"><span>Dept</span></label> | |
| <label class="level-radio"><input type="radio" name="map-level" value="3"><span>Commune</span></label> | |
| <label class="level-radio"><input type="radio" name="map-level" value="4"><span>Postcode</span></label> | |
| <label class="level-radio"><input type="radio" name="map-level" value="5"><span>Section</span></label> | |
| </div> | |
| </div> | |
| <!-- Property Type --> | |
| <div class="panel-section"> | |
| <span class="section-label">Property Type</span> | |
| <div class="type-checkboxes"> | |
| <label class="type-cb"><input type="checkbox" id="cb-appartement" checked><span>Apartments</span></label> | |
| <label class="type-cb"><input type="checkbox" id="cb-maison" checked><span>Houses</span></label> | |
| </div> | |
| </div> | |
| <!-- Area list: scrollable list of items for current level --> | |
| <div class="panel-section"> | |
| <span class="section-label" id="area-list-label">Areas</span> | |
| <div id="area-list" class="area-list"></div> | |
| </div> | |
| <!-- Price range filter --> | |
| <div class="panel-section"> | |
| <span class="section-label">Price Range (€/m²)</span> | |
| <div class="price-inputs"> | |
| <input type="number" id="price-min-input" value="200" min="0" max="50000" step="100"> | |
| <span class="price-sep">–</span> | |
| <input type="number" id="price-max-input" value="25000" min="0" max="50000" step="100"> | |
| </div> | |
| <div class="range-container"> | |
| <div class="slider-bg"></div> | |
| <div class="slider-track" id="slider-track"></div> | |
| <input type="range" id="price-min-slider" min="200" max="25000" value="200" step="100"> | |
| <input type="range" id="price-max-slider" min="200" max="25000" value="25000" step="100"> | |
| </div> | |
| </div> | |
| <!-- Search: geocoding autocomplete --> | |
| <div class="panel-section search-section"> | |
| <span class="section-label">Search Place</span> | |
| <div class="search-wrapper"> | |
| <input type="text" id="place-search" class="place-search" placeholder="Search a city or commune..." autocomplete="off"> | |
| <div id="search-dropdown" class="search-dropdown hidden"></div> | |
| </div> | |
| <div id="place-details" class="place-details hidden"></div> | |
| </div> | |
| <div class="footer"> | |
| Source: DVF (data.gouv.fr)<br> | |
| Method: Time-weighted trimmed mean | |
| </div> | |
| </div> | |
| <!-- Map --> | |
| <div id="map"> | |
| <!-- Floating overlay: stat + legend --> | |
| <div id="map-overlay" class="map-overlay"> | |
| <div class="country-stat"> | |
| <span id="stat-label" class="country-label">National Average</span> | |
| <span id="stat-price" class="country-price">—</span> | |
| <span id="stat-detail" class="stat-detail"></span> | |
| <span id="zoom-indicator" class="zoom-indicator">Zoom: 4.0</span> | |
| </div> | |
| <div id="legend"> | |
| <div class="legend-bar"></div> | |
| <div class="legend-labels"> | |
| <span id="legend-min">—</span> | |
| <span id="legend-max">—</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Floating hover tooltip --> | |
| <div id="tooltip" class="hidden"></div> | |
| <script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script> | |
| <script src="/static/app.js"></script> | |
| </body> | |
| </html> | |