{"id":16878,"date":"2025-08-28T11:04:25","date_gmt":"2025-08-28T09:04:25","guid":{"rendered":"https:\/\/lespouilles.blog\/apulia-spiagge\/"},"modified":"2026-08-31T13:58:45","modified_gmt":"2026-08-31T11:58:45","slug":"apulia-spiagge","status":"publish","type":"page","link":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/","title":{"rendered":"APULIA &#8211; Spiagge"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"16878\" class=\"elementor elementor-16878 elementor-4668\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f6ad25c e-flex e-con-boxed e-con e-parent\" data-id=\"f6ad25c\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;gradient&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2f6dd74 elementor-widget elementor-widget-html\" data-id=\"2f6dd74\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div class=\"apulia-plages-pagehead\">\r\n  <h1 class=\"apulia-plages-pagehead-title\" data-apulia-i18n=\"plage.page_title\">Meteo delle spiagge<\/h1>\r\n  <p class=\"apulia-plages-pagehead-lead\" data-apulia-i18n=\"plage.page_lead\">Seleziona la tua spiaggia in base alla direzione del vento<\/p>\r\n<\/div>\r\n<div id=\"apulia-map-pro\" class=\"apulia-map-pro\" data-apulia-i18n-aria=\"plage.map_aria\" aria-label=\"Carte des plages\">\r\n  <div id=\"apulia-leaflet\" class=\"apulia-leaflet\" aria-hidden=\"true\"><\/div>\r\n<\/div>\r\n\r\n<style>\r\n  \/* =========================\r\n     APULIA MAP PRO \u2014 V5.7.1 (PLAGES LIVE PREMIUM CORRIG\u00c9)\r\n     FIXES (2026-01-14) :\r\n     - LIVE plus petit (moins \u201cgros\u201d visuellement)\r\n     - Heures plus bas (descendues sous la barre)\r\n     - Thumb (pointeur jaune) plus petit + n\u2019\u00e9crase plus les heures\r\n     - Barre orange align\u00e9e avec le thumb (m\u00eame axe vertical)\r\n     - Jour courant toujours visible pendant le scroll (chip centr\u00e9)\r\n     ========================= *\/\r\n\r\n  .apulia-plages-pagehead{\r\n    width:100%;\r\n    margin:0 auto 12px;\r\n    text-align:center;\r\n  }\r\n  .apulia-plages-pagehead-title{\r\n    margin:0 0 6px;\r\n    font-size:26px;\r\n    font-weight:800;\r\n    line-height:1.2;\r\n    color:#ffffff;\r\n    text-align:center;\r\n  }\r\n  .apulia-plages-pagehead-lead{\r\n    margin:0 auto;\r\n    max-width:520px;\r\n    font-size:14px;\r\n    font-weight:500;\r\n    line-height:1.45;\r\n    color:rgba(255,255,255,0.78);\r\n    text-align:center;\r\n  }\r\n\r\n  #apulia-map-pro{\r\n    --orange:#F6A623;\r\n    --white:#ffffff;\r\n    --teal1:#001D26;\r\n    --teal3:#005E75;\r\n\r\n    --border: rgba(255,255,255,0.14);\r\n    --shadow: 0 12px 28px rgba(0,0,0,0.26);\r\n\r\n    --apulia-nav-offset: 84px;\r\n\r\n    position: relative;\r\n    width: 100%;\r\n    margin: 0;\r\n    background: transparent !important;\r\n    border-radius: 20px !important;\r\n    overflow: hidden;\r\n\r\n    height: calc(100vh - var(--apulia-nav-offset));\r\n    min-height: 520px;\r\n  }\r\n  @supports (height: 100dvh){\r\n    #apulia-map-pro{ height: calc(100dvh - var(--apulia-nav-offset)); }\r\n  }\r\n\r\n  #apulia-map-pro .apulia-leaflet{\r\n    position:absolute;\r\n    inset:0;\r\n    z-index: 1;\r\n  }\r\n  #apulia-map-pro .apulia-leaflet.leaflet-container{\r\n    width:100%;\r\n    height:100%;\r\n    background: transparent !important;\r\n    outline: none;\r\n    -webkit-tap-highlight-color: transparent;\r\n    touch-action: pan-x pan-y;\r\n  }\r\n  #apulia-map-pro .leaflet-control-container{ display:none !important; }\r\n\r\n  #apulia-map-pro .leaflet-tile{\r\n    filter: saturate(1.45) contrast(1.10) brightness(1.02) hue-rotate(-28deg);\r\n  }\r\n\r\n  #apulia-map-pro{\r\n    --top-pill-h: 46px;\r\n    --fab-size: 48px;\r\n    --fab-font: 22px;\r\n  }\r\n\r\n  .apulia-ui{\r\n    position:absolute;\r\n    left: 12px;\r\n    right: 12px;\r\n    top: 12px;\r\n    z-index: 9999;\r\n    display:flex;\r\n    gap:10px;\r\n    align-items:center;\r\n  }\r\n\r\n  .apulia-weather-top{\r\n    position:absolute;\r\n    left: 12px;\r\n    right: 12px;\r\n    top: 12px;\r\n    transform:none;\r\n    z-index:9998;\r\n    width:auto;\r\n    pointer-events:auto;\r\n    display:flex;\r\n    justify-content:center;\r\n  }\r\n\r\n\r\n  .apulia-search{\r\n    flex:1;\r\n    height: var(--top-pill-h);\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n    padding: 0 14px;\r\n    border-radius: 999px;\r\n    background: linear-gradient(180deg, var(--teal1) 0%, var(--teal3) 100%);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    box-shadow: var(--shadow);\r\n    backdrop-filter: blur(10px);\r\n  }\r\n  .apulia-search .sico{ font-size: 18px; line-height: 1; color: #fff; opacity: .95; }\r\n  .apulia-search input{\r\n    width:100%;\r\n    border:0;\r\n    outline:none;\r\n    background:transparent;\r\n    font-weight:1000;\r\n    font-size:14px;\r\n    color:#fff;\r\n    height: 100%;\r\n  }\r\n  .apulia-search input::placeholder{ color: rgba(255,255,255,0.88); }\r\n\r\n  .apulia-btn-pill{\r\n    height: var(--top-pill-h);\r\n    border:0;\r\n    border-radius: 999px;\r\n    padding: 0 14px;\r\n    font-weight:1000;\r\n    font-size:13px;\r\n    cursor:pointer;\r\n    user-select:none;\r\n    -webkit-tap-highlight-color: transparent;\r\n    box-shadow: var(--shadow);\r\n    background: linear-gradient(180deg, var(--teal1) 0%, var(--teal3) 100%);\r\n    color: var(--white);\r\n    display:flex;\r\n    align-items:center;\r\n    gap:8px;\r\n    white-space:nowrap;\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n  }\r\n  .apulia-btn-pill:active{ transform: scale(0.99); }\r\n\r\n  .apulia-zone-banner{\r\n    position:absolute;\r\n    left: 12px;\r\n    top: 94px;\r\n    z-index: 10005;\r\n    display:none;\r\n    align-items:center;\r\n    justify-content:center;\r\n    padding: 12px 26px;\r\n    border-radius: 999px;\r\n    background: rgba(246,166,35,0.96);\r\n    color:#001D26;\r\n    font-weight:1000;\r\n    box-shadow: var(--shadow);\r\n    border: 1px solid rgba(0,0,0,0.10);\r\n    right: calc(12px + var(--fab-size) + 12px);\r\n    max-width: calc(100% - (12px + 12px + var(--fab-size) + 12px));\r\n  }\r\n  .apulia-zone-banner.show{ display:flex; }\r\n  .apulia-zone-banner button{\r\n    border:0;\r\n    background: transparent;\r\n    font-weight:1000;\r\n    cursor:pointer;\r\n    -webkit-tap-highlight-color: transparent;\r\n    color:#001D26;\r\n    padding:0;\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n    white-space:nowrap;\r\n  }\r\n\r\n  .apulia-fab-col{\r\n    position:absolute;\r\n    z-index: 9999;\r\n    display:flex;\r\n    flex-direction:column;\r\n    gap:10px;\r\n  }\r\n  .apulia-fab-col.right{ right: 12px; top: 88px; }\r\n\r\n  .apulia-fab{\r\n    width: var(--fab-size);\r\n    height: var(--fab-size);\r\n    border-radius: 999px;\r\n    border: 1px solid rgba(0,0,0,0.10);\r\n    background: rgba(246,166,35,0.96);\r\n    box-shadow: var(--shadow);\r\n    cursor:pointer;\r\n    font-size: 20px;\r\n    font-weight:1000;\r\n    color:#001D26;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    -webkit-tap-highlight-color: transparent;\r\n    position: relative;\r\n  }\r\n  .apulia-fab:active{ transform: scale(0.99); }\r\n\r\n  .apulia-bottom-btn{\r\n    position:absolute;\r\n    bottom: 128px; \/* descendu de 4px *\/\r\n    z-index: 10010;\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n    pointer-events: auto;\r\n  }\r\n  .apulia-bottom-btn.left{ left: 12px; }\r\n  .apulia-bottom-btn.right{ right: 12px; }\r\n\r\n  .apulia-fab.info{ font-size: var(--fab-font); font-weight: 1000; }\r\n\r\n  .apulia-fab.danger{ width: var(--fab-size); height: var(--fab-size); }\r\n  .apulia-danger-ico{ width: 41px; height: 41px; display:block; transform: scale(1.4); transform-origin: center; } \/* ic\u00f4ne triangle agrandie visuellement (+40%) *\/\r\n  .apulia-danger-ico path,\r\n  .apulia-danger-ico line,\r\n  .apulia-danger-ico circle{\r\n    stroke:#001D26;\r\n    stroke-width:2.4;\r\n    stroke-linecap:round;\r\n    stroke-linejoin:round;\r\n    fill:none;\r\n  }\r\n\r\n  .apulia-drawer{\r\n    position:absolute;\r\n    left:12px;\r\n    right:12px;\r\n    top:64px;\r\n    z-index: 10000;\r\n    border-radius: 18px;\r\n    background: linear-gradient(180deg, var(--teal1) 0%, var(--teal3) 100%);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    box-shadow: var(--shadow);\r\n    padding: 12px;\r\n    display:none;\r\n    backdrop-filter: blur(10px);\r\n  }\r\n  .apulia-drawer.show{ display:block; }\r\n  .apulia-drawer h3{\r\n    margin:0 0 8px 0;\r\n    font-size:14px;\r\n    color: var(--white);\r\n    font-weight:1000;\r\n  }\r\n  .apulia-chips{ display:flex; flex-wrap:wrap; gap:10px; }\r\n  .apulia-chip{\r\n    border-radius:999px;\r\n    padding:10px 12px;\r\n    border:1px solid rgba(255,255,255,0.14);\r\n    background: rgba(255,255,255,0.10);\r\n    color: var(--white);\r\n    font-weight:1000;\r\n    cursor:pointer;\r\n    user-select:none;\r\n    -webkit-tap-highlight-color: transparent;\r\n  }\r\n  .apulia-chip.active{\r\n    border-color: rgba(246,166,35,0.65);\r\n    background: rgba(246,166,35,0.14);\r\n    color: var(--orange);\r\n  }\r\n\r\n  .apulia-bottom{\r\n    position:absolute;\r\n    left: 0;\r\n    right: 0;\r\n    bottom: 0;\r\n    padding: 10px 12px 12px 12px;\r\n    z-index: 9999;\r\n    background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.20) 55%, rgba(0,0,0,0.40) 100%);\r\n    pointer-events: none;\r\n  }\r\n  .apulia-bottom-inner{ display:flex; flex-direction:column; gap:10px; margin-bottom: 10px; position: relative; pointer-events: auto; }\r\n\r\n\r\n\r\n  \/* =========================\r\n     CONDITIONS PLAGES \u2014 BANDEAU + SPOTLIGHT\r\n     ========================= *\/\r\n  .apulia-conditions-stack{\r\n    width: min(100%, 420px);\r\n    margin: 0 auto;\r\n    display:flex;\r\n    flex-direction:column;\r\n    gap:8px;\r\n    padding: 0 58px;\r\n    box-sizing:border-box;\r\n  }\r\n\r\n  .apulia-weather-strip{\r\n    width:min(100%, 560px);\r\n    padding: 0;\r\n    display:grid;\r\n    grid-template-columns: repeat(3, minmax(0, 1fr));\r\n    gap:8px;\r\n    color:#fff;\r\n  }\r\n  .apulia-weather-zone{\r\n    min-width:0;\r\n    min-height:66px;\r\n    text-align:center;\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:center;\r\n    justify-content:center;\r\n    gap:4px;\r\n    padding: 7px 5px;\r\n    border-radius: 18px;\r\n    background: linear-gradient(180deg, rgba(0,29,38,0.96) 0%, rgba(0,94,117,0.96) 100%);\r\n    border: 1px solid rgba(255,255,255,0.16);\r\n    box-shadow: var(--shadow);\r\n    backdrop-filter: blur(10px);\r\n  }\r\n  .apulia-weather-zone .wz-name{\r\n    font-size:12px;\r\n    font-weight:1000;\r\n    letter-spacing:.07em;\r\n    text-transform:uppercase;\r\n    color: rgba(255,255,255,0.94);\r\n  }\r\n  .apulia-weather-zone .wz-main{\r\n    font-size:17px;\r\n    font-weight:1000;\r\n    line-height:1.05;\r\n    white-space:nowrap;\r\n  }\r\n  .apulia-weather-zone .wz-sub{\r\n    font-size:11px;\r\n    font-weight:950;\r\n    color: rgba(255,255,255,0.90);\r\n    line-height:1.1;\r\n    white-space:nowrap;\r\n  }\r\n\r\n  .apulia-spotlight{\r\n    width:100%;\r\n    border-radius: 22px;\r\n    background: linear-gradient(180deg, rgba(0,29,38,0.96) 0%, rgba(0,94,117,0.96) 100%);\r\n    border: 1px solid rgba(255,255,255,0.16);\r\n    box-shadow: var(--shadow);\r\n    backdrop-filter: blur(10px);\r\n    color:#fff;\r\n    overflow:hidden;\r\n    cursor:pointer;\r\n  }\r\n  .apulia-spotlight-inner{\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:stretch;\r\n    justify-content:center;\r\n    gap:6px;\r\n    padding: 8px 10px 9px 10px;\r\n    text-align:left;\r\n  }\r\n  .apulia-spotlight-kicker{\r\n    width:100%;\r\n    text-align:center;\r\n    font-size:11px;\r\n    font-weight:1000;\r\n    letter-spacing:.055em;\r\n    text-transform:uppercase;\r\n    color: rgba(246,166,35,0.98);\r\n    line-height:1.05;\r\n    white-space:nowrap;\r\n    overflow:hidden;\r\n    text-overflow:ellipsis;\r\n  }\r\n  .apulia-spotlight-row{\r\n    width:100%;\r\n    min-width:0;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    gap:10px;\r\n  }\r\n  .apulia-spotlight-img{\r\n    flex:0 0 118px;\r\n    width:118px;\r\n    height:70px;\r\n    border-radius: 16px;\r\n    overflow:hidden;\r\n    background: rgba(255,255,255,0.09);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n  }\r\n  .apulia-spotlight-img img{\r\n    width:100%;\r\n    height:100%;\r\n    object-fit:cover;\r\n    display:block;\r\n  }\r\n  .apulia-spotlight-content{\r\n    flex:1 1 auto;\r\n    min-width:0;\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:flex-start;\r\n    justify-content:center;\r\n    gap:3px;\r\n  }\r\n  .apulia-spotlight-name{\r\n    width:100%;\r\n    font-size:15px;\r\n    font-weight:1000;\r\n    color:#fff;\r\n    line-height:1.08;\r\n    white-space:nowrap;\r\n    overflow:hidden;\r\n    text-overflow:ellipsis;\r\n    text-align:left;\r\n  }\r\n  .apulia-spotlight-sea{\r\n    width:100%;\r\n    font-size:12px;\r\n    font-weight:950;\r\n    color: rgba(255,255,255,0.94);\r\n    line-height:1.15;\r\n    white-space:nowrap;\r\n    overflow:hidden;\r\n    text-overflow:ellipsis;\r\n  }\r\n  .apulia-spotlight-meta{\r\n    width:100%;\r\n    font-size:12px;\r\n    font-weight:950;\r\n    color: rgba(255,255,255,0.92);\r\n    line-height:1.15;\r\n    white-space:nowrap;\r\n    overflow:hidden;\r\n    text-overflow:ellipsis;\r\n  }\r\n  .apulia-spotlight-actions{\r\n    display:none;\r\n    gap:8px;\r\n  }\r\n  .apulia-spotlight-actions .spbtn{\r\n    border:0;\r\n    border-radius: 999px;\r\n    padding: 8px 10px;\r\n    font-size:12px;\r\n    font-weight:1000;\r\n    cursor:pointer;\r\n    -webkit-tap-highlight-color: transparent;\r\n    flex:1;\r\n    white-space:nowrap;\r\n  }\r\n  .apulia-spotlight-actions .spbtn.primary{ background: var(--orange); color:#001D26; }\r\n  .apulia-spotlight-actions .spbtn.ghost{\r\n    background: rgba(255,255,255,0.10);\r\n    color:#fff;\r\n    border:1px solid rgba(255,255,255,0.14);\r\n  }\r\n  .apulia-spotlight-empty{\r\n    padding: 12px 14px;\r\n    text-align:center;\r\n    font-size:12px;\r\n    font-weight:950;\r\n    color: rgba(255,255,255,0.88);\r\n  }\r\n\r\n  @media (max-width: 420px){\r\n    .apulia-conditions-stack{ padding: 0 54px; gap:7px; }\r\n    .apulia-weather-top{ left:12px; right:12px; top:12px; width:auto; }\r\n    .apulia-weather-strip{ gap:7px; }\r\n    .apulia-weather-zone{ min-height:62px; padding:6px 4px; border-radius:17px; }\r\n    .apulia-weather-zone .wz-name{ font-size:11px; }\r\n    .apulia-weather-zone .wz-main{ font-size:15px; }\r\n    .apulia-weather-zone .wz-sub{ font-size:10px; }\r\n\r\n    .apulia-spotlight{ border-radius:20px; }\r\n    .apulia-spotlight-inner{ gap:5px; padding:7px 9px 8px 9px; }\r\n    .apulia-spotlight-kicker{ font-size:10.5px; letter-spacing:.045em; }\r\n    .apulia-spotlight-row{ gap:8px; }\r\n    .apulia-spotlight-img{ flex-basis:104px; width:104px; height:64px; border-radius:14px; }\r\n    .apulia-spotlight-name{ font-size:14px; }\r\n    .apulia-spotlight-sea,\r\n    .apulia-spotlight-meta{ font-size:11px; }\r\n    .apulia-spotlight-actions .spbtn{ padding:7px 8px; font-size:11px; }\r\n  }\r\n\r\n  \/* =========================\r\n     TIMELINE\r\n  ========================= *\/\r\n  .apulia-timeline{\r\n    width:100%;\r\n    border-radius: 26px;\r\n    background: linear-gradient(180deg, var(--teal1) 0%, var(--teal3) 100%);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    box-shadow: var(--shadow);\r\n    backdrop-filter: blur(10px);\r\n    padding: 6px 10px;\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n    min-height: 58px; \/* timeline plus fine, premium *\/\r\n  }\r\n\r\n  \/* LIVE plus petit - centr\u00e9 verticalement *\/\r\n  .apulia-live-pill{\r\n    flex: 0 0 auto;\r\n    min-width: 76px;\r\n    height: 38px; \/* r\u00e9duit pour timeline plus fine *\/\r\n    border-radius: 16px;\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    background: rgba(255,255,255,0.08);\r\n    color: #fff;\r\n    font-weight: 1000;\r\n    letter-spacing:.02em;\r\n    display:flex;\r\n    align-items:center;\r\n    justify-content:center;\r\n    gap:8px;\r\n    cursor:pointer;\r\n    -webkit-tap-highlight-color: transparent;\r\n    user-select:none;\r\n    font-size: 12px;\r\n  }\r\n  .apulia-live-pill.active{\r\n    background: rgba(255,255,255,0.08); \/* m\u00eame fond qu'inactif pour \u00e9viter fond persistant *\/\r\n    border-color: rgba(255,255,255,0.14);\r\n  }\r\n  .apulia-live-pill:active{ transform: scale(0.99); }\r\n  .apulia-live-dot{\r\n    width:9px;height:9px;border-radius:999px;background:#ff3b30;\r\n    box-shadow: 0 0 0 5px rgba(255,59,48,0.18);\r\n  }\r\n\r\n  .apulia-track-wrap{\r\n    position: relative;\r\n    flex: 1 1 auto;\r\n    min-width: 0;\r\n    display:flex;\r\n    flex-direction:column;\r\n    gap: 4px;\r\n    padding: 0;\r\n    margin-top: 0;\r\n  }\r\n\r\n  \/* Bandeau jours (overlay hors bulle) *\/\r\n  .apulia-day-strip{\r\n    position: absolute;\r\n    top: -24px;\r\n    left: 0;\r\n    right: 0;\r\n    height: 20px;\r\n    overflow: visible;\r\n    padding: 0;\r\n    pointer-events:none;\r\n    user-select:none;\r\n    z-index: 10001;\r\n  }\r\n  .apulia-day-strip .inner{\r\n    position: relative;\r\n    height: 20px;\r\n    width: 0px; \/* d\u00e9fini en JS *\/\r\n    transform: translateX(0);\r\n    will-change: transform;\r\n  }\r\n  .apulia-day-label{\r\n    position:absolute;\r\n    top: 2px;\r\n    font-weight: 1000;\r\n    font-size: 12px;\r\n    color: rgba(255,255,255,0.80);\r\n    letter-spacing:.06em;\r\n    text-transform: uppercase;\r\n    white-space: nowrap;\r\n    display: none; \/* masqu\u00e9 par d\u00e9faut - affichage permanent supprim\u00e9 *\/\r\n  }\r\n\r\n  \/* Jour courant (overlay hors bulle, affich\u00e9 temporairement \u00e0 la s\u00e9lection) *\/\r\n  .apulia-day-current{\r\n    position: absolute;\r\n    top: -24px;\r\n    left: 50%;\r\n    transform: translateX(-50%);\r\n    height: 20px;\r\n    display:none; \/* cach\u00e9 par d\u00e9faut *\/\r\n    align-items:center;\r\n    padding: 0 10px;\r\n    border-radius: 999px;\r\n    background: rgba(0,0,0,0.18);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    color: rgba(255,255,255,0.96);\r\n    font-weight: 1000;\r\n    font-size: 12px;\r\n    letter-spacing:.06em;\r\n    text-transform: uppercase;\r\n    pointer-events:none;\r\n    box-shadow: 0 10px 22px rgba(0,0,0,0.22);\r\n    backdrop-filter: blur(8px);\r\n    z-index: 10002;\r\n  }\r\n  .apulia-day-current.show{\r\n    display:flex;\r\n  }\r\n\r\n  \/* rail scroll *\/\r\n  .apulia-rail{\r\n    position: relative;\r\n    overflow-x: auto;\r\n    overflow-y: hidden;\r\n    -webkit-overflow-scrolling: touch;\r\n    scroll-snap-type: x mandatory;\r\n    touch-action: pan-x;\r\n    padding: 6px 6px 4px 6px; \/* ajust\u00e9 pour timeline plus fine *\/\r\n  }\r\n  .apulia-rail::-webkit-scrollbar{ height:0; }\r\n\r\n  \/* Barre ORANGE (m\u00eame axe que le thumb) *\/\r\n  .apulia-bar{\r\n    position:absolute;\r\n    left: 6px;\r\n    right: 6px;\r\n    top: 16px;               \/* remont\u00e9e pour plus d'espace avec les heures *\/\r\n    height: 6px;\r\n    border-radius: 999px;\r\n    background: rgba(246,166,35,0.18);\r\n    border: 1px solid rgba(246,166,35,0.26);\r\n    pointer-events:none;\r\n  }\r\n  .apulia-bar > i{\r\n    position:absolute;\r\n    inset: 0;\r\n    border-radius: 999px;\r\n    background: linear-gradient(90deg, rgba(246,166,35,0.95), rgba(246,166,35,0.75));\r\n    width: 0%;\r\n  }\r\n\r\n  .apulia-ticks{\r\n    position: relative;\r\n    display:flex;\r\n    align-items:flex-start;\r\n    gap: var(--pitchgap);\r\n    width: max-content;\r\n    padding: 0 0 0 0;\r\n  }\r\n\r\n  .apulia-tick{\r\n    -webkit-appearance: none;\r\n    appearance: none;\r\n    flex: 0 0 auto;\r\n    width: var(--pitch);\r\n    scroll-snap-align: center;\r\n    background: transparent !important;\r\n    border:0 !important;\r\n    padding: 0 !important;\r\n    margin:0 !important;\r\n    cursor:pointer;\r\n    -webkit-tap-highlight-color: transparent;\r\n    user-select:none;\r\n    color: rgba(255,255,255,0.92);\r\n    text-align:center;\r\n    outline:none !important;\r\n    box-shadow:none !important;\r\n  }\r\n  .apulia-tick:active{ transform: scale(0.99); }\r\n  .apulia-tick:focus,\r\n  .apulia-tick:focus-visible{\r\n    outline:none !important;\r\n    box-shadow: 0 0 0 3px rgba(246,166,35,0.18) !important;\r\n    border-radius: 12px;\r\n  }\r\n  .apulia-tick.active{\r\n    background: transparent !important;\r\n    box-shadow: none !important;\r\n  }\r\n\r\n  \/* Heures plus bas : on pousse tout vers le bas *\/\r\n  .apulia-tick .line{\r\n    width: 3px;\r\n    height: 14px;\r\n    border-radius: 999px;\r\n    margin: 24px auto 0 auto; \/* descendues pour plus d'espace sous la barre *\/\r\n    background: rgba(255,255,255,0.28);\r\n  }\r\n  .apulia-tick.major .line{\r\n    height: 18px;\r\n    background: rgba(255,255,255,0.40);\r\n  }\r\n\r\n  .apulia-tick .lbl{\r\n    display:block;\r\n    font-weight: 950;\r\n    font-size: 12px;\r\n    opacity: .92;\r\n    background: transparent !important;\r\n    margin-top: 22px; \/* espace vertical augment\u00e9 entre barre et heures (8-12px) *\/\r\n  }\r\n\r\n  \/* Thumb triangle invers\u00e9 (\u25bc) align\u00e9 sur la ligne sup\u00e9rieure de la barre *\/\r\n  .apulia-thumb{\r\n    position:absolute;\r\n    top: 16px; \/* align\u00e9 sur la ligne sup\u00e9rieure de la barre (bar top 16px) - sommet du triangle touche la barre *\/\r\n    width: 0;\r\n    height: 0;\r\n    border-left: 6px solid transparent;\r\n    border-right: 6px solid transparent;\r\n    border-top: 10px solid var(--orange);\r\n    background: transparent;\r\n    border-radius: 0;\r\n    box-shadow: 0 2px 8px rgba(0,0,0,0.20);\r\n    transform: translateX(-9999px);\r\n    pointer-events:none;\r\n  }\r\n\r\n  .apulia-tick.active .line{ background: rgba(246,166,35,0.95); }\r\n  .apulia-tick.active .lbl{ color: rgba(246,166,35,0.98); opacity: 1; }\r\n\r\n  #apulia-map-pro .leaflet-popup-content-wrapper{\r\n    background: linear-gradient(180deg, var(--teal1) 0%, var(--teal3) 100%) !important;\r\n    color:#fff !important;\r\n    border-radius: 18px !important;\r\n    border: 1px solid rgba(255,255,255,0.14) !important;\r\n    box-shadow: var(--shadow) !important;\r\n    overflow:hidden;\r\n  }\r\n  #apulia-map-pro .leaflet-popup-tip{\r\n    background: linear-gradient(180deg, var(--teal1) 0%, var(--teal3) 100%) !important;\r\n    border: 1px solid rgba(255,255,255,0.14) !important;\r\n  }\r\n  #apulia-map-pro .leaflet-popup-content{ margin: 12px !important; }\r\n\r\n  .apulia-popup{\r\n    width: 260px;\r\n    font-family: system-ui,-apple-system,Segoe UI,Roboto,Arial;\r\n    color:#fff;\r\n  }\r\n  .apulia-popup .img{\r\n    width:100%;\r\n    height:120px;\r\n    border-radius: 14px;\r\n    overflow:hidden;\r\n    background: rgba(255,255,255,0.08);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    margin-bottom:10px;\r\n  }\r\n  .apulia-popup .img img{ width:100%; height:100%; object-fit:cover; display:block; }\r\n\r\n  .apulia-popup .name{ font-weight:1000; font-size:14px; color:#fff; margin:0 0 6px 0; }\r\n\r\n  .apulia-popup .meta{\r\n    font-weight:900;\r\n    font-size:12px;\r\n    opacity:.92;\r\n    margin:0 0 10px 0;\r\n    color: rgba(255,255,255,0.92);\r\n    line-height: 1.28;\r\n  }\r\n\r\n  .apulia-dot{\r\n    width:10px;height:10px;border-radius:999px;\r\n    display:inline-block;\r\n    margin: 0 6px 0 0;\r\n    vertical-align: -1px;\r\n    border: 1px solid rgba(0,0,0,0.15);\r\n  }\r\n\r\n  .apulia-popup .cta{ display:flex; gap:10px; }\r\n  .apulia-popup .btn{\r\n    border:0; border-radius: 999px; padding:10px 12px; font-weight:1000;\r\n    cursor:pointer; -webkit-tap-highlight-color: transparent; flex:1;\r\n  }\r\n  .apulia-popup .btn.primary{ background: var(--orange); color:#001D26; }\r\n  .apulia-popup .btn.ghost{\r\n    background: rgba(255,255,255,0.10);\r\n    color:#fff;\r\n    border:1px solid rgba(255,255,255,0.14);\r\n  }\r\n\r\n  .apulia-sheet-backdrop{\r\n    position:absolute;\r\n    inset:0;\r\n    background: rgba(0,0,0,0.32);\r\n    z-index: 12000;\r\n    display:none;\r\n  }\r\n  .apulia-sheet-backdrop.show{ display:block; }\r\n\r\n  .apulia-sheet{\r\n    position:absolute;\r\n    left: 12px;\r\n    right: 12px;\r\n    bottom: 14px;\r\n    z-index: 12001;\r\n    border-radius: 22px;\r\n    background: linear-gradient(180deg, var(--teal1) 0%, var(--teal3) 100%);\r\n    box-shadow: var(--shadow);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    transform: translateY(110%);\r\n    transition: transform .22s ease;\r\n    overflow:hidden;\r\n    color: #fff;\r\n    max-height: 78vh;\r\n    display:flex;\r\n    flex-direction:column;\r\n    pointer-events: none;\r\n  }\r\n  .apulia-sheet.show{ transform: translateY(0); pointer-events: auto; }\r\n\r\n  .apulia-sheet .grab{\r\n    width:52px;height:5px;border-radius:999px;\r\n    background: rgba(255,255,255,0.22);\r\n    margin: 10px auto 6px auto;\r\n    flex: 0 0 auto;\r\n  }\r\n\r\n  .apulia-sheet .head{\r\n    padding: 6px 14px 0 14px;\r\n    flex: 0 0 auto;\r\n  }\r\n  .apulia-sheet .title{ font-size:18px; font-weight:1000; margin: 8px 0 6px 0; color:#fff; }\r\n  .apulia-sheet .desc{\r\n    margin:0 0 12px 0;\r\n    color: rgba(255,255,255,0.86);\r\n    font-weight:850;\r\n    font-size:13px;\r\n    line-height:1.3;\r\n  }\r\n\r\n  .apulia-sheet .body{\r\n    padding: 0 14px 16px 14px;\r\n    overflow:auto;\r\n    -webkit-overflow-scrolling: touch;\r\n    flex: 1 1 auto;\r\n  }\r\n\r\n  .apulia-sheet-top{\r\n    display:flex;\r\n    align-items:center;\r\n    gap:10px;\r\n    padding: 2px 14px 0 14px;\r\n    flex: 0 0 auto;\r\n  }\r\n  .apulia-sheet-backbtn{\r\n    border:0;\r\n    background: transparent;\r\n    color: var(--orange);\r\n    font-weight:1000;\r\n    font-size: 28px;\r\n    line-height: 1;\r\n    padding: 6px 6px;\r\n    cursor:pointer;\r\n    -webkit-tap-highlight-color: transparent;\r\n  }\r\n  .apulia-sheet-close{\r\n    position:absolute;\r\n    top: 8px;\r\n    right: 10px;\r\n    width: 36px;\r\n    height: 36px;\r\n    border: 0;\r\n    border-radius: 999px;\r\n    background: rgba(255,255,255,0.10);\r\n    color: var(--orange);\r\n    font-size: 22px;\r\n    font-weight: 1000;\r\n    line-height: 1;\r\n    cursor: pointer;\r\n    z-index: 2;\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    -webkit-tap-highlight-color: transparent;\r\n  }\r\n  .apulia-sheet-close:active{ transform: scale(0.96); }\r\n  .apulia-sheet .head,\r\n  .apulia-sheet-top{\r\n    padding-right: 48px;\r\n  }\r\n  .apulia-sheet-h{\r\n    font-weight:1000;\r\n    font-size:18px;\r\n    color:#fff;\r\n  }\r\n\r\n  .apulia-report-grid{\r\n    display:flex;\r\n    gap:14px;\r\n    padding: 10px 14px 16px 14px;\r\n    flex-wrap:wrap;\r\n    justify-content:space-between;\r\n  }\r\n  .apulia-report-item{\r\n    width: calc(25% - 11px);\r\n    min-width: 72px;\r\n    display:flex;\r\n    flex-direction:column;\r\n    align-items:center;\r\n    gap:10px;\r\n    padding: 10px 8px;\r\n    border-radius: 18px;\r\n    background: rgba(255,255,255,0.10);\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    cursor:pointer;\r\n    -webkit-tap-highlight-color: transparent;\r\n  }\r\n  .apulia-report-item:active{ transform: scale(0.99); }\r\n  .apulia-report-item .ico{\r\n    width:54px;height:54px;border-radius:999px;\r\n    display:flex;align-items:center;justify-content:center;\r\n    background: rgba(255,255,255,0.14);\r\n    font-size:28px;\r\n  }\r\n  .apulia-report-item .lbl{\r\n    font-weight:1000;\r\n    color:#fff;\r\n    font-size:12px;\r\n    text-align:center;\r\n  }\r\n\r\n  .apulia-card{\r\n    border-radius: 18px;\r\n    border: 1px solid rgba(255,255,255,0.14);\r\n    background: rgba(255,255,255,0.08);\r\n    padding: 14px;\r\n    margin-bottom: 12px;\r\n  }\r\n  .apulia-card .ct{ font-weight:1000; color:#fff; font-size:16px; margin: 0 0 10px 0; }\r\n  .apulia-row{ display:flex; gap:12px; align-items:flex-start; margin: 10px 0; }\r\n  .apulia-badge{\r\n    width:14px;height:14px;border-radius:999px;\r\n    margin-top: 3px;\r\n    border:1px solid rgba(0,0,0,0.10);\r\n    flex:0 0 auto;\r\n  }\r\n  .b-green{ background:#2fd16a; }\r\n  .b-blue{ background:#2aa8ff; }\r\n  .b-orange{ background:#F6A623; }\r\n  .b-red{ background:#ff3b30; }\r\n  .apulia-row .txt{\r\n    color: rgba(255,255,255,0.90);\r\n    font-weight:850;\r\n    font-size:13px;\r\n    line-height:1.35;\r\n  }\r\n  .apulia-row .txt strong{ color:#fff; font-weight:1000; }\r\n\r\n  @media (max-width: 520px), (display-mode: standalone){\r\n    .apulia-bottom-btn{\r\n      bottom: 108px; \/* descendu de 20px sur mobile\/PWA (\u00e9tait 128px) *\/\r\n    }\r\n  }\r\n  @media (max-width: 380px){\r\n    .apulia-live-pill{ min-width: 72px; }\r\n    .apulia-timeline{ min-height: 80px; padding: 10px 10px; }\r\n  }\r\n  @media (min-width: 900px){\r\n    .apulia-ui{ left:16px; right:16px; top:16px; }\r\n    .apulia-weather-top{ left:16px; right:16px; top:16px; }\r\n    .apulia-fab-col.right{ right:16px; top:98px; }\r\n    .apulia-bottom-btn.left{ left:16px; }\r\n    .apulia-bottom-btn.right{ right:16px; }\r\n    .apulia-bottom{ padding: 12px 16px 16px 16px; }\r\n    .apulia-zone-banner{ top: 100px; }\r\n    .apulia-ui{ gap:12px; }\r\n    .apulia-timeline{ padding: 12px 12px; min-height: 88px; }\r\n  }\r\n<\/style>\r\n\r\n<link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\">\r\n<script src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\"><\/script>\r\n\r\n<script>\r\n(function(){\r\n  const root = document.getElementById('apulia-map-pro');\r\n  if(!root) return;\r\n\r\n  function T(key, vars){\r\n    var api = window.ApuliaI18n || window.ApuliaI18nPlage || window.ApuliaI18nCompte;\r\n    if(api && typeof api.t === 'function') return api.t(key, vars);\r\n    return key;\r\n  }\r\n\r\n  function translateSeaLabel(raw){\r\n    var api = window.ApuliaI18n || window.ApuliaI18nPlage || window.ApuliaI18nCompte;\r\n    if(api && typeof api.translateSeaLabel === 'function') return api.translateSeaLabel(raw);\r\n    return raw || T('plage.conditions_unknown');\r\n  }\r\n\r\n  function zoneLabel(key){\r\n    var api = window.ApuliaI18n || window.ApuliaI18nPlage || window.ApuliaI18nCompte;\r\n    if(api && typeof api.zoneLabel === 'function') return api.zoneLabel(key);\r\n    return key;\r\n  }\r\n\r\n  function dowShort(d){\r\n    var api = window.ApuliaI18n || window.ApuliaI18nPlage || window.ApuliaI18nCompte;\r\n    if(api && typeof api.dowShort === 'function') return api.dowShort(d);\r\n    const map = ['DIM','LUN','MAR','MER','JEU','VEN','SAM'];\r\n    return map[d.getDay()] || '\u2014';\r\n  }\r\n\r\n  const leafletEl = document.getElementById('apulia-leaflet');\r\n  if(!leafletEl) return;\r\n\r\n  \/\/ Nettoyage (si recollage)\r\n  [...root.querySelectorAll('.apulia-ui, .apulia-weather-top, .apulia-drawer, .apulia-bottom-btn, .apulia-fab-col, .apulia-bottom, .apulia-sheet-backdrop, .apulia-sheet')]\r\n    .forEach(n => n.remove());\r\n\r\n  root.insertAdjacentHTML('beforeend', `\r\n    <div class=\"apulia-weather-top\" id=\"apuliaWeatherTop\">\r\n      <div class=\"apulia-weather-strip\" id=\"apuliaWeatherStrip\" data-apulia-i18n-aria=\"plage.weather_aria\" aria-label=\"Conditions m\u00e9t\u00e9o par zone\">\r\n        <div class=\"apulia-weather-zone\"><div class=\"wz-name\" data-apulia-dynamic>Nord<\/div><div class=\"wz-main\">\u2014<\/div><div class=\"wz-sub\" data-apulia-dynamic>chargement<\/div><\/div>\r\n        <div class=\"apulia-weather-zone\"><div class=\"wz-name\" data-apulia-dynamic>Centre<\/div><div class=\"wz-main\">\u2014<\/div><div class=\"wz-sub\" data-apulia-dynamic>chargement<\/div><\/div>\r\n        <div class=\"apulia-weather-zone\"><div class=\"wz-name\" data-apulia-dynamic>Sud<\/div><div class=\"wz-main\">\u2014<\/div><div class=\"wz-sub\" data-apulia-dynamic>chargement<\/div><\/div>\r\n      <\/div>\r\n    <\/div>\r\n\r\n\r\n    <div id=\"apuliaDrawer\" class=\"apulia-drawer\" aria-label=\"Filtres\">\r\n      <h3>Filtres<\/h3>\r\n      <div class=\"apulia-chips\" id=\"apuliaChips\">\r\n        <div class=\"apulia-chip active\" data-filter=\"all\">Toutes<\/div>\r\n        <div class=\"apulia-chip\" data-filter=\"adriatic\">Adriatique<\/div>\r\n        <div class=\"apulia-chip\" data-filter=\"ionian\">Ionienne<\/div>\r\n        <div class=\"apulia-chip\" data-filter=\"family\">Famille<\/div>\r\n        <div class=\"apulia-chip\" data-filter=\"wild\">Sauvage<\/div>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"apulia-bottom-btn left\" id=\"apuliaBottomLeft\">\r\n      <button class=\"apulia-fab info\" id=\"apuliaInfoBtn\" type=\"button\" data-apulia-i18n-title=\"plage.legend\" data-apulia-i18n-aria=\"plage.legend\" title=\"L\u00e9gende\" aria-label=\"L\u00e9gende\">i<\/button>\r\n    <\/div>\r\n\r\n    <div class=\"apulia-bottom-btn right\" id=\"apuliaBottomRight\">\r\n      <button class=\"apulia-fab danger\" id=\"apuliaReportBtn\" type=\"button\" data-apulia-i18n-title=\"plage.reports\" data-apulia-i18n-aria=\"plage.reports\" title=\"Signalements\" aria-label=\"Signalements\">\r\n        <svg class=\"apulia-danger-ico\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\r\n          <path d=\"M12 3.2 L21 20.5 H3 Z\"><\/path>\r\n          <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"14\"><\/line>\r\n          <circle cx=\"12\" cy=\"17\" r=\"1\"><\/circle>\r\n        <\/svg>\r\n      <\/button>\r\n    <\/div>\r\n\r\n    <div class=\"apulia-fab-col right\" id=\"apuliaFabRight\">\r\n      <button class=\"apulia-fab\" id=\"apuliaLayerBtn\" type=\"button\" data-apulia-i18n-title=\"plage.layer_toggle\" data-apulia-i18n-aria=\"plage.layer_toggle\" title=\"Style jour\/nuit\" aria-label=\"Style jour\/nuit\">\ud83c\udf13<\/button>\r\n      <button class=\"apulia-fab\" id=\"apuliaBeachBtn\" type=\"button\" data-apulia-i18n-title=\"plage.beaches_btn\" data-apulia-i18n-aria=\"plage.beaches_btn\" title=\"Plages\" aria-label=\"Plages\">\ud83c\udfd6\ufe0f<\/button>\r\n      <button class=\"apulia-fab\" id=\"apuliaLocateBtn\" type=\"button\" data-apulia-i18n-title=\"plage.locate\" data-apulia-i18n-aria=\"plage.locate\" title=\"Me localiser\" aria-label=\"Me localiser\">\u2316<\/button>\r\n    <\/div>\r\n\r\n    <div class=\"apulia-bottom\" id=\"apuliaBottom\">\r\n      <div class=\"apulia-bottom-inner\" id=\"apuliaBottomUI\">\r\n\r\n\r\n        <div class=\"apulia-conditions-stack\" id=\"apuliaConditionsStack\">\r\n          <div class=\"apulia-spotlight\" id=\"apuliaSpotlight\" data-apulia-i18n-aria=\"plage.spotlight_aria\" aria-label=\"Plage id\u00e9ale selon les conditions\">\r\n            <div class=\"apulia-spotlight-empty\" data-apulia-dynamic>Analyse des conditions en cours\u2026<\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"apulia-timeline\" id=\"apuliaTimeline\" data-apulia-i18n-aria=\"plage.timeline_aria\" aria-label=\"Timeline 72h (pas 3h)\">\r\n          <button class=\"apulia-live-pill\" id=\"apuliaLiveBtn\" type=\"button\" data-apulia-i18n-aria=\"plage.live_back_aria\" aria-label=\"Revenir en Live\" data-apulia-dynamic>\r\n            <span class=\"apulia-live-dot\"><\/span> LIVE\r\n          <\/button>\r\n\r\n          <div class=\"apulia-track-wrap\">\r\n            <div class=\"apulia-day-strip\" id=\"apuliaDayStrip\">\r\n              <div class=\"apulia-day-current\" id=\"apuliaDayCurrent\">\u2014<\/div>\r\n              <div class=\"inner\" id=\"apuliaDayInner\"><\/div>\r\n            <\/div>\r\n\r\n            <div class=\"apulia-rail\" id=\"apuliaTimeRail\" role=\"listbox\" data-apulia-i18n-aria=\"plage.timeline_hours_aria\" aria-label=\"Heures (72h, pas 3h)\">\r\n              <div class=\"apulia-ticks\" id=\"apuliaTicks\"><\/div>\r\n            <\/div>\r\n\r\n            <div class=\"apulia-bar\" aria-hidden=\"true\"><i id=\"apuliaFill\"><\/i><\/div>\r\n            <div class=\"apulia-thumb\" id=\"apuliaThumb\" aria-hidden=\"true\"><\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"apuliaBackdrop\" class=\"apulia-sheet-backdrop\"><\/div>\r\n\r\n    <div id=\"apuliaReportSheet\" class=\"apulia-sheet\" role=\"dialog\" data-apulia-i18n-aria=\"plage.reports\" aria-label=\"Signalements\">\r\n      <button class=\"apulia-sheet-close\" type=\"button\" data-apulia-i18n-aria=\"plage.close\" aria-label=\"Fermer\">\u00d7<\/button>\r\n      <div class=\"grab\"><\/div>\r\n      <div class=\"head\">\r\n        <div class=\"title\" data-apulia-i18n=\"plage.reports_title\">Signalements<\/div>\r\n        <div class=\"desc\" data-apulia-i18n=\"plage.reports_desc\">Votre contribution compte. Signalez en 1 clic pour aider la communaut\u00e9.<\/div>\r\n      <\/div>\r\n      <div class=\"apulia-report-grid\">\r\n        <div class=\"apulia-report-item\" data-report=\"video\">\r\n          <div class=\"ico\">\ud83d\udcf9<\/div>\r\n          <div class=\"lbl\" data-apulia-i18n=\"plage.report.video\">Vid\u00e9o<\/div>\r\n        <\/div>\r\n        <div class=\"apulia-report-item\" data-report=\"jellyfish\">\r\n          <div class=\"ico\">\ud83e\udebc<\/div>\r\n          <div class=\"lbl\" data-apulia-i18n=\"plage.report.jellyfish\">M\u00e9duses<\/div>\r\n        <\/div>\r\n        <div class=\"apulia-report-item\" data-report=\"algae\">\r\n          <div class=\"ico\">\ud83c\udf3f<\/div>\r\n          <div class=\"lbl\" data-apulia-i18n=\"plage.report.algae\">Algues<\/div>\r\n        <\/div>\r\n        <div class=\"apulia-report-item\" data-report=\"trash\">\r\n          <div class=\"ico\">\ud83d\uddd1\ufe0f<\/div>\r\n          <div class=\"lbl\" data-apulia-i18n=\"plage.report.trash\">D\u00e9chets<\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <div id=\"apuliaLegendSheet\" class=\"apulia-sheet\" role=\"dialog\" data-apulia-i18n-aria=\"plage.legend\" aria-label=\"L\u00e9gende\">\r\n      <button class=\"apulia-sheet-close\" type=\"button\" data-apulia-i18n-aria=\"plage.close\" aria-label=\"Fermer\">\u00d7<\/button>\r\n      <div class=\"grab\"><\/div>\r\n      <div class=\"apulia-sheet-top\">\r\n        <div class=\"apulia-sheet-h\" data-apulia-i18n=\"plage.legend\">L\u00e9gende<\/div>\r\n      <\/div>\r\n      <div class=\"body\">\r\n        <div class=\"apulia-card\">\r\n          <div class=\"ct\" data-apulia-i18n=\"plage.legend_sea_colors\">Les couleurs (\u00e9tat de la mer)<\/div>\r\n          <div class=\"apulia-row\">\r\n            <span class=\"apulia-badge b-green\"><\/span>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.sea.calm_row\"><strong>Mer calme<\/strong> \u2014 id\u00e9ale pour la baignade, confort maximal.<\/div>\r\n          <\/div>\r\n          <div class=\"apulia-row\">\r\n            <span class=\"apulia-badge b-blue\"><\/span>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.sea.light_row\"><strong>Mer peu agit\u00e9e<\/strong> \u2014 petites vagues, agr\u00e9able mais variable.<\/div>\r\n          <\/div>\r\n          <div class=\"apulia-row\">\r\n            <span class=\"apulia-badge b-orange\"><\/span>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.sea.rough_row\"><strong>Mer agit\u00e9e<\/strong> \u2014 houle marqu\u00e9e, prudence recommand\u00e9e.<\/div>\r\n          <\/div>\r\n          <div class=\"apulia-row\">\r\n            <span class=\"apulia-badge b-red\"><\/span>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.sea.strong_row\"><strong>Mer forte<\/strong> \u2014 baignade d\u00e9conseill\u00e9e, restez en s\u00e9curit\u00e9.<\/div>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"apulia-card\">\r\n          <div class=\"ct\" data-apulia-i18n=\"plage.legend_reports\">Signalements<\/div>\r\n          <div class=\"apulia-row\">\r\n            <div style=\"font-size:18px; width:18px;\">\ud83e\udebc<\/div>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.legend.jellyfish_row\"><strong>M\u00e9duses<\/strong> \u2014 pr\u00e9sence signal\u00e9e par la communaut\u00e9.<\/div>\r\n          <\/div>\r\n          <div class=\"apulia-row\">\r\n            <div style=\"font-size:18px; width:18px;\">\ud83c\udf3f<\/div>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.legend.algae_row\"><strong>Algues \/ mucilage<\/strong> \u2014 pr\u00e9sence signal\u00e9e dans la zone.<\/div>\r\n          <\/div>\r\n          <div class=\"apulia-row\">\r\n            <div style=\"font-size:18px; width:18px;\">\ud83d\uddd1\ufe0f<\/div>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.legend.trash_row\"><strong>D\u00e9chets<\/strong> \u2014 zone \u00e0 v\u00e9rifier avant de vous d\u00e9placer.<\/div>\r\n          <\/div>\r\n          <div class=\"apulia-row\">\r\n            <div style=\"font-size:18px; width:18px;\">\ud83d\udcf9<\/div>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.legend.video_row\"><strong>Vid\u00e9o<\/strong> \u2014 aper\u00e7u r\u00e9el utile avant de partir.<\/div>\r\n          <\/div>\r\n          <div class=\"apulia-row\">\r\n            <div style=\"font-size:18px; width:18px;\">\ud83d\udd14<\/div>\r\n            <div class=\"txt\" data-apulia-i18n-html=\"plage.legend.reliability_row\"><strong>Fiabilit\u00e9<\/strong> \u2014 les conditions changent vite : comparez plusieurs indices.<\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/div>\r\n  `);\r\n\r\n  function applyPlageBootI18n(){\r\n    const fb = document.getElementById('apuliaFiltersBtn');\r\n    if(fb) fb.innerHTML = T('plage.filters_btn') + ' <span aria-hidden=\"true\">\ud83c\udf9a\ufe0f<\/span>';\r\n    const search = document.getElementById('apuliaSearch');\r\n    if(search) search.placeholder = T('plage.search_placeholder');\r\n    const empty = document.querySelector('#apuliaSpotlight .apulia-spotlight-empty');\r\n    if(empty) empty.textContent = T('plage.spotlight_analyzing');\r\n    const liveBtnEl = document.getElementById('apuliaLiveBtn');\r\n    if(liveBtnEl) liveBtnEl.innerHTML = '<span class=\"apulia-live-dot\"><\/span> ' + T('plage.live');\r\n    const api = window.ApuliaI18n || window.ApuliaI18nPlage || window.ApuliaI18nCompte;\r\n    if(api && api.hydrate) api.hydrate(root);\r\n  }\r\n\r\n  applyPlageBootI18n();\r\n\r\n  \/\/ ===== Leaflet init\r\n  if (leafletEl._leaflet_map) {\r\n    try { leafletEl._leaflet_map.remove(); } catch(e){}\r\n    leafletEl._leaflet_map = null;\r\n  }\r\n\r\n  const map = L.map(leafletEl, {\r\n    zoomControl: false,\r\n    attributionControl: false,\r\n    inertia: true,\r\n    preferCanvas: true\r\n  }).setView([40.35, 17.65], 8);\r\n  leafletEl._leaflet_map = map;\r\n\r\n  const day = L.tileLayer(\r\n    'https:\/\/{s}.basemaps.cartocdn.com\/rastertiles\/voyager\/{z}\/{x}\/{y}{r}.png?key=cb1_2mol_1_b159c7f7cb30e5aea343d4fd',\r\n    { subdomains: 'abcd', maxZoom: 19, opacity: 1 }\r\n  );\r\n  const night = L.tileLayer(\r\n    'https:\/\/{s}.basemaps.cartocdn.com\/rastertiles\/dark_all\/{z}\/{x}\/{y}{r}.png?key=cb1_2mol_1_b159c7f7cb30e5aea343d4fd',\r\n    { subdomains: 'abcd', maxZoom: 19, opacity: 0.90 }\r\n  );\r\n\r\n  let isNight = false;\r\n  let manualLayerOverride = false;\r\n  day.addTo(map);\r\n\r\n  function setLayerNight(on){\r\n    const want = !!on;\r\n    if(want === isNight) return;\r\n    isNight = want;\r\n    if(isNight){ try{ map.removeLayer(day); }catch(e){} night.addTo(map); }\r\n    else { try{ map.removeLayer(night); }catch(e){} day.addTo(map); }\r\n  }\r\n\r\n  const ui = document.getElementById('apuliaUI');\r\n  const drawer = document.getElementById('apuliaDrawer');\r\n  const fabR = document.getElementById('apuliaFabRight');\r\n  const bottomUI = document.getElementById('apuliaBottomUI');\r\n  const bottomLeft = document.getElementById('apuliaBottomLeft');\r\n  const bottomRight = document.getElementById('apuliaBottomRight');\r\n\r\n  [ui, drawer, fabR, bottomUI, bottomLeft, bottomRight, document.getElementById('apuliaWeatherTop')].forEach(node=>{\r\n    if(!node) return;\r\n    L.DomEvent.disableClickPropagation(node);\r\n    L.DomEvent.disableScrollPropagation(node);\r\n  });\r\n\r\n  \/\/ ===== Places\r\n  const PLACES = [\r\n    { name:'Taranto', lat:40.468, lon:17.241, z:11 },\r\n    { name:'Lecce', lat:40.352, lon:18.174, z:12 },\r\n    { name:'Brindisi', lat:40.638, lon:17.945, z:12 },\r\n    { name:'Bari', lat:41.126, lon:16.868, z:12 },\r\n    { name:'Otranto', lat:40.148, lon:18.491, z:13 },\r\n    { name:'Gallipoli', lat:40.055, lon:17.989, z:13 },\r\n    { name:'Porto Cesareo', lat:40.262, lon:17.898, z:13 }\r\n  ];\r\n\r\n  \/\/ ===== Data endpoints\r\n  let BEACHES = [];\r\n  const BEACHES_API = 'https:\/\/lespouilles.blog\/wp-json\/apulia\/v1\/beaches';\r\n  const MARINE_API  = 'https:\/\/lespouilles.blog\/wp-json\/apulia\/v1\/marine';\r\n\r\n  function numOrNull(v){\r\n    if(v === null || v === undefined) return null;\r\n    const n = parseFloat(String(v).replace(',', '.'));\r\n    return Number.isFinite(n) ? n : null;\r\n  }\r\n  function pick(obj, keys){\r\n    for(const k of keys){\r\n      if(obj && obj[k] !== undefined && obj[k] !== null && obj[k] !== '') return obj[k];\r\n    }\r\n    return null;\r\n  }\r\n  function normalizeBeach(it){\r\n    const acf = it && it.acf ? it.acf : it;\r\n\r\n    const lat = numOrNull(pick(acf, ['latitude_lat','lat','latitude']));\r\n    const lon = numOrNull(pick(acf, ['longitude_lng','lng','lon','longitude']));\r\n    if(lat === null || lon === null) return null;\r\n\r\n    const name = pick(it, ['title','name']) || pick(acf, ['name','titre','title']) || T('plage.beach_default');\r\n    const url  = pick(it, ['permalink','url','link']) || '#';\r\n\r\n    const img = pick(it, ['featured_image','featured-image','image','img']) ||\r\n                (it && it.featured && it.featured.url ? it.featured.url : null) ||\r\n                (acf && acf['featured-image'] ? acf['featured-image'] : null) ||\r\n                null;\r\n\r\n    const type = pick(it, ['type','coast','cote']) || pick(acf, ['type','coast','cote']) || 'all';\r\n\r\n    return {\r\n      id: String(pick(it, ['id','post_id','ID']) || name).toLowerCase().replace(\/\\s+\/g,'-'),\r\n      name: String(name),\r\n      lat, lon,\r\n      type: String(type),\r\n      img: img ? String(img) : '',\r\n      url: String(url)\r\n    };\r\n  }\r\n\r\n  async function loadBeaches(){\r\n    try{\r\n      const r = await fetch(`${BEACHES_API}?_=${Date.now()}`, {\r\n        credentials: 'omit',\r\n        cache: 'no-store',\r\n        mode: 'cors'\r\n      });\r\n      if(!r.ok) throw new Error('HTTP '+r.status);\r\n      const data = await r.json();\r\n      const items = (data && Array.isArray(data.items)) ? data.items : (Array.isArray(data) ? data : []);\r\n      const list = [];\r\n      for(const it of items){\r\n        const b = normalizeBeach(it);\r\n        if(b) list.push(b);\r\n      }\r\n      BEACHES = list;\r\n    }catch(e){\r\n      console.error('[Beaches API] error:', e);\r\n      BEACHES = [];\r\n    }\r\n  }\r\n\r\n  \/\/ ===== Marine snapshot cache\r\n  let marineSnap = { tz: 'Europe\/Rome', points: [] };\r\n\r\n  \/\/ ===== M\u00e9t\u00e9o par zone (Nord \/ Centre \/ Sud)\r\n  \/\/ Source m\u00e9t\u00e9o r\u00e9elle pour le bandeau horizontal NORD \/ CENTRE \/ SUD.\r\n  const WEATHER_ZONES = [\r\n    { key:'Nord', lat:41.126, lon:16.868 },\r\n    { key:'Centre', lat:40.638, lon:17.945 },\r\n    { key:'Sud', lat:39.930, lon:18.355 }\r\n  ];\r\n  let weatherSnap = { hour:'', zones: [] };\r\n  const weatherCache = new Map();\r\n\r\n  function dateKeyFromLocalHour(hourLocalISO){\r\n    return String(hourLocalISO || '').slice(0, 10);\r\n  }\r\n\r\n  function weatherEmoji(code){\r\n    const c = Number(code);\r\n    if(!Number.isFinite(c)) return '\u2600\ufe0f';\r\n    if(c === 0) return '\u2600\ufe0f';\r\n    if([1,2].includes(c)) return '\ud83c\udf24\ufe0f';\r\n    if(c === 3) return '\u2601\ufe0f';\r\n    if([45,48].includes(c)) return '\ud83c\udf2b\ufe0f';\r\n    if([51,53,55,56,57,61,63,65,66,67,80,81,82].includes(c)) return '\ud83c\udf27\ufe0f';\r\n    if([71,73,75,77,85,86].includes(c)) return '\u2744\ufe0f';\r\n    if([95,96,99].includes(c)) return '\u26c8\ufe0f';\r\n    return '\ud83c\udf24\ufe0f';\r\n  }\r\n\r\n  function closestHourlyIndex(times, targetHour){\r\n    if(!Array.isArray(times) || !times.length) return -1;\r\n    const target = String(targetHour || '').slice(0, 13);\r\n    let idx = times.findIndex(t => String(t).slice(0, 13) === target);\r\n    if(idx >= 0) return idx;\r\n    const targetMs = new Date(String(targetHour || '').replace('T',' ') + ':00').getTime();\r\n    if(!Number.isFinite(targetMs)) return 0;\r\n    let best = 0;\r\n    let bestDist = Infinity;\r\n    times.forEach((t, i)=>{\r\n      const ms = new Date(String(t).replace('T',' ') + ':00').getTime();\r\n      const dist = Math.abs(ms - targetMs);\r\n      if(dist < bestDist){ bestDist = dist; best = i; }\r\n    });\r\n    return best;\r\n  }\r\n\r\n  async function loadWeatherZonesForHour(hourLocalISO){\r\n    const hourKey = String(hourLocalISO || '').slice(0, 13);\r\n    if(weatherCache.has(hourKey)){\r\n      weatherSnap = weatherCache.get(hourKey);\r\n      return;\r\n    }\r\n\r\n    const lats = WEATHER_ZONES.map(z=>z.lat).join(',');\r\n    const lons = WEATHER_ZONES.map(z=>z.lon).join(',');\r\n    const dayKey = dateKeyFromLocalHour(hourLocalISO);\r\n    const url =\r\n      `https:\/\/api.open-meteo.com\/v1\/forecast?latitude=${encodeURIComponent(lats)}` +\r\n      `&longitude=${encodeURIComponent(lons)}` +\r\n      `&hourly=temperature_2m,precipitation_probability,weather_code,wind_speed_10m` +\r\n      `&timezone=Europe%2FRome&start_date=${encodeURIComponent(dayKey)}&end_date=${encodeURIComponent(dayKey)}`;\r\n\r\n    try{\r\n      const r = await fetch(url, { credentials:'omit', cache:'no-store', mode:'cors' });\r\n      if(!r.ok) throw new Error('HTTP '+r.status);\r\n      const data = await r.json();\r\n      const blocks = Array.isArray(data) ? data : [data];\r\n\r\n      const zones = WEATHER_ZONES.map((z, zi)=>{\r\n        const block = blocks[zi] || blocks[0] || {};\r\n        const hourly = block.hourly || {};\r\n        const idx = closestHourlyIndex(hourly.time || [], hourLocalISO);\r\n        return {\r\n          key: z.key,\r\n          temp: numOrNull(hourly.temperature_2m && hourly.temperature_2m[idx]),\r\n          rain: numOrNull(hourly.precipitation_probability && hourly.precipitation_probability[idx]),\r\n          wind: numOrNull(hourly.wind_speed_10m && hourly.wind_speed_10m[idx]),\r\n          code: numOrNull(hourly.weather_code && hourly.weather_code[idx])\r\n        };\r\n      });\r\n\r\n      weatherSnap = { hour: hourKey, zones };\r\n      weatherCache.set(hourKey, weatherSnap);\r\n    }catch(e){\r\n      console.error('[Weather API] error:', e);\r\n      weatherSnap = { hour: hourKey, zones: [] };\r\n    }\r\n  }\r\n\r\n  function isoLocalHourStringFromDate(d){\r\n    const y = d.getFullYear();\r\n    const m = String(d.getMonth()+1).padStart(2,'0');\r\n    const day = String(d.getDate()).padStart(2,'0');\r\n    const hh = String(d.getHours()).padStart(2,'0');\r\n    return `${y}-${m}-${day}T${hh}:00`;\r\n  }\r\n\r\n  async function loadMarineSnapshotForHour(hourLocalISO){\r\n    if(!Array.isArray(BEACHES) || BEACHES.length === 0) return;\r\n\r\n    const lats = BEACHES.map(b=>b.lat).join(',');\r\n    const lons = BEACHES.map(b=>b.lon).join(',');\r\n\r\n    const url =\r\n      `${MARINE_API}?lat=${encodeURIComponent(lats)}&lon=${encodeURIComponent(lons)}` +\r\n      `&tz=auto&hour=${encodeURIComponent(hourLocalISO)}` +\r\n      `&_=${Date.now()}`;\r\n\r\n    try{\r\n      const r = await fetch(url, {\r\n        credentials: 'omit',\r\n        cache: 'no-store',\r\n        mode: 'cors'\r\n      });\r\n      if(!r.ok) throw new Error('HTTP '+r.status);\r\n      const data = await r.json();\r\n\r\n      marineSnap = {\r\n        tz: (data && data.timezone) ? data.timezone : 'Europe\/Rome',\r\n        points: (data && Array.isArray(data.points)) ? data.points : []\r\n      };\r\n    }catch(e){\r\n      console.error('[Marine API] error:', e);\r\n      marineSnap = { tz:'Europe\/Rome', points: [] };\r\n    }\r\n  }\r\n\r\n  function getMarinePointForBeach(i){\r\n    const p = marineSnap.points && marineSnap.points[i] ? marineSnap.points[i] : null;\r\n    return p && typeof p === 'object' ? p : null;\r\n  }\r\n\r\n  function gmapsUrl(lat, lon){\r\n    return `https:\/\/www.google.com\/maps\/search\/?api=1&query=${encodeURIComponent(lat + ',' + lon)}`;\r\n  }\r\n\r\n  function pad2(n){ return (n<10?'0':'')+n; }\r\n\r\n  function fmtDayDateShort(d){\r\n    return `${dowShort(d)} ${pad2(d.getDate())}\/${pad2(d.getMonth()+1)}`;\r\n  }\r\n\r\n  function tickLabelForOffset(off){\r\n    if(off === 0) return T('plage.timeline.j');\r\n    if(off === 24) return T('plage.timeline.j1');\r\n    if(off === 48) return T('plage.timeline.j2');\r\n    if(off === 72) return T('plage.timeline.j3');\r\n    return T('plage.timeline.hour', { h: dateForOffset(off).getHours() });\r\n  }\r\n\r\n  function updateTickLabels(){\r\n    if(!ticksEl) return;\r\n    ticksEl.querySelectorAll('.apulia-tick').forEach(btn => {\r\n      const off = parseInt(btn.getAttribute('data-off') || '0', 10);\r\n      const lbl = btn.querySelector('.lbl');\r\n      if(lbl) lbl.textContent = tickLabelForOffset(off);\r\n    });\r\n  }\r\n\r\n  function windDirText(mp){\r\n    const v =\r\n      pick(mp, ['wind_dir_card','wind_dir_cardinal','wind_dir_compass','wind_dir','wind_direction','wind_dir_text']) ||\r\n      null;\r\n\r\n    if(v) return String(v);\r\n\r\n    const deg = numOrNull(pick(mp, ['wind_dir_deg','wind_direction_deg','wind_deg','windDirection']));\r\n    if(deg === null) return '\u2014';\r\n    const dirs = ['N','NE','E','SE','S','SW','W','NW','N'];\r\n    const idx = Math.round((deg % 360) \/ 45);\r\n    return dirs[idx] || '\u2014';\r\n  }\r\n\r\n  function popupHTML(b, mp, hourDisplayText){\r\n    const sea = mp && mp.sea ? mp.sea : null;\r\n    const label = translateSeaLabel(sea && sea.label ? sea.label : null);\r\n    const col   = (sea && sea.color) ? sea.color : '#2aa8ff';\r\n\r\n    const waveM = (mp && mp.wave_height_m !== null && Number.isFinite(Number(mp.wave_height_m))) ? Number(mp.wave_height_m) : null;\r\n    const windKmh = (mp && mp.wind_kmh !== null && Number.isFinite(Number(mp.wind_kmh))) ? Number(mp.wind_kmh) : null;\r\n\r\n    const waveTxt = (waveM !== null) ? `${waveM.toFixed(1)} m` : '\u2014';\r\n    const windTxt = (windKmh !== null) ? `${Math.round(windKmh)} km\/h` : '\u2014';\r\n    const dirTxt  = windDirText(mp);\r\n\r\n    const safeName = (b.name||'').replace(\/\"\/g,'&quot;');\r\n\r\n    return `\r\n      <div class=\"apulia-popup\">\r\n        <div class=\"img\">\r\n          <img decoding=\"async\" src=\"${b.img || ''}\" alt=\"${safeName}\" loading=\"lazy\">\r\n        <\/div>\r\n        <div class=\"name\">${b.name}<\/div>\r\n        <div class=\"meta\">\r\n          <span class=\"apulia-dot\" style=\"background:${col}\"><\/span>\r\n          ${label} \u2022 ${hourDisplayText}<br>\r\n          \ud83c\udf0a ${T('plage.popup.waves')}: ${waveTxt} \u2022 \ud83d\udca8 ${T('plage.popup.wind')}: ${windTxt}<br>\r\n          \ud83e\udded ${T('plage.popup.direction')}: ${dirTxt}\r\n        <\/div>\r\n        <div class=\"cta\">\r\n          <button class=\"btn primary\" type=\"button\" data-apulia-action=\"open\" data-url=\"${b.url || '#'}\">${T('plage.popup.view')}<\/button>\r\n          <button class=\"btn ghost\" type=\"button\" data-apulia-action=\"go\" data-gmaps=\"${gmapsUrl(b.lat,b.lon)}\">${T('plage.popup.go')}<\/button>\r\n        <\/div>\r\n      <\/div>\r\n    `;\r\n  }\r\n\r\n\r\n  function seaRank(sea){\r\n    const label = String((sea && sea.label) ? sea.label : '').toLowerCase();\r\n    const color = String((sea && sea.color) ? sea.color : '').toLowerCase();\r\n    if(color.includes('2fd16a') || label.includes('calme')) return 1;\r\n    if(color.includes('2aa8ff') || label.includes('peu agit')) return 2;\r\n    if(color.includes('f6a623') || label.includes('agit')) return 3;\r\n    if(color.includes('ff3b30') || label.includes('fort')) return 4;\r\n    return 5;\r\n  }\r\n\r\n  function isGoodSea(sea){\r\n    return seaRank(sea) <= 2;\r\n  }\r\n\r\n  function scoreBeachConditions(mp){\r\n    const sea = mp && mp.sea ? mp.sea : null;\r\n    const wave = numOrNull(mp && mp.wave_height_m);\r\n    const wind = numOrNull(mp && mp.wind_kmh);\r\n    let score = 100;\r\n    score -= (seaRank(sea) - 1) * 25;\r\n    if(wave !== null) score -= Math.min(35, wave * 22);\r\n    if(wind !== null) score -= Math.min(25, wind * 0.55);\r\n    return score;\r\n  }\r\n\r\n  function fmtNum(v, decimals){\r\n    const n = numOrNull(v);\r\n    if(n === null) return '\u2014';\r\n    return Number(n).toFixed(decimals).replace('.', ',');\r\n  }\r\n\r\n  function renderWeatherStrip(){\r\n    const strip = document.getElementById('apuliaWeatherStrip');\r\n    if(!strip) return;\r\n\r\n    const liveZones = (weatherSnap && Array.isArray(weatherSnap.zones) && weatherSnap.zones.length) ? weatherSnap.zones : [];\r\n\r\n    \/\/ Fallback si la m\u00e9t\u00e9o externe n'est pas disponible : on affiche au minimum mer + vent depuis le snapshot marine.\r\n    const marineZones = [\r\n      { key:'Nord', items:[] },\r\n      { key:'Centre', items:[] },\r\n      { key:'Sud', items:[] }\r\n    ];\r\n\r\n    (BEACHES || []).forEach((b, i)=>{\r\n      const mp = getMarinePointForBeach(i);\r\n      if(!mp) return;\r\n      if(b.lat >= 41.0) marineZones[0].items.push(mp);\r\n      else if(b.lat >= 40.35) marineZones[1].items.push(mp);\r\n      else marineZones[2].items.push(mp);\r\n    });\r\n\r\n    strip.innerHTML = WEATHER_ZONES.map((base, idx)=>{\r\n      const wz = liveZones.find(z => z.key === base.key) || liveZones[idx] || null;\r\n\r\n      if(wz){\r\n        const icon = weatherEmoji(wz.code);\r\n        const temp = numOrNull(wz.temp);\r\n        const wind = numOrNull(wz.wind);\r\n        const rain = numOrNull(wz.rain);\r\n        const main = `${icon} ${temp !== null ? Math.round(temp) + '\u00b0' : '\u2014'}`;\r\n        const sub = `\ud83d\udca8 ${wind !== null ? Math.round(wind) : '\u2014'} \u00b7 \ud83c\udf27\ufe0f ${rain !== null ? Math.round(rain) + '%' : '\u2014'}`;\r\n        return `<div class=\"apulia-weather-zone\"><div class=\"wz-name\">${zoneLabel(base.key)}<\/div><div class=\"wz-main\">${main}<\/div><div class=\"wz-sub\">${sub}<\/div><\/div>`;\r\n      }\r\n\r\n      const mz = marineZones[idx];\r\n      const items = mz ? mz.items : [];\r\n      if(items.length){\r\n        const winds = items.map(x=>numOrNull(x.wind_kmh)).filter(x=>x!==null);\r\n        const waves = items.map(x=>numOrNull(x.wave_height_m)).filter(x=>x!==null);\r\n        const avgWind = winds.length ? Math.round(winds.reduce((a,b)=>a+b,0)\/winds.length) : null;\r\n        const avgWave = waves.length ? (waves.reduce((a,b)=>a+b,0)\/waves.length) : null;\r\n        const main = `\ud83c\udf0a ${avgWave !== null ? fmtNum(avgWave,1) + ' m' : '\u2014'}`;\r\n        const sub = `\ud83d\udca8 ${avgWind !== null ? avgWind : '\u2014'} \u00b7 \ud83c\udf27\ufe0f \u2014`;\r\n        return `<div class=\"apulia-weather-zone\"><div class=\"wz-name\">${zoneLabel(base.key)}<\/div><div class=\"wz-main\">${main}<\/div><div class=\"wz-sub\">${sub}<\/div><\/div>`;\r\n      }\r\n\r\n      return `<div class=\"apulia-weather-zone\"><div class=\"wz-name\">${zoneLabel(base.key)}<\/div><div class=\"wz-main\">\u2014<\/div><div class=\"wz-sub\">${T('plage.loading')}<\/div><\/div>`;\r\n    }).join('');\r\n  }\r\n\r\n  function resetMarkerFocus(){\r\n    beachMarkers.forEach(x=>{\r\n      if(!x || !x.marker) return;\r\n      try{\r\n        const sea = x.mp && x.mp.sea ? x.mp.sea : null;\r\n        const col = (sea && sea.color) ? sea.color : '#2aa8ff';\r\n        x.marker.setStyle({ radius:9, weight:2, fillColor:col, fillOpacity:0.95, color:'rgba(255,255,255,0.95)' });\r\n      }catch(e){}\r\n    });\r\n  }\r\n\r\n  function setSpotlightFocus(item){\r\n    resetMarkerFocus();\r\n    if(!item || !item.marker) return;\r\n    try{\r\n      item.marker.setStyle({ radius:14, weight:4, fillOpacity:1, color:'rgba(246,166,35,0.98)' });\r\n      item.marker.bringToFront();\r\n    }catch(e){}\r\n  }\r\n\r\n  function renderSpotlight(){\r\n    const box = document.getElementById('apuliaSpotlight');\r\n    if(!box) return;\r\n\r\n    if(!spotlightCandidates.length){\r\n      resetMarkerFocus();\r\n      box.innerHTML = '<div class=\"apulia-spotlight-empty\">' + T('plage.spotlight_empty') + '<\/div>';\r\n      return;\r\n    }\r\n\r\n    if(spotlightIndex >= spotlightCandidates.length) spotlightIndex = 0;\r\n    const item = spotlightCandidates[spotlightIndex];\r\n    const b = item.b;\r\n    const mp = item.mp || {};\r\n    const sea = mp.sea || {};\r\n    const label = translateSeaLabel(sea.label);\r\n    const col = sea.color || '#2aa8ff';\r\n    const waveTxt = fmtNum(mp.wave_height_m, 1) + ' m';\r\n    const windTxt = (()=>{ const n = numOrNull(mp.wind_kmh); return n === null ? '\u2014' : Math.round(n) + ' km\/h'; })();\r\n    const safeName = (b.name || T('plage.beach_default')).replace(\/\"\/g,'&quot;');\r\n    const d = dateForOffset(activeOffset);\r\n    const dateTxt = fmtDayDateShort(d);\r\n\r\n    setSpotlightFocus(item);\r\n\r\n    box.innerHTML = `\r\n      <div class=\"apulia-spotlight-inner\">\r\n        <div class=\"apulia-spotlight-kicker\">${T('plage.spotlight_kicker', { date: dateTxt })}<\/div>\r\n        <div class=\"apulia-spotlight-row\">\r\n          <div class=\"apulia-spotlight-img\"><img decoding=\"async\" src=\"${b.img || ''}\" alt=\"${safeName}\" loading=\"lazy\"><\/div>\r\n          <div class=\"apulia-spotlight-content\">\r\n            <div class=\"apulia-spotlight-name\">${b.name}<\/div>\r\n            <div class=\"apulia-spotlight-sea\"><span class=\"apulia-dot\" style=\"background:${col}\"><\/span>${label}<\/div>\r\n            <div class=\"apulia-spotlight-meta\">\ud83c\udf0a ${waveTxt} \u00b7 \ud83d\udca8 ${windTxt}<\/div>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n    `;\r\n\r\n    box.onclick = ()=>{\r\n      if(b.url && b.url !== '#') window.location.href = b.url;\r\n    };\r\n  }\r\n\r\n\r\n  function coastRouteValue(item){\r\n    const b = item && item.b ? item.b : item;\r\n    if(!b) return 999;\r\n    const lat = Number(b.lat);\r\n    const lon = Number(b.lon);\r\n\r\n    \/\/ Route visuelle voulue : c\u00f4te ionienne depuis Tarente vers le sud,\r\n    \/\/ puis remont\u00e9e c\u00f4t\u00e9 Adriatique. Cela \u00e9vite un balayage gauche\/droite.\r\n    const ionianSide = (lon < 18.30 && lat <= 40.75);\r\n    if(ionianSide){\r\n      \/\/ Tarente \/ Porto Cesareo \/ Gallipoli \/ Leuca : nord -> sud\r\n      return (40.80 - lat) * 100 + Math.max(0, lon - 17.0) * 3;\r\n    }\r\n\r\n    \/\/ Adriatique : Leuca \/ Otranto \/ Lecce \/ Brindisi \/ Bari : sud -> nord\r\n    return 1000 + (lat - 39.70) * 100 + Math.max(0, lon - 18.0) * 2;\r\n  }\r\n\r\n  function restartSpotlightRotation(){\r\n    if(spotlightTimer){ clearInterval(spotlightTimer); spotlightTimer = null; }\r\n    renderSpotlight();\r\n    if(spotlightCandidates.length > 1){\r\n      spotlightTimer = setInterval(()=>{\r\n        spotlightIndex = (spotlightIndex + 1) % spotlightCandidates.length;\r\n        renderSpotlight();\r\n      }, 4000);\r\n    }\r\n  }\r\n\r\n\r\n  let activeFilter = 'all';\r\n\r\n  const markerLayer = L.layerGroup().addTo(map);\r\n  let beachMarkers = [];\r\n  let spotlightCandidates = [];\r\n  let spotlightIndex = 0;\r\n  let spotlightTimer = null;\r\n\r\n  \/\/ ===== Timeline 72h \/ pas 3h\r\n  const rail     = document.getElementById('apuliaTimeRail');\r\n  const ticksEl  = document.getElementById('apuliaTicks');\r\n  const dayInner = document.getElementById('apuliaDayInner');\r\n  const dayCurrentEl = document.getElementById('apuliaDayCurrent');\r\n  const thumb    = document.getElementById('apuliaThumb');\r\n  const fillEl   = document.getElementById('apuliaFill');\r\n  const liveBtn  = document.getElementById('apuliaLiveBtn');\r\n\r\n  const STEP_H = 3;\r\n  const MAX_H  = 72;\r\n\r\n  \/\/ ANCRE = d\u00e9but du jour (00:00)\r\n  function anchorStartOfToday(){\r\n    const d = new Date();\r\n    d.setHours(0,0,0,0);\r\n    return d;\r\n  }\r\n  const ANCHOR = anchorStartOfToday();\r\n\r\n  function clampToStep(off){\r\n    const o = Number(off || 0);\r\n    const clamped = Math.max(0, Math.min(MAX_H, o));\r\n    const snapped = Math.round(clamped \/ STEP_H) * STEP_H;\r\n    return Math.max(0, Math.min(MAX_H, snapped));\r\n  }\r\n\r\n  function dateForOffset(off){\r\n    const d = new Date(ANCHOR.getTime());\r\n    d.setHours(d.getHours() + Number(off || 0));\r\n    return d;\r\n  }\r\n\r\n  function liveOffsetNow(){\r\n    const now = new Date();\r\n    const diffH = (now.getTime() - ANCHOR.getTime()) \/ 3600000;\r\n    return clampToStep(diffH);\r\n  }\r\n\r\n  function hourDisplayTextForOffset(off){\r\n    const d = dateForOffset(off);\r\n    return `${fmtDayDateShort(d)} ${pad2(d.getHours())}:00`;\r\n  }\r\n\r\n  function shouldNightForDate(d){\r\n    const h = d.getHours();\r\n    return (h >= 20 || h <= 6);\r\n  }\r\n\r\n  function dayTextForOffset(off){\r\n    const d = dateForOffset(off);\r\n    return fmtDayDateShort(d);\r\n  }\r\n\r\n  let isLiveMode = true;\r\n  let activeOffset = liveOffsetNow();\r\n  let liveInterval = null;\r\n  let dayChipTimer = null;\r\n\r\n  function setLiveState(on){\r\n    isLiveMode = !!on;\r\n    liveBtn.classList.toggle('active', isLiveMode);\r\n    liveBtn.setAttribute('aria-pressed', isLiveMode ? 'true' : 'false');\r\n    \/\/ Arr\u00eater l'interval si on d\u00e9sactive LIVE\r\n    if(!isLiveMode && liveInterval){\r\n      clearInterval(liveInterval);\r\n      liveInterval = null;\r\n    }\r\n    \/\/ Cacher chip jour en mode LIVE et s'assurer qu'aucun fond persistant ne reste\r\n    if(isLiveMode && dayCurrentEl){\r\n      dayCurrentEl.classList.remove('show');\r\n      if(dayChipTimer) clearTimeout(dayChipTimer);\r\n    }\r\n    \/\/ S'assurer qu'aucun \u00e9tat visuel persistant ne reste apr\u00e8s activation LIVE\r\n    if(isLiveMode){\r\n      requestAnimationFrame(()=>{\r\n        if(liveBtn && isLiveMode){\r\n          liveBtn.style.background = 'rgba(255,255,255,0.08)';\r\n          liveBtn.style.borderColor = 'rgba(255,255,255,0.14)';\r\n        }\r\n      });\r\n    }\r\n  }\r\n\r\n  function showDayChipTemporarily(){\r\n    if(!dayCurrentEl || isLiveMode) return;\r\n    dayCurrentEl.classList.add('show');\r\n    if(dayChipTimer) clearTimeout(dayChipTimer);\r\n    dayChipTimer = setTimeout(()=>{\r\n      if(dayCurrentEl) dayCurrentEl.classList.remove('show');\r\n    }, 1500); \/\/ Auto-hide apr\u00e8s 1500ms\r\n  }\r\n\r\n  function showDayOverlayTemporarily(offset){\r\n    if(!dayCurrentEl || isLiveMode) return;\r\n    const d = dateForOffset(offset);\r\n    dayCurrentEl.textContent = dayTextForOffset(offset);\r\n    dayCurrentEl.classList.add('show');\r\n    if(dayChipTimer) clearTimeout(dayChipTimer);\r\n    dayChipTimer = setTimeout(()=>{\r\n      if(dayCurrentEl) dayCurrentEl.classList.remove('show');\r\n    }, 1500); \/\/ Auto-hide apr\u00e8s 1200-1800ms (1500ms choisi)\r\n  }\r\n\r\n  async function renderMarkers(offsetHours, queryText){\r\n    markerLayer.clearLayers();\r\n    beachMarkers = [];\r\n    spotlightCandidates = [];\r\n\r\n    const q = (queryText || '').trim().toLowerCase();\r\n    if(!Array.isArray(BEACHES) || BEACHES.length === 0) return;\r\n\r\n    const d = dateForOffset(offsetHours);\r\n    const hourISO = isoLocalHourStringFromDate(d);\r\n    await loadMarineSnapshotForHour(hourISO);\r\n    await loadWeatherZonesForHour(hourISO);\r\n\r\n    const hourDisplay = isLiveMode ? T('plage.live') : hourDisplayTextForOffset(offsetHours);\r\n\r\n    BEACHES.forEach((b, i)=>{\r\n      if(activeFilter !== 'all' && b.type !== activeFilter) return;\r\n      if(q && !b.name.toLowerCase().includes(q)) return;\r\n\r\n      const mp = getMarinePointForBeach(i);\r\n      const sea = mp && mp.sea ? mp.sea : null;\r\n      const col = (sea && sea.color) ? sea.color : '#2aa8ff';\r\n\r\n      const m = L.circleMarker([b.lat, b.lon], {\r\n        radius: 9,\r\n        color: 'rgba(255,255,255,0.95)',\r\n        weight: 2,\r\n        fillColor: col,\r\n        fillOpacity: 0.95\r\n      }).addTo(markerLayer);\r\n\r\n      const markerItem = { b, mp, marker:m, score: scoreBeachConditions(mp) };\r\n      beachMarkers.push(markerItem);\r\n      if(mp && mp.sea && isGoodSea(mp.sea)) spotlightCandidates.push(markerItem);\r\n\r\n      m.bindPopup(popupHTML(b, mp, hourDisplay), {\r\n        closeButton:false,\r\n        maxWidth: 280\r\n      });\r\n\r\n      m.on('popupopen', (ev)=>{\r\n        const popupEl = ev.popup.getElement();\r\n        if(!popupEl) return;\r\n\r\n        popupEl.addEventListener('click', (e)=>{\r\n          const openBtn = e.target.closest('[data-apulia-action=\"open\"]');\r\n          if(openBtn){\r\n            const url = openBtn.getAttribute('data-url') || '#';\r\n            if(url && url !== '#') window.location.href = url;\r\n          }\r\n\r\n          const goBtn = e.target.closest('[data-apulia-action=\"go\"]');\r\n          if(goBtn){\r\n            const u = goBtn.getAttribute('data-gmaps');\r\n            if(u) window.open(u, '_blank');\r\n          }\r\n        }, { passive:true, once:false });\r\n      });\r\n    });\r\n\r\n    spotlightCandidates.sort((a,b)=>coastRouteValue(a) - coastRouteValue(b));\r\n    spotlightIndex = 0;\r\n    renderWeatherStrip();\r\n    restartSpotlightRotation();\r\n  }\r\n\r\n  function setCSSVarsForPitch(){\r\n    const w = root.getBoundingClientRect().width;\r\n    let pitch = 56;\r\n    let pitchGap = 10;\r\n\r\n    if(w < 420){ pitch = 48; pitchGap = 10; }\r\n    if(w < 360){ pitch = 44; pitchGap = 10; }\r\n\r\n    root.style.setProperty('--pitch', pitch + 'px');\r\n    root.style.setProperty('--pitchgap', pitchGap + 'px');\r\n  }\r\n\r\n  function buildTicks(){\r\n    if(!ticksEl) return;\r\n\r\n    const frag = document.createDocumentFragment();\r\n    for(let off = 0; off <= MAX_H; off += STEP_H){\r\n      const d = dateForOffset(off);\r\n      const h = d.getHours();\r\n      \/\/ Remplacement: 0h->J, 24h->J+1, 48h->J+2, 72h->J+3\r\n      let label = tickLabelForOffset(off);\r\n\r\n      const btn = document.createElement('button');\r\n      btn.type = 'button';\r\n      btn.className = 'apulia-tick' + ((h % 6 === 0) ? ' major' : '');\r\n      btn.setAttribute('data-off', String(off));\r\n      btn.setAttribute('role', 'option');\r\n      btn.setAttribute('aria-selected', 'false');\r\n      btn.setAttribute('title', hourDisplayTextForOffset(off));\r\n\r\n      btn.innerHTML = `\r\n        <span class=\"line\"><\/span>\r\n        <span class=\"lbl\">${label}<\/span>\r\n      `;\r\n\r\n      btn.addEventListener('click', async ()=>{\r\n        setLiveState(false);\r\n        await applyOffset(off, { center:true, smooth:true });\r\n        showDayOverlayTemporarily(off); \/\/ Afficher overlay \u00e0 la s\u00e9lection\r\n      });\r\n\r\n      frag.appendChild(btn);\r\n    }\r\n\r\n    ticksEl.innerHTML = '';\r\n    ticksEl.appendChild(frag);\r\n  }\r\n\r\n  function getTickByOffset(off){\r\n    const o = clampToStep(off);\r\n    return ticksEl ? ticksEl.querySelector('.apulia-tick[data-off=\"'+o+'\"]') : null;\r\n  }\r\n\r\n  function updateThumbAndFill(){\r\n    const tick = getTickByOffset(activeOffset);\r\n    if(!tick || !rail) return;\r\n\r\n    const railRect = rail.getBoundingClientRect();\r\n    const tickRect = tick.getBoundingClientRect();\r\n\r\n    const tickCenter = (tickRect.left - railRect.left) + (tickRect.width \/ 2);\r\n    \/\/ Thumb triangle: centrer le point (largeur 12px = 6px gauche + 6px droite)\r\n    const thumbX = tickCenter - 6;\r\n\r\n    thumb.style.transform = `translateX(${thumbX}px)`;\r\n\r\n    \/\/ Fill orange: largeur = position du thumb depuis le d\u00e9but du rail (6px padding gauche)\r\n    \/\/ Le fill commence \u00e0 6px (left du .apulia-bar) et va jusqu'\u00e0 tickCenter\r\n    const fillStart = 6; \/\/ padding gauche du rail\r\n    const fillWidthPx = tickCenter - fillStart;\r\n    const railWidth = rail.clientWidth;\r\n    const fillPct = Math.max(0, Math.min(100, (fillWidthPx \/ railWidth) * 100));\r\n    fillEl.style.width = fillPct.toFixed(2) + '%';\r\n  }\r\n\r\n  function setActiveClasses(){\r\n    const btns = ticksEl ? Array.from(ticksEl.querySelectorAll('.apulia-tick')) : [];\r\n    btns.forEach(b=>{\r\n      const v = clampToStep(parseInt(b.getAttribute('data-off') || '0', 10));\r\n      const on = (v === activeOffset);\r\n      b.classList.toggle('active', on);\r\n      b.setAttribute('aria-selected', on ? 'true' : 'false');\r\n    });\r\n  }\r\n\r\n  function centerTick(off, smooth){\r\n    const tick = getTickByOffset(off);\r\n    if(!tick || !rail) return;\r\n    const target = tick.offsetLeft + (tick.offsetWidth\/2) - (rail.clientWidth\/2);\r\n    rail.scrollTo({ left: target, behavior: smooth ? 'smooth' : 'auto' });\r\n  }\r\n\r\n  function closestOffsetFromScroll(){\r\n    if(!rail || !ticksEl) return activeOffset;\r\n    const items = Array.from(ticksEl.querySelectorAll('.apulia-tick'));\r\n    if(items.length === 0) return activeOffset;\r\n\r\n    const center = rail.scrollLeft + (rail.clientWidth \/ 2);\r\n\r\n    let bestOff = activeOffset;\r\n    let bestDist = Infinity;\r\n\r\n    for(const el of items){\r\n      const c = el.offsetLeft + (el.offsetWidth \/ 2);\r\n      const dist = Math.abs(c - center);\r\n      if(dist < bestDist){\r\n        bestDist = dist;\r\n        bestOff = clampToStep(parseInt(el.getAttribute('data-off') || '0', 10));\r\n      }\r\n    }\r\n    return bestOff;\r\n  }\r\n\r\n  \/\/ ===== JOURS AU D\u00c9BUT (0h \/ 24h \/ 48h \/ 72h)\r\n  function buildDayStrip(){\r\n    if(!dayInner || !rail || !ticksEl) return;\r\n\r\n    dayInner.innerHTML = '';\r\n\r\n    const offsets = [0, 24, 48, 72];\r\n    offsets.forEach(off=>{\r\n      const d = dateForOffset(off);\r\n      const el = document.createElement('div');\r\n      el.className = 'apulia-day-label';\r\n      el.setAttribute('data-day-off', String(off));\r\n      el.textContent = fmtDayDateShort(d);\r\n      dayInner.appendChild(el);\r\n    });\r\n\r\n    requestAnimationFrame(()=>{\r\n      dayInner.style.width = (ticksEl.scrollWidth || 0) + 'px';\r\n      positionDayLabels();\r\n      syncDayStripToRail();\r\n    });\r\n  }\r\n\r\n  function positionDayLabels(){\r\n    if(!dayInner || !ticksEl) return;\r\n\r\n    const labels = Array.from(dayInner.querySelectorAll('.apulia-day-label'));\r\n    labels.forEach(lbl=>{\r\n      const off = parseInt(lbl.getAttribute('data-day-off') || '0', 10);\r\n      const tick = getTickByOffset(off);\r\n      if(!tick) return;\r\n\r\n      const x = tick.offsetLeft + 2;\r\n      lbl.style.left = x + 'px';\r\n    });\r\n  }\r\n\r\n  function syncDayStripToRail(){\r\n    if(!rail || !dayInner) return;\r\n    dayInner.style.transform = `translateX(${-rail.scrollLeft}px)`;\r\n  }\r\n\r\n  function updateCurrentDayChip(){\r\n    if(!dayCurrentEl) return;\r\n    dayCurrentEl.textContent = dayTextForOffset(activeOffset);\r\n    \/\/ Ne pas afficher automatiquement, seulement via showDayChipTemporarily()\r\n  }\r\n\r\n  async function applyOffset(off, {center=false, smooth=false} = {}){\r\n    activeOffset = clampToStep(off);\r\n\r\n    updateCurrentDayChip();\r\n    setActiveClasses();\r\n    if(center) centerTick(activeOffset, smooth);\r\n\r\n    if(!manualLayerOverride){\r\n      const d = dateForOffset(activeOffset);\r\n      setLayerNight(shouldNightForDate(d));\r\n    }\r\n\r\n    updateThumbAndFill();\r\n    syncDayStripToRail();\r\n    const searchEl = document.getElementById('apuliaSearch');\r\n    await renderMarkers(activeOffset, searchEl ? searchEl.value : '');\r\n  }\r\n\r\n  let settleTimer = null;\r\n  function onRailScroll(){\r\n    \/\/ D\u00e9sactivation LIVE si scroll manuel\r\n    if(isLiveMode){\r\n      setLiveState(false);\r\n    }\r\n\r\n    updateThumbAndFill();\r\n    syncDayStripToRail();\r\n\r\n    \/\/ Pendant le scroll, on met \u00e0 jour le texte mais on n'affiche PAS le chip\r\n    \/\/ (le chip reste cach\u00e9, affich\u00e9 uniquement \u00e0 la fin du drag via showDayOverlayTemporarily)\r\n    const offCenter = closestOffsetFromScroll();\r\n    if(offCenter !== activeOffset){\r\n      dayCurrentEl.textContent = dayTextForOffset(offCenter);\r\n      \/\/ Ne pas afficher, seulement mettre \u00e0 jour le texte pour la fin du drag\r\n    } else {\r\n      updateCurrentDayChip();\r\n    }\r\n\r\n    clearTimeout(settleTimer);\r\n    settleTimer = setTimeout(async ()=>{\r\n      const off = closestOffsetFromScroll();\r\n      if(off !== activeOffset){\r\n        setLiveState(false);\r\n        await applyOffset(off, { center:true, smooth:true });\r\n        showDayOverlayTemporarily(off); \/\/ Afficher overlay apr\u00e8s drag\/scroll\r\n      }else{\r\n        centerTick(activeOffset, true);\r\n        updateCurrentDayChip();\r\n      }\r\n    }, 120);\r\n  }\r\n\r\n  \/\/ ===== Filters drawer\r\n  const filtersBtn = document.getElementById('apuliaFiltersBtn');\r\n  const chipsWrap = document.getElementById('apuliaChips');\r\n  const drawerEl = document.getElementById('apuliaDrawer');\r\n\r\n  if(filtersBtn){\r\n    filtersBtn.addEventListener('click', (e)=>{\r\n      e.preventDefault();\r\n      drawerEl.classList.toggle('show');\r\n    });\r\n  }\r\n\r\n  if(chipsWrap){\r\n    chipsWrap.addEventListener('click', async (e)=>{\r\n      const chip = e.target.closest('.apulia-chip');\r\n      if(!chip) return;\r\n      chipsWrap.querySelectorAll('.apulia-chip').forEach(x=>x.classList.remove('active'));\r\n      chip.classList.add('active');\r\n      activeFilter = chip.getAttribute('data-filter') || 'all';\r\n      await applyOffset(activeOffset);\r\n    });\r\n  }\r\n\r\n  \/\/ ===== Search\r\n  const searchInput = document.getElementById('apuliaSearch');\r\n  if(searchInput){\r\n    searchInput.addEventListener('input', async ()=> await applyOffset(activeOffset));\r\n\r\n    searchInput.addEventListener('keydown', (e)=>{\r\n      if(e.key !== 'Enter') return;\r\n      e.preventDefault();\r\n      const q = (searchInput.value || '').trim().toLowerCase();\r\n      if(!q) return;\r\n\r\n      const exact = PLACES.find(p => p.name.toLowerCase() === q);\r\n      if(exact){ map.setView([exact.lat, exact.lon], exact.z || 12, { animate:true }); return; }\r\n      const partial = PLACES.find(p => p.name.toLowerCase().includes(q));\r\n      if(partial){ map.setView([partial.lat, partial.lon], partial.z || 12, { animate:true }); return; }\r\n\r\n      const beach = (Array.isArray(BEACHES) ? BEACHES : []).find(b => b.name.toLowerCase().includes(q));\r\n      if(beach){ map.setView([beach.lat, beach.lon], 13, { animate:true }); return; }\r\n    });\r\n  }\r\n\r\n  \/\/ ===== Layer toggle (override manuel)\r\n  document.getElementById('apuliaLayerBtn').addEventListener('click', ()=>{\r\n    manualLayerOverride = true;\r\n    setLayerNight(!isNight);\r\n  });\r\n\r\n  \/\/ ===== Plages button\r\n  document.getElementById('apuliaBeachBtn').addEventListener('click', async ()=>{\r\n    activeFilter = 'all';\r\n    chipsWrap.querySelectorAll('.apulia-chip').forEach(x=>x.classList.remove('active'));\r\n    const allChip = chipsWrap.querySelector('.apulia-chip[data-filter=\"all\"]');\r\n    if(allChip) allChip.classList.add('active');\r\n\r\n    await applyOffset(activeOffset);\r\n    map.setView([40.35, 17.65], 8, { animate:true });\r\n  });\r\n\r\n  \/\/ ===== Locate\r\n  let userMarker = null;\r\n  let userCircle = null;\r\n\r\n  function setUserPos(lat, lon, accuracy){\r\n    if(!userMarker){\r\n      userMarker = L.circleMarker([lat, lon], {\r\n        radius:7, color:'#fff', weight:2,\r\n        fillColor:'#2aa8ff', fillOpacity:0.95\r\n      }).addTo(map);\r\n    }else userMarker.setLatLng([lat, lon]);\r\n\r\n    if(!userCircle){\r\n      userCircle = L.circle([lat, lon], {\r\n        radius: Math.max(accuracy || 0, 25),\r\n        color:'rgba(42,168,255,0.65)',\r\n        weight:2,\r\n        fillColor:'rgba(42,168,255,0.18)',\r\n        fillOpacity:0.55\r\n      }).addTo(map);\r\n    }else{\r\n      userCircle.setLatLng([lat, lon]);\r\n      userCircle.setRadius(Math.max(accuracy || 0, 25));\r\n    }\r\n  }\r\n\r\n  document.getElementById('apuliaLocateBtn').addEventListener('click', ()=>{\r\n    if(!navigator.geolocation) return;\r\n    navigator.geolocation.getCurrentPosition((pos)=>{\r\n      const lat = pos.coords.latitude, lon = pos.coords.longitude;\r\n      setUserPos(lat, lon, pos.coords.accuracy);\r\n      map.setView([lat, lon], 11, { animate:true });\r\n    }, ()=>{}, { enableHighAccuracy:true, timeout:6000 });\r\n  });\r\n\r\n  \/\/ ===== Sheets\r\n  const backdrop = document.getElementById('apuliaBackdrop');\r\n  const reportSheet = document.getElementById('apuliaReportSheet');\r\n  const legendSheet = document.getElementById('apuliaLegendSheet');\r\n  const reportBtn = document.getElementById('apuliaReportBtn');\r\n  const infoBtn = document.getElementById('apuliaInfoBtn');\r\n\r\n  function closeAllSheets(){\r\n    if(backdrop) backdrop.classList.remove('show');\r\n    if(reportSheet) reportSheet.classList.remove('show');\r\n    if(legendSheet) legendSheet.classList.remove('show');\r\n  }\r\n\r\n  function openReport(e){\r\n    if(e){ e.preventDefault(); e.stopPropagation(); }\r\n    if(backdrop) backdrop.classList.add('show');\r\n    if(reportSheet) reportSheet.classList.add('show');\r\n    if(legendSheet) legendSheet.classList.remove('show');\r\n    if(drawerEl) drawerEl.classList.remove('show');\r\n  }\r\n\r\n  function openLegend(e){\r\n    if(e){ e.preventDefault(); e.stopPropagation(); }\r\n    if(backdrop) backdrop.classList.add('show');\r\n    if(legendSheet) legendSheet.classList.add('show');\r\n    if(reportSheet) reportSheet.classList.remove('show');\r\n    if(drawerEl) drawerEl.classList.remove('show');\r\n  }\r\n\r\n  if(reportBtn) reportBtn.addEventListener('click', openReport);\r\n  if(infoBtn) infoBtn.addEventListener('click', openLegend);\r\n  root.querySelectorAll('.apulia-sheet-close').forEach((btn)=>{\r\n    btn.addEventListener('click', (e)=>{\r\n      e.preventDefault();\r\n      e.stopPropagation();\r\n      closeAllSheets();\r\n    });\r\n  });\r\n\r\n  if(backdrop){\r\n    backdrop.addEventListener('click', ()=>{\r\n      closeAllSheets();\r\n      if(drawerEl) drawerEl.classList.remove('show');\r\n    });\r\n  }\r\n\r\n  if(reportSheet){\r\n    reportSheet.addEventListener('click', (e)=>{\r\n      const item = e.target.closest('.apulia-report-item');\r\n      if(!item) return;\r\n      closeAllSheets();\r\n    });\r\n  }\r\n\r\n  map.on('click', ()=>{ if(drawerEl) drawerEl.classList.remove('show'); });\r\n\r\n  \/\/ ===== LIVE button (heure actuelle, snap 3h)\r\n  liveBtn.addEventListener('click', async ()=>{\r\n    \/\/ Supprimer imm\u00e9diatement tout overlay avant d'activer LIVE\r\n    if(dayCurrentEl){\r\n      dayCurrentEl.classList.remove('show');\r\n      if(dayChipTimer){\r\n        clearTimeout(dayChipTimer);\r\n        dayChipTimer = null;\r\n      }\r\n    }\r\n    setLiveState(true);\r\n    const off = liveOffsetNow();\r\n    await applyOffset(off, { center:true, smooth:true });\r\n\r\n    \/\/ D\u00e9marrer update continu en mode LIVE\r\n    if(liveInterval) clearInterval(liveInterval);\r\n    liveInterval = setInterval(async ()=>{\r\n      if(!isLiveMode) {\r\n        clearInterval(liveInterval);\r\n        liveInterval = null;\r\n        return;\r\n      }\r\n      const currentOff = liveOffsetNow();\r\n      if(currentOff !== activeOffset){\r\n        await applyOffset(currentOff, { center:true, smooth:true });\r\n      }\r\n    }, 1000); \/\/ Update chaque seconde\r\n  });\r\n\r\n  \/\/ ===== Boot\r\n  (async function boot(){\r\n    await loadBeaches();\r\n\r\n    setCSSVarsForPitch();\r\n    buildTicks();\r\n    buildDayStrip();\r\n\r\n    if(rail){\r\n      rail.addEventListener('scroll', onRailScroll, { passive:true });\r\n    }\r\n\r\n    window.addEventListener('resize', ()=>{\r\n      setCSSVarsForPitch();\r\n      positionDayLabels();\r\n      syncDayStripToRail();\r\n      centerTick(activeOffset, false);\r\n      updateThumbAndFill();\r\n      updateCurrentDayChip();\r\n    }, { passive:true });\r\n\r\n    \/\/ start = LIVE r\u00e9el\r\n    setLiveState(true);\r\n    activeOffset = liveOffsetNow();\r\n    updateCurrentDayChip();\r\n\r\n    const d0 = dateForOffset(activeOffset);\r\n    setLayerNight(shouldNightForDate(d0));\r\n\r\n    await applyOffset(activeOffset, { center:true, smooth:false });\r\n\r\n    \/\/ D\u00e9marrer update continu en mode LIVE au boot\r\n    if(liveInterval) clearInterval(liveInterval);\r\n    liveInterval = setInterval(async ()=>{\r\n      if(!isLiveMode) {\r\n        clearInterval(liveInterval);\r\n        liveInterval = null;\r\n        return;\r\n      }\r\n      const currentOff = liveOffsetNow();\r\n      if(currentOff !== activeOffset){\r\n        await applyOffset(currentOff, { center:true, smooth:true });\r\n      }\r\n    }, 1000); \/\/ Update chaque seconde\r\n  })();\r\n\r\n  function refreshPlageI18n(){\r\n    applyPlageBootI18n();\r\n    updateTickLabels();\r\n    buildDayStrip();\r\n    updateCurrentDayChip();\r\n    renderWeatherStrip();\r\n    restartSpotlightRotation();\r\n  }\r\n\r\n  window.addEventListener('apulia:i18n_ready', function(){\r\n    refreshPlageI18n();\r\n  });\r\n\r\n  var _i18nApi = window.ApuliaI18n || window.ApuliaI18nPlage || window.ApuliaI18nCompte;\r\n  if(_i18nApi && typeof _i18nApi.scheduleRefresh === 'function'){\r\n    _i18nApi.scheduleRefresh();\r\n  }\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Meteo delle spiagge Seleziona la tua spiaggia in base alla direzione del vento<\/p>\n","protected":false},"author":1,"featured_media":16731,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-16878","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Quale spiaggia scegliere oggi in Puglia?<\/title>\n<meta name=\"description\" content=\"Scegli la migliore spiaggia della Puglia in base al vento, allo stato del mare e alle condizioni del giorno sulle coste Adriatica e Ionica.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Quale spiaggia scegliere oggi in Puglia?\" \/>\n<meta property=\"og:description\" content=\"Scegli la migliore spiaggia della Puglia in base al vento, allo stato del mare e alle condizioni del giorno sulle coste Adriatica e Ionica.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/\" \/>\n<meta property=\"og:site_name\" content=\"APULIA \u2013 Application et guide des Pouilles\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/share\/1CMLv8ojyW\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-31T11:58:45+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/lespouilles.blog\/wp-content\/uploads\/2026\/01\/Apulia-IA-plage-683x1024.png\" \/>\n\t<meta property=\"og:image:width\" content=\"683\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minuto\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/\",\"url\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/\",\"name\":\"Quale spiaggia scegliere oggi in Puglia?\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lespouilles.blog\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/Apulia-IA-plage.png\",\"datePublished\":\"2025-08-28T09:04:25+00:00\",\"dateModified\":\"2026-08-31T11:58:45+00:00\",\"description\":\"Scegli la migliore spiaggia della Puglia in base al vento, allo stato del mare e alle condizioni del giorno sulle coste Adriatica e Ionica.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/#primaryimage\",\"url\":\"https:\\\/\\\/lespouilles.blog\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/Apulia-IA-plage.png\",\"contentUrl\":\"https:\\\/\\\/lespouilles.blog\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/Apulia-IA-plage.png\",\"width\":1024,\"height\":1536},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/apulia-spiagge\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"APULIA &#8211; Spiagge\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/#website\",\"url\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/\",\"name\":\"Les Pouilles \u2013 Guide voyage. L'application Apulia pour organiser votre s\u00e9jour\",\"description\":\"APULIA est l\u2019application qui facilite votre voyage dans les Pouilles et vous accompagne avant et pendant votre s\u00e9jour. Plages, h\u00e9bergements, activit\u00e9s, m\u00e9t\u00e9o des plages, conseils locaux et s\u00e9jours personnalis\u00e9s.\",\"publisher\":{\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/#organization\",\"name\":\"APULIA\",\"url\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/lespouilles.blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/logo-Apulia-transparent.png\",\"contentUrl\":\"https:\\\/\\\/lespouilles.blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/logo-Apulia-transparent.png\",\"width\":1024,\"height\":576,\"caption\":\"APULIA\"},\"image\":{\"@id\":\"https:\\\/\\\/lespouilles.blog\\\/it\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/share\\\/1CMLv8ojyW\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Quale spiaggia scegliere oggi in Puglia?","description":"Scegli la migliore spiaggia della Puglia in base al vento, allo stato del mare e alle condizioni del giorno sulle coste Adriatica e Ionica.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/","og_locale":"it_IT","og_type":"article","og_title":"Quale spiaggia scegliere oggi in Puglia?","og_description":"Scegli la migliore spiaggia della Puglia in base al vento, allo stato del mare e alle condizioni del giorno sulle coste Adriatica e Ionica.","og_url":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/","og_site_name":"APULIA \u2013 Application et guide des Pouilles","article_publisher":"https:\/\/www.facebook.com\/share\/1CMLv8ojyW\/","article_modified_time":"2026-08-31T11:58:45+00:00","og_image":[{"width":683,"height":1024,"url":"https:\/\/lespouilles.blog\/wp-content\/uploads\/2026\/01\/Apulia-IA-plage-683x1024.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Tempo di lettura stimato":"1 minuto"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/","url":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/","name":"Quale spiaggia scegliere oggi in Puglia?","isPartOf":{"@id":"https:\/\/lespouilles.blog\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/#primaryimage"},"image":{"@id":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/#primaryimage"},"thumbnailUrl":"https:\/\/lespouilles.blog\/wp-content\/uploads\/2026\/01\/Apulia-IA-plage.png","datePublished":"2025-08-28T09:04:25+00:00","dateModified":"2026-08-31T11:58:45+00:00","description":"Scegli la migliore spiaggia della Puglia in base al vento, allo stato del mare e alle condizioni del giorno sulle coste Adriatica e Ionica.","breadcrumb":{"@id":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/lespouilles.blog\/it\/apulia-spiagge\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/#primaryimage","url":"https:\/\/lespouilles.blog\/wp-content\/uploads\/2026\/01\/Apulia-IA-plage.png","contentUrl":"https:\/\/lespouilles.blog\/wp-content\/uploads\/2026\/01\/Apulia-IA-plage.png","width":1024,"height":1536},{"@type":"BreadcrumbList","@id":"https:\/\/lespouilles.blog\/it\/apulia-spiagge\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/lespouilles.blog\/it\/"},{"@type":"ListItem","position":2,"name":"APULIA &#8211; Spiagge"}]},{"@type":"WebSite","@id":"https:\/\/lespouilles.blog\/it\/#website","url":"https:\/\/lespouilles.blog\/it\/","name":"Les Pouilles \u2013 Guide voyage. L'application Apulia pour organiser votre s\u00e9jour","description":"APULIA est l\u2019application qui facilite votre voyage dans les Pouilles et vous accompagne avant et pendant votre s\u00e9jour. Plages, h\u00e9bergements, activit\u00e9s, m\u00e9t\u00e9o des plages, conseils locaux et s\u00e9jours personnalis\u00e9s.","publisher":{"@id":"https:\/\/lespouilles.blog\/it\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/lespouilles.blog\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Organization","@id":"https:\/\/lespouilles.blog\/it\/#organization","name":"APULIA","url":"https:\/\/lespouilles.blog\/it\/","logo":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/lespouilles.blog\/it\/#\/schema\/logo\/image\/","url":"https:\/\/lespouilles.blog\/wp-content\/uploads\/2026\/06\/logo-Apulia-transparent.png","contentUrl":"https:\/\/lespouilles.blog\/wp-content\/uploads\/2026\/06\/logo-Apulia-transparent.png","width":1024,"height":576,"caption":"APULIA"},"image":{"@id":"https:\/\/lespouilles.blog\/it\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/share\/1CMLv8ojyW\/"]}]}},"_links":{"self":[{"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/pages\/16878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/comments?post=16878"}],"version-history":[{"count":3,"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/pages\/16878\/revisions"}],"predecessor-version":[{"id":19649,"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/pages\/16878\/revisions\/19649"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/media\/16731"}],"wp:attachment":[{"href":"https:\/\/lespouilles.blog\/it\/wp-json\/wp\/v2\/media?parent=16878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}