# PRD — Venice Hotel Interactive Map
**Version:** 1.0  
**Target:** Claude Code (autonomous implementation)  
**Stack:** Single-file HTML · Leaflet.js · OpenStreetMap · Zero backend · Zero cost

---

## 1. Obiettivo

Creare un'unica pagina web (`index.html`) che funzioni come mappa turistica interattiva di Venezia per i clienti di un hotel. Accessibile via QR code, senza app da scaricare, senza costi di hosting se deployata su GitHub Pages / Netlify / Cloudflare Pages.

---

## 2. Requisiti Funzionali

### 2.1 Mappa
- Libreria: **Leaflet.js 1.9.x** (CDN)
- Tile provider: **OpenStreetMap** (gratuito, no API key)
- Centro mappa iniziale: Venezia centro (`45.4408, 12.3155`), zoom `14`
- Bounds limitati alla laguna veneziana (impedire scroll infinito)
- Responsive: mobile-first, funziona su qualsiasi smartphone senza zoom manuale

### 2.2 Punti di Interesse (POI)
- **72 POI** totali, definiti in un array JSON all'interno del file HTML (facilmente editabile)
- Ogni POI ha:
  ```json
  {
    "id": 1,
    "name": "Nome del luogo",
    "category": "ristorante",
    "lat": 45.4408,
    "lng": 12.3155,
    "description": "Breve descrizione (max 100 caratteri)",
    "address": "Indirizzo o sestiere",
    "tip": "Consiglio dell'hotel (opzionale)",
    "url": "https://... (opzionale)"
  }
  ```

### 2.3 Categorie e Icone
Minimo 6 categorie con colori/icone distinti:

| Categoria | Colore marker | Emoji icona |
|-----------|---------------|-------------|
| `ristorante` | #E8472A | 🍽️ |
| `museo` | #6B3FA0 | 🏛️ |
| `chiesa` | #C4962A | ⛪ |
| `aperitivo` | #F59E0B | 🍹 |
| `trasporto` | #2563EB | 🚢 |
| `shopping` | #16A34A | 🛍️ |
| `hotel` | #DC2626 | ⭐ (posizione hotel, fisso) |

### 2.4 Interazione
- Click su marker → **popup** con: nome, indirizzo, descrizione, tip hotel, link esterno (se presente)
- **Filtro categorie** — barra orizzontale in basso (mobile) o sidebar (desktop) con toggle per categoria
- **Search bar** — filtra POI per nome in real-time
- Popup include bottone "Apri in Google Maps" che lancia navigazione nativa
- Cluster automatico dei marker quando zoom < 13 (plugin Leaflet.markercluster)

### 2.5 UI / UX
- Header minimale con: logo hotel (placeholder sostituibile), nome mappa, lingua toggle IT/EN
- Footer: "© [Hotel Name] — Mappa aggiornata [data]"
- Tema visivo: elegante, veneziano — palette caldi (oro, bordeaux, avorio)
- Font: **Playfair Display** (titoli) + **Lato** (body) via Google Fonts
- Dark/light mode NON richiesto (mantieni semplice)
- Loading state con spinner mentre la mappa inizializza

---

## 3. Requisiti Non Funzionali

| Requisito | Specifica |
|-----------|-----------|
| **Costo** | €0 — nessuna API a pagamento, nessun backend |
| **Hosting** | File statico (GitHub Pages, Netlify, Cloudflare Pages) |
| **Performance** | First load < 3s su connessione 4G |
| **Compatibilità** | iOS Safari 14+, Chrome Android 90+, Chrome/Firefox desktop |
| **Offline** | Non richiesto (v1) |
| **Privacy** | Nessun cookie, nessun tracking, nessun dato utente raccolto |
| **Manutenzione** | Aggiornare i POI modificando solo l'array JSON nel file |

---

## 4. Architettura del File

```
index.html
│
├── <head>
│   ├── Meta viewport, og:tags per condivisione social
│   ├── CDN: Leaflet CSS + JS
│   ├── CDN: Leaflet.markercluster CSS + JS
│   └── CDN: Google Fonts (Playfair Display, Lato)
│
├── <style>  ← tutto il CSS inline
│
├── <body>
│   ├── #header         (logo + titolo + search + lang toggle)
│   ├── #map            (div mappa, height: calc(100vh - header - filter-bar))
│   ├── #filter-bar     (toggle categoria, sticky bottom su mobile)
│   └── #footer
│
└── <script>
    ├── const HOTEL = { name, lat, lng, ... }
    ├── const POIS = [ ...72 oggetti... ]   ← EDIT ZONE
    ├── initMap()
    ├── renderMarkers(filteredCategories)
    ├── bindFilters()
    ├── bindSearch()
    └── i18n = { it: {...}, en: {...} }
```

---

## 5. POI Placeholder (da compilare)

Claude Code deve generare **72 POI reali e verificati** di Venezia, distribuiti così:

| Categoria | Quantità |
|-----------|----------|
| Ristoranti / Bacari | 18 |
| Musei / Gallerie | 12 |
| Chiese / Monumenti | 12 |
| Aperitivo / Bar | 10 |
| Trasporti (vaporetti, traghetti) | 8 |
| Shopping / Mercati | 7 |
| Hotel (posizione fissa) | 1 (placeholder) |
| **Totale** | **~68–72** |

Coordinate devono essere precise (verificabili su OpenStreetMap).

---

## 6. Personalizzazione Hotel (sezione dedicata)

All'inizio dello script, blocco `CONFIG` facilmente editabile senza toccare il resto del codice:

```javascript
const CONFIG = {
  hotel: {
    name: "Hotel Name",          // sostituire
    lat: 45.4408,                // sostituire
    lng: 12.3155,                // sostituire
    address: "Indirizzo hotel",  // sostituire
    logo: "",                    // URL logo o stringa SVG
    primaryColor: "#8B2252",     // colore brand hotel
  },
  map: {
    defaultZoom: 14,
    minZoom: 12,
    maxZoom: 18,
  },
  defaultLang: "it",
};
```

---

## 7. Deploy Instructions (includere nel file come commento HTML)

```html
<!--
  DEPLOY GRATUITO:
  1. GitHub Pages: push index.html su repo pubblico → Settings → Pages → main branch
  2. Netlify:      drag & drop index.html su netlify.com/drop
  3. Cloudflare:   drag & drop su pages.cloudflare.com

  QR CODE GRATUITO: qr-code-generator.com → inserisci URL → stampa
  
  AGGIORNARE POI: modifica l'array POIS nello <script>, salva, ri-deploy
-->
```

---

## 8. Out of Scope (v1)

- CMS o pannello admin
- Prenotazioni o link di affiliazione
- Analytics
- PWA / Service Worker
- Autenticazione
- Backend di qualsiasi tipo

---

## 9. Definition of Done

- [ ] Singolo file `index.html` funzionante apribile localmente con doppio click
- [ ] 68–72 POI reali di Venezia con coordinate verificate
- [ ] Filtri per categoria funzionanti
- [ ] Search bar funzionante
- [ ] Popup con "Apri in Google Maps" funzionante
- [ ] Responsive su mobile (375px) e desktop (1280px)
- [ ] CONFIG block documentato e isolato
- [ ] Commento deploy incluso
- [ ] Zero dipendenze npm, zero build step, zero costi
