/**
* LUCCIOLE NELLA NEBBIA - CORE APP SCRIPT (EXPANDED & REFINED)
* Multilingual Engine (IT/EN), Dark Mode, Hero Crossfade Slider (2s interval & DJI Neo video support),
* Service Detail Modals, Activity & Itinerary Modals (with cover image & concise copy),
* Real Testimonials, and GDPR Cookie Banner.
*/
(function () {
'use strict';
// Multilingual Micro-copy Dictionary (Strictly concise, max 10 words per phrase)
const I18N = {
it: {
// Header & Nav
nav_oggi: "🗓️ Oggi al Villaggio",
nav_alloggi: "Alloggi/Piazzole",
nav_territorio: "Esperienze e Territorio",
nav_ristorante: "Ristorante",
nav_servizi: "Servizi",
nav_recensioni: "Recensioni",
nav_faq: "F.A.Q.",
nav_chi_siamo: "Chi Siamo",
nav_contatti: "Contatti",
nav_prenota: "Prenota Ora",
// Hero
hero_badge: "Villaggio Turistico · 3 Stelle",
hero_title: "Natura, silenzio e tradizione a 2 passi dal grande fiume Po",
hero_lead: "Villaggio ecosostenibile con villette, roulotte, ristorante tipico e tradizionale, piscina al sale e pontile sul fiume Po.",
hero_btn_explore: "Esplora il Villaggio",
hero_btn_restaurant: "Il Nostro Ristorante",
hero_btn_book: "Verifica Disponibilità",
// Booking Bar & Feedback Toast
lbl_checkin: "Check-In",
lbl_checkout: "Check-Out",
lbl_alloggio: "Alloggio",
lbl_ospiti: "Ospiti",
opt_all_villetta: "Villette (6 temi)",
opt_all_caravan: "Roulotte Vintage (4 temi)",
opt_all_tent: "Piazzola Tenda",
opt_all_camper: "Piazzola Camper / Van",
btn_calculate_quote: "Calcola Preventivo",
btn_verify_availability: "Verifica Disponibilità",
toast_booking_success: "Richiesta inviata! Riceverai a breve un'email di riepilogo.",
modal_lbl_amenities: "Caratteristiche & Servizi",
// Section Headers
eyebrow_alloggi: "Ospitalità & Natura",
title_alloggi: "I Nostri Alloggi/Piazzole Ecosostenibili",
desc_alloggi: "Scegli tra villette a tema, roulotte vintage e piazzole ombreggiate.",
// Esperienze e Territorio (10 Cards)
eyebrow_territorio: "Esperienze & Territorio",
title_territorio: "Esperienze e Territorio",
desc_territorio: "Scopri le eccellenze del Grande Fiume, tra piste ciclabili, storia, eventi e relax.",
exp_badge_1: "SPECIALE",
exp_title_1: "Eventi delle Lucciole",
exp_desc_1: "Eventi speciali in struttura: Halloween, Pasqua, Cene Degustazione e serate a tema.",
exp_badge_2: "2ª DOM",
exp_title_2: "Mercatino Antiquariato Stellata",
exp_desc_2: "Centinaia di espositori nel borgo di Stellata ogni seconda domenica del mese.",
exp_badge_3: "SAB / DOM",
exp_title_3: "La Rocca Possente di Stellata",
exp_desc_3: "Aperture weekend: visita alla fortezza simbolo di Stellata baluardo sul Po.",
exp_badge_4: "SEMPRE",
exp_title_4: "Le Grandi Ciclovie",
exp_desc_4: "Destra Po, EuroVelo 7, EuroVelo 8 e VENTO con accesso diretto dal villaggio.",
exp_badge_5: "SEMPRE",
exp_title_5: "Via Romea Strata",
exp_desc_5: "Antico cammino di pellegrinaggio lungo le rive del Po per il turismo lento.",
exp_badge_6: "SETTIMANALE",
exp_title_6: "Mercati Tradizionali Vicini",
exp_desc_6: "Lunedì e Venerdì (Ferrara), Martedì (Bondeno), Giovedì (Sermide).",
exp_badge_7: "CULTURA",
exp_title_7: "Storia, Antiquariato e Cultura",
exp_desc_7: "Dalla Rocca Possente di Stellata al Castello Estense di Ferrara, fino ai musei storici del fiume Po.",
exp_badge_8: "SU PRENOTAZIONE",
exp_title_8: "Escursioni in Barca sul Po",
exp_desc_8: "Navigazione fluviale dal nostro pontile. Prenotazione obbligatoria (meteo permettendo).",
exp_badge_9: "TUTTO L'ANNO",
exp_title_9: "Eventi Locali e Sagre",
exp_desc_9: "Sagre paesane, fiere e tradizioni enogastronomiche attive tutto l'anno nel territorio ferrarese e mantovano.",
exp_badge_10: "01/06 - 15/09",
exp_title_10: "Piscina al Sale",
exp_desc_10: "Aperta tutti i giorni nella stagione estiva (01/06 - 15/09). Ingresso gratuito per gli ospiti.",
tab_all: "Tutti",
tab_villette: "Villette (6)",
tab_caravan: "Roulotte (4)",
tab_camping: "Campeggio (22)",
card_from: "da",
card_per_night: "/notte",
btn_view_book: "Prenota Alloggio",
// Alloggi Cards Copy
villetta_card_title: "Villette Ecosostenibili",
villetta_card_desc: "Sei casette in legno a tema con veranda privata.",
villetta_feat_1: "Climatizzazione (aria condizionata/riscaldamento)",
villetta_feat_2: "Cucina attrezzata e veranda esterna privata",
villetta_feat_3: "Struttura accessibile per disabili · Zero barriere",
villetta_feat_4: "Bagno privato con doccia calda solare e piscina inclusa",
caravan_card_title: "Roulotte Vintage",
caravan_card_desc: "Esperienza retro con comfort moderno sotto gli alberi.",
caravan_feat_1: "Climatizzazione (aria condizionata/riscaldamento)",
caravan_feat_2: "Mini frigo, biancheria inclusa e veranda relax",
caravan_feat_3: "Servizi igienici comuni caldi, puliti e accessibili",
camping_card_title: "Piazzole Tenda & Camper",
camping_card_desc: "22 ampie piazzole da 55mq su manto erboso ombreggiato.",
camping_feat_1: "Ombra costante da alberi d'alto fusto",
camping_feat_2: "Allaccio corrente 220V e scarico acque",
camping_feat_3: "Lavanderia a gettoni e area barbecue",
// Ristorante
eyebrow_ristorante: "Sapori del Territorio",
title_ristorante: "Ristorante & Bar Lucciole",
desc_ristorante: "Cucina tipica emiliana con prodotti freschi dell'orto a km zero.",
rist_feat_1: "Pasta fresca all'uovo tirata a mano",
rist_feat_2: "Salumi tipici ferraresi e vini delle sabbie",
rist_feat_3: "Colazione artigianale e centrifughe fresche di stagione",
rist_feat_4: "Accessibile ai disabili / Zero barriere architettoniche",
rist_hours_title: "Giorni & Orari di Apertura",
rist_hours_dinner: "Cena: Lun, Mar, Ven, Sab, Dom dalle 19:30",
rist_hours_lunch: "Pranzo: Domenica dalle 12:30",
rist_hours_breakfast: "Colazione a buffet: tutti i giorni 08:00 - 10:00",
btn_menu_whatsapp: "Richiedi Menù del Giorno",
btn_view_menu: "Sfoglia il Menù",
btn_book_whatsapp: "Prenota su WhatsApp",
// Servizi
eyebrow_servizi: "Esperienza Completa",
title_servizi: "Servizi per il Tuo Benessere",
desc_servizi: "Ogni dettaglio è pensato per il relax tuo e della tua famiglia.",
srv_pool_title: "Piscina al Sale",
srv_pool_desc: "Acqua purificata al sale marino senza cloro chimico aggiunto.",
srv_pet_title: "Pet-Friendly",
srv_pet_desc: "Gli amici a 4 zampe sono i benvenuti nel villaggio.",
srv_rec_title: "Reception 12 Ore",
srv_rec_desc: "Accoglienza attiva 8-20, accesso disabili e WhatsApp sempre disponibile.",
srv_parking_title: "Parcheggio Privato",
srv_parking_desc: "Ampio parcheggio interno e recintato, gratuito per tutti i nostri ospiti.",
srv_parking_detail: "Parcheggio gratuito · Custodito e illuminato",
srv_wifi_title: "Wi-Fi Gratuito",
srv_wifi_desc: "Connessione ultraveloce in ogni punto del villaggio.",
srv_bfast_title: "Colazione a Buffet",
srv_bfast_desc: "Dolce e salato ogni mattina con dolci fatti in casa.",
srv_green_title: "Servizi Comuni Campeggio",
srv_green_desc: "Colonnina allaccio elettrico, camper service, bagni comuni accessibili ai disabili, lavanderia e area BBQ (a pagamento e su prenotazione).",
srv_bike_title: "Noleggio Biciclette",
srv_bike_desc: "Direttamente in reception per pedalare lungo la Destra Po.",
srv_greenery_title: "Relax nel Verde",
srv_greenery_desc: "Giardini curati, fioriture di lavanda, delosperma e gerani.",
btn_more_details: "Scopri dettagli →",
btn_book_this_service: "Prenota Soggiorno",
btn_close_modal: "Chiudi",
// Testimonials / Recensioni
eyebrow_recensioni: "Dicono di Noi · Esperienze Reali",
title_recensioni: "Cosa Raccontano i Nostri Ospiti",
desc_recensioni: "Autentiche testimonianze verificate da Google e Booking.com.",
// Chi siamo
about_title: "Stellata di Bondeno: Dove la Terra Incontra il Po",
about_desc: "Siamo nati per offrire un turismo autentico e sostenibile nel cuore della pianura padana.",
stat_stars: "Stelle Ufficiali",
stat_pitches: "Piazzole Alberate",
stat_cottages: "Villette a Tema",
stat_river: "Distanza dall'Argine",
// Contatti
eyebrow_contatti: "Parla con Noi",
title_contatti: "Contatti & Prenotazioni",
desc_contatti: "Siamo a tua disposizione tutti i giorni dalle 08:00 alle 20:00.",
lbl_addr: "Indirizzo",
lbl_tel: "Telefono Fisso",
lbl_mob: "Cellulare & WhatsApp",
lbl_mail: "Email Diretta",
lbl_reception: "Orari Reception",
btn_send_direct_wa: "Scrivici su WhatsApp",
// ACSI Partner Banner
acsi_tag: "Partnership Ufficiale",
acsi_title: "Siamo orgogliosamente convenzionati con ACSI",
acsi_desc: "Accogliamo i possessori di CampingCard ACSI offrendo tariffe agevolate e tutti i migliori comfort immersi nella natura del Po.",
acsi_verified: "Club Convenzionato",
// Modal Booking
modal_title: "Richiesta di Prenotazione Online",
modal_complete_title: "Completa la tua richiesta",
modal_complete_subtitle: "Inserisci i tuoi dati per finalizzare la richiesta di prenotazione.",
modal_subtitle: "Compila i dettagli e ricevi conferma immediata su WhatsApp o Email.",
modal_lbl_type: "Tipologia di Soggiorno",
modal_lbl_dates: "Date Selezionate",
modal_lbl_adults: "Adulti (15+ anni)",
modal_lbl_child_young: "Bambini (0-5 anni) - Gratis",
modal_lbl_child_old: "Ragazzi (6-14 anni)",
modal_lbl_pets: "Animali Domestici",
modal_lbl_name: "Nome e Cognome *",
modal_lbl_firstname: "Nome *",
modal_lbl_lastname: "Cognome *",
modal_lbl_email: "Indirizzo Email *",
modal_lbl_phone: "Numero di Telefono *",
modal_lbl_notes: "Note o richieste particolari",
modal_btn_submit: "Invia Richiesta",
modal_btn_submit_request: "Invia Richiesta",
modal_btn_submit_mail: "Richiedi via Email",
modal_btn_whatsapp: "Invia via WhatsApp",
// FAQ (Domande Frequenti)
eyebrow_faq: "Informazioni Utili",
title_faq: "Domande Frequenti",
desc_faq: "Tutto quello che c'è da sapere prima e durante il tuo soggiorno nel nostro villaggio.",
faq_q1: "Gli animali sono ammessi?",
faq_a1: "Sì, siamo una struttura Pet Friendly. I vostri amici a quattro zampe sono i benvenuti nei nostri spazi all'aperto e in alloggi dedicati.",
faq_q2: "Quali sono gli orari di Check-in e Check-out?",
faq_a2: "Il Check-in è disponibile dalle 14:00 alle 20:00. Il Check-out è richiesto entro le 10:30.",
faq_q3: "La piscina è aperta a tutti?",
faq_a3: "La piscina al sale è stagionale (01/06 - 15/09) e l'accesso è riservato e gratuito per gli ospiti che soggiornano nel villaggio.",
faq_q4: "C'è il parcheggio?",
faq_a4: "Sì, offriamo un parcheggio privato e gratuito all'interno della struttura per i nostri ospiti.",
btn_mobile_sticky_book: "Prenota Ora",
// Cookie Banner
cookie_text: "Utilizziamo cookie tecnici per assicurare il corretto funzionamento del sito e migliorare la tua esperienza di navigazione in conformità al GDPR.",
cookie_accept: "Accetta",
cookie_decline: "Rifiuta"
},
en: {
// Header & Nav
nav_oggi: "🗓️ Today at Village",
nav_alloggi: "Accommodations/Pitches",
nav_territorio: "Experiences & Territory",
nav_ristorante: "Restaurant",
nav_servizi: "Services",
nav_recensioni: "Reviews",
nav_faq: "F.A.Q.",
nav_chi_siamo: "About Us",
nav_contatti: "Contacts",
nav_prenota: "Book Now",
// Hero
hero_badge: "Holiday Resort · 3 Stars",
hero_title: "Nature, silence and tradition 2 steps from the great Po river",
hero_lead: "Eco-resort featuring wooden cottages, vintage caravans, traditional dining, saltwater pool and pier on the Po river.",
hero_btn_explore: "Explore Village",
hero_btn_restaurant: "Our Restaurant",
hero_btn_book: "Check Availability",
// Booking Bar & Feedback Toast
lbl_checkin: "Check-In",
lbl_checkout: "Check-Out",
lbl_alloggio: "Accommodation",
lbl_ospiti: "Guests",
opt_all_villetta: "Eco Cottages (6 themes)",
opt_all_caravan: "Vintage Caravans (4 themes)",
opt_all_tent: "Tent Pitch",
opt_all_camper: "Camper / RV Pitch",
btn_calculate_quote: "Get Instant Quote",
btn_verify_availability: "Check Availability",
toast_booking_success: "Request sent! You will soon receive a summary email.",
modal_lbl_amenities: "Features & Amenities",
// Section Headers
eyebrow_alloggi: "Hospitality & Nature",
title_alloggi: "Our Eco-Friendly Accommodations & Pitches",
desc_alloggi: "Choose between themed cottages, vintage caravans and shaded campsite pitches.",
// Experiences & Territory (10 Cards)
eyebrow_territorio: "Experiences & Territory",
title_territorio: "Experiences & Territory",
desc_territorio: "Discover the highlights of the Great River Po, with bike trails, history, events and relaxation.",
exp_badge_1: "SPECIAL",
exp_title_1: "Lucciole Special Events",
exp_desc_1: "Special events on site: Halloween, Easter, tasting dinners and theme evenings.",
exp_badge_2: "2nd SUN",
exp_title_2: "Stellata Antique Fair",
exp_desc_2: "Hundreds of exhibitors in Stellata village every second Sunday of the month.",
exp_badge_3: "SAT / SUN",
exp_title_3: "Rocca Possente of Stellata",
exp_desc_3: "Weekend openings: visit the historic fortress landmark on the Po river.",
exp_badge_4: "ALWAYS",
exp_title_4: "The Great Cycleways",
exp_desc_4: "Destra Po, EuroVelo 7, EuroVelo 8 and VENTO with direct trail access.",
exp_badge_5: "ALWAYS",
exp_title_5: "Romea Strata Pilgrimage",
exp_desc_5: "Ancient walking pilgrimage route along the Po banks for slow tourism.",
exp_badge_6: "WEEKLY",
exp_title_6: "Nearby Local Markets",
exp_desc_6: "Mon & Fri (Ferrara), Tue (Bondeno local & produce), Thu (Sermide).",
exp_badge_7: "CULTURE",
exp_title_7: "History, Antiques & Culture",
exp_desc_7: "From the Rocca Possente of Stellata to the Estense Castle in Ferrara, and the historic museums of the Po River.",
exp_badge_8: "RESERVATION",
exp_title_8: "Po River Boat Excursions",
exp_desc_8: "River cruise embarking from our private dock. Booking required (weather permitting).",
exp_badge_9: "YEAR-ROUND",
exp_title_9: "Local Events & Festivals",
exp_desc_9: "Traditional village festivals, food fairs and cultural events active all year round.",
exp_badge_10: "01/06 - 15/09",
exp_title_10: "Saltwater Pool",
exp_desc_10: "Open every day during the summer season (01/06 - 15/09). Free entry for our guests.",
tab_all: "All",
tab_villette: "Cottages (6)",
tab_caravan: "Caravans (4)",
tab_camping: "Camping (22)",
card_from: "from",
card_per_night: "/night",
btn_view_book: "Book Unit",
// Alloggi Cards Copy
villetta_card_title: "Eco-Friendly Cottages",
villetta_card_desc: "Six independent themed wooden cottages with private porch.",
villetta_feat_1: "Air conditioning & heating climate control",
villetta_feat_2: "Equipped kitchenette and private outdoor porch",
villetta_feat_3: "Accessible for disabled guests · Zero barriers",
villetta_feat_4: "Private bathroom with solar-heated shower and pool access",
caravan_card_title: "Vintage Caravans",
caravan_card_desc: "Retro outdoor vibe with modern comfort under the trees.",
caravan_feat_1: "Air conditioning & climate control",
caravan_feat_2: "Mini fridge, bed linen included and shaded veranda",
caravan_feat_3: "Warm, pristine and accessible shared bathrooms",
camping_card_title: "Tent & Camper Pitches",
camping_card_desc: "22 spacious 55sqm pitches on driveable shaded grass lawn.",
camping_feat_1: "Constant natural shade from mature trees",
camping_feat_2: "220V electricity and water drain service",
camping_feat_3: "Coin laundry and masonry barbecue area",
// Ristorante
eyebrow_ristorante: "Regional Flavours",
title_ristorante: "Lucciole Restaurant & Bar",
desc_ristorante: "Authentic Emilian recipes made with fresh organic garden ingredients.",
rist_feat_1: "Handmade fresh egg pasta and tortelli",
rist_feat_2: "Local artisanal cured meats and regional wines",
rist_feat_3: "Buffet breakfast and fresh cold-pressed seasonal juices",
rist_feat_4: "Accessible for disabled guests / Zero architectural barriers",
rist_hours_title: "Opening Hours",
rist_hours_dinner: "Dinner: Mon, Tue, Fri, Sat, Sun from 19:30",
rist_hours_lunch: "Lunch: Sunday from 12:30",
rist_hours_breakfast: "Buffet Breakfast: daily 08:00 - 10:00",
btn_menu_whatsapp: "Request Daily Menu",
btn_view_menu: "Browse Menu",
btn_book_whatsapp: "Book on WhatsApp",
// Servizi
eyebrow_servizi: "Complete Comfort",
title_servizi: "Services for Your Well-being",
desc_servizi: "Every detail crafted for you and your family's relaxation.",
srv_pool_title: "Saltwater Swimming Pool",
srv_pool_desc: "Sea salt purified water without added chlorine.",
srv_pet_title: "Pet-Friendly Resort",
srv_pet_desc: "Pets are warmly welcomed throughout the village.",
srv_rec_title: "12-Hour Reception",
srv_rec_desc: "Staff available 8-20, accessible facilities & responsive WhatsApp support.",
srv_parking_title: "Private Parking",
srv_parking_desc: "Spacious, fenced on-site parking, free for all resort guests.",
srv_parking_detail: "Free private parking · Secure and well-lit",
srv_wifi_title: "Free High-Speed Wi-Fi",
srv_wifi_desc: "Fast connection across every corner of the village.",
srv_bfast_title: "Buffet Breakfast",
srv_bfast_desc: "Sweet and savoury spread with homemade daily pies.",
srv_green_title: "Campsite Shared Facilities",
srv_green_desc: "Electric hookup pillar, camper service, wheelchair-accessible shared bathrooms, laundry and BBQ area (paid, on reservation).",
srv_bike_title: "Bicycle Rental",
srv_bike_desc: "Directly at reception for scenic rides along the Destra Po.",
srv_greenery_title: "Green Relaxation",
srv_greenery_desc: "Lush gardens, blooms of lavender, delosperma and geraniums.",
btn_more_details: "View details →",
btn_book_this_service: "Book Your Stay",
btn_close_modal: "Close",
// Testimonials
eyebrow_recensioni: "Guest Reviews · Authentic Stories",
title_recensioni: "What Our Guests Say About Us",
desc_recensioni: "Verified real reviews from Google and Booking.com.",
// Chi siamo
about_title: "Stellata di Bondeno: Where Land Meets the Po",
about_desc: "Created to deliver genuine, sustainable hospitality in the heart of northern Italy.",
stat_stars: "Official Stars",
stat_pitches: "Shaded Pitches",
stat_cottages: "Themed Cottages",
stat_river: "From River Bank",
// Contatti
eyebrow_contatti: "Get in Touch",
title_contatti: "Contact & Reservations",
desc_contatti: "We are gladly at your service every day from 08:00 to 20:00.",
lbl_addr: "Address",
lbl_tel: "Landline Phone",
lbl_mob: "Mobile & WhatsApp",
lbl_mail: "Direct Email",
lbl_reception: "Reception Hours",
btn_send_direct_wa: "Chat on WhatsApp",
// ACSI Partner Banner
acsi_tag: "Official Partnership",
acsi_title: "Proudly affiliated with ACSI",
acsi_desc: "We welcome CampingCard ACSI holders with special rates and top comfort surrounded by nature.",
acsi_verified: "Affiliated Club",
// Modal Booking
modal_title: "Online Booking Request",
modal_complete_title: "Complete your request",
modal_complete_subtitle: "Enter your details to finalize your booking request.",
modal_subtitle: "Fill in the details to receive instant confirmation via WhatsApp or Email.",
modal_lbl_type: "Accommodation Type",
modal_lbl_dates: "Selected Dates",
modal_lbl_adults: "Adults (15+ yrs)",
modal_lbl_child_young: "Children (0-5 yrs) - Free",
modal_lbl_child_old: "Children (6-14 yrs)",
modal_lbl_pets: "Pets",
modal_lbl_name: "Full Name *",
modal_lbl_firstname: "First Name *",
modal_lbl_lastname: "Last Name *",
modal_lbl_email: "Email Address *",
modal_lbl_phone: "Phone Number *",
modal_lbl_notes: "Special requests or notes",
modal_btn_submit: "Submit Request",
modal_btn_submit_request: "Submit Request",
modal_btn_submit_mail: "Request via Email",
modal_btn_whatsapp: "Send via WhatsApp",
// FAQ (Frequently Asked Questions)
eyebrow_faq: "Useful Information",
title_faq: "Frequently Asked Questions",
desc_faq: "Everything you need to know before and during your stay at our resort.",
faq_q1: "Are pets allowed?",
faq_a1: "Yes, we are a Pet Friendly resort. Your four-legged friends are warmly welcome in our outdoor areas and dedicated accommodations.",
faq_q2: "What are the Check-in and Check-out times?",
faq_a2: "Check-in is available from 14:00 to 20:00. Check-out is required by 10:30.",
faq_q3: "Is the pool open to everyone?",
faq_a3: "The saltwater swimming pool is seasonal (01/06 - 15/09) and access is exclusively reserved and free for staying resort guests.",
faq_q4: "Is parking available?",
faq_a4: "Yes, we offer free private on-site parking for all our staying guests.",
btn_mobile_sticky_book: "Book Now",
// Cookie Banner
cookie_text: "We use technical cookies to ensure smooth website operation and provide the best user experience in accordance with GDPR.",
cookie_accept: "Accept",
cookie_decline: "Decline"
}
};
// Structured Service Modal Details (Rich, concise, 3-photo lazy-load arrays & SVG Amenities)
const SERVICE_DETAILS = {
"piscina-sale": {
icon: `
`,
photos: [
"assets/images/pool.jpg",
"assets/images/hero.jpg",
"assets/images/villette.jpg"
],
it: {
title: "Piscina al Sale Marino Naturale",
badge: "100% Ecologica · Senza Cloro Chimico",
summary: "Purificazione naturale al sale marino: acqua cristallina che rispetta la pelle e non irrita gli occhi.",
photoLabels: ["Piscina al sale marino", "Solarium con lettini", "Vista sulla tenuta"],
amenities: [
{ icon: `
`, label: "Sale Marino" },
{ icon: `
`, label: "Solarium & Lettini" },
{ icon: `
`, label: "Senza Cloro" },
{ icon: `
`, label: "Accesso Gratuito" }
],
bullets: [
"Profondità 1.50m ideale per nuoto e relax",
"Solarium attrezzato con lettini e ombrelloni",
"Accesso libero e gratuito per tutti gli ospiti",
"Cuffia obbligatoria per la massima igiene"
]
},
en: {
title: "Natural Saltwater Swimming Pool",
badge: "100% Eco-Friendly · No Added Chemical Chlorine",
summary: "Natural marine salt purification: crystal-clear water gentle on skin and eyes.",
photoLabels: ["Natural saltwater pool", "Sundeck with loungers", "Estate view"],
amenities: [
{ icon: `
`, label: "Natural Sea Salt" },
{ icon: `
`, label: "Equipped Sundeck" },
{ icon: `
`, label: "Chlorine Free" },
{ icon: `
`, label: "Free Guest Access" }
],
bullets: [
"1.50m depth ideal for leisure and swimming",
"Equipped sundeck with sunbeds and umbrellas",
"Free unlimited access for all resort guests",
"Swim cap required for pristine hygiene"
]
}
},
"pet-friendly": {
icon: `
`,
photos: [
"assets/images/hero.jpg",
"assets/images/caravan.jpg",
"assets/images/villette.jpg"
],
it: {
title: "Villaggio Pet-Friendly",
badge: "Cani & Animali Benvenuti",
summary: "Cani e gatti sempre benvenuti nelle villette dedicate, nei caravan e in piazzola.",
photoLabels: ["Spazi aperti sul Po", "Verande per animali", "Villette nel verde"],
amenities: [
{ icon: `
`, label: "Cani & Gatti Ammessi" },
{ icon: `
`, label: "Passeggiate Argine" },
{ icon: `
`, label: "Ciotole Reception" },
{ icon: `
`, label: "Docce Risciacquo" }
],
bullets: [
"Ampi giardini e percorsi pedonali sull'argine",
"Ciotole acqua e cibo fornite alla reception",
"Punti risciacquo rapido dopo le passeggiate",
"Guinzaglio nelle aree comuni (€4/notte per animale)"
]
},
en: {
title: "Pet-Friendly Resort",
badge: "Dogs & Pets Welcome",
summary: "Dogs and cats warmly welcomed across cottages, caravans and shaded pitches.",
photoLabels: ["Open riverfront spaces", "Pet-friendly verandas", "Green cottage setting"],
amenities: [
{ icon: `
`, label: "Dogs & Cats Allowed" },
{ icon: `
`, label: "River Embankment" },
{ icon: `
`, label: "Bowls at Desk" },
{ icon: `
`, label: "Washdown Points" }
],
bullets: [
"Vast leafy grounds and scenic river trails",
"Water and food bowls available at front desk",
"Outdoor washdown spots after walks",
"Leash in common areas (€4/night per pet)"
]
}
},
"reception-12h": {
icon: `
`,
photos: [
"assets/images/restaurant.jpg",
"assets/images/hero.jpg",
"assets/images/villette.jpg"
],
it: {
title: "Reception & Assistenza 12 Ore",
badge: "08:00 - 20:00 · WhatsApp H24",
summary: "Accoglienza dedicata per check-in, mappe del territorio e prenotazione escursioni.",
photoLabels: ["Punto accoglienza & bar", "Mappe e info percorsi", "Assistenza ospiti"],
amenities: [
{ icon: `
`, label: "Orari 08:00 - 20:00" },
{ icon: `
`, label: "WhatsApp H24" },
{ icon: `
`, label: "Mappe del Territorio" },
{ icon: `
`, label: "Noleggio Bici" }
],
bullets: [
"Check-in rapido con mappe cicloturistiche",
"Assistenza WhatsApp: +39 327 7329994",
"Noleggio bici ed escursioni in barca",
"Deposito bagagli e consigli su sagre ed eventi"
]
},
en: {
title: "12-Hour Reception & Guest Care",
badge: "08:00 - 20:00 · Fast WhatsApp Support",
summary: "Dedicated staff for check-in, local route maps and boat tour bookings.",
photoLabels: ["Front desk & bar", "Maps and trail info", "Guest care services"],
amenities: [
{ icon: `
`, label: "Hours 08:00 - 20:00" },
{ icon: `
`, label: "WhatsApp H24" },
{ icon: `
`, label: "Local Trail Maps" },
{ icon: `
`, label: "Bike Rental" }
],
bullets: [
"Quick check-in with cycleway route maps",
"Instant WhatsApp support: +39 327 7329994",
"Bike rentals and river boat tour bookings",
"Luggage storage and local event tips"
]
}
},
"wifi-gratuito": {
icon: `
`,
photos: [
"assets/images/villette.jpg",
"assets/images/caravan.jpg",
"assets/images/pool.jpg"
],
it: {
title: "Wi-Fi Gratuito in Tutta la Struttura",
badge: "Fibra Ottica ad Alta Velocità",
summary: "Connessione internet veloce e affidabile in tutte le aree del villaggio e a bordo piscina.",
photoLabels: ["Wi-Fi nelle casette", "Copertura piazzole", "Connessione in piscina"],
amenities: [
{ icon: `
`, label: "Fibra Ultraveloce" },
{ icon: `
`, label: "Villette & Caravan" },
{ icon: `
`, label: "22 Piazzole" },
{ icon: `
`, label: "Senza Password" }
],
bullets: [
"Access point dedicati in ogni villetta e caravan",
"Copertura su tutte le 22 piazzole del campeggio",
"Segnale stabile per smart working e videochiamate",
"Accesso libero e immediato senza password complesse"
]
},
en: {
title: "Free High-Speed Wi-Fi",
badge: "Full Fiber Coverage",
summary: "Fast and reliable internet across all cottages, camping pitches and poolside.",
photoLabels: ["Wi-Fi in cottages", "Camping pitch coverage", "Poolside signal"],
amenities: [
{ icon: `
`, label: "High-Speed Fiber" },
{ icon: `
`, label: "Cottages & Caravans" },
{ icon: `
`, label: "22 Camping Pitches" },
{ icon: `
`, label: "No Complex Login" }
],
bullets: [
"Dedicated access points per cottage and caravan",
"Full coverage across all 22 campsite pitches",
"Stable connection for remote work & streaming",
"Instant one-click access with no complex portal"
]
}
},
"colazione": {
icon: `
`,
photos: [
"assets/images/restaurant.jpg",
"assets/images/pool.jpg",
"assets/images/hero.jpg"
],
it: {
title: "Colazione a Buffet Dolce & Salata",
badge: "Tutti i Giorni · 08:00 - 10:00",
summary: "Dolci fatti in casa, salumi tipici emiliani ed estratti freschi del nostro orto.",
photoLabels: ["Buffet dolce e salato", "Colazione all'aperto", "Prodotti a km zero"],
amenities: [
{ icon: `
`, label: "Buffet Artigianale" },
{ icon: `
`, label: "Torte Casalinghe" },
{ icon: `
`, label: "Salumi Tipici" },
{ icon: `
`, label: "Estratti Freschi" }
],
bullets: [
"Torte e crostate artigianali sfornate ogni giorno",
"Salumi e formaggi del territorio con pane fresco",
"Caffetteria espressa italiana e spremute fresche",
"Opzioni senza glutine e vegetariane su richiesta"
]
},
en: {
title: "Sweet & Savoury Buffet Breakfast",
badge: "Daily · 08:00 - 10:00",
summary: "Daily baked homemade pastries, local artisan cold cuts and fresh garden juices.",
photoLabels: ["Sweet & savoury buffet", "Outdoor morning dining", "Local ingredients"],
amenities: [
{ icon: `
`, label: "Artisanal Buffet" },
{ icon: `
`, label: "Homemade Cakes" },
{ icon: `
`, label: "Local Cold Cuts" },
{ icon: `
`, label: "Fresh Juices" }
],
bullets: [
"Freshly baked homemade cakes and tarts daily",
"Local Emilian cold cuts, cheeses and fresh bread",
"Authentic Italian espresso bar and fruit juices",
"Gluten-free and vegetarian items on request"
]
}
},
"servizi-campeggio": {
icon: `
`,
photos: [
"assets/images/villette.jpg",
"assets/images/pool.jpg",
"assets/images/caravan.jpg"
],
it: {
title: "Servizi Comuni Campeggio",
badge: "Comfort Completo · 100% Green",
summary: "Colonnina allaccio elettrico, camper service, bagni comuni, lavanderia e area BBQ (a pagamento e su prenotazione).",
photoLabels: ["Pannelli solari & docce", "Area barbecue nel verde", "Lavanderia a gettoni"],
amenities: [
{ icon: `
`, label: "Allaccio 220V" },
{ icon: `
`, label: "Docce Calde Solari" },
{ icon: `
`, label: "Camper Service" },
{ icon: `
`, label: "Area BBQ" }
],
bullets: [
"Colonnine per allaccio elettrico 220V e camper service",
"Bagni riscaldati con docce calde da solare termico e fasciatoio",
"Lavanderia a gettoni e vasche dedicate per stoviglie",
"Area barbecue in muratura prenotabile con griglia e lavello"
]
},
en: {
title: "Campsite Shared Facilities",
badge: "Full Comfort · 100% Eco-Friendly",
summary: "Electric hookup pillars, camper service, shared bathrooms, laundry and BBQ area (paid and on reservation).",
photoLabels: ["Solar thermal & showers", "Masonry BBQ area", "Coin laundry facility"],
amenities: [
{ icon: `
`, label: "220V Hookup" },
{ icon: `
`, label: "Solar Showers" },
{ icon: `
`, label: "Camper Service" },
{ icon: `
`, label: "BBQ Area" }
],
bullets: [
"220V electrical hookup pillars and camper dump/fill service",
"Heated bathrooms with solar hot showers & nursery",
"Coin-operated laundry and dishwashing sinks",
"Bookable masonry barbecue with food prep area by the pool"
]
}
},
"green-facilities": {
icon: `
`,
photos: [
"assets/images/villette.jpg",
"assets/images/pool.jpg",
"assets/images/caravan.jpg"
],
it: {
title: "Servizi Comuni Campeggio",
badge: "Comfort Completo · 100% Green",
summary: "Colonnina allaccio elettrico, camper service, bagni comuni, lavanderia e area BBQ (a pagamento e su prenotazione).",
photoLabels: ["Pannelli solari & docce", "Area barbecue nel verde", "Lavanderia a gettoni"],
amenities: [
{ icon: `
`, label: "Allaccio 220V" },
{ icon: `
`, label: "Docce Calde Solari" },
{ icon: `
`, label: "Camper Service" },
{ icon: `
`, label: "Area BBQ" }
],
bullets: [
"Colonnine per allaccio elettrico 220V e camper service",
"Bagni riscaldati con docce calde da solare termico e fasciatoio",
"Lavanderia a gettoni e vasche dedicate per stoviglie",
"Area barbecue in muratura prenotabile con griglia e lavello"
]
},
en: {
title: "Campsite Shared Facilities",
badge: "Full Comfort · 100% Eco-Friendly",
summary: "Electric hookup pillars, camper service, shared bathrooms, laundry and BBQ area (paid and on reservation).",
photoLabels: ["Solar thermal & showers", "Masonry BBQ area", "Coin laundry facility"],
amenities: [
{ icon: `
`, label: "220V Hookup" },
{ icon: `
`, label: "Solar Showers" },
{ icon: `
`, label: "Camper Service" },
{ icon: `
`, label: "BBQ Area" }
],
bullets: [
"220V electrical hookup pillars and camper dump/fill service",
"Heated bathrooms with solar hot showers & nursery",
"Coin-operated laundry and dishwashing sinks",
"Bookable masonry barbecue with food prep area by the pool"
]
}
},
"noleggio-bici": {
icon: `
`,
photos: [
"assets/images/hero.jpg",
"assets/images/villette.jpg",
"assets/images/caravan.jpg"
],
it: {
title: "Noleggio Biciclette & E-Bike",
badge: "Direttamente in Reception",
summary: "City bike ed e-bike disponibili per scoprire la pista ciclabile Destra Po ed EuroVelo 8.",
photoLabels: ["Biciclette in reception", "Pista ciclabile Destra Po", "Mappe e accessori"],
amenities: [
{ icon: `
`, label: "City & E-Bike" },
{ icon: `
`, label: "Caschi & Lucchetti" },
{ icon: `
`, label: "Mappe EuroVelo 8" },
{ icon: `
`, label: "Punto Ricarica" }
],
bullets: [
"Noleggio giornaliero o per l'intero soggiorno",
"Bici tradizionali ed e-bike a pedalata assistita",
"Accessori inclusi: caschetto, lucchetto e kit gonfiaggio",
"Mappe percorsi cicloturistici verso Ferrara e Mantova"
]
},
en: {
title: "Bicycle & E-Bike Rental",
badge: "Directly at Front Desk",
summary: "City bikes and e-bikes available to explore the scenic Destra Po and EuroVelo 8 cycle trails.",
photoLabels: ["Bikes at reception", "Destra Po cycling path", "Maps and gear"],
amenities: [
{ icon: `
`, label: "City & E-Bikes" },
{ icon: `
`, label: "Helmets & Locks" },
{ icon: `
`, label: "EuroVelo 8 Maps" },
{ icon: `
`, label: "Charging Point" }
],
bullets: [
"Daily or whole-stay flexible bike rental",
"Standard classic bikes and pedal-assist e-bikes",
"Included gear: helmet, security lock and pump kit",
"Scenic trail maps towards Ferrara and Mantua"
]
}
},
"relax-nel-verde": {
icon: `
`,
photos: [
"assets/images/hero.jpg",
"assets/images/villette.jpg",
"assets/images/pool.jpg"
],
it: {
title: "Relax nel Verde & Giardini Fioriti",
badge: "Spazi Esterni · Fioriture Stagionali",
summary: "Giardini curati con aiuole di lavanda profumata, delosperma colorato e ombra naturale di salici e querce.",
photoLabels: ["Fioriture di lavanda", "Vialetti e giardini", "Ombra naturale sul Po"],
amenities: [
{ icon: `
`, label: "Aiuole di Lavanda" },
{ icon: `
`, label: "Delosperma Fiorito" },
{ icon: `
`, label: "Gerani Rustici" },
{ icon: `
`, label: "Ombra dei Salici" }
],
bullets: [
"Aiuole di lavanda officinale per percorsi aromatici",
"Fioriture vivaci di delosperma e gerani rustici",
"Angoli d'ombra con salici e querce per lettura e relax",
"Frutteto biologico comune con fichi, melograni e more"
]
},
en: {
title: "Green Relaxation & Blooming Gardens",
badge: "Outdoor Grounds · Seasonal Blooms",
summary: "Landscaped gardens with fragrant lavender beds, vivid delosperma and natural willow shade.",
photoLabels: ["Fragrant lavender beds", "Pathways & gardens", "River willow shade"],
amenities: [
{ icon: `
`, label: "Lavender Beds" },
{ icon: `
`, label: "Delosperma Blooms" },
{ icon: `
`, label: "Rustic Geraniums" },
{ icon: `
`, label: "Natural Willow Shade" }
],
bullets: [
"Fragrant lavender borders for aromatic garden strolls",
"Vibrant delosperma blossoms and rustic geraniums",
"Natural shade spots under willows and mature oaks",
"Organic orchard with zero-km figs, pomegranates & berries"
]
}
},
"parcheggio-privato": {
icon: `
`,
photos: [
"assets/images/hero.jpg",
"assets/images/villette.jpg",
"assets/images/caravan.jpg"
],
it: {
title: "Parcheggio Privato Gratuito",
badge: "Interno & Recintato · Gratuito per gli Ospiti",
summary: "Ampio parcheggio interno, ombreggiato e recintato, con comodo accesso diretto a tutti gli alloggi.",
photoLabels: ["Area parcheggio interna", "Accesso sicuro al villaggio", "Spazi riservati"],
amenities: [
{ icon: `
`, label: "Gratuito" },
{ icon: `
`, label: "Recintato & Sicuro" },
{ icon: `
`, label: "Illuminato H24" },
{ icon: `
`, label: "Posti Camper/Auto" }
],
bullets: [
"Posto auto gratuito garantito per ogni alloggio e piazzola",
"Area interna protetta, recintata e costantemente illuminata",
"Comodo accesso a villette, roulotte e zona campeggio",
"Possibilità di parcheggio per carrelli barca e van"
]
},
en: {
title: "Free Private On-Site Parking",
badge: "Fenced & Secure · Free for Guests",
summary: "Spacious, shaded and fenced internal parking area with easy direct access to all accommodations.",
photoLabels: ["Internal parking lot", "Secure village gates", "Dedicated parking bays"],
amenities: [
{ icon: `
`, label: "100% Free" },
{ icon: `
`, label: "Fenced & Secure" },
{ icon: `
`, label: "24h Well-Lit" },
{ icon: `
`, label: "Car & Camper Bays" }
],
bullets: [
"Guaranteed free parking spot for every unit and pitch",
"Protected internal lot, fully fenced and well-lit at night",
"Effortless access to cottages, caravans and camping area",
"Parking space available for boat trailers and vans"
]
}
}
};
// Structured Activity Modal Details (Rich, concise, 3-photo lazy-load arrays)
const ACTIVITY_DETAILS = {
"cicloturismo": {
photos: [
"assets/images/hero.jpg",
"assets/images/villette.jpg",
"assets/images/caravan.jpg"
],
it: {
title: "Cicloturismo Destra Po & EuroVelo 8",
badge: "Itinerario Ciclabile · Destra Po",
summary: "Pedala sulla ciclabile più lunga d'Italia partendo direttamente dal cancello del villaggio.",
photoLabels: ["Pista ciclabile Destra Po", "Noleggio bici ed e-bike", "Partenza dal villaggio"],
bullets: [
"Accesso ciclabile diretto dal villaggio",
"Noleggio bici muscolari ed e-bike con punto ricarica",
"Itinerari pianeggianti per Ferrara (28 km) e Mantova (45 km)",
"Piccola officina con attrezzi e pompa per manutenzione"
]
},
en: {
title: "Destra Po Cycling Route & EuroVelo 8",
badge: "Cycling Route · Destra Po",
summary: "Ride along Italy's longest scenic cycling path right from our resort gates.",
photoLabels: ["Destra Po cycle route", "Bike & e-bike rental", "Direct resort access"],
bullets: [
"Direct cycling route access from the village",
"Standard bike & e-bike rental with charging point",
"Flat scenic routes to Ferrara (28 km) and Mantua (45 km)",
"On-site bike repair tools and pump station"
]
}
},
"escursioni-barca": {
photos: [
"assets/images/hero.jpg",
"assets/images/pool.jpg",
"assets/images/restaurant.jpg"
],
it: {
title: "Escursioni in Barca & Isola Tontola",
badge: "Navigazione Fluviale · Po e Panaro",
summary: "Naviga sul Po fino alla Riserva Naturale Isola Tontola con partenza dal nostro pontile privato.",
photoLabels: ["Pontile d'imbarco sul Po", "Riserva Isola Tontola", "Escursione in batana"],
bullets: [
"Pontile galleggiante privato a 100 metri",
"Noleggio batana tipica in legno o tour con skipper",
"Itinerari per birdwatching ed esplorazione fluviale",
"Navigazione panoramica verso la confluenza del Panaro"
]
},
en: {
title: "River Boat Tours & Isola Tontola",
badge: "River Navigation · Po & Panaro",
summary: "Sail the Po up to Isola Tontola Nature Reserve departing from our private pier.",
photoLabels: ["Private river pier", "Isola Tontola reserve", "Traditional boat tour"],
bullets: [
"Private docking pier just 100 meters away",
"Traditional wooden boat rental or skippered tour",
"Scenic routes for birdwatching and wetland discovery",
"Boat trips to the historic Panaro confluence"
]
}
},
"pesca": {
photos: [
"assets/images/hero.jpg",
"assets/images/restaurant.jpg",
"assets/images/caravan.jpg"
],
it: {
title: "Pesca Sportiva, Siluro & Adriatico",
badge: "Catch & Release · Fiume & Mare",
summary: "Spot esclusivi per carpfishing e siluro notturno sul Po, oltre a uscite in mare aperto.",
photoLabels: ["Spot di pesca sul Po", "Battute al siluro notturno", "Uscite in Adriatico"],
bullets: [
"Postazioni rinomate per carpfishing e siluro notturno",
"Etica no-kill nel rispetto dell'ecosistema fluviale",
"Battute guidate in mare per la pesca al tonno rosso",
"Possibilità di ormeggio per barche da pesca private"
]
},
en: {
title: "Sport Fishing, Catfish & Sea",
badge: "Catch & Release · No-Kill",
summary: "Top spots for carpfishing and night catfish on the Po, plus offshore sea fishing trips.",
photoLabels: ["River fishing spots", "Night catfish angling", "Adriatic tuna trips"],
bullets: [
"Renowned river spots for carp and giant catfish",
"Strict catch & release environmental policy",
"Guided offshore bluefin tuna trips in the Adriatic",
"Mooring spots available for private fishing boats"
]
}
},
"oasi-naturali": {
photos: [
"assets/images/pool.jpg",
"assets/images/hero.jpg",
"assets/images/villette.jpg"
],
it: {
title: "Oasi Naturalistiche & Bosco Panfilia",
badge: "Natura Protetta · Oasi WWF",
summary: "Passeggiate e birdwatching nel Bosco della Panfilia e tra le lucciole delle golene del Po.",
photoLabels: ["Bosco della Panfilia", "Flora e fauna protetta", "Passeggiate serali"],
bullets: [
"Sentieri nel Bosco della Panfilia a Sant'Agostino",
"Oasi di Vigarano Pieve per fotografia e birdwatching",
"Boschi golenali con salici, pioppi e querce secolari",
"Camminate notturne per ammirare lo spettacolo delle lucciole"
]
},
en: {
title: "Nature Oases & Panfilia Woods",
badge: "Protected Nature · Wetland Oases",
summary: "Scenic walking trails and birdwatching in ancient woods and river floodplains.",
photoLabels: ["Panfilia nature woods", "Protected river flora", "Evening firefly trails"],
bullets: [
"Nature trails in Bosco della Panfilia forest",
"Vigarano Pieve reserve for photography and birding",
"Floodplain woods with willows, poplars and ancient oaks",
"Night walks to witness natural fireflies along the banks"
]
}
},
"citta-arte": {
photos: [
"assets/images/villette.jpg",
"assets/images/restaurant.jpg",
"assets/images/hero.jpg"
],
it: {
title: "Borghi Storici & Città d'Arte",
badge: "Cultura · UNESCO & Castelli",
summary: "Castelli estensi, rocche medievali e capolavori del Rinascimento a pochi minuti dal villaggio.",
photoLabels: ["Rocca Possente Stellata", "Ferrara Rinascimentale", "Mantova e laghi"],
bullets: [
"Rocca Possente di Stellata a soli 5 minuti a piedi",
"Ferrara Rinascimentale UNESCO e Castello Estense (25 min)",
"Mantova gonzaghesca e Palazzo Te (40 min)",
"Gite in giornata verso il Delta del Po e Pomposa"
]
},
en: {
title: "Historic Hamlets & Art Cities",
badge: "Culture · UNESCO & Castles",
summary: "Estense castles, medieval fortresses and Renaissance UNESCO art nearby.",
photoLabels: ["Stellata fortress", "Renaissance Ferrara", "Mantua & Te Palace"],
bullets: [
"Rocca Possente of Stellata just 5 minutes walk away",
"Renaissance Ferrara UNESCO & Castle in 25 minutes",
"Historic Mantua and Palazzo Te in 40 minutes",
"Day trips to the Po Delta and Pomposa Abbey"
]
}
},
"eventi-tradizioni": {
photos: [
"assets/images/restaurant.jpg",
"assets/images/villette.jpg",
"assets/images/hero.jpg"
],
it: {
title: "Grandi Eventi, Sagre & Festival",
badge: "Eventi · Folklore & Fiere",
summary: "Festival internazionali, mercatini storici e grandi rievocazioni lungo le rive del Po.",
photoLabels: ["Mercatino antiquariato", "Bundan Celtic Festival", "Ferrara Buskers Festival"],
bullets: [
"Mercatino dell'Antiquariato di Stellata (ogni 2ª domenica)",
"Bundan Celtic Festival & Sagra dell'Anatra a Stellata",
"Ferrara Buskers Festival e Balloons Festival",
"Rassegne enogastronomiche con prodotti tipici emiliani"
]
},
en: {
title: "Great Events & Local Festivals",
badge: "Events · Folklore & Fairs",
summary: "International festivals, historic antique fairs and folklore along the Po.",
photoLabels: ["Antique market Stellata", "Bundan Celtic fest", "Ferrara Buskers fest"],
bullets: [
"Historic Stellata Antique Fair (every 2nd Sunday)",
"Bundan Celtic Festival & Duck Fair in Stellata",
"Ferrara Buskers Festival & Hot Air Balloons Fest",
"Culinary events celebrating local Emilian gastronomy"
]
}
},
"borghi-storia": {
photos: [
"assets/images/villette.jpg",
"assets/images/hero.jpg",
"assets/images/restaurant.jpg"
],
it: {
title: "Mercatino & Rocca Possente di Stellata",
badge: "Storia · Antiquariato & Cultura",
summary: "Vivi il fascino medievale e lo storico mercatino dell'antiquariato a due passi da noi.",
photoLabels: ["Rocca Possente UNESCO", "Bancarelle antiquariato", "Territorio del Po"],
bullets: [
"Rocca Possente di Stellata (patrimonio UNESCO) a 5 min",
"Mercatino dell'antiquariato ogni 2ª domenica del mese",
"Museo Civico Archeologico G. Ferraresi (Stellata)",
"Ferrara e il Castello Estense a 25 min di auto o treno"
]
},
en: {
title: "Antique Market & Rocca Possente Fortress",
badge: "History · Vintage Market & Culture",
summary: "Experience historic charm and the renowned vintage antique market steps away.",
photoLabels: ["UNESCO fortress", "Antique fair stalls", "Po river land"],
bullets: [
"UNESCO Rocca Possente of Stellata 5 min walk away",
"Historic antique & vintage fair every 2nd Sunday",
"G. Ferraresi Archaeological Museum (Stellata)",
"Renaissance Ferrara and Estense Castle in 25 minutes"
]
}
}
};
let currentLang = 'it';
let heroSliderTimer = null;
let currentSlideIndex = 0;
function initApp() {
initTheme();
initLanguage();
initNavbar();
initFilters();
initHeroSlider();
initServiceModals();
initActivityModals();
initCookieBanner();
initScrollAnimations();
initCustomGoogleMap();
}
/* --- DARK / LIGHT THEME ENGINE --- */
function initTheme() {
const themeToggleBtn = document.getElementById('theme-toggle-btn');
const savedTheme = localStorage.getItem('lnn_theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
updateThemeIcon(savedTheme);
} else {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
const initialTheme = prefersDark ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', initialTheme);
updateThemeIcon(initialTheme);
}
if (themeToggleBtn) {
themeToggleBtn.addEventListener('click', () => {
const cur = document.documentElement.getAttribute('data-theme') || 'light';
const next = cur === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('lnn_theme', next);
updateThemeIcon(next);
});
}
}
function updateThemeIcon(theme) {
const iconContainer = document.getElementById('theme-icon');
if (!iconContainer) return;
if (theme === 'dark') {
iconContainer.innerHTML = `
`;
} else {
iconContainer.innerHTML = `
`;
}
}
/* --- MULTILINGUAL ENGINE (IT / EN) --- */
function initLanguage() {
const savedLang = localStorage.getItem('lnn_lang') || 'it';
setLanguage(savedLang);
const langBtns = document.querySelectorAll('[data-lang-switch]');
langBtns.forEach(btn => {
btn.addEventListener('click', () => {
const lang = btn.getAttribute('data-lang-switch');
setLanguage(lang);
});
});
}
function setLanguage(lang) {
if (!I18N[lang]) lang = 'it';
currentLang = lang;
document.documentElement.setAttribute('lang', lang === 'it' ? 'it-IT' : 'en-US');
localStorage.setItem('lnn_lang', lang);
// Update active class on switcher
document.querySelectorAll('[data-lang-switch]').forEach(btn => {
if (btn.getAttribute('data-lang-switch') === lang) {
btn.classList.add('active');
} else {
btn.classList.remove('active');
}
});
// Translate DOM Elements
const elements = document.querySelectorAll('[data-i18n]');
elements.forEach(el => {
const key = el.getAttribute('data-i18n');
if (I18N[lang][key]) {
el.textContent = I18N[lang][key];
}
});
// Translate Placeholders
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
const key = el.getAttribute('data-i18n-placeholder');
if (I18N[lang][key]) {
el.setAttribute('placeholder', I18N[lang][key]);
}
});
// Recalculate Booking Quote if open
if (window.LuccioleBooking && typeof window.LuccioleBooking.recalc === 'function') {
window.LuccioleBooking.recalc();
}
}
/* --- HERO DYNAMIC CROSSFADE SLIDER (2-second interval & DJI Neo support) --- */
function initHeroSlider() {
const slides = document.querySelectorAll('.hero-slide');
const dots = document.querySelectorAll('.hero-dot');
const sliderContainer = document.querySelector('.hero-section');
if (slides.length <= 1) return;
function goToSlide(index) {
slides.forEach((s, idx) => {
if (idx === index) {
s.classList.add('active');
const video = s.querySelector('video');
if (video) {
video.currentTime = 0;
video.play().catch(() => {});
}
} else {
s.classList.remove('active');
}
});
dots.forEach((d, idx) => {
if (idx === index) {
d.classList.add('active');
} else {
d.classList.remove('active');
}
});
currentSlideIndex = index;
}
function nextSlide() {
const nextIdx = (currentSlideIndex + 1) % slides.length;
goToSlide(nextIdx);
}
function startTimer() {
stopTimer();
heroSliderTimer = setInterval(nextSlide, 2000);
}
function stopTimer() {
if (heroSliderTimer) {
clearInterval(heroSliderTimer);
heroSliderTimer = null;
}
}
dots.forEach((dot, idx) => {
dot.addEventListener('click', () => {
goToSlide(idx);
startTimer();
});
});
if (sliderContainer) {
sliderContainer.addEventListener('mouseenter', stopTimer);
sliderContainer.addEventListener('mouseleave', startTimer);
}
startTimer();
}
/* --- REUSABLE VANILLA JS MODAL SLIDER CONTROLLER (LAZY LOADING) --- */
function createModalSliderController(trackId, prevBtnId, nextBtnId, dotsContainerId) {
const track = document.getElementById(trackId);
const prevBtn = document.getElementById(prevBtnId);
const nextBtn = document.getElementById(nextBtnId);
const dotsContainer = document.getElementById(dotsContainerId);
let currentIndex = 0;
let totalSlides = 3;
function updateView() {
if (!track) return;
const slides = track.querySelectorAll('.modal-slide');
slides.forEach((slide, idx) => {
if (idx === currentIndex) {
slide.classList.add('active');
const img = slide.querySelector('img.modal-slide-img');
if (img && img.dataset.src && (!img.src || !img.src.includes(img.dataset.src))) {
img.src = img.dataset.src;
}
} else {
slide.classList.remove('active');
}
});
if (dotsContainer) {
const dots = dotsContainer.querySelectorAll('.modal-dot');
dots.forEach((dot, idx) => {
if (idx === currentIndex) {
dot.classList.add('active');
} else {
dot.classList.remove('active');
}
});
}
}
function goTo(index) {
if (totalSlides === 0) return;
currentIndex = (index + totalSlides) % totalSlides;
updateView();
}
function next() {
goTo(currentIndex + 1);
}
function prev() {
goTo(currentIndex - 1);
}
if (prevBtn) {
prevBtn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
prev();
});
}
if (nextBtn) {
nextBtn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
next();
});
}
if (dotsContainer) {
dotsContainer.addEventListener('click', (e) => {
const dot = e.target.closest('.modal-dot');
if (dot && dot.hasAttribute('data-slide-index')) {
const idx = parseInt(dot.getAttribute('data-slide-index'), 10);
goTo(idx);
}
});
}
// Touch swipe support for mobile
if (track) {
let touchStartX = 0;
let touchEndX = 0;
track.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
}, { passive: true });
track.addEventListener('touchend', (e) => {
touchEndX = e.changedTouches[0].screenX;
if (touchStartX - touchEndX > 45) {
next();
} else if (touchEndX - touchStartX > 45) {
prev();
}
}, { passive: true });
}
function loadImages(photos, labels) {
currentIndex = 0;
if (!track) return;
const slides = track.querySelectorAll('.modal-slide');
totalSlides = photos && photos.length ? photos.length : slides.length;
slides.forEach((slide, idx) => {
const img = slide.querySelector('img.modal-slide-img');
const placeholderText = slide.querySelector('.modal-slide-placeholder span');
const photoUrl = photos && photos[idx] ? photos[idx] : '';
const labelText = labels && labels[idx] ? labels[idx] : `Foto ${idx + 1}`;
if (img) {
img.dataset.src = photoUrl;
img.alt = labelText;
if (idx === 0) {
img.src = photoUrl;
} else {
img.removeAttribute('src');
}
}
if (placeholderText) {
placeholderText.textContent = labelText;
}
});
updateView();
}
return {
goTo,
next,
prev,
loadImages,
getCurrentIndex: () => currentIndex
};
}
let serviceModalSlider = null;
let activityModalSlider = null;
/* --- SERVICE DETAIL MODAL SYSTEM --- */
function initServiceModals() {
const serviceModal = document.getElementById('service-modal');
const openBtns = document.querySelectorAll('[data-open-service-modal]');
const closeBtns = document.querySelectorAll('[data-close-service-modal]');
if (!serviceModal) return;
// Initialize Service Modal Slider Controller
serviceModalSlider = createModalSliderController(
'service-slider-track',
'service-slider-prev',
'service-slider-next',
'service-slider-dots'
);
openBtns.forEach(btn => {
btn.addEventListener('click', (e) => {
e.preventDefault();
const serviceId = btn.getAttribute('data-open-service-modal');
renderAndOpenServiceModal(serviceId);
});
});
closeBtns.forEach(btn => {
btn.addEventListener('click', closeServiceModal);
});
serviceModal.addEventListener('click', (e) => {
if (e.target === serviceModal) closeServiceModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && serviceModal.classList.contains('active')) {
closeServiceModal();
}
});
const bookFromServiceBtn = document.getElementById('service-modal-book-cta');
if (bookFromServiceBtn) {
bookFromServiceBtn.addEventListener('click', () => {
closeServiceModal();
if (window.LuccioleBooking && typeof window.LuccioleBooking.open === 'function') {
window.LuccioleBooking.open({ type: 'villetta' });
}
});
}
}
function renderAndOpenServiceModal(serviceId) {
const serviceModal = document.getElementById('service-modal');
const data = SERVICE_DETAILS[serviceId];
if (!data || !serviceModal) return;
const langData = data[currentLang] || data['it'];
const iconEl = document.getElementById('service-modal-icon');
const titleEl = document.getElementById('service-modal-title');
const badgeEl = document.getElementById('service-modal-badge');
const summaryEl = document.getElementById('service-modal-summary');
const listEl = document.getElementById('service-modal-bullets');
const amenitiesEl = document.getElementById('service-modal-amenities');
if (iconEl) iconEl.innerHTML = data.icon;
if (titleEl) titleEl.textContent = langData.title;
if (badgeEl) badgeEl.textContent = langData.badge;
if (summaryEl) summaryEl.textContent = langData.summary;
// Render Visual Amenities Grid
if (amenitiesEl) {
amenitiesEl.innerHTML = '';
if (langData.amenities && langData.amenities.length) {
langData.amenities.forEach(am => {
const card = document.createElement('div');
card.className = 'modal-amenity-card';
card.innerHTML = `
${am.icon}
${am.label}
`;
amenitiesEl.appendChild(card);
});
}
}
// Render Bullet Points
if (listEl) {
listEl.innerHTML = '';
langData.bullets.forEach(b => {
const li = document.createElement('li');
li.className = 'bullet-item';
li.style.fontSize = '0.92rem';
li.innerHTML = `
${b}
`;
listEl.appendChild(li);
});
}
// Load Photos into Lazy Modal Slider
if (serviceModalSlider && data.photos) {
serviceModalSlider.loadImages(data.photos, langData.photoLabels);
}
serviceModal.classList.add('active');
document.body.style.overflow = 'hidden';
}
function closeServiceModal() {
const serviceModal = document.getElementById('service-modal');
if (!serviceModal) return;
serviceModal.classList.remove('active');
document.body.style.overflow = '';
}
/* --- ACTIVITY & ITINERARY MODAL SYSTEM --- */
function initActivityModals() {
const activityModal = document.getElementById('activity-modal');
const openBtns = document.querySelectorAll('[data-open-activity-modal]');
const closeBtns = document.querySelectorAll('[data-close-activity-modal]');
if (!activityModal) return;
// Initialize Activity Modal Slider Controller
activityModalSlider = createModalSliderController(
'activity-slider-track',
'activity-slider-prev',
'activity-slider-next',
'activity-slider-dots'
);
openBtns.forEach(btn => {
btn.addEventListener('click', (e) => {
e.preventDefault();
const activityId = btn.getAttribute('data-open-activity-modal');
renderAndOpenActivityModal(activityId);
});
});
closeBtns.forEach(btn => {
btn.addEventListener('click', closeActivityModal);
});
activityModal.addEventListener('click', (e) => {
if (e.target === activityModal) closeActivityModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && activityModal.classList.contains('active')) {
closeActivityModal();
}
});
// Keyboard Arrow navigation for active modal sliders
document.addEventListener('keydown', (e) => {
const isServiceOpen = serviceModal && serviceModal.classList.contains('active');
const isActivityOpen = activityModal && activityModal.classList.contains('active');
if (e.key === 'ArrowRight') {
if (isServiceOpen && serviceModalSlider) serviceModalSlider.next();
if (isActivityOpen && activityModalSlider) activityModalSlider.next();
} else if (e.key === 'ArrowLeft') {
if (isServiceOpen && serviceModalSlider) serviceModalSlider.prev();
if (isActivityOpen && activityModalSlider) activityModalSlider.prev();
}
});
}
function renderAndOpenActivityModal(activityId) {
const activityModal = document.getElementById('activity-modal');
const data = ACTIVITY_DETAILS[activityId];
if (!data || !activityModal) return;
const langData = data[currentLang] || data['it'];
const titleEl = document.getElementById('activity-modal-title');
const badgeEl = document.getElementById('activity-modal-badge');
const summaryEl = document.getElementById('activity-modal-summary');
const listEl = document.getElementById('activity-modal-bullets');
const waBtn = document.getElementById('activity-modal-wa-cta');
if (titleEl) titleEl.textContent = langData.title;
if (badgeEl) badgeEl.textContent = langData.badge;
if (summaryEl) summaryEl.textContent = langData.summary;
if (waBtn) {
const msg = currentLang === 'en'
? `Hello Lucciole nella Nebbia! I would like information about the activity: ${langData.title}`
: `Buongiorno Lucciole nella Nebbia! Vorrei informazioni sull'itinerario/attività: ${langData.title}`;
waBtn.href = `https://wa.me/393277329994?text=${encodeURIComponent(msg)}`;
}
if (listEl) {
listEl.innerHTML = '';
langData.bullets.forEach(b => {
const li = document.createElement('li');
li.className = 'bullet-item';
li.style.fontSize = '0.92rem';
li.innerHTML = `
${b}
`;
listEl.appendChild(li);
});
}
// Load Photos into Lazy Activity Modal Slider
if (activityModalSlider && data.photos) {
activityModalSlider.loadImages(data.photos, langData.photoLabels);
}
activityModal.classList.add('active');
document.body.style.overflow = 'hidden';
}
function closeActivityModal() {
const activityModal = document.getElementById('activity-modal');
if (!activityModal) return;
activityModal.classList.remove('active');
document.body.style.overflow = '';
}
/* --- COOKIE BANNER (GDPR COMPLIANT) --- */
function initCookieBanner() {
const banner = document.getElementById('cookie-banner');
const acceptBtn = document.getElementById('cookie-accept-btn');
const declineBtn = document.getElementById('cookie-decline-btn');
if (!banner) return;
const consent = localStorage.getItem('lnn_cookie_consent');
if (!consent) {
setTimeout(() => {
banner.classList.add('show');
}, 700);
}
if (acceptBtn) {
acceptBtn.addEventListener('click', () => {
localStorage.setItem('lnn_cookie_consent', 'accepted');
banner.classList.remove('show');
});
}
if (declineBtn) {
declineBtn.addEventListener('click', () => {
localStorage.setItem('lnn_cookie_consent', 'declined');
banner.classList.remove('show');
});
}
}
/* --- NAVBAR & SCROLL BEHAVIOR --- */
function initNavbar() {
const mobileToggle = document.getElementById('mobile-menu-toggle');
const mainNav = document.getElementById('main-nav');
const navLinks = document.querySelectorAll('.nav-link');
if (mobileToggle && mainNav) {
mobileToggle.addEventListener('click', (e) => {
e.stopPropagation();
const isOpen = mainNav.classList.toggle('mobile-open');
mobileToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
});
// Close when clicking outside
document.addEventListener('click', (e) => {
if (mainNav.classList.contains('mobile-open') && !mainNav.contains(e.target) && !mobileToggle.contains(e.target)) {
mainNav.classList.remove('mobile-open');
mobileToggle.setAttribute('aria-expanded', 'false');
}
});
// Close on Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && mainNav.classList.contains('mobile-open')) {
mainNav.classList.remove('mobile-open');
mobileToggle.setAttribute('aria-expanded', 'false');
}
});
}
navLinks.forEach(link => {
link.addEventListener('click', () => {
if (mainNav) {
mainNav.classList.remove('mobile-open');
if (mobileToggle) mobileToggle.setAttribute('aria-expanded', 'false');
}
});
});
const sections = document.querySelectorAll('section[id]');
window.addEventListener('scroll', () => {
let currentSectionId = '';
const scrollPos = window.scrollY + 120;
sections.forEach(sec => {
const top = sec.offsetTop;
const height = sec.offsetHeight;
if (scrollPos >= top && scrollPos < top + height) {
currentSectionId = sec.getAttribute('id');
}
});
navLinks.forEach(l => {
if (l.getAttribute('href') === `#${currentSectionId}`) {
l.classList.add('active');
} else {
l.classList.remove('active');
}
});
}, { passive: true });
}
/* --- FILTER TABS --- */
function initFilters() {
const filterBtns = document.querySelectorAll('[data-filter]');
const filterItems = document.querySelectorAll('[data-category]');
filterBtns.forEach(btn => {
btn.addEventListener('click', () => {
const category = btn.getAttribute('data-filter');
filterBtns.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
filterItems.forEach(item => {
if (category === 'all' || item.getAttribute('data-category') === category) {
item.style.display = '';
item.style.opacity = '1';
} else {
item.style.display = 'none';
item.style.opacity = '0';
}
});
});
});
}
/* --- SCROLL ANIMATIONS (INTERSECTION OBSERVER) --- */
function initScrollAnimations() {
const revealElements = document.querySelectorAll('.reveal-on-scroll');
if (!revealElements.length) return;
if (!('IntersectionObserver' in window)) {
revealElements.forEach(el => el.classList.add('visible'));
return;
}
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
obs.unobserve(entry.target);
}
});
}, {
threshold: 0.12,
rootMargin: '0px 0px -40px 0px'
});
revealElements.forEach(el => observer.observe(el));
}
/* --- CUSTOM STYLIZED GOOGLE MAP (NATURAL SAGE GREEN PALETTE) --- */
function initCustomGoogleMap() {
const mapContainer = document.getElementById('custom-google-map');
if (!mapContainer) return;
const lat = parseFloat(mapContainer.getAttribute('data-lat')) || 44.9458;
const lng = parseFloat(mapContainer.getAttribute('data-lng')) || 11.4125;
const centerCoords = { lat, lng };
// Custom Natural Sage & Earth Palette JSON Stylesheet
const naturalSageMapStyle = [
{
"featureType": "all",
"elementType": "geometry",
"stylers": [{ "color": "#f4f7f4" }]
},
{
"featureType": "all",
"elementType": "labels.text.fill",
"stylers": [{ "color": "#3b4d40" }]
},
{
"featureType": "all",
"elementType": "labels.text.stroke",
"stylers": [{ "color": "#ffffff" }, { "weight": 3 }]
},
{
"featureType": "administrative",
"elementType": "geometry.stroke",
"stylers": [{ "color": "#b5c7b8" }, { "weight": 1 }]
},
{
"featureType": "landscape.natural",
"elementType": "geometry",
"stylers": [{ "color": "#e2ece3" }]
},
{
"featureType": "poi",
"elementType": "geometry",
"stylers": [{ "color": "#d6e5d8" }]
},
{
"featureType": "poi.park",
"elementType": "geometry",
"stylers": [{ "color": "#c5dcce" }]
},
{
"featureType": "road",
"elementType": "geometry",
"stylers": [{ "color": "#ffffff" }]
},
{
"featureType": "road.highway",
"elementType": "geometry",
"stylers": [{ "color": "#d9e7dc" }]
},
{
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [{ "color": "#c4d8c8" }]
},
{
"featureType": "road.arterial",
"elementType": "geometry",
"stylers": [{ "color": "#ffffff" }]
},
{
"featureType": "transit",
"elementType": "geometry",
"stylers": [{ "color": "#d4e4d7" }]
},
{
"featureType": "water",
"elementType": "geometry",
"stylers": [{ "color": "#a2c2ac" }]
},
{
"featureType": "water",
"elementType": "labels.text.fill",
"stylers": [{ "color": "#2c4c36" }]
}
];
// Check if Google Maps JS SDK is already loaded
if (window.google && window.google.maps) {
const map = new google.maps.Map(mapContainer, {
center: centerCoords,
zoom: 14,
styles: naturalSageMapStyle,
mapTypeControl: false,
streetViewControl: false,
fullscreenControl: true,
zoomControl: true
});
const marker = new google.maps.Marker({
position: centerCoords,
map: map,
title: 'Lucciole nella Nebbia 3★ - Stellata di Bondeno',
animation: google.maps.Animation.DROP
});
const infoWindow = new google.maps.InfoWindow({
content: `
Lucciole nella Nebbia 3★
Via Argine Po 35/a · Stellata (FE)
`
});
marker.addListener('click', () => {
infoWindow.open(map, marker);
});
}
// Direct directions button handler
const loadMapBtn = document.getElementById('btn-load-live-map');
if (loadMapBtn) {
loadMapBtn.addEventListener('click', () => {
window.open('https://maps.google.com/?q=Via+Argine+Po+35/a+Stellata+Ferrara', '_blank');
});
}
}
// Initialize
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initApp);
} else {
initApp();
}
// Global app handle
window.LuccioleApp = {
setLanguage,
getLanguage: () => currentLang,
openServiceModal: renderAndOpenServiceModal,
openActivityModal: renderAndOpenActivityModal
};
})();