{"id":17841,"date":"2026-04-16T06:34:09","date_gmt":"2026-04-16T06:34:09","guid":{"rendered":"https:\/\/www.visitatavernes.es\/?page_id=17841"},"modified":"2026-04-16T06:34:14","modified_gmt":"2026-04-16T06:34:14","slug":"trip-planner","status":"publish","type":"page","link":"https:\/\/www.visitatavernes.es\/en\/trip-planner\/","title":{"rendered":"Trip Planner"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"17841\" class=\"elementor elementor-17841\" wpc-filter-elementor-widget=\"1\" data-elementor-post-type=\"page\">\n\t\t\t\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-32a435f elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"32a435f\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-2d5cdae\" data-id=\"2d5cdae\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-f100b5d elementor-widget elementor-widget-html\" data-id=\"f100b5d\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\"\/>\n<meta name=\"viewport\" content=\"width=1920, initial-scale=0.25, maximum-scale=5, user-scalable=yes\"\/>\n<title>Travel Planner for Tavernes de la Valldigna | Visit Tavernes<\/title>\n<meta content=\"Organize your itinerary in Tavernes de la Valldigna by day and time slot with activities, restaurants, accommodation, events and an estimated budget.\" name=\"description\"\/>\n<meta content=\"Tavernes de la Valldigna, travel planner, what to do in Tavernes, Tavernes restaurants, Tavernes routes, Tavernes beaches, Tavernes accommodation\" name=\"keywords\"\/>\n<meta content=\"index,follow\" name=\"robots\"\/>\n<meta content=\"Travel Planner for Tavernes de la Valldigna\" property=\"og:title\"\/>\n<meta content=\"Organize your itinerary in Tavernes de la Valldigna by days and time slots with activities, heritage, nature, dining, leisure, events and accommodation.\" property=\"og:description\"\/>\n<meta content=\"website\" property=\"og:type\"\/>\n\n<link\n  rel=\"stylesheet\"\n  href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\"\n  integrity=\"sha256-p4NxAoJBhIIN+hmNHrzRCf9tD\/miZyoHS5obTRR9BMY=\"\n  crossorigin=\"\"\n\/>\n\n<style>\n:root{\n  --bg:#eef3f8;\n  --panel:#fff;\n  --line:#d8e3ef;\n  --line2:#bfd1e3;\n  --text:#12385f;\n  --muted:#5f7892;\n  --brand:#0d6fb8;\n  --brand2:#0a5a96;\n  --soft:#f7fbff;\n  --accent:#f08b2d;\n  --ok:#2d8b57;\n  --shadow:0 10px 28px rgba(17,58,98,.08);\n  --radius:18px;\n}\n\n*{box-sizing:border-box}\n\nhtml,body{\n  margin:0;\n  padding:0;\n  width:100%;\n  min-height:100%;\n  overflow:auto;\n}\n\nbody{\n  font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;\n  background:transparent !important;\n  color:var(--text);\n}\n\n.elementor-widget-html,\n.elementor-widget-container,\n.elementor-shortcode,\n.elementor{\n  width:100%;\n  max-width:none;\n  overflow:visible;\n}\n\n.app-viewport{\n  width:100%;\n  min-height:100vh;\n  overflow:auto;\n  display:flex;\n  justify-content:center;\n  align-items:flex-start;\n  -webkit-overflow-scrolling:touch;\n  overscroll-behavior:contain;\n  background:transparent;\n}\n\n.app-scale-wrap{\n  position:relative;\n  flex:0 0 auto;\n  overflow:hidden;\n}\n\n.app-scale{\n  position:relative;\n  transform-origin:top left;\n  will-change:transform;\n}\n\n.app-shell{\n  width:1920px;\n  min-width:1920px;\n  max-width:1920px;\n  margin:0;\n  background:linear-gradient(180deg,#f6f9fc 0%, #eef3f8 100%);\n  border:1px solid var(--line);\n  border-radius:24px;\n  padding:18px;\n  overflow:hidden;\n  isolation:isolate;\n}\n\n.app{\n  display:grid;\n  grid-template-columns:260px 900px 340px 420px;\n  gap:16px;\n  width:1920px;\n  min-height:calc(100vh - 60px);\n  height:calc(100vh - 60px);\n  align-items:stretch;\n}\n\n.panel{\n  background:var(--panel);\n  border:1px solid var(--line);\n  border-radius:var(--radius);\n  box-shadow:var(--shadow);\n}\n\n.left,.center,.right,.map-col{\n  min-height:0;\n}\n\n.left{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n  min-height:0;\n  overflow-y:auto;\n  overflow-x:hidden;\n  padding-right:8px;\n  scrollbar-gutter:stable;\n}\n\n.center{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n  min-width:0;\n  min-height:0;\n  overflow:hidden;\n}\n\n.right{\n  display:flex;\n  flex-direction:column;\n  min-width:0;\n  min-height:0;\n  overflow:hidden;\n}\n\n.map-col{\n  display:flex;\n  flex-direction:column;\n  min-width:0;\n  min-height:0;\n  overflow:hidden;\n}\n\n.left::-webkit-scrollbar,\n.center-scroll::-webkit-scrollbar,\n.catalog-results::-webkit-scrollbar,\n.map-side-scroll::-webkit-scrollbar,\nbody::-webkit-scrollbar{\n  width:16px;\n  height:14px;\n}\n\n.left::-webkit-scrollbar-track,\n.center-scroll::-webkit-scrollbar-track,\n.catalog-results::-webkit-scrollbar-track,\n.map-side-scroll::-webkit-scrollbar-track,\nbody::-webkit-scrollbar-track{\n  background:#e7eef6;\n  border-radius:999px;\n}\n\n.left::-webkit-scrollbar-thumb,\n.center-scroll::-webkit-scrollbar-thumb,\n.catalog-results::-webkit-scrollbar-thumb,\n.map-side-scroll::-webkit-scrollbar-thumb,\nbody::-webkit-scrollbar-thumb{\n  background:linear-gradient(180deg,#9ab1c7,#6f88a3);\n  border-radius:999px;\n  border:3px solid #e7eef6;\n}\n\nbody,\n.left,\n.center-scroll,\n.catalog-results,\n.map-side-scroll{\n  scrollbar-width:auto;\n  scrollbar-color:#7b96b3 #e7eef6;\n}\n\n.box{padding:16px}\n\n.brand{\n  display:flex;\n  gap:12px;\n  align-items:center;\n  padding:16px 18px;\n  background:linear-gradient(135deg,#eef7ff,#ffffff);\n  border:1px solid var(--line);\n  border-radius:18px;\n}\n\n.brand-wordmark{\n  display:flex;\n  align-items:center;\n  gap:14px;\n  width:100%;\n}\n\n.brand-logo{\n  width:54px;\n  height:auto;\n  display:block;\n  flex:0 0 auto;\n}\n\n.brand-kicker{\n  font-size:13px;\n  font-weight:800;\n  letter-spacing:.12em;\n  color:var(--brand);\n}\n\n.brand-main{\n  font-size:23px;\n  line-height:1.05;\n  font-weight:800;\n  color:var(--text);\n}\n\n.brand-subline{\n  font-size:13px;\n  color:var(--muted);\n  margin-top:4px;\n}\n\n.stack{display:grid;gap:12px}\n.field label{display:block;font-size:13px;color:var(--muted);margin-bottom:6px}\ninput,select,textarea,button{font:inherit}\n\n.field input,\n.field select,\n.field textarea{\n  width:100%;\n  padding:11px 12px;\n  border:1px solid var(--line2);\n  border-radius:12px;\n  background:#fff;\n  color:var(--text);\n}\n\n.trip-form{\n  display:grid;\n  grid-template-columns:repeat(2,minmax(160px,1fr));\n  gap:14px;\n  align-items:start;\n}\n\n.trip-form .field textarea{\n  min-height:76px;\n  resize:vertical;\n}\n\n.hero-grid{\n  display:grid;\n  grid-template-columns:1fr 1.05fr;\n  gap:18px;\n  align-items:start;\n}\n\n.hero-title h2{\n  font-size:26px;\n  line-height:1.08;\n  margin:0 0 10px;\n}\n\n.hero-title p{\n  margin:0;\n  color:var(--muted);\n  line-height:1.6;\n}\n\n.prefs-box{\n  margin-top:14px;\n  padding:10px 12px;\n  border:1px solid var(--line);\n  border-radius:14px;\n  background:var(--soft);\n  color:var(--muted);\n  font-size:14px;\n  line-height:1.5;\n}\n\n.btns{\n  display:flex;\n  gap:10px;\n  flex-wrap:wrap;\n}\n\n.btn{\n  border:0;\n  background:var(--brand);\n  color:#fff;\n  padding:11px 14px;\n  border-radius:12px;\n  cursor:pointer;\n  font-weight:700;\n}\n\n.btn.alt{\n  background:#fff;\n  color:var(--text);\n  border:1px solid var(--line2);\n}\n\n.btn.orange{background:var(--accent)}\n.btn.small{padding:10px 12px;font-size:15px}\n\n.stats{\n  display:grid;\n  grid-template-columns:1fr 1fr;\n  gap:10px;\n}\n\n.stat{\n  background:var(--soft);\n  border:1px solid var(--line);\n  border-radius:14px;\n  padding:12px;\n}\n\n.stat .num{\n  font-size:25px;\n  font-weight:900;\n}\n\n.stat .lbl{\n  font-size:13px;\n  color:var(--muted);\n}\n\n.budget-line{\n  display:flex;\n  justify-content:space-between;\n  gap:10px;\n  padding:9px 0;\n  border-bottom:1px dashed var(--line);\n}\n\n.budget-total{\n  font-size:30px;\n  font-weight:900;\n  margin-top:12px;\n}\n\n.itinerary-panel,\n.catalog-panel{\n  display:flex;\n  flex-direction:column;\n  min-height:0;\n}\n\n.center-scroll{\n  flex:1;\n  min-height:0;\n  overflow-y:auto;\n  overflow-x:hidden;\n  padding:4px 12px 4px 2px;\n  scrollbar-gutter:stable both-edges;\n}\n\n.catalog-panel{\n  padding:0;\n  overflow:hidden;\n}\n\n.catalog-fixed{\n  padding:16px 16px 10px;\n  border-bottom:1px solid var(--line);\n  background:#fff;\n  flex:0 0 auto;\n}\n\n.catalog-results{\n  flex:1;\n  min-height:0;\n  overflow-y:auto;\n  overflow-x:hidden;\n  padding:12px 12px 16px;\n  scrollbar-gutter:stable;\n}\n\n.day-card{\n  padding:14px;\n  border:1px solid var(--line);\n  border-radius:16px;\n  background:#fff;\n  margin-bottom:14px;\n}\n\n.day-head{\n  display:flex;\n  justify-content:space-between;\n  align-items:center;\n  gap:12px;\n  margin-bottom:12px;\n}\n\n.day-head h3{\n  margin:0;\n  font-size:23px;\n}\n\n.day-date{\n  font-size:13px;\n  color:var(--muted);\n  font-weight:700;\n  background:var(--soft);\n  padding:6px 10px;\n  border-radius:999px;\n  border:1px solid var(--line);\n}\n\n.slot-grid{\n  display:grid;\n  grid-template-columns:repeat(4,minmax(160px,1fr));\n  gap:12px;\n}\n\n.slot{\n  border:1px solid var(--line);\n  border-radius:14px;\n  background:var(--soft);\n  padding:12px;\n  display:flex;\n  flex-direction:column;\n  gap:10px;\n  min-height:280px;\n}\n\n.slot h4{\n  margin:0;\n  font-size:19px;\n}\n\n.slot-meta{\n  font-size:11px;\n  color:var(--muted);\n}\n\n.slot-empty{\n  border:1px dashed var(--line2);\n  border-radius:12px;\n  padding:12px;\n  color:var(--muted);\n  font-size:14px;\n  background:#fff;\n}\n\n.plan-item{\n  background:#fff;\n  border:1px solid var(--line);\n  border-radius:14px;\n  padding:10px;\n  display:grid;\n  gap:8px;\n}\n\n.plan-top{\n  display:flex;\n  justify-content:space-between;\n  gap:8px;\n  align-items:flex-start;\n}\n\n.plan-title{\n  font-weight:800;\n  line-height:1.25;\n}\n\n.price-pill{\n  font-size:11px;\n  font-weight:800;\n  background:#edf7ef;\n  color:var(--ok);\n  padding:5px 8px;\n  border-radius:999px;\n  border:1px solid #bde0c7;\n  white-space:nowrap;\n}\n\n.tags{\n  display:flex;\n  flex-wrap:wrap;\n  gap:6px;\n}\n\n.tag{\n  font-size:11px;\n  padding:4px 8px;\n  border-radius:999px;\n  border:1px solid var(--line);\n  background:#fff;\n  color:var(--brand2);\n}\n\n.tag.type-restaurante{background:#fff5eb;border-color:#ffd3a8;color:#b86400}\n.tag.type-alojamiento{background:#eef9ef;border-color:#c8ebd0;color:#2d8b57}\n.tag.type-evento{background:#fff0f0;border-color:#f0c7c7;color:#b24a4a}\n.tag.type-ocio{background:#f7f0ff;border-color:#dccbff;color:#7546c8}\n.tag.reco{background:#eaf5ff;border-color:#bcd9f4;color:#0d6fb8;font-weight:800}\n.tag.planned{background:#fff7e8;border-color:#ffd28a;color:#8f5b00;font-weight:800}\n\n.controls-inline{\n  display:flex;\n  gap:6px;\n  align-items:center;\n  flex-wrap:wrap;\n}\n\n.small-select{\n  padding:8px 10px;\n  border:1px solid var(--line2);\n  border-radius:10px;\n  background:#fff;\n  color:var(--text);\n  min-width:75px;\n}\n\n.tiny-btn{\n  padding:8px 10px;\n  border-radius:10px;\n  border:1px solid var(--line2);\n  background:#fff;\n  cursor:pointer;\n}\n\n.tiny-btn.primary{\n  background:var(--brand);\n  color:#fff;\n  border-color:var(--brand);\n}\n\n.catalog-head h3{\n  margin:0 0 8px;\n  font-size:28px;\n  line-height:1.05;\n}\n\n.catalog-head p{\n  margin:0 0 14px;\n  color:var(--muted);\n  font-size:15px;\n  line-height:1.6;\n  max-width:42ch;\n}\n\n.catalog-count{\n  display:inline-flex;\n  margin-top:10px;\n  font-size:13px;\n  font-weight:800;\n  padding:6px 10px;\n  border-radius:999px;\n  background:var(--soft);\n  border:1px solid var(--line);\n}\n\n.filters{\n  display:grid;\n  grid-template-columns:repeat(2,minmax(0,1fr));\n  gap:10px;\n  margin-top:12px;\n}\n\n.search{grid-column:1\/-1}\n.catalog-grid{display:grid;gap:12px}\n\n.catalog-card{\n  background:#fff;\n  border:1px solid var(--line);\n  border-radius:16px;\n  padding:12px;\n  display:grid;\n  gap:8px;\n}\n\n.catalog-top{\n  display:flex;\n  justify-content:space-between;\n  gap:10px;\n  align-items:flex-start;\n}\n\n.catalog-top h4{\n  margin:0;\n  font-size:19px;\n  line-height:1.25;\n}\n\n.score{\n  font-size:13px;\n  font-weight:900;\n  background:#f1f7ff;\n  color:var(--brand);\n  padding:6px 8px;\n  border-radius:999px;\n  border:1px solid #cfe2f5;\n  white-space:nowrap;\n}\n\n.catalog-card p{\n  margin:0;\n  color:var(--muted);\n  line-height:1.5;\n  font-size:15px;\n}\n\n.help{\n  font-size:13px;\n  color:var(--muted);\n}\n\n.empty{\n  padding:14px;\n  border:1px dashed var(--line2);\n  border-radius:14px;\n  background:var(--soft);\n  color:var(--muted);\n  font-size:15px;\n}\n\n.icon-badge{\n  display:inline-flex;\n  align-items:center;\n  justify-content:center;\n  width:28px;\n  height:28px;\n  border-radius:999px;\n  background:#eef7ff;\n  border:1px solid #cfe2f5;\n  font-size:16px;\n  flex:0 0 auto;\n}\n\n.title-row{\n  display:flex;\n  align-items:flex-start;\n  gap:8px;\n}\n\n.catalog-link,\n.plan-link,\n.map-focus-link{\n  display:inline-flex;\n  align-items:center;\n  gap:6px;\n  margin-top:2px;\n  font-size:13px;\n  font-weight:700;\n  color:var(--brand2);\n  text-decoration:none;\n  cursor:pointer;\n}\n\n.catalog-link:hover,\n.plan-link:hover,\n.map-focus-link:hover{\n  text-decoration:underline;\n}\n\n.catalog-card .help-strong{\n  color:var(--text);\n  font-weight:600;\n}\n\n.map-panel{\n  display:flex;\n  flex-direction:column;\n  min-height:0;\n  overflow:hidden;\n  padding:0;\n}\n\n.map-header{\n  padding:14px 14px 10px;\n  border-bottom:1px solid var(--line);\n  background:#fff;\n}\n\n.map-header h3{\n  margin:0 0 6px;\n  font-size:23px;\n}\n\n.map-header p{\n  margin:0;\n  font-size:14px;\n  color:var(--muted);\n  line-height:1.5;\n}\n\n.map-stats{\n  display:flex;\n  gap:8px;\n  flex-wrap:wrap;\n  margin-top:10px;\n}\n\n.map-pill{\n  font-size:11px;\n  font-weight:800;\n  padding:5px 8px;\n  border-radius:999px;\n  background:var(--soft);\n  border:1px solid var(--line);\n  color:var(--brand2);\n}\n\n.map-controls{\n  display:flex;\n  align-items:center;\n  gap:10px;\n  flex-wrap:wrap;\n  margin-top:10px;\n}\n\n.map-toggle{\n  display:inline-flex;\n  align-items:center;\n  gap:6px;\n  font-size:13px;\n  color:var(--text);\n  font-weight:700;\n}\n\n#travelMap{\n  flex:1;\n  min-height:420px;\n  width:100%;\n}\n\n.map-side-scroll{\n  max-height:220px;\n  overflow:auto;\n  border-top:1px solid var(--line);\n  padding:10px 12px 12px;\n  background:#fbfdff;\n}\n\n.map-list{\n  display:grid;\n  grid-template-columns:repeat(2,minmax(0,1fr));\n  gap:10px;\n}\n\n.map-list-item{\n  padding:10px;\n  border:1px solid var(--line);\n  border-radius:12px;\n  background:#fff;\n  display:grid;\n  gap:4px;\n  align-content:start;\n}\n\n.map-list-item strong{\n  color:var(--text);\n  font-size:14px;\n}\n\n.map-list-item .meta{\n  font-size:13px;\n  color:var(--muted);\n  line-height:1.4;\n}\n\n.leaflet-popup-content{\n  font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;\n  color:#12385f;\n  line-height:1.45;\n}\n\n.leaflet-popup-content strong{\n  display:block;\n  margin-bottom:4px;\n}\n\n\/* === Layout actualizado === *\/\n.app{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n  width:1920px;\n  min-height:auto;\n  height:auto;\n  align-items:stretch;\n}\n\n.top-layout{\n  display:grid;\n  grid-template-columns:minmax(0,1.05fr) minmax(0,1.95fr);\n  gap:16px;\n  align-items:start;\n}\n\n.hero-card,\n.controls-card{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n}\n\n.hero-split{\n  display:grid;\n  grid-template-columns:220px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.brand{\n  min-height:100%;\n}\n\n.trip-tools-row{\n  display:grid;\n  grid-template-columns:repeat(3,minmax(0,1fr)) auto;\n  gap:14px;\n  align-items:end;\n}\n\n.day-actions{\n  display:flex;\n  gap:10px;\n  flex-wrap:wrap;\n}\n\n.trip-form{\n  grid-template-columns:repeat(4,minmax(0,1fr));\n}\n\n.trip-form .field:last-child{\n  grid-column:span 2;\n}\n\n.top-actions{\n  display:flex;\n  gap:10px;\n  flex-wrap:wrap;\n}\n\n.stats-budget-row{\n  display:grid;\n  grid-template-columns:320px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.stats-card,\n.budget-card{\n  padding:16px;\n  border:1px solid var(--line);\n  border-radius:16px;\n  background:var(--soft);\n}\n\n.content-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1.6fr) 430px;\n  gap:16px;\n  align-items:start;\n}\n\n.content-left,\n.content-right{\n  min-width:0;\n}\n\n.itinerary-panel{\n  min-height:760px;\n}\n\n.center-scroll{\n  max-height:920px;\n}\n\n.catalog-panel{\n  min-height:760px;\n}\n\n.catalog-results{\n  max-height:920px;\n}\n\n.map-bottom{\n  overflow:hidden;\n}\n\n.map-bottom-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1fr) 330px;\n  min-height:620px;\n}\n\n#travelMap{\n  width:100%;\n  height:620px;\n  min-height:620px;\n}\n\n.map-side-scroll{\n  max-height:none;\n  border-top:0;\n  border-left:1px solid var(--line);\n  padding:12px;\n  background:#fbfdff;\n}\n\n.catalog-top h4{\n  margin:0;\n}\n\n@media (max-width: 1200px){\n  .trip-form{\n    grid-template-columns:repeat(2,minmax(0,1fr));\n  }\n\n  .trip-form .field:last-child{\n    grid-column:1 \/ -1;\n  }\n}\n\n\n\/* === Layout pantalla completa v2 === *\/\n.app-viewport{\n  width:100%;\n  min-height:100vh;\n  overflow:visible;\n  display:block;\n  background:transparent;\n}\n\n.app-scale-wrap{\n  width:100% !important;\n  height:auto !important;\n  overflow:visible;\n}\n\n.app-scale{\n  width:100% !important;\n  height:auto !important;\n  transform:none !important;\n}\n\n.app-shell{\n  width:100%;\n  min-width:0;\n  max-width:none;\n  border-radius:0;\n  border-left:0;\n  border-right:0;\n  padding:16px;\n}\n\n.app{\n  width:100%;\n  min-width:0;\n}\n\n.top-layout{\n  display:grid;\n  grid-template-columns:420px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.content-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1fr);\n  gap:16px;\n}\n\n.content-right{\n  order:-1;\n}\n\n.catalog-panel{\n  min-height:auto;\n}\n\n.catalog-fixed{\n  border-bottom:0;\n  padding:16px;\n}\n\n.catalog-head{\n  display:grid;\n  grid-template-columns:320px minmax(0,1fr);\n  gap:20px;\n  align-items:start;\n}\n\n.catalog-head > div:first-child{\n  min-width:0;\n}\n\n.filters{\n  display:grid;\n  grid-template-columns:repeat(7,minmax(120px,1fr));\n  gap:10px;\n  margin-top:0;\n  align-items:end;\n}\n\n.filters .search{\n  grid-column:span 1;\n}\n\n.catalog-results{\n  max-height:none;\n  padding:0 16px 16px;\n}\n\n.catalog-grid{\n  grid-template-columns:repeat(3,minmax(0,1fr));\n  align-items:start;\n}\n\n.itinerary-panel{\n  min-height:0;\n}\n\n.center-scroll{\n  max-height:none;\n  overflow:visible;\n  padding-right:0;\n}\n\n.stats-budget-row{\n  grid-template-columns:220px minmax(0,1fr);\n}\n\n.budget-card{\n  order:3;\n}\n\n.bottom-budget{\n  margin-top:16px;\n}\n\n.map-bottom{\n  margin-top:16px;\n}\n\n.map-bottom-grid{\n  grid-template-columns:minmax(0,1fr) 360px;\n  min-height:680px;\n}\n\n#travelMap{\n  height:680px;\n  min-height:680px;\n  display:block;\n}\n\n@media (max-width: 1600px){\n  .catalog-grid{\n    grid-template-columns:repeat(2,minmax(0,1fr));\n  }\n  .filters{\n    grid-template-columns:repeat(4,minmax(120px,1fr));\n  }\n}\n\n@media (max-width: 1200px){\n  .top-layout,\n  .catalog-head,\n  .stats-budget-row,\n  .map-bottom-grid{\n    grid-template-columns:1fr;\n  }\n\n  .filters{\n    grid-template-columns:repeat(2,minmax(120px,1fr));\n  }\n\n  .catalog-grid{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\/* === Ajuste disposici\u00f3n final === *\/\n.top-layout{\n  display:block;\n}\n\n.hero-card,\n.controls-card{\n  display:block;\n}\n\n.unified-top{\n  display:grid;\n  grid-template-columns:420px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.unified-top-right{\n  display:grid;\n  gap:16px;\n}\n\n.unified-top .top-actions{\n  margin-top:12px;\n}\n\n.content-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1.15fr) minmax(520px,0.85fr);\n  gap:16px;\n  align-items:start;\n}\n\n.itinerary-panel{\n  min-height:720px;\n}\n\n.catalog-panel{\n  min-height:720px;\n  overflow:hidden;\n}\n\n.catalog-fixed{\n  padding:16px;\n  border-bottom:1px solid var(--line);\n}\n\n.catalog-head{\n  display:grid;\n  grid-template-columns:1fr;\n  gap:14px;\n}\n\n.filters{\n  display:grid;\n  grid-template-columns:repeat(3,minmax(0,1fr));\n  gap:10px;\n  align-items:end;\n}\n\n.filters .search{\n  grid-column:1 \/ -1;\n}\n\n.catalog-results{\n  max-height:760px;\n  overflow-y:auto;\n  overflow-x:hidden;\n  padding:16px;\n  scrollbar-gutter:stable;\n}\n\n.catalog-grid{\n  display:grid;\n  grid-template-columns:1fr;\n  gap:12px;\n}\n\n.center-scroll{\n  max-height:760px;\n  overflow-y:auto;\n  overflow-x:hidden;\n  padding-right:8px;\n  scrollbar-gutter:stable;\n}\n\n.map-bottom-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1fr) 320px;\n  gap:0;\n  min-height:720px;\n}\n\n#travelMap{\n  height:720px;\n  min-height:720px;\n}\n\n.map-side-scroll{\n  max-height:720px;\n  overflow-y:auto;\n  overflow-x:hidden;\n  border-left:1px solid var(--line);\n  border-top:0;\n  padding:12px;\n  background:#fbfdff;\n  scrollbar-gutter:stable;\n}\n\n.bottom-budget{\n  margin-top:16px;\n}\n\n@media (max-width: 1400px){\n  .content-grid{\n    grid-template-columns:1fr;\n  }\n  .filters{\n    grid-template-columns:repeat(2,minmax(0,1fr));\n  }\n}\n\n@media (max-width: 1100px){\n  .unified-top{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\/* === Ajustes finos solicitados === *\/\n.unified-top{\n  grid-template-columns:1fr;\n}\n\n.unified-top > div:first-child{\n  display:grid;\n  grid-template-columns:220px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.hero-split{\n  grid-template-columns:1fr;\n  gap:12px;\n}\n\n.hero-split > div:last-child{\n  min-width:0;\n}\n\n.unified-top-right{\n  display:grid;\n  grid-template-columns:1fr auto;\n  gap:16px;\n  align-items:start;\n}\n\n.trip-tools-row{\n  grid-column:1 \/ -1;\n}\n\n.trip-form{\n  grid-column:1 \/ -1;\n}\n\n.stats-budget-row{\n  display:block;\n}\n\n.stats-card{\n  display:none;\n}\n\n.bottom-budget{\n  margin-top:16px;\n}\n\n.bottom-budget .stats{\n  margin-bottom:16px;\n}\n\n.content-grid{\n  grid-template-columns:minmax(0,1fr) minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.catalog-panel,\n.itinerary-panel{\n  min-height:980px;\n  height:980px;\n}\n\n.catalog-results,\n.center-scroll{\n  height:calc(980px - 88px);\n  max-height:calc(980px - 88px);\n  overflow-y:auto;\n  overflow-x:hidden;\n}\n\n.catalog-grid{\n  grid-template-columns:1fr;\n}\n\n.catalog-card{\n  display:grid;\n  gap:12px;\n  min-height:190px;\n  padding:16px;\n}\n\n.slot-grid{\n  display:grid;\n  grid-template-columns:repeat(4,minmax(0,1fr));\n  gap:12px;\n}\n\n.slot{\n  min-height:220px;\n}\n\n.quick-slot-actions{\n  display:flex;\n  flex-wrap:wrap;\n  gap:6px;\n  margin-top:6px;\n}\n\n.quick-add-btn{\n  padding:7px 10px;\n  border-radius:999px;\n  border:1px solid var(--line2);\n  background:#fff;\n  color:var(--text);\n  cursor:pointer;\n  font-size:13px;\n  font-weight:700;\n}\n\n.quick-add-btn:hover{\n  background:var(--soft);\n}\n\n.day-card{\n  margin-bottom:10px;\n}\n\n.map-bottom-grid{\n  grid-template-columns:minmax(0,0.82fr) minmax(0,1.18fr);\n}\n\n@media (max-width: 1400px){\n  .content-grid{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\/* === Ajuste exclusivo franja superior === *\/\n.top-banner{\n  width:100%;\n  min-height:118px;\n  border:1px solid var(--line);\n  border-radius:14px;\n  background:linear-gradient(135deg,#eef7ff,#ffffff);\n  display:flex;\n  align-items:center;\n  justify-content:flex-start;\n  padding:18px 24px;\n}\n\n.top-banner .brand-wordmark{\n  display:flex;\n  align-items:center;\n  gap:14px;\n  width:auto;\n}\n\n.top-banner .brand-logo{\n  width:42px;\n  max-width:100%;\n  height:auto;\n  display:block;\n  flex:0 0 auto;\n  object-fit:contain;\n}\n\n.top-banner .brand-kicker{\n  font-size:13px;\n  font-weight:800;\n  letter-spacing:.12em;\n  color:var(--brand);\n}\n\n.top-banner .brand-main{\n  font-size:23px;\n  line-height:1.05;\n  font-weight:800;\n  color:var(--text);\n}\n\n.top-banner .brand-subline{\n  font-size:13px;\n  color:var(--muted);\n  margin-top:4px;\n}\n\n\n\/* === Superior limpio === *\/\n.unified-top-clean{\n  display:grid;\n  grid-template-columns:260px minmax(0,1fr);\n  gap:18px;\n  align-items:start;\n}\n\n.top-clean-main{\n  display:contents;\n}\n\n.top-clean-left{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n}\n\n.unified-top-clean .top-banner{\n  min-height:108px;\n}\n\n.unified-top-clean .trip-tools-row{\n  grid-column:1 \/ -1;\n  display:grid;\n  grid-template-columns:1fr 1fr 1fr auto;\n  gap:10px;\n  align-items:end;\n}\n\n@media (max-width: 1200px){\n  .unified-top-clean{\n    grid-template-columns:1fr;\n  }\n\n  .unified-top-clean .trip-tools-row{\n    grid-template-columns:1fr;\n  }\n}\n\n\n.catalog-extra-filters{\n  display:grid;\n  grid-template-columns:repeat(3,minmax(0,1fr));\n  gap:10px;\n  margin-bottom:10px;\n}\n\n@media (max-width: 1100px){\n  .catalog-extra-filters{\n    grid-template-columns:1fr;\n  }\n}\n\n\n@media (max-width: 900px){\n  .map-bottom-grid{\n    grid-template-columns:1fr;\n  }\n\n  .map-list{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\n\n\/* === Budget en dos bloques laterales === *\/\n.bottom-budget{\n  display:block;\n}\n\n.budget-two-cols{\n  display:grid;\n  grid-template-columns:minmax(0,1fr) 260px;\n  gap:16px;\n  align-items:stretch;\n}\n\n.budget-main-col,\n.budget-side-col{\n  border:1px solid var(--line);\n  background:var(--soft);\n  border-radius:16px;\n  padding:14px;\n  height:100%;\n}\n\n.budget-main-col{\n  display:flex;\n  flex-direction:column;\n}\n\n.budget-side-col{\n  display:flex;\n}\n\n.budget-total{\n  margin-top:auto;\n}\n\n.budget-mini-stats{\n  display:grid;\n  grid-template-columns:repeat(2,minmax(0,1fr));\n  grid-auto-rows:1fr;\n  gap:8px;\n  width:100%;\n  height:100%;\n}\n\n.mini-stat{\n  border:1px solid var(--line);\n  background:#fff;\n  border-radius:12px;\n  padding:10px;\n  display:flex;\n  flex-direction:column;\n  justify-content:center;\n  gap:4px;\n  min-height:0;\n}\n\n.mini-stat-label{\n  font-size:11px;\n  color:var(--muted);\n  line-height:1.1;\n}\n\n.mini-stat-value{\n  font-size:17px;\n  color:var(--text);\n  line-height:1.1;\n}\n\n@media (max-width: 900px){\n  .budget-two-cols{\n    grid-template-columns:1fr;\n  }\n}\n\n<\/style>\n<\/head>\n<body>\n<div class=\"app-viewport\" id=\"appViewport\">\n  <div class=\"app-scale-wrap\" id=\"appScaleWrap\">\n    <div class=\"app-scale\" id=\"appScale\">\n      <div class=\"app-shell\">\n        <div class=\"app\">\n        <section class=\"top-layout\">\n          <section class=\"panel box unified-top-clean\">\n            <div class=\"top-clean-main\">\n              <div class=\"top-clean-left\">\n                <div class=\"top-actions\">\n                  <button class=\"btn orange\" id=\"btnCopy\">Copy summary<\/button>\n                  <button class=\"btn alt\" id=\"btnClear\">Clear plan<\/button>\n                  <button class=\"btn alt small\" id=\"btnDownload\">Download PDF<\/button>\n                <\/div>\n              <\/div>\n\n              <div class=\"top-banner\">\n                <div aria-label=\"Visita Tavernes\" class=\"brand-wordmark\">\n                  <img decoding=\"async\" class=\"brand-logo\" alt=\"Turisme Tavernes Valldigna\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAG0AAAB5CAYAAAAzv6\/bAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAB6QSURBVHhe7Z15dFXV2f8\/+5xzp4TMJGBkUMAwo6ARiojFiChVRMQiJRYUGaTAkv5U2teWwYGlS1FwUVsHKtZXW8VlHUAREUQU0FJ4QUAFKWCAQELmm9zxnOf3x829DTcJhAyYRD5rnZVk73PPOXd\/z977eZ49RImIcJ4WhRadcJ7mz3nRWiCqRTWPTf2oSkWnNEuan2gikcOyBMuyEAQCJuLzIF4fBK1GFVApBWkp2F2u6KxmSbMRzRIh6PNhHcklePAI5r7DBPd+T3D\/D1hH8rAKipEKP8q0EGlc0YiLoe2W13B27dwiatuPKpppWVgVHqzc43j+\/gGev69BcguwLBMtaCGWBZYFVmXtA2jkpxUN1MXppO19D5vNEZ3dLDnnollWEMvrJ3j4KN5\/rMH\/6TbM7w5ilbrBHwwJdA4Rh4Frym0kLvk9uqZHZzdLzploYplYFR58u76j4q2P8K38GPKLINDITd1ZInEukv7+JDE3Dg31bS2AphfNEiy\/H39+PuVzn8Hz4SakrBzNah7ehroghbZb\/hd7pw7RWc2WJis5EcEKBvGXlFGy6HkKBk\/A++bHqBJPsxFMEEhNQouNjc5q1jRJ6YmEalfFxq8ovH4y7seXw7HCc95fnQkFGMkJ4LJHZzVrGl00UyxMdzkli5dTctsszJ370IJWo1t9jYFoCtolg71lWI1hGlU00zIJHDpC4ZQ\/4HliBZT5Q45wc8XQMLp2QumNWgxNTqM8rSBYgQD+nd9RMnkevnc+RdyeZlm7TsHQsV98YYuxGsM0jmiBIJ6juRRNeIDgph1ofhPV3AUDlK5jdL4QjZ+YaGYwSMX\/fUPxjfdiffcDmM24OYzGZkO7IDU6tdnTINGCloV317eUTpkH+3NaRO2qinI60BLjopObPfUWTUQwC4oou+9xZO\/BZmfOnxmF1iYW5XRGZzR76iWaiBAsLKZ4+gKC\/9rbvC3EWhEkPgb0ltWfUS\/RRDD9fspWvE3goy0oXyD6jBaDFhsD6uyL4MfmrJ9YTAvvlh1ULHwO5fVHZ7cs7EZL1OzsRLNECJZX4P7jsyhPA4ZRVOXQvq6BoaNsGspmQ9lsiF1HHAbYDJShg6GHztNU6HONhCjQDB2rMS96jjirKL\/l8VL8zAq8855DROrvPOsaesf26Ff2xnZlH4zel6Bf2A49oQ1KgekLYBWVYuXmEzyYQ\/DbQ5j7fsD8\/iDm0ZNoZn1v\/F9EgeOGn5H0j8UYcS3LgqyzaKZlEti1j8IbpiB5JdHZdcLSLVRyEjFzJ9Pm16OxxbpA10EL1aRIZEJCxg4ilSPXFmJaBAN+PP\/eg3fBn\/D\/33dQ7m2QY2wbMYjklU9jtGlZotW5eRSPl4qX38YqLI3OqhOiBD3jIpJXPk3ijF9hS0lAuZwouw1l6ChNCzWZSoUE1LVQut0W8qdiXdgS4okbmknbd5eR9NdHUV0uRBrgHFr+AMqMTm3+1Ek0yzLx7\/oW7z8+RAXrV0hi04l7ei7OQf3RnA5UPSwApRSazYaWlEjMqGtp+\/cnUWmJ9e\/ryj0\/6qh5falTyQWDASr++g5mUVl0Vp1RLie2Tukouy0666xRSqE57NgyLsbo3rXeM6ik1I1YLa+q1Uk0CooJfPZvtGD9v6By2NENo96VoiaUrqES6j\/qbJaWg8cXndzsOaNolmVR8dpqrCMnKm31+qHsBmI08mwnTUNPiK\/3cymfv9599I\/JGUUzK8op\/8ubiK8BjrQCXHY0o+FN4ykoBcnx9dUM8fsxf8iNTm72nFY0sSwCe\/+DFLpRDQwvKrsDbEZ08imICGYwiOXzYfm8WMFgyPSvDaXQ05IQ6vlwQYvg94dPf49myBlF82\/ZCb5GaPedjlB043RYFt6tOymZv4zih\/9E4Idj0Weciqaht0tG6lnTVCCI\/7uDWFY9Rf+ROKNovo8+QwWC0VlnjTqdaFbIiZZAkMD2vVQ8+Qqep1\/FysmNONfUULBKU2jt2tU7MiOmEPzPESTQsoLetYsmgukuI7htD5j1txrDqPhYlF5dNDMQxHfgML49+\/Hv\/R7JPRnKECFw+Ci+vd+HjkNHQnP7q6IUetsklKp+3bqgBCSvEKnwRmc1a2oVTSyLwO7vodRb7ze5KlpSYijwG4WUlVF0+\/8j\/4pxFAyaQPniFSGHN2BRMmUhBVeM42TmHZT+5tHqfY9SkJJQb0MEBOt4AdIA\/\/PHoHopViKmSXDHt402hUClxtfc9wgoM4gKmBA0UeEBVQEtYEHABNNETBMVpY5SCiM5DjG0egsnJWX4P\/83ZmO8meeIWkXDtDC\/Pdg4YR4BIy0VrdZVKVJ5\/BcLM5Ieyql+DkqhXC60NjGnptcZBYEg5f\/7HtIIXcC5olbRxBKCufnVm6T6oEBLSah1fqFl19Ev647jukHYr81E75iKntEJ+7VXYssaiN6\/e+01SWmhyTm1XPtMiGkS+PcerKPHG+cFPQfUKhqWhRSWVnu564MAempSaCAzCgUom0H8wpkkv7eM5H8uxRg5BOevbyb57SWkvPssbRbOqF0zRWW\/VtsZp0cJiN\/E96\/d1Q2dZkqtoinAcrurN0n1QUClJNdYsKIAIzRqrTkdaI7K4Rp75e9OJ4bhAM2ofKpTUUpDS66\/aKDQAiaBT7dhNSC2ei6pVTQRCU3tbgREU2ipiTUWrLRxEv\/4HLQBPRARlKHjmnw7ztHXIrZQH6j6dSNm\/r1Y1T8eMvtTGjA8Q6VTv\/nfLb+mARAINE5F0xV6Us39js3mxDX4chypKaE+T9Nw9cnA2fViNE1H03ScqW2JybwUXav5cbW2ybX2l3XCsjD352C5K1pEv1ZzKVTSgGL4Lwo0hwMVG1PzBZX676h1OEnTThVBhUaya0IALSm+xheizgho3iDBgzlIfScrnUNqLomIYA0oiAgK1caF0vRqflajoEAlN1A0ABHk6AmQ5t9E1ipao6FAJbSp1\/SCuqCUQiU2jmhWSXmjdAdNTdOUZFWUQkuIqzka0ggopWEktGm4aEqhWkB\/xjkRDdAS2zTMUDgdCoiLbXBLbilQrpaxjLfpRVMKFd+08wq1OFeDa5omgmqXXGMAoLlxbkRLbITmqzaUQouLa5jRpEBsGvrFHZruORuRJhdNKdDi20QnNyoqLhZpSGErhXZBKlpaSsj9aOacgydU6E252lKFXApqGGCtM7qG7YreNQ7SNkeaXjQFKiEe1YR9hXLYIc5e7xZSDB3nz69oEbWMcyGapSn0+Jgm7SuUptc6ilAXRNexXTUA\/XxNC6Oh4uKaJhpSiSgN\/YLUer0YYmg4+nRF79kttHqnBdD0T6kELT62XgVaVxSgX5hej5omaG1iaPPwTIzGnkjbhDS5aAogoeHO7+lQgLow9axrimgK\/dIMbJl9m875bwLO7lvWA4WCJjb5RQT9wrSzXvSuYhzETvslqt5zTH4czu5bnjUCStDjmrh5VAqtfVqNU\/Rqw9LAPjoL58ihGPrpp6s3N+r+LeuFQjQdFdv0W6fr7ZPOalWOSksidtYEVJv6L5X6sWha0RQQYwenvelrWmIcymYL96K1o0CcNuKfeRB7v+61joY3Z5r2iZVCT4xHOwfNj3LYUQ5b5Vh2LajQ1AfXxJuJ+cUwdHvL2lE1TJOLRtvEes+1PysMG+pM29radOzDBxH\/yCz0GFeLshir0rSiaQqVltRkA6BVUYYBrto3JxObht4hlcRlf8RITm4xIauaaNonVwojNTk6tUlQNh0VU7NoouvoA3qS9MHz2C5qGcMvp6PJRdNT20anNgli6OiO6qJZykK\/qi+JLz2MvdtFoTkl50WrDQmNU7VLOaNBVxPhNQR1XUug2Qxw2iPLNVBgGWAM7EfK357A2b1Li24Sq9K036KyT6tLsFhECHg8BI4cI5gTOvy5x7HquEBfNB1p46yc8Kogxk7szPGkvvsnbOlpoT6vldCEooV2mTOSa18tUxUBrINHybvqTvKuvIO8gePJv+YurKMnok+tEU3TMJISwGGgd2xH7JO\/JeHR+zBSklqVYDStaICuoxLqNmqtEPD7USdOIieK4EQRFJaG\/tNTnVCQnoKe2ZvEDcuJu+eX6DEx9Yj8N3+aVDRlM1CnMcMbE00p2tw9lrb\/XIajc0f0FjTUcrY0sWi2yijFucHeMR0jqW7NcUumaUWz28B27kSzRAiaJsFgsNajrojIKUdzoklFw26g7OfOCPD5fDz22GOMHz+e8ePHc8cdd0R+v\/vuu8nNza2zAKZpsmXLFhYsWECgme0z0qSiKZvtjFsrNTYOhwOXy4XNZmP16tWcOHECp9OJy+VCOws\/TUQ4fPgw69ata3Y7+tS6Ha5Z6ibv0tFYP+TVe6GdcVkPUjYsx0iIj86qhoiFf+e3FAwaj\/grCyk5nrRNr2Lr2SX69BoRCf2LZYDy8nK6du3K0qVLGTNmDEopgsEgmqbhdIb8Oa\/Xi4hgt9uxLCvydzhqYpomRUVFpKenYxgGPp+PQCCAiESuE073+\/0opbAsC6UUNpsNESFYub+X3W7H4XCgaRqmaeL3+\/H7Qz6oruuRa9WFWl89Rcg5Dh3a2R+6Bi77WWzKqbCUFhrI1MPXUGcVbFZKoes6uq6jVS5MDKcVFxeTlZXFypUrMU0TEWHx4sVMnDgRt9vNW2+9xVVXXUVWVhZ9+\/bltdde4+OPPyY7OxvTNCkvL+eBBx6gf\/\/+9OnTh6uuuooVK1bg8\/n485\/\/zMCBA8nKyiIjI4NBgwbxl7\/8hQkTJtC7d2\/69OnDjBkzKC8vR0T44YcfInndu3fn5ptvZufOnZh13BajdmltBo5Rw5Ci+u2HKICR0bnOhkh4Radj3EiUWWkwuJxoDdiEsyoiQn5+PuXl5RHrsrS0lIKCAgAqKio4dOgQc+fO5bbbbsPlcrFp0yby8vIAWLduHZ999hkvv\/wyvXr14vnnn+eZZ57hhhtuwO12U1hYyP3338\/Pf\/5zli1bxsKFCxk1ahRr167lu+++Y+rUqVx77bXceuutLF++nG+++YbXX3+dlJQU5s6dy2OPPcaKFSuIjz9zq4TUhmmK5fWJ5fHW\/\/D5o696WqygWf3zQTP6tDpRVlYmqamp8vrrr4vf75fc3Fzp0qWLPPfccxIMBsWyLHnwwQdl2LBhUlxcLC+99JL06NFDcnNzJRgMis\/nk1dffVW6desm5eXl8uKLL0qfPn1k165dUlRUJPn5+bJv3z7xeDyycOFCufTSSyU\/P19M05Tt27dL586d5f3335dgMChut1tGjBghM2fOlPz8fLn55ptlxowZUlBQIIWFhbJq1Srp0qWLHDp0KPpr1EitzSOaFhoNdjrqf9S5aQyhdK36589isk5DCPdDhmGg6\/opvp5Siptuuon+\/fszbtw4Ro8ezaxZszhw4EDkHF3XsdvtaJqGw+HAZrNht9vRdR3DMCL9pmmaeDweVq9ezZgxY7j11luZN29epD+sC+emRJoR4YKparTUBYfDEWnCJk6cSCAQ4IEHHuDkycpd86pwOuc+3McOHz6cJUuWsHTpUpYuXcqyZctISkqKPr1GfjKi2e12YmJiOHr0KB6PB7fbTV5eHk6n84xz+EWEp556igULFpCRkcG4ceO47777KCwsxO12R59+WgzDoF27dhw\/fpwuXbrQvXt3SkpK+P3vf19nQ6RVixa2IAFiY2OZPXs2r7zyCr\/5zW+YPn06n332GaNHj8Zms6GUqubHhdOUUtxwww1s3ryZe+65h4ceeogHH3yQnj17kpIS2v+k6r2Iunf4bypr7KhRo9i2bRuTJk1i9uzZzJ49mxEjRuBy1W2qob5gwYIF0YmtAcuyKCoqYsiQIRE\/q0+fPlxwwQXk5ORgt9uZOXMmY8eOxWaz4fV6cblcDBkyBLvdjohE0q655ho6duxIv379OHLkCCUlJQwePJhHHnmEtm3bUlFRQXJyMoMHD8Zms2GaJl6vl8GDB5OaGvr3laWlJWRkZNC3b18yMjLIzMwkJycHv9\/PmDFjmD59OnFxcadtWsPU6ly3dEQEv9+PYRiRtz7s7IabobDRQaXIpmlGzg\/3ecFgELvdjqp0zsM+nqZpkXPDDrRhGBGDwjRNNE1D13VEhEAgEPEfw\/cLh8eq+pZ1odWK1pppVaLJGaLyNfVbLZFWJZrf72f\/\/v2UlpZGmkMqxTIMg4yMjDr3G82ZViWa2+1m0qRJfPrppwAUFxcTGxuLzWYjPj6e1atX06NHj\/OiNSfCnbtpmlRUVNCjRw8WL17Mrbfeit1uP8VQ0DStmll+OsIDqNHREqoYMWHDI5xW9T5VCRtE4RagKjVdK5qW38BXQasMIblcrsjwi91ux1n5v6z37NnDDTfcQO\/evRk9ejRff\/01xcXFTJ48mSeeeCIiTH5+Prfffjtr1qzB6\/Xy+uuvc+WVV9K\/f38WLVpEUVERIsIXX3zBLbfcwkMPPcQVV1zBmjVrePnllxk\/fjzTp0\/n0ksvZezYsezfvz8i4okTJ5gzZw59+vRh2LBhfPTRR3i9XoLBIIcPH2by5Mn07duXa665hg8++ACPp\/pGqa1KtDDhmlC1Ruzfv5+xY8fSs2dP5s+fT0JCAvfeey8lJSX079+fv\/71r3g8HkzTZP369ezZs4eLL76YV199lfnz53PLLbcwadIk3nnnHRYsWIBlWRQWFrJ161Z27drFjBkzSE9PJycnh3Xr1gEwbdo0ioqK+NWvfoXb7aa0tJRp06axY8cOZs+ezcCBA7n33nvZtWsXZWVlPPjgg5w8eZL58+czcuRIpk2bxubNm6uH204JH7ciqkb5fT6f7NixQyZNmiT79++XsrIy2bdvn1xyySWydu1aOXbsmLRr107Wrl0rbrdbpk2bJiNGjJC8vDwZPXq0jB8\/XnJzc6WgoEBWrFghaWlpcvLkSXnnnXfkggsukC1btojf7xePxyMLFiyQXr16ycGDB8Xj8ciWLVukbdu2smPHDvnmm2+ka9eu8sYbb0hRUZEcP35csrKyZPbs2XL48GHp3bu3vPbaa1JSUiJFRUUyY8YMWbt2rQSDwVO+W6usadEopejRowcPP\/wwq1ev5vHHH2fZsmX4fD68Xi\/x8fEMGDCAN998k5KSEr7++muGDx+O0+mkoKCAQ4cOMW\/ePP7whz\/w7rvvIiKRmKPL5SI9PR2bzRbpI+Pi4oiPj8fpdJKYmIjdbsfr9VJRUYHf7+fNN9\/kf\/7nf5g3bx55eXkcOXIEp9NJ3759+d3vfsd9993H6tWrmT9\/PldffXW1PvQnIZqIsH37doYMGcK2bduIj48nJSUFqZxaYLPZuP7669m+fTtfffUVxcXFjB49OhLNSElJoWfPnvTo0YOhQ4cyb948EhIS4AwRfarkh+9lWRZdu3alR48e9O7dm7vuuovs7Gzi4uJ48sknWbRoEXFxcTz77LMMHDiQL7\/8MvqSPw3RLMti586deL1enn32WebMmcNdd91FbGxoVNwwDG6++WZycnJ44oknyMzMpH379pFa06lTJ+655x6mT5\/O1Vdfze7du88oVjThl8PlcpGVlcWMGTOYMmUKmqZRXFxMfn4+7733HsOHD2fx4sWsW7eO2NhYvvjii2pT\/34SoimlSEpKIhAIsHXrVo4fP86SJUsiY2GaptGpUycGDRrE7t27GTZsGA6HA13XGTRoEB988AEbNmxg9+7dLFiwgG3btkWs07oiIrRr147k5GSWLl3K7t27WbduHU888QQANpuNF154gYcffpjDhw\/z+eefc\/z4cTp27FjNZWi1ommaRkZGBgkJCWiaxrBhw5gyZQp\/\/OMfuf322yksLKRXr16RORm6rjNx4kT69OnDz372s8iI8\/Tp07nzzjtZuHAhkyZNIi4ujpdeegm73U5cXBydO3fG4QjtyKppGm3btqVTp04R\/8vpdNKtWzdcLheJiYk8++yzxMfHk52dzSOPPMLUqVMZM2YMiYmJPP744xw4cIAxY8bwyCOPMGfOHG688cZq\/lqrcq6rYpompaWluFwu7JUL4n0+H263GxHB4XBU8+PC\/lJ4ugCVNSRsRFiWhcvlwuVyoet6xEUIny8ieDweLMuKTIkLBAJUVFQQExODYRiRYRuPx4Ou65GIjaocRQjfyzAMYmNjI1MYqtJqRWvNtNrmsSbO9H6eKb+50KpqmmmaFBcXo+s6iYmJkXTLsnC73Xg8Htq2bVutjwhTWFiIpmnEx8cjIhQWFuJwOGodGSgqKgKI9IumaUaauiblFFe7hePxeOTuu++WrKwsCQQCkfTy8nKZMWOGDBkypFp0IUwwGJQ77rhDfvvb34rX65WSkhIZPHiwLFq06JRrhbEsS2bMmCFTp04Vt9sdmbtYUlIilmVFn96otKrmUdd1Bg4cyJ49ezh48GCkucvLy2PDhg1kZ2ejKsfZwgHc8DkiEolYhCPtXq8Xn893SrNZ9bNVz09ISKBfv36RqEj0PcI\/o4+qz1DTPaLzaG19mmEYDBgwAKUUO3fujBTMxo0bERFuvPFGioqK+PDDD\/nb3\/7G22+\/zX\/+859qzmtNiAilpaWsX7+eV155hbVr1+LxeCKF2qFDB8aNG4fNZsOyLI4dO8Zbb73FCy+8wMaNG3n77bfZv38\/Pp+PrVu3snHjRlatWsWrr77Kxo0bI1ZtIBBg3759rFy5kldeeYWPP\/6YwsLCU8WLrnotneLiYhk8eLDcc889EggExOfzSXZ2towcOVIKCgpk6tSp0r59exkwYIB06NBBBg0aJPn5+RIIBGTUqFEyc+ZMqaiokMLCQhkwYIDMnz9f\/H6\/eL1eWbRokaSmpkrnzp0lPT1dEhIS5M4775TS0lJZtWqVpKSkSFlZmRQWFkpWVpakpaVJ3759JS0tTZxOpyxfvlwKCwvltttuk8TEROnQoYN06NAhEtj2er1y7Ngx6devn3Tu3Fn69+8v7dq1kzlz5ojH44l8x1ZV06gM4E6ePJk1a9ZQWlqK2+1m3759EYd569atLF68mM8\/\/5wPP\/yQkpIS1q9fH32ZalRUVPD++++TnZ3Nrl27WL9+PXFxcZEaEG5SqRwG2rdvH88\/\/zxffvklb7zxRqTWq8olVN26dWPr1q3s3r2bX\/ziFzz\/\/PO43W62b9+OaZps3ryZzZs3M3fuXDZs2EBFRUXkWVqdaIZhMGLECCzLYtOmTezdu5eioiJGjhxJXFwcn3zyCd27d+err77i8OHD2Gw2Tpw487YXfr+f4uJirrvuOuLi4rjkkksYPHhwjZboyZMn0XWdyy67DKfTSWZmJunp6RGrUtd1+vfvT3p6OgkJCYwYMYKioiIsyyIrK4v333+fQ4cO8eWXXyKVfW3V1aitTrSwyd6rVy\/WrFnDCy+8QO\/evenWrRsVFRXcf\/\/9jB49milTpjBr1ixOnDhRY2cfTbimhGOOSqlaZwRLlXmRYaHCEZYwYYMlnBeugbm5udx0001kZ2czbdo0nn76aayoQdBWJxqV8\/aHDRvGhg0bWL16Nddffz0Oh4OTJ0+yatUqXnzxRTZt2sTHH39Mp06doIoo4d+j08KFHF4YaFX6fjUJHh8fTyAQ4OjRo\/h8PvLy8k55OWrz44LBIMuXLyc5OZm1a9eyadMmlixZUi2M1SpFMwyDUaNGkZubi2maXHbZZZE4YDAYjMQFjx07Flk0CNCmTRuOHDlCTk4OgUAAp9PJ0aNHycnJQdM00tLS+OCDD8jJyeGrr77iiy++OKUWhMXo1KkTaWlpPPXUU7z22mvMmjWL8vLyyHmnw+PxYBhGJAi9a9eun0ZN03WdSy65hMzMTC666CK6d++Opmm0b9+ezMxMJk6cyPDhw5kwYQJ+vz\/SPI0aNYp\/\/etf3HTTTZSWlpKdnc27777LL3\/5S3w+H7fddhv\/\/Oc\/GTp0KGPHjkVEIiPWhmHgcoU2\/mzfvj3PPfcceXl5PPbYY3Tt2pWOHTtGmlVb5dq1MDabLZL261\/\/mgMHDnD99ddz3XXX8eKLL6JXThsP06rCWFWxLIu9e\/ciIvTs2RPDMLAqF2Vs27YNt9tNx44dMU2T9u3bc9FFF+H3+\/n6668pKyvj8ssvx+l0snPnTioqKrjyyivRNC3iuLdv3x6n04ndbqd79+4UFhayZ88ehg4dypEjR3j00Ue599576dmzJ8ePHyczM5N33nmHzMxMvv32W2w2G71790YpxbFjxzh06BADBoT+dcqBAwf45ptvMAyDDh064Ha7ufzyy4mJCW1F32pFo0rfVLUPCfdH4bTon+F+LFwrwk1T1b\/D+VXTw5\/TNI38\/HwmTJjAsWPH6N+\/P9u2bePiiy9m5cqVEeMl\/LnwPcNUvVZN96G1i\/ZjYZombrebTz75hN27d9OrVy+uu+464uPjqxkV9eG8aE1E2Nm2KmcZVzX\/G8p50VogDa+r5znnnBetBXJetBbIedFaIP8fH7bWR3OG4MYAAAAASUVORK5CYII=\"\/>\n                  <div class=\"brand-text\">\n                    <div class=\"brand-kicker\">VISIT TAVERNES DE LA VALLDIGNA<\/div>\n                    <div class=\"brand-main\"><\/div> Plan your trip by day and time slot with all the options available in Tavernes: activities, heritage, nature, dining, leisure, events and accommodation\n                    <div class=\"brand-subline\">Travel Planner<\/div>\n                  <\/div>\n                <\/div>\n              <\/div>\n\n              <div class=\"trip-tools-row\">\n                <div class=\"field\">\n                  <label for=\"tripName\">Trip name<\/label>\n                  <input id=\"tripName\" value=\"Tavernes getaway\"\/>\n                <\/div>\n                <div class=\"field\">\n                  <label for=\"tripStart\">Start date<\/label>\n                  <input id=\"tripStart\" type=\"date\"\/>\n                <\/div>\n                <div class=\"field\">\n                  <label for=\"numDays\">Number of days<\/label>\n                  <select id=\"numDays\"><\/select>\n                <\/div>\n                <div class=\"day-actions\">\n                  <button class=\"btn alt\" id=\"btnGenerate\">Apply days<\/button>\n                  <button class=\"btn\" id=\"btnAddDay\">Add a day<\/button>\n                <\/div>\n              <\/div>\n            <\/div>\n          <\/section>\n\n        <section class=\"content-grid\">\n          <aside class=\"panel catalog-panel content-right\">\n            <div class=\"catalog-fixed\">\n              <div class=\"catalog-head\">\n                <div>\n                  <h3>General Catalogue of Tavernes de la Valldigna<\/h3>\n                  \n                  <div class=\"catalog-count\" id=\"catalogCount\">0 options<\/div>\n                <\/div>\n\n                <div class=\"catalog-extra-filters\">\n                  <div class=\"field\">\n                    <label>Who are you travelling with<\/label>\n                    <select id=\"tripWho\">\n                      <option value=\"pareja\">Couple<\/option>\n                      <option value=\"familia\">Family<\/option>\n                      <option value=\"amigos\">Friends<\/option>\n                      <option value=\"solo\">Solo<\/option>\n                      <option value=\"grupo\">Group<\/option>\n                    <\/select>\n                  <\/div>\n                  <div class=\"field\">\n                    <label>How do you get around<\/label>\n                    <select id=\"tripMove\">\n                      <option value=\"cualquiera\">Any means<\/option>\n                      <option value=\"coche\">Mostly by car<\/option>\n                      <option value=\"pie\">Mostly by foot<\/option>\n                      <option value=\"bici\">Mostly by bike<\/option>\n                    <\/select>\n                  <\/div>\n                  <div class=\"field\">\n                    <label>Pace<\/label>\n                    <select id=\"tripPace\">\n                      <option value=\"equilibrado\">Balanced<\/option>\n                      <option value=\"tranquilo\">Relaxed<\/option>\n                      <option value=\"activo\">Active<\/option>\n                    <\/select>\n                  <\/div>\n                <\/div>\n\n                <div class=\"filters\">\n                  <div class=\"field\">\n                    <label>Type<\/label>\n                    <select id=\"filterType\">\n                      <option value=\"\">All<\/option>\n                      <option value=\"actividad\">Activity<\/option>\n                      <option value=\"restaurante\">Restaurant<\/option>\n                      <option value=\"alojamiento\">Accommodation<\/option>\n                      <option value=\"evento\">Event<\/option>\n                      <option value=\"ocio\">Leisure<\/option>\n                    <\/select>\n                  <\/div>\n\n                  <div class=\"field\">\n                    <label>Area<\/label>\n                    <select id=\"filterZone\">\n                      <option value=\"\">Any<\/option>\n                      <option value=\"beach\">Beach<\/option>\n                      <option value=\"city\">City<\/option>\n                      <option value=\"valldigna\">Valldigna area<\/option>\n                      <option value=\"monduber\">Mountain \/ Mond\u00faver<\/option>\n                    <\/select>\n                  <\/div>\n\n                  <div class=\"field\">\n                    <label>Time slot<\/label>\n                    <select id=\"filterSlot\">\n                      <option value=\"\">All<\/option>\n                      <option value=\"morning\">Morning<\/option>\n                      <option value=\"midday\">Midday<\/option>\n                      <option value=\"afternoon\">Afternoon<\/option>\n                      <option value=\"night\">Night<\/option>\n                    <\/select>\n                  <\/div>\n\n                  <div class=\"field\">\n                    <label>Transport<\/label>\n                    <select id=\"filterMove\">\n                      <option value=\"\">Any<\/option>\n                      <option value=\"pie\">Foot<\/option>\n                      <option value=\"bici\">Bike<\/option>\n                      <option value=\"coche\">Car<\/option>\n                    <\/select>\n                  <\/div>\n\n                  <div class=\"field\">\n                    <label>Interest<\/label>\n                    <select id=\"filterInterest\">\n                      <option value=\"\">Any<\/option>\n                      <option value=\"beach\">Beach and sea<\/option>\n                      <option value=\"naturaleza\">Nature<\/option>\n                      <option value=\"senderismo\">Hiking<\/option>\n                      <option value=\"patrimonio\">Heritage and culture<\/option>\n                      <option value=\"gastronomia\">Gastronomy<\/option>\n                      <option value=\"familia\">Family plans<\/option>\n                      <option value=\"afternoon_social\">Afternoon social atmosphere<\/option>\n                    <\/select>\n                  <\/div>\n\n                  <div class=\"field\">\n                    <label>Duration<\/label>\n                    <select id=\"filterDuration\">\n                      <option value=\"\">Any<\/option>\n                      <option value=\"corta\">Up to 1.5 h<\/option>\n                      <option value=\"media\">Between 1.5 and 3 h<\/option>\n                      <option value=\"larga\">More than 3 h<\/option>\n                    <\/select>\n                  <\/div>\n\n                  <div class=\"field search\">\n                    <label>Search<\/label>\n                    <input id=\"search\" placeholder=\"E.g. rice, beach, hotel, Bolomor, hiking...\"\/>\n                  <\/div>\n                <\/div>\n              <\/div>\n            <\/div>\n            <div class=\"catalog-results\">\n              <div class=\"catalog-grid\" id=\"catalogGrid\"><\/div>\n            <\/div>\n          <\/aside>\n\n          <section class=\"panel box itinerary-panel content-left\" style=\"padding-bottom:10px\">\n            <h3 style=\"margin:0 0 12px;font-size:25px\">Itinerary<\/h3>\n            <div class=\"center-scroll\" id=\"daysContainer\"><\/div>\n          <\/section>\n        <\/section>\n\n        <section class=\"panel map-panel map-bottom\">\n          <div class=\"map-header\">\n            <h3>Interactive map<\/h3>\n            <p>Click on a card to center its location. The points update with the filters and the map helps distribute your trip more efficiently.<\/p>\n            <div class=\"map-stats\">\n              <span class=\"map-pill\" id=\"mapVisibleCount\">0 visible locations<\/span>\n              <span class=\"map-pill\" id=\"mapPlannedCount\">0 added to the trip<\/span>\n              <span class=\"map-pill\">\ud83e\udded Activity<\/span>\n              <span class=\"map-pill\">\ud83c\udf7d\ufe0f Restaurant<\/span>\n              <span class=\"map-pill\">\ud83d\udecf\ufe0f Accommodation<\/span>\n              <span class=\"map-pill\">\ud83c\udf89 Event<\/span>\n              <span class=\"map-pill\">\ud83c\udf19 Leisure<\/span>\n            <\/div>\n            <div class=\"map-controls\">\n              <label class=\"map-toggle\">\n                <input type=\"checkbox\" id=\"mapOnlyPlanned\"\/>\n                Show only items added to the trip\n              <\/label>\n            <\/div>\n          <\/div>\n          <div class=\"map-bottom-grid\">\n            <div id=\"travelMap\"><\/div>\n            <div class=\"map-side-scroll\">\n              <div class=\"map-list\" id=\"mapList\"><\/div>\n            <\/div>\n          <\/div>\n        <\/section>\n\n        <section class=\"panel box bottom-budget\">\n          <div class=\"budget-two-cols\">\n            <div class=\"budget-main-col\">\n              <h3 style=\"margin:0 0 10px;font-size:25px\">Budget<\/h3>\n              <div class=\"budget-line\"><span>Activities<\/span><strong id=\"bAct\">0 \u20ac<\/strong><\/div>\n              <div class=\"budget-line\"><span>Restaurants<\/span><strong id=\"bFood\">0 \u20ac<\/strong><\/div>\n              <div class=\"budget-line\"><span>Accommodation<\/span><strong id=\"bStay\">0 \u20ac<\/strong><\/div>\n              <div class=\"budget-line\"><span>Leisure and events<\/span><strong id=\"bOther\">0 \u20ac<\/strong><\/div>\n              <div class=\"budget-total\" id=\"bTotal\">0 \u20ac<\/div>\n            <\/div>\n\n            <div class=\"budget-side-col\">\n              <div class=\"budget-mini-stats\">\n                <div class=\"mini-stat\">\n                  <span class=\"mini-stat-label\">Days<\/span>\n                  <strong class=\"mini-stat-value\" id=\"statDays\">0<\/strong>\n                <\/div>\n                <div class=\"mini-stat\">\n                  <span class=\"mini-stat-label\">Hours<\/span>\n                  <strong class=\"mini-stat-value\" id=\"statHours\">0 h<\/strong>\n                <\/div>\n                <div class=\"mini-stat\">\n                  <span class=\"mini-stat-label\">Stops<\/span>\n                  <strong class=\"mini-stat-value\" id=\"statStops\">0<\/strong>\n                <\/div>\n                <div class=\"mini-stat\">\n                  <span class=\"mini-stat-label\">Budget<\/span>\n                  <strong class=\"mini-stat-value\" id=\"statBudget\">0 \u20ac<\/strong>\n                <\/div>\n              <\/div>\n            <\/div>\n          <\/div>\n        <\/section>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n<script\n  src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\"\n  integrity=\"sha256-20nQCchB9co0qIjJZRGuk2\/Z9VM+kNiyxNV1lvTlZBo=\"\n  crossorigin=\"\"\n><\/script>\n\n<script>\nconst PLANNER_BASE_WIDTH = 1940;\nconst PLANNER_BASE_HEIGHT = 1060;\n\nconst catalog = [\n  {\"id\":\"act-1\",\"title\":\"Beach of Tavernes\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":2,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Walk, swim and main beach stretch.\",\"cost\":0,\"score\":95,\"notes\":\"beach swimming promenade sea\"},\n  {\"id\":\"act-2\",\"title\":\"Llac de la Goleta\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Easy walk next to the Goleta area.\",\"cost\":0,\"score\":88,\"notes\":\"beach promenade relaxation\"},\n  {\"id\":\"act-3\",\"title\":\"Clot de la Font\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Relaxed nature stop in a fresh setting.\",\"cost\":0,\"score\":90,\"notes\":\"nature relaxation\"},\n  {\"id\":\"act-4\",\"title\":\"Granata Fountain\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":1.5,\"move\":[\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Natural setting for a peaceful visit.\",\"cost\":0,\"score\":84,\"notes\":\"peaceful nature\"},\n  {\"id\":\"act-5\",\"title\":\"Les Fontetes de Cant\u00fas\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":2,\"move\":[\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Inland spot for walking and outdoor time.\",\"cost\":0,\"score\":83,\"notes\":\"inland promenade\"},\n  {\"id\":\"act-6\",\"title\":\"Mond\u00faver Route\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\"],\"desc\":\"Mountain outing for those wanting a more demanding route.\",\"cost\":0,\"score\":92,\"notes\":\"hiking mountain active\"},\n  {\"id\":\"act-7\",\"title\":\"Visit to Bolomor Cave\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\"],\"desc\":\"Visit the site and discover its archaeological value.\",\"cost\":0,\"score\":89,\"notes\":\"culture heritage history\"},\n  {\"id\":\"act-8\",\"title\":\"Bolomor Cave Route\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":2,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"A walk through the surrounding area without entering the interior of the site.\",\"cost\":0,\"score\":81,\"notes\":\"walk nature history\"},\n  {\"id\":\"act-9\",\"title\":\"Sailing school\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Water-based activity for beginners or as a guided session.\",\"cost\":0,\"score\":85,\"notes\":\"beach sea sport active family\"},\n  {\"id\":\"act-10\",\"title\":\"Kitesurf lane\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Sports access area linked to kitesurf practice.\",\"cost\":0,\"score\":76,\"notes\":\"beach wind sport\"},\n  {\"id\":\"act-11\",\"title\":\"Boat entry channel\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Nautical access point next to the beach entrance.\",\"cost\":0,\"score\":70,\"notes\":\"nautical beach\"},\n  {\"id\":\"act-12\",\"title\":\"Beach of Goleta\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Stretch of beach and promenade in La Goleta, gateway to the dune ecosystem of the Ruta dels Sentits.\",\"cost\":0,\"score\":93,\"notes\":\"beach dunes promenade\"},\n  {\"id\":\"act-13\",\"title\":\"Moll\u00f3 Park\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Accessible park for cycling, skating and outdoor fitness equipment.\",\"cost\":0,\"score\":82,\"notes\":\"family children cycling\"},\n  {\"id\":\"act-14\",\"title\":\"North Park\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Sports and leisure area with courts and seasonal summer activities.\",\"cost\":0,\"score\":84,\"notes\":\"family sport leisure\"},\n  {\"id\":\"act-15\",\"title\":\"Watchtower\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Historic coastal watchtower with defensive heritage value, next to a leisure area and pond.\",\"cost\":0,\"score\":94,\"notes\":\"heritage culture walk\"},\n  {\"id\":\"act-16\",\"title\":\"Beach entrance cycle lane\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":1,\"move\":[\"bici\",\"pie\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Comfortable cycle route connecting with the Watchtower and La Goleta.\",\"cost\":0,\"score\":80,\"notes\":\"cycling beach ride\"},\n  {\"id\":\"act-17\",\"title\":\"Ruta dels Sentits\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":3.5,\"move\":[\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"A 14 km Blue Trail linking dunes, marshland, orchards and woodland surroundings.\",\"cost\":0,\"score\":97,\"notes\":\"hiking cycling nature marsh beach\"},\n  {\"id\":\"act-18\",\"title\":\"Ullal Gran\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Wetland linked to an underground spring, a refuge for birds and a very photogenic stop.\",\"cost\":0,\"score\":89,\"notes\":\"nature photos birds\"},\n  {\"id\":\"act-19\",\"title\":\"Ullal de les Penyetes\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Wetland point complementary to Ullal Gran, ideal for an interpretive walk.\",\"cost\":0,\"score\":84,\"notes\":\"nature walk\"},\n  {\"id\":\"act-20\",\"title\":\"Sangonera Fountain\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":1,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Mountain spring located in the surroundings of the Route de les Creus.\",\"cost\":0,\"score\":82,\"notes\":\"mountain walk\"},\n  {\"id\":\"act-21\",\"title\":\"Sant Lloren\u00e7 Natural Area\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Mountain setting linked to the hermitage and several routes leading to viewpoints.\",\"cost\":0,\"score\":86,\"notes\":\"nature viewpoint heritage\"},\n  {\"id\":\"act-22\",\"title\":\"Mediterranean Viewpoint\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Classic viewpoint in Tavernes with panoramic views over the coast and the Valldigna valley.\",\"cost\":0,\"score\":91,\"notes\":\"viewpoint photos landscape\"},\n  {\"id\":\"act-23\",\"title\":\"Massalari Peak\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":3,\"move\":[\"pie\"],\"slots\":[\"morning\"],\"desc\":\"Mountain summit and surrounding area for hikers looking for a longer route.\",\"cost\":0,\"score\":84,\"notes\":\"hiking mountain active\"},\n  {\"id\":\"act-24\",\"title\":\"Massalari Bell\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":3.5,\"move\":[\"pie\"],\"slots\":[\"morning\"],\"desc\":\"Out-and-back route through the Serra de les Creus to the bell installed by hikers.\",\"cost\":0,\"score\":88,\"notes\":\"active hiking\"},\n  {\"id\":\"act-25\",\"title\":\"Route de les Creus\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":4,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Waymarked route ascending to les Creus, Fontetes de Cant\u00fas, Castellets and the viewpoint.\",\"cost\":0,\"score\":96,\"notes\":\"hiking mountain active\"},\n  {\"id\":\"act-26\",\"title\":\"Pas de Cabres Via Ferrata\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":5,\"move\":[\"pie\"],\"slots\":[\"morning\"],\"desc\":\"K2 via ferrata with two equipped sections ending at the second cross.\",\"cost\":0,\"score\":90,\"notes\":\"adventure active mountain\"},\n  {\"id\":\"act-27\",\"title\":\"Les Marujes Via Ferrata\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":2.5,\"move\":[\"pie\"],\"slots\":[\"morning\"],\"desc\":\"K3 via ferrata in Penya Roja with a Tibetan bridge and vertical sections.\",\"cost\":0,\"score\":89,\"notes\":\"adventure active\"},\n  {\"id\":\"act-28\",\"title\":\"Cadira Route\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":2.8,\"move\":[\"pie\"],\"slots\":[\"morning\"],\"desc\":\"Circular route through Cam\u00ed de la Cadira, La Cisterna and Pla de les Foietes.\",\"cost\":0,\"score\":93,\"notes\":\"hiking landscape\"},\n  {\"id\":\"act-29\",\"title\":\"Ombria Route\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":3,\"move\":[\"pie\"],\"slots\":[\"morning\"],\"desc\":\"Circular route through l'Ombria, Barranc de Cremades and Pla de les Foietes.\",\"cost\":0,\"score\":90,\"notes\":\"active hiking\"},\n  {\"id\":\"act-30\",\"title\":\"Reina Mora Castle\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":2,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Moderate route to a legendary site in the mountains, linked to the medieval past.\",\"cost\":0,\"score\":87,\"notes\":\"hiking history heritage\"},\n  {\"id\":\"act-31\",\"title\":\"Via Verda - Trenet (GR-236)\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":2.5,\"move\":[\"bici\",\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"29 km route along the former Carcaixent-Gandia-D\u00e9nia railway, ideal for cycling.\",\"cost\":0,\"score\":92,\"notes\":\"cycling active route\"},\n  {\"id\":\"act-32\",\"title\":\"Nordic Walking Circuit\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":2.5,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Active circuit through the viewpoint area, Rac\u00f3 de Joana and Rac\u00f3 Red\u00f3.\",\"cost\":0,\"score\":80,\"notes\":\"active sport walking\"},\n  {\"id\":\"act-33\",\"title\":\"Rac\u00f3 de Joana\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":1.5,\"move\":[\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Natural area in the surroundings of the viewpoint and the Nordic walking circuit.\",\"cost\":0,\"score\":79,\"notes\":\"nature walk cycling\"},\n  {\"id\":\"act-34\",\"title\":\"La Cisterna\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":0.8,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Historic cistern visible in the surroundings of the Cadira Route and l'Ombria.\",\"cost\":0,\"score\":76,\"notes\":\"heritage mountain\"},\n  {\"id\":\"act-35\",\"title\":\"Pla de les Foietes\",\"type\":\"actividad\",\"zone\":\"monduber\",\"hours\":1,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"High plateau and scenic balcony included in several mountain routes.\",\"cost\":0,\"score\":78,\"notes\":\"landscape viewpoint\"},\n  {\"id\":\"act-36\",\"title\":\"City Hall\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Emblematic building in the urban centre, suitable for a heritage walk.\",\"cost\":0,\"score\":74,\"notes\":\"heritage centre\"},\n  {\"id\":\"act-37\",\"title\":\"Sant Pere Church\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Historic church in the old quarter with a dome, chapel and museum.\",\"cost\":0,\"score\":90,\"notes\":\"culture heritage history\"},\n  {\"id\":\"act-38\",\"title\":\"Sant Josep Church\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.75,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Church included among Tavernes\u2019 emblematic buildings.\",\"cost\":0,\"score\":78,\"notes\":\"heritage culture\"},\n  {\"id\":\"act-39\",\"title\":\"Calvari\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.75,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Climb and visit to one of the emblematic landmarks of the urban centre.\",\"cost\":0,\"score\":79,\"notes\":\"city walk\"},\n  {\"id\":\"act-40\",\"title\":\"Mol\u00ed Vell del Pla\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.75,\"move\":[\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Notable example of hydraulic archaeology from the Cistercian period.\",\"cost\":0,\"score\":85,\"notes\":\"heritage culture\"},\n  {\"id\":\"act-41\",\"title\":\"Mol\u00ed de Tonet\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.75,\"move\":[\"pie\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Reference point of local industrial heritage linked to the valley\u2019s technical evolution.\",\"cost\":0,\"score\":80,\"notes\":\"heritage\"},\n  {\"id\":\"act-42\",\"title\":\"Ermita de Sant Lloren\u00e7\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Hermitage and historic site linked to l\u2019Alcudiola and the route up to the viewpoint.\",\"cost\":0,\"score\":82,\"notes\":\"heritage viewpoint\"},\n  {\"id\":\"act-43\",\"title\":\"Municipal Market\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.75,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\"],\"desc\":\"Useful stop for local produce and everyday local atmosphere.\",\"cost\":0,\"score\":77,\"notes\":\"local produce\"},\n  {\"id\":\"act-44\",\"title\":\"House of Culture\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Cultural venue active throughout the year with outdoor space for events.\",\"cost\":0,\"score\":83,\"notes\":\"culture\"},\n  {\"id\":\"act-45\",\"title\":\"VCF Mural at Carlos Pellicer Pavilion\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Large urban art mural promoted by the Fundaci\u00f3 Valencia CF at the Carlos Pellicer pavilion.\",\"cost\":0,\"score\":85,\"notes\":\"urban art\"},\n  {\"id\":\"act-46\",\"title\":\"House of Culture Mural (Estell\u00e9s)\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":0.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Large-format urban mural on the fa\u00e7ade of the House of Culture dedicated to Estell\u00e9s.\",\"cost\":0,\"score\":84,\"notes\":\"urban art culture\"},\n  {\"id\":\"act-47\",\"title\":\"Torreta Iron Mural\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":0.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Art intervention on the route between the Watchtower and the Torreta.\",\"cost\":0,\"score\":74,\"notes\":\"art by the beach\"},\n  {\"id\":\"act-48\",\"title\":\"Badell and Vaca River Area\",\"type\":\"actividad\",\"zone\":\"valldigna\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Walk through the surroundings of the Vaca River tributary, included in several local routes.\",\"cost\":0,\"score\":78,\"notes\":\"nature walk\"},\n  {\"id\":\"act-49\",\"title\":\"Promenade and beach bars\",\"type\":\"actividad\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Relaxed stroll along the seafront with atmosphere, bars and summer activity.\",\"cost\":0,\"score\":86,\"notes\":\"beach atmosphere promenade\"},\n  {\"id\":\"act-50\",\"title\":\"Cultural Walk Through the Historic Centre\",\"type\":\"actividad\",\"zone\":\"city\",\"hours\":2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Urban route combining City Hall, churches, the market, mills and the House of Culture.\",\"cost\":0,\"score\":80,\"notes\":\"culture city heritage\"},\n\n  {\"id\":\"res-51\",\"title\":\"Baladre\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"midday\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant with rice dishes, terrace atmosphere, pool and drinks option.\",\"cost\":24,\"score\":92,\"notes\":\"beach rice atmosphere\"},\n  {\"id\":\"res-52\",\"title\":\"Bar Restaurant Calipso\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant serving Mediterranean cuisine.\",\"cost\":22,\"score\":84,\"notes\":\"beach Mediterranean\"},\n  {\"id\":\"res-53\",\"title\":\"Restaurant Macario\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.6,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Mediterranean and Valencian cuisine with a strong emphasis on rice dishes and Valencian paella.\",\"cost\":28,\"score\":94,\"notes\":\"rice paella beach\"},\n  {\"id\":\"res-54\",\"title\":\"Casablanca Beer & Grill\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside option focused on grill dishes and casual dining.\",\"cost\":24,\"score\":83,\"notes\":\"casual friends\"},\n  {\"id\":\"res-55\",\"title\":\"Cervecer\u00eda Los Delfines\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside beer bar suitable for tapas, snacks or a relaxed meal.\",\"cost\":18,\"score\":81,\"notes\":\"tapas friends beach\"},\n  {\"id\":\"res-56\",\"title\":\"Dall\u2019Italiano\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Italian beachside restaurant with homemade pasta and pizzas in the evening.\",\"cost\":24,\"score\":93,\"notes\":\"pizza Italian family night\"},\n  {\"id\":\"res-57\",\"title\":\"El Fog\u00f3n de More\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant suitable for lunch and dinner.\",\"cost\":22,\"score\":80,\"notes\":\"beach\"},\n  {\"id\":\"res-58\",\"title\":\"Haveli Tavernes\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Indian restaurant by the beach.\",\"cost\":22,\"score\":87,\"notes\":\"Indian dinner\"},\n  {\"id\":\"res-59\",\"title\":\"La Bombonera Gastrobar\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"midday\",\"afternoon\",\"night\"],\"desc\":\"Beachside gastrobar suitable for afternoon social time, tapas, lunch or dinner.\",\"cost\":24,\"score\":82,\"notes\":\"afternoon social friends beach\"},\n  {\"id\":\"res-60\",\"title\":\"La Gallina Loca\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant for lunch or dinner.\",\"cost\":22,\"score\":80,\"notes\":\"beach\"},\n  {\"id\":\"res-61\",\"title\":\"La Mordidita Beach Club\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"midday\",\"afternoon\",\"night\"],\"desc\":\"Beach club suitable for meals, afternoon social time and evening atmosphere.\",\"cost\":26,\"score\":85,\"notes\":\"afternoon social friends beach\"},\n  {\"id\":\"res-62\",\"title\":\"L\u2019Excusa Perfecta\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant suitable for lunch and dinner.\",\"cost\":23,\"score\":80,\"notes\":\"beach\"},\n  {\"id\":\"res-63\",\"title\":\"Restaurant Puerta del Sol\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"midday\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant suitable for lunch or dinner during a day by the sea.\",\"cost\":24,\"score\":84,\"notes\":\"beach restaurant lunch dinner\"},\n  {\"id\":\"res-64\",\"title\":\"N\u00f2mada Lounge & Restaurant\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"midday\",\"night\"],\"desc\":\"Lounge and restaurant by the sea, suitable for lunch, dinner or extending after-meal time.\",\"cost\":26,\"score\":86,\"notes\":\"couples beach dinner\"},\n  {\"id\":\"res-65\",\"title\":\"Restaurant Altamar\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant suitable for lunch and dinner.\",\"cost\":26,\"score\":88,\"notes\":\"beach\"},\n  {\"id\":\"res-66\",\"title\":\"Restaurant El Medi \/ Mediterrani\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Restaurant serving Mediterranean cuisine by the beach.\",\"cost\":25,\"score\":86,\"notes\":\"Mediterranean beach\"},\n  {\"id\":\"res-67\",\"title\":\"Restaurant Les Ones\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Beachside restaurant suitable for lunch and dinner.\",\"cost\":23,\"score\":84,\"notes\":\"beach\"},\n  {\"id\":\"res-68\",\"title\":\"Restaurant Luna Park\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Restaurant on Tavernes beach.\",\"cost\":25,\"score\":83,\"notes\":\"beach\"},\n  {\"id\":\"res-69\",\"title\":\"Restaurant San Bernardo\",\"type\":\"restaurante\",\"zone\":\"beach\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Restaurant serving traditional cuisine by the beach.\",\"cost\":22,\"score\":84,\"notes\":\"traditional beach\"},\n  {\"id\":\"res-70\",\"title\":\"Aires del Sur\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Restaurant specializing in fried dishes and meat dishes.\",\"cost\":21,\"score\":84,\"notes\":\"meat dishes\"},\n  {\"id\":\"res-71\",\"title\":\"Bar \u00c1ngel\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Bar closely linked to the local mid-morning meal tradition.\",\"cost\":12,\"score\":89,\"notes\":\"local mid-morning meal\"},\n  {\"id\":\"res-72\",\"title\":\"Bar Els Amics\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"City bar suitable for the local mid-morning meal, tapas or lunch.\",\"cost\":20,\"score\":78,\"notes\":\"mid-morning meal tapas\"},\n  {\"id\":\"res-73\",\"title\":\"Bar La Cosa Nostra\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Urban bar-restaurant suitable for lunch or dinner.\",\"cost\":16,\"score\":79,\"notes\":\"urban\"},\n  {\"id\":\"res-74\",\"title\":\"Bar Restaurant Astim\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"City bar-restaurant suitable for the local mid-morning meal or lunch.\",\"cost\":15,\"score\":78,\"notes\":\"mid-morning meal\"},\n  {\"id\":\"res-75\",\"title\":\"Bar Tapas Cristal\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Tapas venue in Tavernes suitable for a relaxed meal.\",\"cost\":17,\"score\":80,\"notes\":\"tapas friends\"},\n  {\"id\":\"res-76\",\"title\":\"Bar Murciano\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"City bar especially associated with the local mid-morning meal tradition.\",\"cost\":18,\"score\":79,\"notes\":\"mid-morning meal\"},\n  {\"id\":\"res-77\",\"title\":\"Ca Saoret\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Well-known local venue associated with the traditional mid-morning meal, with Mediterranean and Spanish cuisine. Winner of the Cacau d\u2019Or award.\",\"cost\":19,\"score\":95,\"notes\":\"local signature mid-morning meal\"},\n  {\"id\":\"res-78\",\"title\":\"Cervesseria Garatge\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Urban beer bar suitable for snacks and afternoon social time.\",\"cost\":18,\"score\":79,\"notes\":\"beer afternoon social friends\"},\n  {\"id\":\"res-79\",\"title\":\"Exqsa Perfecta \u2013 Passeig\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Urban option suitable for lunch or dinner.\",\"cost\":19,\"score\":77,\"notes\":\"urban\"},\n  {\"id\":\"res-80\",\"title\":\"La Casa Viva\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"midday\",\"afternoon\",\"night\"],\"desc\":\"Vegetarian and vegan restaurant with gluten-free options.\",\"cost\":24,\"score\":92,\"notes\":\"vegetarian vegan healthy\"},\n  {\"id\":\"res-81\",\"title\":\"Legends\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\"],\"desc\":\"Bar focused on the local late breakfast \/ brunch tradition.\",\"cost\":14,\"score\":82,\"notes\":\"mid-morning meal\"},\n  {\"id\":\"res-82\",\"title\":\"Pizzeria La Vall Expr\u00e9s\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":0.8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"midday\",\"night\"],\"desc\":\"Wood-fired pizzeria offering pizzas and roast chicken for takeaway.\",\"cost\":15,\"score\":88,\"notes\":\"pizza family\"},\n  {\"id\":\"res-83\",\"title\":\"Pizzer\u00eda Tropical\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Pizzeria in Tavernes city.\",\"cost\":17,\"score\":79,\"notes\":\"pizza\"},\n  {\"id\":\"res-84\",\"title\":\"Restaurant 5 Hermanas\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Urban restaurant suitable for lunch and dinner.\",\"cost\":20,\"score\":82,\"notes\":\"urban\"},\n  {\"id\":\"res-85\",\"title\":\"Restaurant Bar Pizzeria Anais\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Bar-pizzeria in the city.\",\"cost\":18,\"score\":78,\"notes\":\"pizza\"},\n  {\"id\":\"res-86\",\"title\":\"Restaurant Chino Gran Muralla\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Chinese restaurant in Tavernes city.\",\"cost\":18,\"score\":78,\"notes\":\"Asian\"},\n  {\"id\":\"res-87\",\"title\":\"Restaurant Club de Tenis Valldigna\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Restaurant linked to the tennis club.\",\"cost\":22,\"score\":76,\"notes\":\"club\"},\n  {\"id\":\"res-88\",\"title\":\"Restaurant Delicias\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Urban restaurant suitable for lunch and dinner.\",\"cost\":17,\"score\":77,\"notes\":\"urban\"},\n  {\"id\":\"res-89\",\"title\":\"Restaurant Pizzer\u00eda Ibis\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Restaurant-pizzeria in Tavernes city.\",\"cost\":17,\"score\":77,\"notes\":\"pizza\"},\n  {\"id\":\"res-90\",\"title\":\"Restaurant Mei Zhou\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Asian restaurant in Tavernes city.\",\"cost\":18,\"score\":78,\"notes\":\"Asian\"},\n  {\"id\":\"res-91\",\"title\":\"Restaurant V\u00edctor\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"City bar-restaurant suitable for the local mid-morning meal or lunch.\",\"cost\":25,\"score\":79,\"notes\":\"mid-morning meal\"},\n  {\"id\":\"res-92\",\"title\":\"Rustiks\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Urban restaurant for lunch or dinner.\",\"cost\":19,\"score\":78,\"notes\":\"dinner\"},\n  {\"id\":\"res-93\",\"title\":\"Super Pizza\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":0.8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Takeaway pizzas.\",\"cost\":14,\"score\":76,\"notes\":\"pizza\"},\n  {\"id\":\"res-94\",\"title\":\"The Black Burger\",\"type\":\"restaurante\",\"zone\":\"city\",\"hours\":1.2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Burger restaurant in Tavernes city.\",\"cost\":18,\"score\":83,\"notes\":\"burger friends family\"},\n\n  {\"id\":\"alo-95\",\"title\":\"Hotel Valldigna\",\"type\":\"alojamiento\",\"zone\":\"city\",\"hours\":8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Hotel in Tavernes city.\",\"cost\":0,\"score\":88,\"notes\":\"alojamiento hotel\"},\n  {\"id\":\"alo-96\",\"title\":\"Villa Ursula\",\"type\":\"alojamiento\",\"zone\":\"beach\",\"hours\":8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Accommodation junto a la zona beachside.\",\"cost\":0,\"score\":85,\"notes\":\"alojamiento beach\"},\n  {\"id\":\"alo-97\",\"title\":\"VMC Rooms\",\"type\":\"alojamiento\",\"zone\":\"beach\",\"hours\":8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Rooms cerca de the beach.\",\"cost\":0,\"score\":84,\"notes\":\"alojamiento beach\"},\n  {\"id\":\"alo-98\",\"title\":\"Rooms Avenida\",\"type\":\"alojamiento\",\"zone\":\"city\",\"hours\":8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Urban accommodation in Tavernes city.\",\"cost\":0,\"score\":80,\"notes\":\"accommodation city\"},\n  {\"id\":\"alo-99\",\"title\":\"Camping Car La Finca\",\"type\":\"alojamiento\",\"zone\":\"beach\",\"hours\":8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Camper area next to the beach.\",\"cost\":0,\"score\":79,\"notes\":\"camper beach\"},\n  {\"id\":\"alo-100\",\"title\":\"Ohana Beach Camper Area\",\"type\":\"alojamiento\",\"zone\":\"beach\",\"hours\":8,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Restaurant on Tavernes beach.\",\"cost\":0,\"score\":77,\"notes\":\"camper beach\"},\n\n  {\"id\":\"eve-101\",\"title\":\"Tavernes Fallas\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"afternoon\",\"night\"],\"desc\":\"Traditional festival held from 16 to 19 March.\",\"cost\":0,\"score\":87,\"notes\":\"festival celebration\"},\n  {\"id\":\"eve-102\",\"title\":\"Festivern\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"midday\",\"afternoon\",\"night\"],\"desc\":\"Festival held from 29 to 31 December.\",\"cost\":0,\"score\":91,\"notes\":\"music festival friends\"},\n  {\"id\":\"eve-103\",\"title\":\"Del Poble Fest\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"midday\",\"afternoon\",\"night\"],\"desc\":\"Festival held on dates that vary depending on each edition.\",\"cost\":0,\"score\":82,\"notes\":\"festival\"},\n  {\"id\":\"eve-104\",\"title\":\"Sant Joan\",\"type\":\"evento\",\"zone\":\"beach\",\"hours\":3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"midday\",\"afternoon\",\"night\"],\"desc\":\"Traditional celebration on the night of 23 June.\",\"cost\":0,\"score\":84,\"notes\":\"beach fiesta night\"},\n  {\"id\":\"eve-105\",\"title\":\"Sant Jaume Fair\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Popular fair with attractions and a festive atmosphere.\",\"cost\":0,\"score\":83,\"notes\":\"familia feria\"},\n\n  {\"id\":\"eve-112\",\"title\":\"April - Holy Week\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Traditional programme associated with Holy Week in Tavernes.\",\"cost\":0,\"score\":84,\"notes\":\"Holy Week tradition processions\"},\n  {\"id\":\"eve-113\",\"title\":\"Major Festivities\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":4,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"morning\",\"midday\",\"afternoon\",\"night\"],\"desc\":\"Event troncal del calendario local con actos repartidos durante la jornada.\",\"cost\":0,\"score\":90,\"notes\":\"fiestas mayores tradition town\"},\n  {\"id\":\"eve-114\",\"title\":\"1st of May\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Traditional 1st of May celebration with local programming.\",\"cost\":0,\"score\":82,\"notes\":\"May tradition celebration\"},\n  {\"id\":\"eve-115\",\"title\":\"9th of October\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Commemorative programme for 9 October within the local calendar.\",\"cost\":0,\"score\":82,\"notes\":\"9 October tradition celebration\"},\n  {\"id\":\"eve-116\",\"title\":\"Porrat de la Sang\",\"type\":\"evento\",\"zone\":\"valldigna\",\"hours\":2.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\"],\"desc\":\"Traditional porrat linked to local custom and suitable for family plans.\",\"cost\":0,\"score\":84,\"notes\":\"traditional family porrat\"},\n  {\"id\":\"eve-117\",\"title\":\"Porrat de Sant Lloren\u00e7\",\"type\":\"evento\",\"zone\":\"monduber\",\"hours\":2.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\"],\"desc\":\"Traditional porrat linked to the Sant Lloren\u00e7 area, combining local tradition and nature.\",\"cost\":0,\"score\":84,\"notes\":\"Sant Lloren\u00e7 porrat tradition\"},\n  {\"id\":\"eve-118\",\"title\":\"Sete S\u00f3is Sete Luas\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":3,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Cultural and music festival held according to the annual programme.\",\"cost\":0,\"score\":86,\"notes\":\"festival music culture\"},\n  {\"id\":\"eve-119\",\"title\":\"Choir Festival\",\"type\":\"evento\",\"zone\":\"city\",\"hours\":2.5,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Choral music festival held according to the annual programme.\",\"cost\":0,\"score\":84,\"notes\":\"choir festival music\"},\n\n  {\"id\":\"oci-107\",\"title\":\"Drinks or afternoon social at Baladre\",\"type\":\"ocio\",\"zone\":\"beach\",\"hours\":2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Afternoon social time and drinks at Baladre, one of the liveliest spots by the beach.\",\"cost\":0,\"score\":82,\"notes\":\"afternoon social drinks friends\"},\n  {\"id\":\"oci-108\",\"title\":\"Seafront evening stroll\",\"type\":\"ocio\",\"zone\":\"beach\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"night\"],\"desc\":\"Gentle option to round off the day.\",\"cost\":0,\"score\":75,\"notes\":\"beach night walk relaxed\"},\n  {\"id\":\"oci-109\",\"title\":\"Night Walk Through Tavernes City\",\"type\":\"ocio\",\"zone\":\"city\",\"hours\":1,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"night\"],\"desc\":\"Relaxed walk through the city centre.\",\"cost\":0,\"score\":68,\"notes\":\"city relaxed walk\"},\n  {\"id\":\"oci-110\",\"title\":\"Drinks or afternoon social at La Bombonera Gastrobar\",\"type\":\"ocio\",\"zone\":\"beach\",\"hours\":2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Afternoon social time and drinks next to the beach.\",\"cost\":0,\"score\":80,\"notes\":\"afternoon social drinks beach\"},\n  {\"id\":\"oci-111\",\"title\":\"Drinks or afternoon social at La Mordidita Beach Club\",\"type\":\"ocio\",\"zone\":\"beach\",\"hours\":2,\"move\":[\"coche\",\"pie\",\"bici\"],\"slots\":[\"afternoon\",\"night\"],\"desc\":\"Beach club with an afternoon social atmosphere and evening leisure setting.\",\"cost\":0,\"score\":82,\"notes\":\"afternoon social friends beach\"}\n];\n\nconst coordPatch = {\n  \"Beach of Tavernes\": { \"lat\": 39.090078963337994, \"lng\": -0.2170801784160719 },\n  \"Llac de la Goleta\": { \"lat\": 39.10312853744882, \"lng\": -0.22278208556330922 },\n  \"Clot de la Font\": { \"lat\": 39.05708169837652, \"lng\": -0.2745747423274704 },\n  \"Granata Fountain\": { \"lat\": 39.09340321510781, \"lng\": -0.28952816613671006 },\n  \"Visit to Bolomor Cave\": { \"lat\": 39.06389524256403, \"lng\": -0.2503037292673149 },\n  \"Sailing school\": { \"lat\": 39.10325976200742, \"lng\": -0.22155410309260565 },\n  \"Kitesurf lane\": { \"lat\": 39.081956563207164, \"lng\": -0.21150778129306116 },\n  \"Boat entry channel\": { \"lat\": 39.08746337411143, \"lng\": -0.21483372077186944 },\n  \"Beach of Goleta\": { \"lat\": 39.09912177293142, \"lng\": -0.22074944077030723 },\n  \"Moll\u00f3 Park\": { \"lat\": 39.10409105232547, \"lng\": -0.22618615830573205 },\n  \"North Park\": { \"lat\": 39.10494858305977, \"lng\": -0.22326791488051762 },\n  \"Watchtower\": { \"lat\": 39.086219905452495, \"lng\": -0.2179107262353749 },\n  \"Beach entrance cycle lane\": { \"lat\": 39.08719423981628, \"lng\": -0.21684857144468592 },\n  \"Ullal Gran\": { \"lat\": 39.081696791340356, \"lng\": -0.24162182660775022 },\n  \"Sangonera Fountain\": { \"lat\": 39.086984213592814, \"lng\": -0.2916866316306998 },\n  \"Sant Lloren\u00e7 Natural Area\": { \"lat\": 39.082276678853574, \"lng\": -0.2553871316309047 },\n  \"Mediterranean Viewpoint\": { \"lat\": 39.08500826482173, \"lng\": -0.24860650723306568 },\n  \"Massalari Peak\": { \"lat\": 39.09562987342248, \"lng\": -0.2976822847644695 },\n  \"Massalari Bell\": { \"lat\": 39.0901676476069, \"lng\": -0.281375696705547 },\n  \"Route de les Creus\": { \"lat\": 39.08090715367388, \"lng\": -0.2774274853867399 },\n  \"Pas de Cabres Via Ferrata\": { \"lat\": 39.07977059871669, \"lng\": -0.273598729838858 },\n  \"Les Marujes Via Ferrata\": { \"lat\": 39.07644345499099, \"lng\": -0.283686755199953 },\n  \"Nordic Walking Circuit\": { \"lat\": 39.07504353681741, \"lng\": -0.2598953242164171 },\n  \"La Cisterna\": { \"lat\": 39.0831555373413, \"lng\": -0.258103608759979 },\n  \"City Hall\": { \"lat\": 39.07184834218302, \"lng\": -0.2677240316312862 },\n  \"Sant Pere Church\": { \"lat\": 39.07284595241503, \"lng\": -0.26713767210484973 },\n  \"Sant Josep Church\": { \"lat\": 39.07457572479507, \"lng\": -0.2715793974193275 },\n  \"Calvari\": { \"lat\": 39.07532619598619, \"lng\": -0.26917211534507374 },\n  \"Mol\u00ed Vell del Pla\": { \"lat\": 39.065478544993255, \"lng\": -0.27233504342227705 },\n  \"Municipal Market\": { \"lat\": 39.0721666178573, \"lng\": -0.26569366046757914 },\n  \"House of Culture\": { \"lat\": 39.073160576305916, \"lng\": -0.26638481341513565 },\n  \"VCF Mural at Carlos Pellicer Pavilion\": { \"lat\": 39.07007956648436, \"lng\": -0.26425654974295515 },\n  \"House of Culture Mural (Estell\u00e9s)\": { \"lat\": 39.06948728618269, \"lng\": -0.26813629639738595 },\n  \"Baladre\": { \"lat\": 39.08222922110664, \"lng\": -0.21526300028398643 },\n  \"Bar Restaurant Calipso\": { \"lat\": 39.092593742093975, \"lng\": -0.21813275912833915 },\n  \"Restaurant Macario\": { \"lat\": 39.10013509162634, \"lng\": -0.22136580460720873 },\n  \"Casablanca Beer & Grill\": { \"lat\": 39.08758166016625, \"lng\": -0.21594852511362625 },\n  \"Cervecer\u00eda Los Delfines\": { \"lat\": 39.08269095619182, \"lng\": -0.21330960391158235 },\n  \"Dall\u2019Italiano\": { \"lat\": 39.081931011306786, \"lng\": -0.21326937077557143 },\n  \"El Fog\u00f3n de More\": { \"lat\": 39.08508524960249, \"lng\": -0.21496452687923168 },\n  \"Haveli Tavernes\": { \"lat\": 39.08596799466984, \"lng\": -0.21474726794750276 },\n  \"La Bombonera Gastrobar\": { \"lat\": 39.083207297645615, \"lng\": -0.21334715483280298 },\n  \"La Gallina Loca\": { \"lat\": 39.09759662915328, \"lng\": -0.2203788931174758 },\n  \"La Mordidita Beach Club\": { \"lat\": 39.09865452495847, \"lng\": -0.22263932493635763 },\n  \"L\u2019Excusa Perfecta\": { \"lat\": 39.10183314164362, \"lng\": -0.22269615521231936 },\n  \"Restaurant Puerta del Sol\": { \"lat\": 39.0874844360736, \"lng\": -0.21542362867441925 },\n  \"N\u00f2mada Lounge & Restaurant\": { \"lat\": 39.10327141897599, \"lng\": -0.22226968396992064 },\n  \"Restaurant Altamar\": { \"lat\": 39.09787801712504, \"lng\": -0.22050239144070466 },\n  \"Restaurant El Medi \/ Mediterrani\": { \"lat\": 39.083367612566704, \"lng\": -0.2133256971602638 },\n  \"Restaurant Les Ones\": { \"lat\": 39.08325726597179, \"lng\": -0.2137226641022385 },\n  \"Restaurant Luna Park\": { \"lat\": 39.09403529809503, \"lng\": -0.21818594437244127 },\n  \"Restaurant San Bernardo\": { \"lat\": 39.096585343265886, \"lng\": -0.21930880842708134 },\n  \"Aires del Sur\": { \"lat\": 39.073485808964236, \"lng\": -0.26310478465489145 },\n  \"Bar \u00c1ngel\": { \"lat\": 39.074026466353715, \"lng\": -0.260235937301254 },\n  \"Bar Els Amics\": { \"lat\": 39.079003406629425, \"lng\": -0.26548287629794376 },\n  \"Bar La Cosa Nostra\": { \"lat\": 39.0715615961676, \"lng\": -0.26686403163129535 },\n  \"Bar Restaurant Astim\": { \"lat\": 39.07006052332613, \"lng\": -0.2671105162863127 },\n  \"Bar Tapas Cristal\": { \"lat\": 39.06954474653355, \"lng\": -0.26881350279511246 },\n  \"Bar Murciano\": { \"lat\": 39.06892090578349, \"lng\": -0.2650382865088393 },\n  \"Ca Saoret\": { \"lat\": 39.07167760949219, \"lng\": -0.2673813422567982 },\n  \"Cervesseria Garatge\": { \"lat\": 39.07336013192499, \"lng\": -0.26317563843912056 },\n  \"Exqsa Perfecta \u2013 Passeig\": { \"lat\": 39.071616567994056, \"lng\": -0.2667012590695635 },\n  \"La Casa Viva\": { \"lat\": 39.07002836537868, \"lng\": -0.2707287390922631 },\n  \"Legends\": { \"lat\": 39.0734096392343, \"lng\": -0.2601931027950059 },\n  \"Pizzeria La Vall Expr\u00e9s\": { \"lat\": 39.07320306411841, \"lng\": -0.2639315451224509 },\n  \"Pizzer\u00eda Tropical\": { \"lat\": 39.07081749181977, \"lng\": -0.2624474586137511 },\n  \"Restaurant 5 Hermanas\": { \"lat\": 39.083325476624694, \"lng\": -0.24284615861324998 },\n  \"Restaurant Bar Pizzeria Anais\": { \"lat\": 39.0712050908591, \"lng\": -0.26755574697644235 },\n  \"Restaurant Chino Gran Muralla\": { \"lat\": 39.07574263418766, \"lng\": -0.25906917301761523 },\n  \"Restaurant Club de Tenis Valldigna\": { \"lat\": 39.07929487071183, \"lng\": -0.26252038535322453 },\n  \"Restaurant Delicias\": { \"lat\": 39.074783488325465, \"lng\": -0.2627904612189703 },\n  \"Restaurant Pizzer\u00eda Ibis\": { \"lat\": 39.07152214279915, \"lng\": -0.2627456162862469 },\n  \"Restaurant Mei Zhou\": { \"lat\": 39.07081466105959, \"lng\": -0.2623482018539252 },\n  \"Restaurant V\u00edctor\": { \"lat\": 39.07812365121439, \"lng\": -0.2433022569232853 },\n  \"Rustiks\": { \"lat\": 39.0706599557694, \"lng\": -0.2641044181401787 },\n  \"Super Pizza\": { \"lat\": 39.07134204383321, \"lng\": -0.2659134010280008 },\n  \"The Black Burger\": { \"lat\": 39.07223422096353, \"lng\": -0.2671728653132802 },\n  \"Hotel Valldigna\": { \"lat\": 39.070667354520786, \"lng\": -0.266997013491229 },\n  \"Villa Ursula\": { \"lat\": 39.09434719968148, \"lng\": -0.21837400279415725 },\n  \"VMC Rooms\": { \"lat\": 39.08511231506302, \"lng\": -0.21484919188933363 },\n  \"Rooms Avenida\": { \"lat\": 39.070667354520786, \"lng\": -0.266997013491229 },\n  \"Camping Car La Finca\": { \"lat\": 39.08131993016402, \"lng\": -0.21393286870035835 },\n  \"Ohana Beach Camper Area\": { \"lat\": 39.08763521685332, \"lng\": -0.21826241725137896 }\n};\n\nfor (const item of catalog) {\n  const match = coordPatch[item.title];\n  if (match) {\n    item.lat = match.lat;\n    item.lng = match.lng;\n  }\n}\n\ncatalog.sort((a, b) => a.title.localeCompare(b.title, 'en', { sensitivity: 'base' }));\n\nconst state = {\n  tripName:'Tavernes getaway',\n  startDate:'',\n  days:[],\n  nextUid:1\n};\n\nconst slotsOrder = ['morning','midday','afternoon','night'];\nconst slotLabels = {'morning':'Morning','midday':'Midday','afternoon':'Afternoon','night':'Night'};\nconst zoneLabels = {beach:'Beach', town:'Town', valldigna:'Valldigna area', monduber:'Mountain \/ Mond\u00faver'};\nconst typeLabels = {actividad:'Activity', restaurante:'Restaurant', alojamiento:'Accommodation', evento:'Event', ocio:'Leisure'};\nconst typeIcons = {actividad:'\ud83e\udded', restaurante:'\ud83c\udf7d\ufe0f', alojamiento:'\ud83d\udecf\ufe0f', evento:'\ud83c\udf89', ocio:'\ud83c\udf19'};\n\nconst officialLinks = {\n  restaurantes:'https:\/\/www.visitatavernes.es\/guia-restaurantes\/',\n  alojamientos:'https:\/\/www.visitatavernes.es\/alojamientos-y-campings-de-caravanas-tavernes-de-la-valldigna\/',\n  bolomor:'https:\/\/www.visitatavernes.es\/visita-cova-del-bolomor\/',\n  edificios:'https:\/\/www.visitatavernes.es\/edificios-emblematicos\/',\n  naturales:'https:\/\/www.visitatavernes.es\/parajes-naturales\/',\n  beachs:'https:\/\/www.visitatavernes.es\/nuestras-beachs\/',\n  senderismo:'https:\/\/www.visitatavernes.es\/senderismo\/'\n};\n\nconst officialUrlByTitle = {\n  \"Beach of Tavernes\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Llac de la Goleta\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Clot de la Font\": \"https:\/\/www.visitatavernes.es\/en\/clot-de-la-font-fountain\/\",\n  \"Granata Fountain\": \"https:\/\/www.visitatavernes.es\/en\/font-de-la-granata-fountain\/\",\n  \"Les Fontetes de Cant\u00fas\": \"https:\/\/www.visitatavernes.es\/en\/cantus-water-sources\/\",\n  \"Mond\u00faver Route\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"Visit to Bolomor Cave\": \"https:\/\/www.visitatavernes.es\/en\/visit-cova-del-bolomor\/\",\n  \"Bolomor Cave Route\": \"https:\/\/www.visitatavernes.es\/en\/route-cova-del-bolomor\/\",\n  \"Sailing school\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Kitesurf lane\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Boat entry channel\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Beach of Goleta\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Moll\u00f3 Park\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"North Park\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Watchtower\": \"https:\/\/www.visitatavernes.es\/en\/guaita-tower\/\",\n  \"Beach entrance cycle lane\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Ruta dels Sentits\": \"https:\/\/www.visitatavernes.es\/en\/route-of-the-senses\/\",\n  \"Ullal Gran\": \"https:\/\/www.visitatavernes.es\/en\/ullal-gran-i-de-les-penyetes-wellspring\/\",\n  \"Ullal de les Penyetes\": \"https:\/\/www.visitatavernes.es\/en\/ullal-gran-i-de-les-penyetes-wellspring\/\",\n  \"Sangonera Fountain\": \"https:\/\/www.visitatavernes.es\/en\/font-de-la-sangonera-fountain\/\",\n  \"Sant Lloren\u00e7 Natural Area\": \"https:\/\/www.visitatavernes.es\/en\/sant-llorenc\/\",\n  \"Mediterranean Viewpoint\": \"https:\/\/www.visitatavernes.es\/en\/mirador-de-la-mediterrania-viewpoint\/\",\n  \"Massalari Peak\": \"https:\/\/www.visitatavernes.es\/en\/puntal-del-massalari-pilaster\/\",\n  \"Massalari Bell\": \"https:\/\/www.visitatavernes.es\/en\/puntal-del-massalari-pilaster\/\",\n  \"Route de les Creus\": \"https:\/\/www.visitatavernes.es\/en\/the-creus-trek\/\",\n  \"Pas de Cabres Via Ferrata\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"Les Marujes Via Ferrata\": \"https:\/\/www.visitatavernes.es\/en\/via-ferrata-les-marujes-trek\/\",\n  \"Cadira Route\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"Ombria Route\": \"https:\/\/www.visitatavernes.es\/en\/the-ombria-trek\/\",\n  \"Reina Mora Castle\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"Via Verda - Trenet (GR-236)\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"Nordic Walking Circuit\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"Rac\u00f3 de Joana\": \"https:\/\/www.visitatavernes.es\/en\/raco-de-joana-ullals\/\",\n  \"La Cisterna\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"Pla de les Foietes\": \"https:\/\/www.visitatavernes.es\/en\/trekking\/\",\n  \"City Hall\": \"https:\/\/www.visitatavernes.es\/en\/town-hall\/\",\n  \"Sant Pere Church\": \"https:\/\/www.visitatavernes.es\/en\/saint-peter-church\/\",\n  \"Sant Josep Church\": \"https:\/\/www.visitatavernes.es\/en\/saint-joseph-church\/\",\n  \"Calvari\": \"https:\/\/www.visitatavernes.es\/en\/hermitage-of-the-crist-de-la-sang-christ-of-the-blood\/\",\n  \"Mol\u00ed Vell del Pla\": \"https:\/\/www.visitatavernes.es\/en\/the-pla-mill\/\",\n  \"Mol\u00ed de Tonet\": \"https:\/\/www.visitatavernes.es\/en\/emblematic-buildings\/\",\n  \"Ermita de Sant Lloren\u00e7\": \"https:\/\/www.visitatavernes.es\/en\/hermitage-of-st-llorenc-de-lalcudiola\/\",\n  \"Municipal Market\": \"https:\/\/www.visitatavernes.es\/en\/municipal-market\/\",\n  \"House of Culture\": \"https:\/\/www.visitatavernes.es\/en\/the-cultural-center\/\",\n  \"VCF Mural at Carlos Pellicer Pavilion\": \"\",\n  \"House of Culture Mural (Estell\u00e9s)\": \"\",\n  \"Torreta Iron Mural\": \"\",\n  \"Badell and Vaca River Area\": \"https:\/\/www.visitatavernes.es\/en\/natural-landscape\/\",\n  \"Promenade and beach bars\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Cultural Walk Through the Historic Centre\": \"https:\/\/www.visitatavernes.es\/en\/emblematic-buildings\/\",\n  \"Baladre\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Bar Restaurant Calipso\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Macario\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Casablanca Beer & Grill\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Cervecer\u00eda Los Delfines\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Dall\u2019Italiano\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"El Fog\u00f3n de More\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Haveli Tavernes\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"La Bombonera Gastrobar\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"La Gallina Loca\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"La Mordidita Beach Club\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"L\u2019Excusa Perfecta\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Puerta del Sol\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"N\u00f2mada Lounge & Restaurant\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Altamar\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant El Medi \/ Mediterrani\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Les Ones\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Luna Park\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant San Bernardo\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Aires del Sur\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Bar \u00c1ngel\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Bar Els Amics\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Bar La Cosa Nostra\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Bar Restaurant Astim\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Bar Tapas Cristal\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Bar Murciano\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Ca Saoret\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Cervesseria Garatge\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Exqsa Perfecta \u2013 Passeig\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"La Casa Viva\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Legends\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Pizzeria La Vall Expr\u00e9s\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Pizzer\u00eda Tropical\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant 5 Hermanas\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Bar Pizzeria Anais\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Chino Gran Muralla\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Club de Tenis Valldigna\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Delicias\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Pizzer\u00eda Ibis\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant Mei Zhou\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Restaurant V\u00edctor\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Rustiks\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Super Pizza\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"The Black Burger\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Hotel Valldigna\": \"https:\/\/www.visitatavernes.es\/alojamientos-y-campings-de-caravanas-tavernes-de-la-valldigna\/\",\n  \"Villa Ursula\": \"https:\/\/www.visitatavernes.es\/alojamientos-y-campings-de-caravanas-tavernes-de-la-valldigna\/\",\n  \"VMC Rooms\": \"https:\/\/www.visitatavernes.es\/alojamientos-y-campings-de-caravanas-tavernes-de-la-valldigna\/\",\n  \"Rooms Avenida\": \"https:\/\/www.visitatavernes.es\/alojamientos-y-campings-de-caravanas-tavernes-de-la-valldigna\/\",\n  \"Camping Car La Finca\": \"https:\/\/www.visitatavernes.es\/alojamientos-y-campings-de-caravanas-tavernes-de-la-valldigna\/\",\n  \"Ohana Beach Camper Area\": \"https:\/\/www.visitatavernes.es\/alojamientos-y-campings-de-caravanas-tavernes-de-la-valldigna\/\",\n  \"Tavernes Fallas\": \"https:\/\/www.visitatavernes.es\/en\/march-falles\/\",\n  \"Festivern\": \"https:\/\/www.visitatavernes.es\/en\/festivern\/\",\n  \"Del Poble Fest\": \"\",\n  \"Sant Joan\": \"https:\/\/www.visitatavernes.es\/en\/june-sant-joan\/\",\n  \"Sant Jaume Fair\": \"https:\/\/www.visitatavernes.es\/en\/july-saint-james-fair\/\",\n  \"Drinks or afternoon social at Baladre\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Seafront evening stroll\": \"https:\/\/www.visitatavernes.es\/en\/our-beaches\/\",\n  \"Night Walk Through Tavernes City\": \"https:\/\/www.visitatavernes.es\/en\/emblematic-buildings\/\",\n  \"Drinks or afternoon social at La Bombonera Gastrobar\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"Drinks or afternoon social at La Mordidita Beach Club\": \"https:\/\/www.visitatavernes.es\/en\/restaurants-guide\/\",\n  \"April - Holy Week\": \"https:\/\/www.visitatavernes.es\/en\/april-easter-or-holy-week\/\",\n  \"Major Festivities\": \"https:\/\/www.visitatavernes.es\/en\/september-major-festivals\/\",\n  \"1st of May\": \"https:\/\/www.visitatavernes.es\/en\/may-1st-of-may\/\",\n  \"9th of October\": \"https:\/\/www.visitatavernes.es\/en\/october-9th-of-october\/\",\n  \"Porrat de la Sang\": \"https:\/\/www.visitatavernes.es\/en\/july-porrat-de-la-sang-bloods-porrat\/\",\n  \"Porrat de Sant Lloren\u00e7\": \"https:\/\/www.visitatavernes.es\/en\/august-porrat-de-sant-llorenc\/\",\n  \"Sete S\u00f3is Sete Luas\": \"https:\/\/www.visitatavernes.es\/en\/sete-sois-sete-luas\/\",\n  \"Choir Festival\": \"\"\n};\n\n\nconst tripName = document.getElementById('tripName');\nconst tripStart = document.getElementById('tripStart');\nconst numDays = document.getElementById('numDays');\nconst daysContainer = document.getElementById('daysContainer');\nconst catalogGrid = document.getElementById('catalogGrid');\nconst catalogCount = document.getElementById('catalogCount');\nconst tripWho = document.getElementById('tripWho');\nconst tripMove = document.getElementById('tripMove');\nconst tripPace = document.getElementById('tripPace');\nconst mapVisibleCount = document.getElementById('mapVisibleCount');\nconst mapPlannedCount = document.getElementById('mapPlannedCount');\nconst mapList = document.getElementById('mapList');\nconst mapOnlyPlanned = document.getElementById('mapOnlyPlanned');\n\nfor(let i=1;i<=10;i++){\n  const op=document.createElement('option');\n  op.value=i;\n  op.textContent=i;\n  if(i===1) op.selected=true;\n  numDays.appendChild(op);\n}\n\nfunction euro(v){\n  return new Intl.NumberFormat('en-GB',{style:'currency',currency:'EUR',maximumFractionDigits:0}).format(v || 0);\n}\nfunction fmtHours(v){\n  return v ? String(v).replace('.0','') + ' h' : 'Variable duration';\n}\nfunction prettyMoves(arr){\n  const list=(arr && arr.length ? arr : ['coche','pie','bici']);\n  const order=['pie','bici','coche'];\n  return order.filter(o=>list.includes(o)).join(' \u00b7 ');\n}\nfunction dateLabel(offset){\n  const base = new Date(state.startDate + 'T00:00:00');\n  base.setDate(base.getDate() + offset);\n  return base.toLocaleDateString('en-GB',{weekday:'long', day:'numeric', month:'long'});\n}\nfunction normalizeText(t){\n  return (t || '').toLowerCase().normalize('NFD').replace(\/[\\u0300-\\u036f]\/g,'');\n}\nfunction getTypeIcon(type){\n  return typeIcons[type] || '\ud83d\udccd';\n}\n\nfunction getGoogleMapsDirectionsUrl(item){\n  if(!item || !Number.isFinite(item.lat) || !Number.isFinite(item.lng)) return '';\n  return `https:\/\/www.google.com\/maps\/dir\/?api=1&destination=${item.lat},${item.lng}`;\n}\n\nfunction getTodayISO(){\n  const today = new Date();\n  const yyyy = today.getFullYear();\n  const mm = String(today.getMonth() + 1).padStart(2, '0');\n  const dd = String(today.getDate()).padStart(2, '0');\n  return `${yyyy}-${mm}-${dd}`;\n}\n\n\nfunction inferInterestTags(item){\n  const hay = normalizeText([item.title,item.desc,item.zone,item.type,item.notes || ''].join(' '));\n  const tags = [];\n  if (hay.includes('beach') || hay.includes('goleta') || hay.includes('mar')) tags.push('beach');\n  if (hay.includes('naturaleza') || hay.includes('ullal') || hay.includes('paraje') || hay.includes('font') || hay.includes('clot')) tags.push('naturaleza');\n  if (hay.includes('senderismo') || hay.includes('ruta') || hay.includes('ferrata') || hay.includes('monduber') || hay.includes('cruces')) tags.push('senderismo');\n  if (hay.includes('patrimonio') || hay.includes('iglesia') || hay.includes('moli') || hay.includes('ayuntamiento') || hay.includes('cultura') || hay.includes('bolomor') || hay.includes('torre')) tags.push('patrimonio');\n  if (item.type === 'restaurante') tags.push('gastronomia');\n  if (hay.includes('familia') || hay.includes('ni\u00f1os') || hay.includes('cine') || hay.includes('feria') || hay.includes('pizza')) tags.push('familia');\n  if (hay.includes('afternoono') || hay.includes('copas') || hay.includes('beach club') || hay.includes('festival') || hay.includes('ambiente')) tags.push('afternoono');\n  return [...new Set(tags)];\n}\n\nfunction matchesDuration(item, filterDuration){\n  const h = Number(item.hours) || 0;\n  if(!filterDuration) return true;\n  if(filterDuration === 'corta') return h <= 1.5;\n  if(filterDuration === 'media') return h > 1.5 && h <= 3;\n  if(filterDuration === 'larga') return h > 3;\n  return true;\n}\n\nfunction inferSearchIntent(searchText){\n  const q = normalizeText(searchText);\n  if(!q) return '';\n  if(q.includes('restaurante') || q.includes('have lunch') || q.includes('have dinner') || q.includes('local mid-morning meal') || q.includes('pizza') || q.includes('arroz')) return 'restaurante';\n  if(q.includes('hotel') || q.includes('alojamiento') || q.includes('apartamento') || q.includes('camper') || q.includes('dormir')) return 'alojamiento';\n  if(q.includes('evento') || q.includes('festival') || q.includes('feria') || q.includes('fallas') || q.includes('cine')) return 'evento';\n  if(q.includes('copas') || q.includes('afternoono') || q.includes('ocio') || q.includes('night')) return 'ocio';\n  if(q.includes('beach') || q.includes('ruta') || q.includes('bolomor') || q.includes('senderismo') || q.includes('mirador') || q.includes('paraje') || q.includes('actividad')) return 'actividad';\n  return '';\n}\n\nfunction getPreferenceModel(){\n  return {\n    who: tripWho.value,\n    move: tripMove.value,\n    pace: tripPace.value,\n    notes: ''\n  };\n}\n\nfunction getPersonalScore(item){\n  const pref = getPreferenceModel();\n  let score = item.score || 0;\n  let reasons = [];\n\n  if(pref.move !== 'cualquiera'){\n    if((item.move || []).includes(pref.move)){\n      score += 12;\n      reasons.push('matches your transport choice');\n    } else {\n      score -= 10;\n    }\n  }\n\n  if(pref.pace === 'tranquilo'){\n    if((item.hours || 0) <= 1.5){ score += 10; reasons.push('relaxed pace'); }\n    if((item.hours || 0) >= 3.5){ score -= 8; }\n    if(item.type === 'ocio' || item.type === 'restaurante'){ score += 4; }\n  }\n\n  if(pref.pace === 'activo'){\n    if((item.hours || 0) >= 2){ score += 10; reasons.push('active pace'); }\n    if(item.zone === 'monduber' || (item.notes || '').includes('senderismo') || (item.notes || '').includes('deporte')){ score += 8; }\n  }\n\n  if(pref.pace === 'equilibrado'){\n    if((item.hours || 0) >= 1 && (item.hours || 0) <= 2.5){ score += 5; }\n  }\n\n  if(pref.who === 'familia'){\n    if((item.notes || '').includes('familia') || item.type === 'actividad'){ score += 8; reasons.push('family plan'); }\n    if(item.type === 'ocio' && (item.notes || '').includes('copas')){ score -= 8; }\n    if(item.type === 'restaurante' && ((item.notes || '').includes('pizza') || (item.notes || '').includes('local'))){ score += 5; }\n  }\n\n  if(pref.who === 'pareja'){\n    if(item.zone === 'beach' || item.type === 'restaurante'){ score += 6; reasons.push('good option for couples'); }\n    if((item.notes || '').includes('pareja') || (item.notes || '').includes('mirador')){ score += 5; }\n  }\n\n  if(pref.who === 'amigos'){\n    if(item.type === 'ocio' || item.type === 'evento'){ score += 10; reasons.push('better for friends'); }\n    if((item.notes || '').includes('afternoono') || (item.notes || '').includes('festival') || (item.notes || '').includes('copas')){ score += 8; }\n  }\n\n  if(pref.who === 'solo'){\n    if((item.hours || 0) <= 2){ score += 5; }\n    if(item.type === 'actividad' || item.type === 'restaurante'){ score += 4; }\n  }\n\n  if(pref.who === 'grupo'){\n    if(item.type === 'restaurante' || item.type === 'evento' || item.type === 'ocio'){ score += 7; reasons.push('useful for groups'); }\n  }\n\n  if(pref.notes){\n    const hay = normalizeText([item.title,item.desc,item.zone,item.type,item.notes || ''].join(' '));\n    const words = pref.notes.split(\/[\\s,;]+\/).filter(Boolean);\n    let hits = 0;\n    words.forEach(w => {\n      if(w.length >= 3 && hay.includes(w)) hits++;\n    });\n    if(hits){\n      score += hits * 8;\n      reasons.push('matches your notes');\n    }\n  }\n\n  return {\n    finalScore: Math.round(score),\n    recommended: score >= (item.score + 12),\n    reasons\n  };\n}\n\nfunction getTopRecommendations(){\n  return catalog\n    .map(item => ({...item, pref:getPersonalScore(item)}))\n    .sort((a,b)=>b.pref.finalScore - a.pref.finalScore)\n    .slice(0,3)\n    .map(x=>x.title);\n}\n\nfunction getOfficialLink(item){\n  if (officialUrlByTitle[item.title] !== undefined) {\n    return officialUrlByTitle[item.title] || '';\n  }\n\n  const hay = normalizeText([item.title, item.desc, item.notes || '', item.zone].join(' '));\n\n  if (hay.includes('bolomor')) return officialLinks.bolomor;\n  if (item.type === 'restaurante') return officialLinks.restaurantes;\n  if (item.type === 'alojamiento') return officialLinks.alojamientos;\n\n  if (hay.includes('iglesia de san pedro') || hay.includes('iglesia de san jose') || hay.includes('ayuntamiento') || hay.includes('moli') || hay.includes('calvario') || hay.includes('casa de la cultura') || hay.includes('ermita')) return officialLinks.edificios;\n  if (hay.includes('beach') || hay.includes('goleta') || hay.includes('paseo maritimo') || hay.includes('torre de guaita')) return officialLinks.beachs;\n  if (hay.includes('ruta') || hay.includes('senderismo') || hay.includes('ferrata') || hay.includes('cruces') || hay.includes('ombria') || hay.includes('cadira') || hay.includes('les marujes') || hay.includes('via verda')) return officialLinks.senderismo;\n  if (hay.includes('ullal') || hay.includes('clot') || hay.includes('font') || hay.includes('mirador') || hay.includes('paratge') || hay.includes('massalari') || hay.includes('cantus') || hay.includes('sangonera') || hay.includes('sant llorenc')) return officialLinks.naturales;\n\n  return item.type === 'actividad' ? officialLinks.naturales : '';\n}\n\nfunction buildEnhancedDescription(item){\n  const icon = getTypeIcon(item.type);\n  const duration = fmtHours(item.hours);\n  const zone = zoneLabels[item.zone] || item.zone;\n  const interestTags = inferInterestTags(item);\n  const bestMoment = (item.slots || []).length ? (item.slots || []).map(s => slotLabels[s]).join(', ') : 'cualquier momento';\n  const move = prettyMoves(item.move);\n\n  let intro = item.desc || '';\n  let practical = '';\n\n  if(item.type === 'actividad'){\n    practical = `This is a ${zone.toLowerCase()} option that works well for ${bestMoment.toLowerCase()}. Allow about ${duration.toLowerCase()} and keep in mind it works best if you get around by ${move}.`;\n  } else if(item.type === 'restaurante'){\n    practical = `A good option for planning a ${bestMoment.toLowerCase()}. It is most practical to allow about ${duration.toLowerCase()} and use it as lunch or dinner within the itinerary.`;\n  } else if(item.type === 'alojamiento'){\n    practical = `It works well as a base for organizing the trip comfortably. It helps you set your resting point and distribute the day\u2019s plans better.`;\n  } else if(item.type === 'evento'){\n    practical = `It fits especially well in ${bestMoment.toLowerCase()} and can add a livelier touch to the itinerary if it matches your dates.`;\n  } else if(item.type === 'ocio'){\n    practical = `Funciona muy bien para cerrar el d\u00eda o alargar la afternoon. Es una opci\u00f3n \u00fatil si buscas ambiente sin complicarte con desplazamientos largos.`;\n  }\n\n  if(interestTags.includes('familia')) practical += ' It usually works well for family trips.';\n  if(interestTags.includes('afternoono')) practical += ' It is a good fit if you are looking for atmosphere or after-lunch drinks.';\n  if(interestTags.includes('patrimonio')) practical += ' It adds cultural value to the trip.';\n  if(interestTags.includes('naturaleza')) practical += ' It adds scenery and contact with the natural surroundings.';\n\n  return `<span class=\"help-strong\">${icon} ${intro}<\/span> ${practical}`;\n}\n\nfunction createDays(n){\n  state.days = [];\n  for(let i=0;i<n;i++){\n    state.days.push({\n      id:'day-'+(i+1),\n      title:'Day ' + (i+1),\n      slots:{morning:[], midday:[], afternoon:[], night:[]}\n    });\n  }\n  numDays.value = String(state.days.length);\n  renderAll();\n}\n\nfunction addDay(){\n  const idx = state.days.length + 1;\n  state.days.push({\n    id:'day-'+idx,\n    title:'Day ' + idx,\n    slots:{morning:[], midday:[], afternoon:[], night:[]}\n  });\n  numDays.value = state.days.length;\n  renderAll();\n}\n\nfunction addItemToPlan(itemId, dayIndex, slot){\n  const source = catalog.find(x => x.id === itemId);\n  if(!source || !state.days[dayIndex]) return;\n  const clone = JSON.parse(JSON.stringify(source));\n  clone.uid = 'u' + (state.nextUid++);\n  state.days[dayIndex].slots[slot].push(clone);\n  renderAll();\n}\n\nfunction removeItem(dayIndex, slot, uid){\n  state.days[dayIndex].slots[slot] = state.days[dayIndex].slots[slot].filter(x => x.uid !== uid);\n  renderAll();\n}\n\nfunction getPlannedOccurrences(){\n  const map = {};\n  state.days.forEach((day) => {\n    slotsOrder.forEach(slot => {\n      (day.slots[slot] || []).forEach(item => {\n        if(!map[item.id]) map[item.id] = [];\n        map[item.id].push(`${day.title} \u00b7 ${slotLabels[slot]}`);\n      });\n    });\n  });\n  return map;\n}\n\nfunction getPlannedItemIds(){\n  const ids = new Set();\n  state.days.forEach(day => {\n    slotsOrder.forEach(slot => {\n      (day.slots[slot] || []).forEach(item => ids.add(item.id));\n    });\n  });\n  return ids;\n}\n\nfunction updateStats(){\n  const allItems = state.days.flatMap(d => slotsOrder.flatMap(s => d.slots[s]));\n  const totalStops = allItems.length;\n  const totalHours = allItems.reduce((a,b)=>a+(Number(b.hours)||0),0);\n  const totals = {actividad:0, restaurante:0, alojamiento:0, evento:0, ocio:0};\n\n  allItems.forEach(item => {\n    totals[item.type] = (totals[item.type]||0) + (Number(item.cost)||0);\n  });\n\n  const other = (totals.evento||0) + (totals.ocio||0);\n\n  document.getElementById('statDays').textContent = state.days.length;\n  document.getElementById('statStops').textContent = totalStops;\n  document.getElementById('statHours').textContent = totalHours.toFixed(1).replace('.0','') + ' h';\n  document.getElementById('statBudget').textContent = euro(Object.values(totals).reduce((a,b)=>a+b,0)).replace(',00','');\n  const statDays = document.getElementById('statDays');\n  const statStops = document.getElementById('statStops');\n  const statHours = document.getElementById('statHours');\n  const statBudget = document.getElementById('statBudget');\n  if(statDays) statDays.textContent = state.days.length;\n  if(statStops) statStops.textContent = totalStops;\n  if(statHours) statHours.textContent = totalHours.toFixed(1).replace('.0','') + ' h';\n  if(statBudget) statBudget.textContent = euro(Object.values(totals).reduce((a,b)=>a+b,0)).replace(',00','');\n  document.getElementById('bAct').textContent = euro(totals.actividad||0).replace(',00','');\n  document.getElementById('bFood').textContent = euro(totals.restaurante||0).replace(',00','');\n  document.getElementById('bStay').textContent = euro(totals.alojamiento||0).replace(',00','');\n  document.getElementById('bOther').textContent = euro(other).replace(',00','');\n  document.getElementById('bTotal').textContent = euro(Object.values(totals).reduce((a,b)=>a+b,0)).replace(',00','');\n\n  const prefsSummary = document.getElementById('prefsSummary');\n  if (prefsSummary) {\n    prefsSummary.textContent =\n      `Dynamic recommendation active. Based on your travel profile, the catalogue highlights proposals compatible with ${tripWho.options[tripWho.selectedIndex].text.toLowerCase()}, your way of getting around and the chosen pace. Examples: ${getTopRecommendations().join(', ')}.`;\n  }\n}\n\nfunction renderDays(){\n  if(!state.days.length){\n    daysContainer.innerHTML = '<div class=\"empty\">Click <strong>Generate days<\/strong> to start building the trip.<\/div>';\n    return;\n  }\n\n  const plannedIds = getPlannedItemIds();\n\n  daysContainer.innerHTML = state.days.map((day, dayIndex) => `\n    <div class=\"day-card\">\n      <div class=\"day-head\">\n        <h3>${day.title}<\/h3>\n        <div class=\"day-date\">${dateLabel(dayIndex)}<\/div>\n      <\/div>\n      <div class=\"slot-grid\">\n        ${slotsOrder.map(slot => `\n          <div class=\"slot\">\n            <div>\n              <h4>${slotLabels[slot]}<\/h4>\n              <div class=\"slot-meta\">${(day.slots[slot]||[]).length} plan(s)<\/div>\n            <\/div>\n            ${(day.slots[slot]||[]).length ? day.slots[slot].map(item => `\n              <div class=\"plan-item\">\n                <div class=\"plan-top\">\n                  <div class=\"title-row\">\n                    <span class=\"icon-badge\">${getTypeIcon(item.type)}<\/span>\n                    <div class=\"plan-title\">${item.title}<\/div>\n                  <\/div>\n                  <div class=\"price-pill\">${Number(item.cost)||0 ? euro(item.cost).replace(',00','') : 'Free'}<\/div>\n                <\/div>\n                <div class=\"tags\">\n                  <span class=\"tag type-${item.type}\">${typeLabels[item.type]}<\/span>\n                  <span class=\"tag\">${zoneLabels[item.zone] || item.zone}<\/span>\n                  <span class=\"tag\">${fmtHours(item.hours)}<\/span>\n                  <span class=\"tag\">${prettyMoves(item.move)}<\/span>\n                  ${plannedIds.has(item.id) ? '<span class=\"tag planned\">In your trip<\/span>' : ''}\n                <\/div>\n                <div class=\"help\">${buildEnhancedDescription(item)}<\/div>\n                <div class=\"controls-inline\">\n                  ${item.lat && item.lng ? `<span class=\"map-focus-link\" data-map-focus=\"${item.id}\">View on map<\/span>` : ''}\n                  ${item.lat && item.lng ? `<a class=\"plan-link\" href=\"${getGoogleMapsDirectionsUrl(item)}\" target=\"_blank\" rel=\"noopener noreferrer\">Get directions<\/a>` : ''}\n                  ${getOfficialLink(item) ? `<a class=\"plan-link\" href=\"${getOfficialLink(item)}\" target=\"_blank\" rel=\"noopener noreferrer\">View official info<\/a>` : ''}\n                  <button class=\"tiny-btn\" onclick=\"removeItem(${dayIndex}, '${slot}', '${item.uid}')\">Remove<\/button>\n                <\/div>\n              <\/div>\n            `).join('') : '<div class=\"slot-empty\">No items yet.<\/div>'}\n          <\/div>\n        `).join('')}\n      <\/div>\n    <\/div>\n  `).join('');\n\n  bindMapFocusLinks();\n}\n\nfunction matchesFilters(item){\n  const t = document.getElementById('filterType').value;\n  const z = document.getElementById('filterZone').value;\n  const s = document.getElementById('filterSlot').value;\n  const m = document.getElementById('filterMove').value;\n  const i = document.getElementById('filterInterest').value;\n  const d = document.getElementById('filterDuration').value;\n  const rawSearch = document.getElementById('search').value.trim();\n  const q = normalizeText(rawSearch);\n  const intent = inferSearchIntent(rawSearch);\n\n  if(t && item.type !== t) return false;\n  if(z && item.zone !== z) return false;\n  if(s && !(item.slots||[]).includes(s)) return false;\n  if(m && !((item.move||['coche','pie','bici']).includes(m))) return false;\n  if(d && !matchesDuration(item, d)) return false;\n\n  if(i){\n    const interests = inferInterestTags(item);\n    if(!interests.includes(i)) return false;\n  }\n\n  if(intent && !t && item.type !== intent){\n    const interests = inferInterestTags(item);\n    if(intent !== 'actividad' || item.type !== 'actividad'){\n      if(item.type !== intent && !interests.includes(intent)) return false;\n    }\n  }\n\n  if(q){\n    const hay = normalizeText([\n      item.title,\n      item.desc,\n      item.zone,\n      item.type,\n      item.notes || '',\n      (item.slots||[]).join(' '),\n      (item.move||[]).join(' '),\n      inferInterestTags(item).join(' ')\n    ].join(' '));\n\n    const words = q.split(\/\\s+\/).filter(Boolean);\n    const matched = words.every(word => hay.includes(word) || word.length < 3);\n    if(!matched) return false;\n  }\n\n  return true;\n}\n\nfunction getVisibleCatalogItems(){\n  return catalog\n    .filter(matchesFilters)\n    .map(item => ({\n      ...item,\n      pref: getPersonalScore(item),\n      officialLink: getOfficialLink(item)\n    }))\n    .sort((a, b) => a.title.localeCompare(b.title, 'en', { sensitivity: 'base' }));\n}\n\nfunction renderCatalog(){\n  const items = getVisibleCatalogItems();\n  const plannedIds = getPlannedItemIds();\n\n  catalogCount.textContent = `${items.length} options`;\n\n  if(!items.length){\n    catalogGrid.innerHTML = '<div class=\"empty\">There are no results for those filters. Try clearing the search or broadening the area and time slot.<\/div>';\n    renderMap([]);\n    return;\n  }\n\n  catalogGrid.innerHTML = items.map(item => `\n    <div class=\"catalog-card\">\n      <div class=\"catalog-top\">\n        <div class=\"title-row\">\n          <span class=\"icon-badge\">${getTypeIcon(item.type)}<\/span>\n          <div><h4>${item.title}<\/h4><\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"tags\">\n        <span class=\"tag type-${item.type}\">${typeLabels[item.type]}<\/span>\n        <span class=\"tag\">${zoneLabels[item.zone] || item.zone}<\/span>\n        <span class=\"tag\">${fmtHours(item.hours)}<\/span>\n        <span class=\"tag\">${prettyMoves(item.move)}<\/span>\n        ${(item.slots||[]).map(s=>`<span class=\"tag\">${slotLabels[s]}<\/span>`).join('')}\n        ${plannedIds.has(item.id) ? '<span class=\"tag planned\">In your trip<\/span>' : ''}\n      <\/div>\n\n      <p>${buildEnhancedDescription(item)}<\/p>\n\n      <div class=\"help\">\n        ${item.type==='restaurante'\n          ? 'Estimated average price: ' + euro(item.cost).replace(',00','')\n          : (Number(item.cost)||0 ? 'Estimated cost: ' + euro(item.cost).replace(',00','') : 'No estimated cost')}\n      <\/div>\n\n      ${item.pref.reasons.length ? `<div class=\"help\">Priority: ${item.pref.reasons.slice(0,2).join(' \u00b7 ')}<\/div>` : ''}\n\n      <div class=\"controls-inline\">\n        ${item.lat && item.lng ? `<a class=\"catalog-link\" href=\"${getGoogleMapsDirectionsUrl(item)}\" target=\"_blank\" rel=\"noopener noreferrer\">Get directions<\/a>` : ''}\n        ${item.officialLink ? `<a class=\"catalog-link\" href=\"${item.officialLink}\" target=\"_blank\" rel=\"noopener noreferrer\">View official information<\/a>` : ''}\n      <\/div>\n\n      <div class=\"controls-inline\">\n        <select class=\"small-select add-day\" data-item=\"${item.id}\">\n          ${state.days.map((d, idx)=>`<option value=\"${idx}\">${d.title}<\/option>`).join('')}\n        <\/select>\n      <\/div>\n\n      <div class=\"quick-slot-actions\">\n        ${slotsOrder.map(slot => `<button class=\"quick-add-btn\" data-quick-add=\"${item.id}\" data-slot=\"${slot}\">${slotLabels[slot]}<\/button>`).join('')}\n      <\/div>\n    <\/div>\n  `).join('');\n\n  document.querySelectorAll('[data-quick-add]').forEach(btn => {\n    btn.addEventListener('click', () => {\n      const id = btn.getAttribute('data-quick-add');\n      const slot = btn.getAttribute('data-slot') || 'morning';\n      const day = Number(document.querySelector(`.add-day[data-item=\"${id}\"]`).value || 0);\n      addItemToPlan(id, day, slot);\n    });\n  });\n\n  bindMapFocusLinks();\n  renderMap(items);\n}\n\nfunction buildSummaryText(){\n  const lines = [];\n  lines.push(state.tripName);\n  lines.push('');\n  lines.push(`Profile: ${tripWho.options[tripWho.selectedIndex].text} \u00b7 ${tripMove.options[tripMove.selectedIndex].text} \u00b7 ${tripPace.options[tripPace.selectedIndex].text}`);\n  lines.push('');\n\n  state.days.forEach((day, idx) => {\n    lines.push(`${day.title} \u00b7 ${dateLabel(idx)}`);\n    slotsOrder.forEach(slot => {\n      if(day.slots[slot].length){\n        lines.push(`  ${slotLabels[slot]}:`);\n        day.slots[slot].forEach(it => lines.push(`  - ${it.title} (${typeLabels[it.type]}, ${zoneLabels[it.zone] || it.zone})`));\n      }\n    });\n    lines.push('');\n  });\n\n  lines.push('Total budget: ' + document.getElementById('bTotal').textContent);\n  return lines.join('\\n');\n}\n\nfunction copySummary(){\n  navigator.clipboard.writeText(buildSummaryText());\n}\n\nfunction downloadSummary(){\n  const win = window.open('', '_blank');\n  if(!win) return;\n\n  const safeTitle = state.tripName || 'Itinerary en Tavernes';\n  const totalBudget = document.getElementById('bTotal').textContent;\n\n  let html = `\n    <html>\n    <head>\n      <title>${safeTitle}<\/title>\n      <style>\n        body{font-family:Arial,sans-serif;color:#12385f;margin:40px;line-height:1.5}\n        h1{margin:0 0 10px;font-size:28px}\n        h2{margin:28px 0 8px;font-size:20px}\n        h3{margin:18px 0 6px;font-size:17px}\n        .meta{margin-bottom:20px;color:#5f7892}\n        .day{margin-bottom:24px;padding-bottom:12px;border-bottom:1px solid #d8e3ef}\n        .item{margin:6px 0 10px 14px}\n        .budget{margin-top:24px;font-size:19px;font-weight:bold}\n      \n\/* === Layout actualizado === *\/\n.app{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n  width:1920px;\n  min-height:auto;\n  height:auto;\n  align-items:stretch;\n}\n\n.top-layout{\n  display:grid;\n  grid-template-columns:minmax(0,1.05fr) minmax(0,1.95fr);\n  gap:16px;\n  align-items:start;\n}\n\n.hero-card,\n.controls-card{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n}\n\n.hero-split{\n  display:grid;\n  grid-template-columns:220px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.brand{\n  min-height:100%;\n}\n\n.trip-tools-row{\n  display:grid;\n  grid-template-columns:repeat(3,minmax(0,1fr)) auto;\n  gap:14px;\n  align-items:end;\n}\n\n.day-actions{\n  display:flex;\n  gap:10px;\n  flex-wrap:wrap;\n}\n\n.trip-form{\n  grid-template-columns:repeat(4,minmax(0,1fr));\n}\n\n.trip-form .field:last-child{\n  grid-column:span 2;\n}\n\n.top-actions{\n  display:flex;\n  gap:10px;\n  flex-wrap:wrap;\n}\n\n.stats-budget-row{\n  display:grid;\n  grid-template-columns:320px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.stats-card,\n.budget-card{\n  padding:16px;\n  border:1px solid var(--line);\n  border-radius:16px;\n  background:var(--soft);\n}\n\n.content-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1.6fr) 430px;\n  gap:16px;\n  align-items:start;\n}\n\n.content-left,\n.content-right{\n  min-width:0;\n}\n\n.itinerary-panel{\n  min-height:760px;\n}\n\n.center-scroll{\n  max-height:920px;\n}\n\n.catalog-panel{\n  min-height:760px;\n}\n\n.catalog-results{\n  max-height:920px;\n}\n\n.map-bottom{\n  overflow:hidden;\n}\n\n.map-bottom-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1fr) 330px;\n  min-height:620px;\n}\n\n#travelMap{\n  width:100%;\n  height:620px;\n  min-height:620px;\n}\n\n.map-side-scroll{\n  max-height:none;\n  border-top:0;\n  border-left:1px solid var(--line);\n  padding:12px;\n  background:#fbfdff;\n}\n\n.catalog-top h4{\n  margin:0;\n}\n\n@media (max-width: 1200px){\n  .trip-form{\n    grid-template-columns:repeat(2,minmax(0,1fr));\n  }\n\n  .trip-form .field:last-child{\n    grid-column:1 \/ -1;\n  }\n}\n\n\n\/* === Layout pantalla completa v2 === *\/\n.app-viewport{\n  width:100%;\n  min-height:100vh;\n  overflow:visible;\n  display:block;\n  background:transparent;\n}\n\n.app-scale-wrap{\n  width:100% !important;\n  height:auto !important;\n  overflow:visible;\n}\n\n.app-scale{\n  width:100% !important;\n  height:auto !important;\n  transform:none !important;\n}\n\n.app-shell{\n  width:100%;\n  min-width:0;\n  max-width:none;\n  border-radius:0;\n  border-left:0;\n  border-right:0;\n  padding:16px;\n}\n\n.app{\n  width:100%;\n  min-width:0;\n}\n\n.top-layout{\n  display:grid;\n  grid-template-columns:420px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.content-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1fr);\n  gap:16px;\n}\n\n.content-right{\n  order:-1;\n}\n\n.catalog-panel{\n  min-height:auto;\n}\n\n.catalog-fixed{\n  border-bottom:0;\n  padding:16px;\n}\n\n.catalog-head{\n  display:grid;\n  grid-template-columns:320px minmax(0,1fr);\n  gap:20px;\n  align-items:start;\n}\n\n.catalog-head > div:first-child{\n  min-width:0;\n}\n\n.filters{\n  display:grid;\n  grid-template-columns:repeat(7,minmax(120px,1fr));\n  gap:10px;\n  margin-top:0;\n  align-items:end;\n}\n\n.filters .search{\n  grid-column:span 1;\n}\n\n.catalog-results{\n  max-height:none;\n  padding:0 16px 16px;\n}\n\n.catalog-grid{\n  grid-template-columns:repeat(3,minmax(0,1fr));\n  align-items:start;\n}\n\n.itinerary-panel{\n  min-height:0;\n}\n\n.center-scroll{\n  max-height:none;\n  overflow:visible;\n  padding-right:0;\n}\n\n.stats-budget-row{\n  grid-template-columns:220px minmax(0,1fr);\n}\n\n.budget-card{\n  order:3;\n}\n\n.bottom-budget{\n  margin-top:16px;\n}\n\n.map-bottom{\n  margin-top:16px;\n}\n\n.map-bottom-grid{\n  grid-template-columns:minmax(0,1fr) 360px;\n  min-height:680px;\n}\n\n#travelMap{\n  height:680px;\n  min-height:680px;\n  display:block;\n}\n\n@media (max-width: 1600px){\n  .catalog-grid{\n    grid-template-columns:repeat(2,minmax(0,1fr));\n  }\n  .filters{\n    grid-template-columns:repeat(4,minmax(120px,1fr));\n  }\n}\n\n@media (max-width: 1200px){\n  .top-layout,\n  .catalog-head,\n  .stats-budget-row,\n  .map-bottom-grid{\n    grid-template-columns:1fr;\n  }\n\n  .filters{\n    grid-template-columns:repeat(2,minmax(120px,1fr));\n  }\n\n  .catalog-grid{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\/* === Ajuste disposici\u00f3n final === *\/\n.top-layout{\n  display:block;\n}\n\n.hero-card,\n.controls-card{\n  display:block;\n}\n\n.unified-top{\n  display:grid;\n  grid-template-columns:420px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.unified-top-right{\n  display:grid;\n  gap:16px;\n}\n\n.unified-top .top-actions{\n  margin-top:12px;\n}\n\n.content-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1.15fr) minmax(520px,0.85fr);\n  gap:16px;\n  align-items:start;\n}\n\n.itinerary-panel{\n  min-height:720px;\n}\n\n.catalog-panel{\n  min-height:720px;\n  overflow:hidden;\n}\n\n.catalog-fixed{\n  padding:16px;\n  border-bottom:1px solid var(--line);\n}\n\n.catalog-head{\n  display:grid;\n  grid-template-columns:1fr;\n  gap:14px;\n}\n\n.filters{\n  display:grid;\n  grid-template-columns:repeat(3,minmax(0,1fr));\n  gap:10px;\n  align-items:end;\n}\n\n.filters .search{\n  grid-column:1 \/ -1;\n}\n\n.catalog-results{\n  max-height:760px;\n  overflow-y:auto;\n  overflow-x:hidden;\n  padding:16px;\n  scrollbar-gutter:stable;\n}\n\n.catalog-grid{\n  display:grid;\n  grid-template-columns:1fr;\n  gap:12px;\n}\n\n.center-scroll{\n  max-height:760px;\n  overflow-y:auto;\n  overflow-x:hidden;\n  padding-right:8px;\n  scrollbar-gutter:stable;\n}\n\n.map-bottom-grid{\n  display:grid;\n  grid-template-columns:minmax(0,1fr) 320px;\n  gap:0;\n  min-height:720px;\n}\n\n#travelMap{\n  height:720px;\n  min-height:720px;\n}\n\n.map-side-scroll{\n  max-height:720px;\n  overflow-y:auto;\n  overflow-x:hidden;\n  border-left:1px solid var(--line);\n  border-top:0;\n  padding:12px;\n  background:#fbfdff;\n  scrollbar-gutter:stable;\n}\n\n.bottom-budget{\n  margin-top:16px;\n}\n\n@media (max-width: 1400px){\n  .content-grid{\n    grid-template-columns:1fr;\n  }\n  .filters{\n    grid-template-columns:repeat(2,minmax(0,1fr));\n  }\n}\n\n@media (max-width: 1100px){\n  .unified-top{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\/* === Ajustes finos solicitados === *\/\n.unified-top{\n  grid-template-columns:1fr;\n}\n\n.unified-top > div:first-child{\n  display:grid;\n  grid-template-columns:220px minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.hero-split{\n  grid-template-columns:1fr;\n  gap:12px;\n}\n\n.hero-split > div:last-child{\n  min-width:0;\n}\n\n.unified-top-right{\n  display:grid;\n  grid-template-columns:1fr auto;\n  gap:16px;\n  align-items:start;\n}\n\n.trip-tools-row{\n  grid-column:1 \/ -1;\n}\n\n.trip-form{\n  grid-column:1 \/ -1;\n}\n\n.stats-budget-row{\n  display:block;\n}\n\n.stats-card{\n  display:none;\n}\n\n.bottom-budget{\n  margin-top:16px;\n}\n\n.bottom-budget .stats{\n  margin-bottom:16px;\n}\n\n.content-grid{\n  grid-template-columns:minmax(0,1fr) minmax(0,1fr);\n  gap:16px;\n  align-items:start;\n}\n\n.catalog-panel,\n.itinerary-panel{\n  min-height:980px;\n  height:980px;\n}\n\n.catalog-results,\n.center-scroll{\n  height:calc(980px - 88px);\n  max-height:calc(980px - 88px);\n  overflow-y:auto;\n  overflow-x:hidden;\n}\n\n.catalog-grid{\n  grid-template-columns:1fr;\n}\n\n.catalog-card{\n  display:grid;\n  gap:12px;\n  min-height:190px;\n  padding:16px;\n}\n\n.slot-grid{\n  display:grid;\n  grid-template-columns:repeat(4,minmax(0,1fr));\n  gap:12px;\n}\n\n.slot{\n  min-height:220px;\n}\n\n.quick-slot-actions{\n  display:flex;\n  flex-wrap:wrap;\n  gap:6px;\n  margin-top:6px;\n}\n\n.quick-add-btn{\n  padding:7px 10px;\n  border-radius:999px;\n  border:1px solid var(--line2);\n  background:#fff;\n  color:var(--text);\n  cursor:pointer;\n  font-size:13px;\n  font-weight:700;\n}\n\n.quick-add-btn:hover{\n  background:var(--soft);\n}\n\n.day-card{\n  margin-bottom:10px;\n}\n\n.map-bottom-grid{\n  grid-template-columns:minmax(0,0.82fr) minmax(0,1.18fr);\n}\n\n@media (max-width: 1400px){\n  .content-grid{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\/* === Ajuste exclusivo franja superior === *\/\n.top-banner{\n  width:100%;\n  min-height:118px;\n  border:1px solid var(--line);\n  border-radius:14px;\n  background:linear-gradient(135deg,#eef7ff,#ffffff);\n  display:flex;\n  align-items:center;\n  justify-content:flex-start;\n  padding:18px 24px;\n}\n\n.top-banner .brand-wordmark{\n  display:flex;\n  align-items:center;\n  gap:14px;\n  width:auto;\n}\n\n.top-banner .brand-logo{\n  width:42px;\n  max-width:100%;\n  height:auto;\n  display:block;\n  flex:0 0 auto;\n  object-fit:contain;\n}\n\n.top-banner .brand-kicker{\n  font-size:13px;\n  font-weight:800;\n  letter-spacing:.12em;\n  color:var(--brand);\n}\n\n.top-banner .brand-main{\n  font-size:23px;\n  line-height:1.05;\n  font-weight:800;\n  color:var(--text);\n}\n\n.top-banner .brand-subline{\n  font-size:13px;\n  color:var(--muted);\n  margin-top:4px;\n}\n\n\n\/* === Superior limpio === *\/\n.unified-top-clean{\n  display:grid;\n  grid-template-columns:260px minmax(0,1fr);\n  gap:18px;\n  align-items:start;\n}\n\n.top-clean-main{\n  display:contents;\n}\n\n.top-clean-left{\n  display:flex;\n  flex-direction:column;\n  gap:16px;\n}\n\n.unified-top-clean .top-banner{\n  min-height:108px;\n}\n\n.unified-top-clean .trip-tools-row{\n  grid-column:1 \/ -1;\n  display:grid;\n  grid-template-columns:1fr 1fr 1fr auto;\n  gap:10px;\n  align-items:end;\n}\n\n@media (max-width: 1200px){\n  .unified-top-clean{\n    grid-template-columns:1fr;\n  }\n\n  .unified-top-clean .trip-tools-row{\n    grid-template-columns:1fr;\n  }\n}\n\n\n.catalog-extra-filters{\n  display:grid;\n  grid-template-columns:repeat(3,minmax(0,1fr));\n  gap:10px;\n  margin-bottom:10px;\n}\n\n@media (max-width: 1100px){\n  .catalog-extra-filters{\n    grid-template-columns:1fr;\n  }\n}\n\n\n@media (max-width: 900px){\n  .map-bottom-grid{\n    grid-template-columns:1fr;\n  }\n\n  .map-list{\n    grid-template-columns:1fr;\n  }\n}\n\n\n\n\n\/* === Budget en dos bloques laterales === *\/\n.bottom-budget{\n  display:block;\n}\n\n.budget-two-cols{\n  display:grid;\n  grid-template-columns:minmax(0,1fr) 260px;\n  gap:16px;\n  align-items:stretch;\n}\n\n.budget-main-col,\n.budget-side-col{\n  border:1px solid var(--line);\n  background:var(--soft);\n  border-radius:16px;\n  padding:14px;\n  height:100%;\n}\n\n.budget-main-col{\n  display:flex;\n  flex-direction:column;\n}\n\n.budget-side-col{\n  display:flex;\n}\n\n.budget-total{\n  margin-top:auto;\n}\n\n.budget-mini-stats{\n  display:grid;\n  grid-template-columns:repeat(2,minmax(0,1fr));\n  grid-auto-rows:1fr;\n  gap:8px;\n  width:100%;\n  height:100%;\n}\n\n.mini-stat{\n  border:1px solid var(--line);\n  background:#fff;\n  border-radius:12px;\n  padding:10px;\n  display:flex;\n  flex-direction:column;\n  justify-content:center;\n  gap:4px;\n  min-height:0;\n}\n\n.mini-stat-label{\n  font-size:11px;\n  color:var(--muted);\n  line-height:1.1;\n}\n\n.mini-stat-value{\n  font-size:17px;\n  color:var(--text);\n  line-height:1.1;\n}\n\n@media (max-width: 900px){\n  .budget-two-cols{\n    grid-template-columns:1fr;\n  }\n}\n\n<\/style>\n    <\/head>\n    <body>\n      <h1>${safeTitle}<\/h1>\n      <div class=\"meta\">\n        <div><strong>Profile:<\/strong> ${tripWho.options[tripWho.selectedIndex].text} \u00b7 ${tripMove.options[tripMove.selectedIndex].text} \u00b7 ${tripPace.options[tripPace.selectedIndex].text}<\/div>\n\n      <\/div>\n  `;\n\n  state.days.forEach((day, idx) => {\n    html += `<div class=\"day\">`;\n    html += `<h2>${day.title} \u00b7 ${dateLabel(idx)}<\/h2>`;\n    slotsOrder.forEach(slot => {\n      if(day.slots[slot].length){\n        html += `<h3>${slotLabels[slot]}<\/h3>`;\n        day.slots[slot].forEach(it => {\n          html += `<div class=\"item\"><strong>${getTypeIcon(it.type)} ${it.title}<\/strong><br>${typeLabels[it.type]} \u00b7 ${zoneLabels[it.zone] || it.zone} \u00b7 ${fmtHours(it.hours)}<\/div>`;\n        });\n      }\n    });\n    html += `<\/div>`;\n  });\n\n  html += `<div class=\"budget\">Total budget: ${totalBudget}<\/div>`;\n  html += `<\/body><\/html>`;\n\n  win.document.open();\n  win.document.write(html);\n  win.document.close();\n  win.focus();\n  win.print();\n}\n\nfunction renderAll(){\n  state.tripName = tripName.value.trim() || 'Trip to Tavernes';\n  state.startDate = tripStart.value || getTodayISO();\n  renderDays();\n  renderCatalog();\n  updateStats();\n\n  requestAnimationFrame(() => {\n    setTimeout(() => {\n      if (typeof map !== 'undefined' && map) {\n        map.invalidateSize();\n      }\n    }, 120);\n  });\n}\n\nconst map = L.map('travelMap', { zoomControl:true }).setView([39.073, -0.241], 12);\n\nL.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\n  maxZoom: 19,\n  attribution: '&copy; OpenStreetMap'\n}).addTo(map);\n\nlet mapMarkers = {};\nlet mapLayerGroup = L.layerGroup().addTo(map);\n\nwindow.addEventListener('load', () => {\n  setTimeout(() => {\n    if (typeof map !== 'undefined' && map) {\n      map.invalidateSize();\n    }\n  }, 300);\n});\n\nfunction markerHtmlForType(type, isPlanned){\n  const bg = {\n    actividad:'#0d6fb8',\n    restaurante:'#f08b2d',\n    alojamiento:'#2d8b57',\n    evento:'#d9534f',\n    ocio:'#7546c8'\n  }[type] || '#5f7892';\n\n  const border = isPlanned ? '#ffbf47' : '#ffffff';\n  const ring = isPlanned ? '0 0 0 3px rgba(255,191,71,.35), 0 4px 10px rgba(0,0,0,.18)' : '0 4px 10px rgba(0,0,0,.15)';\n  const size = isPlanned ? 34 : 30;\n  const fontSize = isPlanned ? 16 : 15;\n\n  return `\n    <div style=\"\n      width:${size}px;\n      height:${size}px;\n      border-radius:999px;\n      background:${bg};\n      color:#fff;\n      display:flex;\n      align-items:center;\n      justify-content:center;\n      font-size:${fontSize}px;\n      border:3px solid ${border};\n      box-shadow:${ring};\n      font-weight:700;\n    \">\n      ${getTypeIcon(type)}\n    <\/div>\n  `;\n}\n\nfunction getMarkerIcon(type, isPlanned){\n  const size = isPlanned ? 34 : 30;\n  return L.divIcon({\n    html: markerHtmlForType(type, isPlanned),\n    className: '',\n    iconSize: [size,size],\n    iconAnchor: [size\/2,size\/2],\n    popupAnchor: [0,-14]\n  });\n}\n\nfunction getPopupHtml(item, plannedOccurrences){\n  const official = getOfficialLink(item);\n  const plannedBlock = plannedOccurrences.length\n    ? `<div style=\"margin-top:6px;\"><strong>In your trip:<\/strong> ${plannedOccurrences.join(' \u00b7 ')}<\/div>`\n    : '';\n\n  const directionsUrl = getGoogleMapsDirectionsUrl(item);\n  const directionsBlock = directionsUrl\n    ? `<div style=\"margin-top:6px;\"><a href=\"${directionsUrl}\" target=\"_blank\" rel=\"noopener noreferrer\">Get directions<\/a><\/div>`\n    : '';\n\n  const officialBlock = official\n    ? `<div style=\"margin-top:6px;\"><a href=\"${official}\" target=\"_blank\" rel=\"noopener noreferrer\">View official information<\/a><\/div>`\n    : '';\n\n  return `\n    <div>\n      <strong>${getTypeIcon(item.type)} ${item.title}<\/strong>\n      <div>${typeLabels[item.type]} \u00b7 ${zoneLabels[item.zone] || item.zone}<\/div>\n      <div>${fmtHours(item.hours)} \u00b7 ${prettyMoves(item.move)}<\/div>\n      <div style=\"margin-top:4px;\">${item.desc}<\/div>\n      ${plannedBlock}\n      ${directionsBlock}\n      ${officialBlock}\n    <\/div>\n  `;\n}\n\nfunction renderMap(items){\n  mapLayerGroup.clearLayers();\n  mapMarkers = {};\n\n  const plannedOccurrencesMap = getPlannedOccurrences();\n  const plannedIds = getPlannedItemIds();\n\n  const visibleCatalogGeolocated = items.filter(item => Number.isFinite(item.lat) && Number.isFinite(item.lng));\n  const plannedGeolocated = catalog.filter(item => plannedIds.has(item.id) && Number.isFinite(item.lat) && Number.isFinite(item.lng));\n  const sourceItems = mapOnlyPlanned.checked ? plannedGeolocated : visibleCatalogGeolocated;\n\n  const uniqueMap = new Map();\n  sourceItems.forEach(item => uniqueMap.set(item.id, item));\n  const finalItems = [...uniqueMap.values()];\n\n  mapVisibleCount.textContent = `${finalItems.length} visible locations`;\n  mapPlannedCount.textContent = `${plannedGeolocated.length} added to the trip`;\n\n  mapList.innerHTML = finalItems.length\n    ? finalItems.map(item => {\n        const occ = plannedOccurrencesMap[item.id] || [];\n        return `\n          <div class=\"map-list-item\">\n            <strong>${getTypeIcon(item.type)} ${item.title}<\/strong>\n            <div class=\"meta\">${typeLabels[item.type]} \u00b7 ${zoneLabels[item.zone] || item.zone} \u00b7 ${fmtHours(item.hours)}<\/div>\n            ${occ.length ? `<div class=\"meta\"><strong>In your trip:<\/strong> ${occ.join(' \u00b7 ')}<\/div>` : ''}\n            <div class=\"controls-inline\">\n              <span class=\"map-focus-link\" data-map-focus=\"${item.id}\">Center on map<\/span>\n              <a class=\"map-focus-link\" href=\"${getGoogleMapsDirectionsUrl(item)}\" target=\"_blank\" rel=\"noopener noreferrer\">Get directions<\/a>\n            <\/div>\n          <\/div>\n        `;\n      }).join('')\n    : `<div class=\"empty\">There are no visible locations on the map with the current settings.<\/div>`;\n\n  finalItems.forEach(item => {\n    const occ = plannedOccurrencesMap[item.id] || [];\n    const isPlanned = occ.length > 0;\n    const marker = L.marker([item.lat, item.lng], { icon: getMarkerIcon(item.type, isPlanned) });\n    marker.bindPopup(getPopupHtml(item, occ));\n    marker.addTo(mapLayerGroup);\n    mapMarkers[item.id] = marker;\n  });\n\n  if(finalItems.length === 1){\n    map.setView([finalItems[0].lat, finalItems[0].lng], 16);\n  } else if(finalItems.length > 1){\n    const bounds = L.latLngBounds(finalItems.map(item => [item.lat, item.lng]));\n    map.fitBounds(bounds.pad(0.04));\n    const currentZoom = map.getZoom();\n    if(currentZoom > 14){\n      map.setZoom(14);\n    }\n  } else {\n    map.setView([39.073, -0.241], 13);\n  }\n\n  bindMapFocusLinks();\n  setTimeout(() => {\n    if (typeof map !== 'undefined' && map) {\n      map.invalidateSize();\n    }\n  }, 80);\n}\n\nfunction focusItemOnMap(itemId){\n  const item = catalog.find(x => x.id === itemId);\n  if(!item || !item.lat || !item.lng) return;\n\n  const plannedIds = getPlannedItemIds();\n  if(mapOnlyPlanned.checked && !plannedIds.has(itemId)){\n    mapOnlyPlanned.checked = false;\n    renderCatalog();\n  }\n\n  const marker = mapMarkers[itemId];\n  map.setView([item.lat, item.lng], 16, {animate:true});\n\n  if(marker){\n    setTimeout(() => marker.openPopup(), 250);\n  }\n}\n\nfunction bindMapFocusLinks(){\n  document.querySelectorAll('[data-map-focus]').forEach(el => {\n    el.onclick = () => focusItemOnMap(el.getAttribute('data-map-focus'));\n  });\n}\n\nfunction scalePlannerApp(){\n  const viewport = document.getElementById('appViewport');\n  const wrap = document.getElementById('appScaleWrap');\n  const scaleBox = document.getElementById('appScale');\n\n  if(!viewport || !wrap || !scaleBox) return;\n\n  wrap.style.width = '100%';\n  wrap.style.height = 'auto';\n  scaleBox.style.width = '100%';\n  scaleBox.style.height = 'auto';\n  scaleBox.style.transform = 'none';\n  viewport.style.minHeight = 'auto';\n\n  requestAnimationFrame(() => {\n    setTimeout(() => {\n      if (typeof map !== 'undefined' && map) {\n        map.invalidateSize();\n      }\n    }, 120);\n  });\n}\n\ndocument.getElementById('btnGenerate').addEventListener('click', () => createDays(Number(numDays.value||1)));\ndocument.getElementById('btnAddDay').addEventListener('click', addDay);\ndocument.getElementById('btnClear').addEventListener('click', () => createDays(Number(numDays.value||1)));\ndocument.getElementById('btnCopy').addEventListener('click', copySummary);\ndocument.getElementById('btnDownload').addEventListener('click', downloadSummary);\n\nnumDays.addEventListener('change', () => createDays(Number(numDays.value||1)));\ntripName.addEventListener('input', renderAll);\ntripStart.addEventListener('change', renderAll);\ntripWho.addEventListener('change', renderAll);\ntripMove.addEventListener('change', renderAll);\ntripPace.addEventListener('change', renderAll);\n\nmapOnlyPlanned.addEventListener('change', renderCatalog);\n\n['filterType','filterZone','filterSlot','filterMove','filterInterest','filterDuration','search'].forEach(id => {\n  document.getElementById(id).addEventListener('input', renderCatalog);\n  document.getElementById(id).addEventListener('change', renderCatalog);\n});\n\nif (tripStart && !tripStart.value) {\n  tripStart.value = getTodayISO();\n}\n\ncreateDays(1);\n\nwindow.addEventListener('load', scalePlannerApp);\nwindow.addEventListener('resize', scalePlannerApp);\n\nsetTimeout(() => {\n  if (typeof map !== 'undefined' && map) {\n    map.invalidateSize();\n  }\n  scalePlannerApp();\n}, 250);\n<\/script>\n<\/body>\n<\/html>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Travel Planner for Tavernes de la Valldigna | Visit Tavernes Copy summary Clear plan Download PDF VISIT TAVERNES DE LA VALLDIGNA Plan your trip by day and time slot with all the options available in Tavernes: activities, heritage, nature, dining, leisure, events and accommodation Travel Planner Trip name Start date Number of days Apply days [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-17841","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/pages\/17841","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/comments?post=17841"}],"version-history":[{"count":9,"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/pages\/17841\/revisions"}],"predecessor-version":[{"id":17994,"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/pages\/17841\/revisions\/17994"}],"wp:attachment":[{"href":"https:\/\/www.visitatavernes.es\/en\/wp-json\/wp\/v2\/media?parent=17841"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}