{"id":4295,"date":"2026-06-21T16:53:50","date_gmt":"2026-06-21T14:53:50","guid":{"rendered":"https:\/\/2026.ecoparquedetrasmiera.com\/?post_type=tribe_venue&#038;p=4295"},"modified":"2026-07-03T11:10:32","modified_gmt":"2026-07-03T09:10:32","slug":"playa-de-el-sable","status":"publish","type":"eco_recintos","link":"https:\/\/2026.ecoparquedetrasmiera.com\/en-gb\/espacio\/playa-de-el-sable\/","title":{"rendered":"Playa de El Sable"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">La playa del Sable se encuentra en el n\u00facleo de Isla Playa, siendo una playa de car\u00e1cter urbano y familiar. Muy animada en periodo estival y tranquile el resto del a\u00f1o, con fina arena dorada es ideal para familias con ni\u00f1os peque\u00f1os, ya que se encuentra resguardada por un islote rocoso que le hace similar a una gran piscina de aguas tranquilas y cristalinas. Cuenta con la bandera azul y la Q de calidad Tur\u00edstica, y est\u00e1 certificada en calidad ambiental y accesibilidad.<\/p>\n\n\n<style>.wp-block-kadence-advancedgallery.kb-gallery-wrap-id-4295_914c2e-76{overflow:hidden;}.kb-gallery-id-4295_914c2e-76 .kadence-blocks-gallery-item .kb-gal-image-radius, .kb-gallery-id-4295_914c2e-76 .kb-slide-item .kb-gal-image-radius img{border-radius:0px 0px 0px 0px;;}.kb-gallery-wrap-id-4295_914c2e-76.wp-block-kadence-advancedgallery{overflow:visible;}.kb-gallery-wrap-id-4295_914c2e-76.wp-block-kadence-advancedgallery .kt-blocks-carousel{overflow:visible;}<\/style><div class=\"kb-gallery-wrap-id-4295_914c2e-76 alignnone wp-block-kadence-advancedgallery\"><div class=\"kb-gallery-ul kb-gallery-non-static kb-gallery-type-carousel kb-gallery-id-4295_914c2e-76 kb-gallery-caption-style-bottom-hover kb-gallery-filter-none kb-gallery-magnific-init\" data-image-filter=\"none\" data-lightbox-caption=\"true\"><div class=\"kt-blocks-carousel splide kt-carousel-container-dotstyle-dark kt-carousel-arrowstyle-whiteondark kt-carousel-dotstyle-dark kb-slider-group-arrow kb-slider-arrow-position-center\" data-columns-xxl=\"3\" data-columns-xl=\"3\" data-columns-md=\"3\" data-columns-sm=\"2\" data-columns-xs=\"1\" data-columns-ss=\"1\" data-slider-anim-speed=\"400\" data-slider-scroll=\"1\" data-slider-arrows=\"true\" data-slider-dots=\"true\" data-slider-hover-pause=\"false\" data-slider-auto=\"\" data-slider-speed=\"7000\" data-slider-gap=\"10px\" data-slider-gap-tablet=\"10px\" data-slider-gap-mobile=\"10px\" data-show-pause-button=\"false\" data-slider-label=\"Photo Gallery Carousel\"><div class=\"splide__track\"><ul class=\"kt-blocks-carousel-init kb-gallery-carousel splide__list\"><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO.jpg\" data-id=\"4311\" class=\"wp-image-4311 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-2-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO.jpg\" data-id=\"4309\" class=\"wp-image-4309 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-16-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO.jpg\" data-id=\"4310\" class=\"wp-image-4310 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-1-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO-683x1024.jpg\" width=\"683\" height=\"1024\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO.jpg\" data-id=\"4308\" class=\"wp-image-4308 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO-683x1024.jpg 683w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO-200x300.jpg 200w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO-768x1152.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO-1024x1536.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-15-RO.jpg 1080w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO-683x1024.jpg\" width=\"683\" height=\"1024\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO.jpg\" data-id=\"4307\" class=\"wp-image-4307 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO-683x1024.jpg 683w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO-200x300.jpg 200w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO-768x1152.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO-1024x1536.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-14-RO.jpg 1080w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO-683x1024.jpg\" width=\"683\" height=\"1024\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO.jpg\" data-id=\"4306\" class=\"wp-image-4306 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO-683x1024.jpg 683w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO-200x300.jpg 200w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO-768x1152.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO-1024x1536.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-13-RO.jpg 1080w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO-683x1024.jpg\" width=\"683\" height=\"1024\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO.jpg\" data-id=\"4305\" class=\"wp-image-4305 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO-683x1024.jpg 683w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO-200x300.jpg 200w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO-768x1152.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO-1024x1536.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-12-RO.jpg 1080w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO.jpg\" data-id=\"4304\" class=\"wp-image-4304 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-11-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO-683x1024.jpg\" width=\"683\" height=\"1024\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO.jpg\" data-id=\"4303\" class=\"wp-image-4303 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO-683x1024.jpg 683w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO-200x300.jpg 200w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO-768x1152.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO-1024x1536.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-10-RO.jpg 1080w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO.jpg\" data-id=\"4302\" class=\"wp-image-4302 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-9-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO.jpg\" data-id=\"4301\" class=\"wp-image-4301 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-8-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO-683x1024.jpg\" width=\"683\" height=\"1024\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO.jpg\" data-id=\"4300\" class=\"wp-image-4300 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO-683x1024.jpg 683w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO-200x300.jpg 200w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO-768x1152.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO-1024x1536.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-7-RO.jpg 1080w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO.jpg\" data-id=\"4299\" class=\"wp-image-4299 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-6-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO.jpg\" data-id=\"4297\" class=\"wp-image-4297 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-4-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO-1024x683.jpg\" width=\"1024\" height=\"683\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO.jpg\" data-id=\"4298\" class=\"wp-image-4298 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO-1024x683.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO-300x200.jpg 300w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO-768x512.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-5-RO.jpg 1080w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><li class=\"kb-slide-item kb-gallery-carousel-item splide__slide\"><div class=\"kadence-blocks-gallery-item\"><div class=\"kadence-blocks-gallery-item-inner\"><figure class=\"kb-gallery-figure kb-gallery-item-has-link kadence-blocks-gallery-item-hide-caption\"><a href=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO.jpg\" data-description=\"Playa El Sable\" class=\"kb-gallery-item-link\"   role=\"button\" aria-haspopup=\"dialog\"><div class=\"kb-gal-image-radius\"><div class=\"kb-gallery-image-contain kadence-blocks-gallery-intrinsic kb-gallery-image-ratio-land32 kb-has-image-ratio-land32\" ><img alt=\"\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO-683x1024.jpg\" width=\"683\" height=\"1024\" alt=\"\" data-full-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO.jpg\" data-light-image=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO.jpg\" data-id=\"4296\" class=\"wp-image-4296 skip-lazy\" srcset=\"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO-683x1024.jpg 683w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO-200x300.jpg 200w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO-768x1152.jpg 768w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO-1024x1536.jpg 1024w, https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/uploads\/2026\/06\/Playa-El-Sable-3-RO.jpg 1080w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/div><\/div><\/a><\/figure><\/div><\/div><\/li><\/ul><\/div><\/div><\/div><\/div>\n\n\n    <style>\n        .eco-vista-bloque { display: none; width: 100%; }\n        .eco-vista-bloque.eco-activa { display: block !important; }\n        #eco-mapa-webcams-canvas { width: 100%; height: 580px; border-radius: 16px; border: 1px solid #d0cfc7; box-shadow: 0 10px 30px rgba(0,0,0,0.04); position: relative; }\n        #eco-mapa-webcams-canvas .leaflet-pane { z-index: 400 !important; }\n        #eco-mapa-webcams-canvas .leaflet-popup-pane { z-index: 700 !important; }\n        .eco-video-container-lista { width: 100%; aspect-ratio: 16\/9; background: #10160f; position: relative; overflow: hidden; }\n        .eco-video-container-lista video { width: 100%; height: 100%; display: block; position: relative; z-index: 1; }\n        .eco-camara-caida-aviso { position: absolute; inset: 0; background: #1a2219; color: #ffffff; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 20px; text-align: center; font-family: inherit; z-index: 5; border-radius: 12px; }\n        .eco-camara-caida-aviso svg { width: 42px; height: 42px; fill: none; stroke: #ff9800; stroke-width: 2; }\n        .eco-camara-caida-aviso p { margin: 0; font-size: 13px; font-weight: 600; color: #ecefe9; max-width: 240px; line-height: 1.4; }\n        .eco-popup-webcam-box { padding: 4px; width: 280px; font-family: inherit; }\n        .eco-popup-webcam-header { display: flex !important; justify-content: space-between !important; align-items: center !important; margin-bottom: 14px !important; border-bottom: none !important; padding-bottom: 0 !important; }\n        .eco-popup-webcam-titulo { margin: 0 !important; color: #1a2e16 !important; font-weight: 700 !important; font-size: 14px !important; line-height: 1.2 !important; }\n        .eco-popup-video-container { width: 100%; background: #000; border-radius: 8px; overflow: hidden; aspect-ratio: 16\/9; position: relative; }\n        .eco-popup-video-container video { width: 100%; height: 100%; display: block; }\n        .eco-webcam-pin { display: flex !important; align-items: center !important; justify-content: center !important; border-radius: 50% !important; border: 3px solid #ffffff !important; box-shadow: 0 4px 14px rgba(10,32,16,0.2) !important; background: #7DBA00 !important; }\n        .eco-webcam-pin i { color: #ffffff !important; font-size: 12px !important; }\n        .eco-skeleton { background: #e2e8f0; background-image: linear-gradient(90deg, #e2e8f0 0px, #f1f5f9 40px, #e2e8f0 80px); background-size: 200% 100%; animation: ecoSkeletonShine 1.5s infinite linear; }\n        .eco-skeleton-pildora { width: 60px; height: 32px; border-radius: 20px; display: inline-block; }\n        \/* ---- P\u00cdLDORAS DE TIEMPO\/OLEAJE (temperatura, viento, olas) ---- *\/\n        .eco-popup-clima-info { flex-wrap: wrap; row-gap: 6px; }\n        .eco-clima-link-pildora { text-decoration: none !important; display: inline-flex; flex-shrink: 0; }\n        .eco-clima-flex-render { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; background: #f0f6e6; border: 1px solid #dbe8cb; border-radius: 20px; padding: 6px 12px; box-sizing: border-box; font-family: inherit; line-height: 1; flex-shrink: 0; }\n        .eco-clima-flex-render span { font-size: 16px; font-weight: 700; color: #1a2e16; white-space: nowrap; }\n        .eco-clima-flex-render svg { width: 19px; height: 19px; flex-shrink: 0; }\n        .eco-mar-pildora { background: #eaf5f8; border-color: #d3e8ee; }\n        .eco-skeleton-bloque { width: 100%; height: 45px; border-radius: 30px; margin-top: 14px; }\n        @keyframes ecoSkeletonShine { 0% { background-position: -100% 0; } 100% { background-position: 100% 0; } }\n        .eco-bloque-marino { width: 100%; box-sizing: border-box; display: block; }\n        .eco-bloque-marino.oculto-limpio { display: none !important; }\n        .eco-marino-link-wrap { text-decoration: none !important; width: 100%; display: block; cursor: pointer; transition: transform 0.2s ease; margin-top: 14px; padding-top: 14px; border-top: 1px dashed #e2e6e1; }\n        .eco-marino-link-wrap:hover { transform: scale(1.01); }\n        .eco-marino-pildora-unica { display: inline-flex; align-items: center; gap: 12px; background: #f0f7f9; padding: 10px 16px; border-radius: 30px; border: 1px solid #e0edf1; width: 100%; justify-content: space-between; box-sizing: border-box; }\n        .eco-marino-seccion { display: flex; align-items: center; gap: 8px; }\n        .eco-marino-seccion svg { width: 18px; height: 18px; flex-shrink: 0; }\n        .eco-marino-separador { width: 1px; height: 16px; background: #ccdce0; }\n        .eco-marino-meta { display: flex; flex-direction: column; line-height: 1.1; }\n        .eco-marino-label { font-size: 9px; text-transform: uppercase; color: #6b7a66; font-weight: 700; letter-spacing: 0.5px; }\n        .eco-marino-valor { font-size: 12px; font-weight: 700; color: #1a2e16; white-space: nowrap; }\n        @keyframes ecoVientoEfecto {\n            0% { transform: rotate(var(--rotacion-viento)) translateX(0); }\n            50% { transform: rotate(calc(var(--rotacion-viento) + 8deg)) translateX(1px); }\n            100% { transform: rotate(var(--rotacion-viento)) translateX(0); }\n        }\n        .eco-flecha-viento-anim { animation: ecoVientoEfecto 2.5s ease-in-out infinite; display: inline-flex; align-items: center; justify-content: center; transform-origin: 50% 50%; overflow: visible; width: 12px; height: 12px; flex-shrink: 0; }\n        .eco-flecha-viento-anim svg { width: 12px; height: 12px; overflow: visible; display: block; }\n        @keyframes ecoNubeBalanceo { 0% { transform: translateY(0) scale(1); } 50% { transform: translateY(-2px) scale(1.02); } 100% { transform: translateY(0) scale(1); } }\n        .eco-svg-clima svg, .eco-svg-clima path { animation: ecoNubeBalanceo 4s ease-in-out infinite; }\n        @keyframes ecoRayosGiro { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n        .eco-rayos-sol { transform-box: fill-box; transform-origin: center; animation: ecoRayosGiro 18s linear infinite; }\n        @keyframes ecoOlaVaiven { 0% { transform: translateX(0) scaleY(1); } 50% { transform: translateX(2px) scaleY(1.1); } 100% { transform: translateX(0) scaleY(1); } }\n        .eco-mar-pildora svg, .eco-oleaje-pildora svg { animation: ecoOlaVaiven 3s ease-in-out infinite; }\n        @keyframes ecoMareaVaiven { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(3px); } }\n        .eco-flecha-marea-anim { display: inline-flex; animation: ecoMareaVaiven 1.8s ease-in-out infinite; }\n\n        \/* ---- FILTROS POR CATEGOR\u00cdA ---- *\/\n        .eco-tarjeta-recinto.eco-tarjeta-oculta { display: none !important; }\n\n        \/* ---- CARGA DIFERIDA DE V\u00cdDEO (play bajo demanda) ---- *\/\n        .eco-video-placeholder { position: absolute; inset: 0; background-color: #10160f; background-image: linear-gradient(145deg, #1a2e16, #0e1a0b); background-size: cover; background-position: center; display: flex; align-items: center; justify-content: center; z-index: 2; }\n        .eco-video-container-lista.iniciada .eco-video-placeholder { display: none; }\n        .badge-en-vivo { position: absolute; top: 10px; left: 10px; z-index: 4; background: rgba(0,0,0,0.55); color: #fff; font-size: 10px; font-weight: 800; letter-spacing: 0.4px; padding: 5px 10px; border-radius: 20px; display: inline-flex; align-items: center; gap: 6px; }\n        .punto-parpadeo { width: 6px; height: 6px; border-radius: 50%; background: #ef4444; display: inline-block; animation: ecoParpadeo 1.4s infinite; }\n        @keyframes ecoParpadeo { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }\n        .eco-play-overlay { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 58px; height: 58px; border-radius: 50%; background: #4a9e38; border: none; color: #fff; font-size: 18px; display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 3; box-shadow: 0 6px 18px rgba(0,0,0,0.3); transition: all 0.2s ease; }\n        .eco-play-overlay:hover { background: #2d6a20; transform: translate(-50%, -50%) scale(1.06); }\n        .eco-play-overlay i { margin-left: 3px; }\n        .eco-video-container-lista.iniciada .eco-play-overlay,\n        .eco-video-container-lista.cargando .eco-play-overlay { display: none; }\n        .eco-video-loading-spinner { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 40px; height: 40px; border-radius: 50%; border: 3px solid rgba(255,255,255,0.25); border-top-color: #6fcf5a; z-index: 4; animation: ecoSpinCarga 0.8s linear infinite; }\n        @keyframes ecoSpinCarga { to { transform: translate(-50%, -50%) rotate(360deg); } }\n\n\n        \/* ---- AVISOS AEMET OFICIALES (color real) ---- *\/\n       .eco-avisos-contenedor { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }\n.eco-aviso-aemet { display: flex; align-items: flex-start; gap: 9px; border-radius: 10px; padding: 10px 12px; font-family: inherit; }\n.eco-aviso-aemet.nivel-amarillo { background: #fffbeb; border: 1px solid #fde68a; }\n.eco-aviso-aemet.nivel-naranja { background: #fff7ed; border: 1px solid #fdba74; }\n.eco-aviso-aemet.nivel-rojo { background: #fef2f2; border: 1px solid #fca5a5; }\n.eco-aviso-aemet .aviso-icono { width: 15px; height: 15px; margin-top: 1px; flex-shrink: 0; }\n.nivel-amarillo .aviso-icono { color: #d69a06; }\n.nivel-naranja .aviso-icono { color: #ea690f; }\n.nivel-rojo .aviso-icono { color: #d6293e; }\n.eco-aviso-aemet .aviso-txt { flex: 1; min-width: 0; }\n.eco-aviso-aemet .aviso-fila-superior { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }\n.eco-aviso-aemet .aviso-evento { font-size: 12.5px; font-weight: 700; line-height: 1.35; }\n.nivel-amarillo .aviso-evento { color: #92620a; }\n.nivel-naranja .aviso-evento { color: #9a3f12; }\n.nivel-rojo .aviso-evento { color: #a91e1e; }\n.eco-aviso-aemet .aviso-horario-txt { font-size: 11px; font-weight: 600; color: #8a7f68; white-space: nowrap; flex-shrink: 0; }\n.eco-aviso-aemet .aviso-subtipo { font-size: 11px; font-weight: 600; color: #8a7f68; margin-top: 2px; }\n.eco-aviso-aemet .aviso-desc { font-size: 11.5px; font-weight: 500; line-height: 1.4; color: #6b6156; margin-top: 3px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; white-space: pre-line; }\n\n\/* Bloque completo en azul cuando el aviso es \"pr\u00f3ximo\" (a\u00fan no ha empezado) *\/\n.eco-aviso-aemet.nivel-proximo { background: #eff6ff; border: 1px solid #bfdbfe; }\n.nivel-proximo .aviso-icono { color: #2563eb; }\n.nivel-proximo .aviso-evento { color: #1d4ed8; }\n.nivel-proximo .aviso-horario-txt { color: #3b82f6; }\n.nivel-proximo .aviso-subtipo { color: #5b7bb8; }\n\n        @media (max-width: 767px) {\n            #eco-mapa-webcams-canvas { height: 440px; }\n            .eco-marino-pildora-unica { flex-direction: column; gap: 10px; border-radius: 14px; align-items: flex-start; height: auto !important; padding: 14px !important; }\n            .eco-marino-separador { display: none; }\n        }\n        #eco-seccion-webcams-unificada { padding-left: 16px !important; padding-right: 16px !important; box-sizing: border-box !important; }\n        #eco-webcams-render-lista { padding-left: 4px !important; padding-right: 4px !important; box-sizing: border-box !important; }\n        \n        \/* Ajustes espec\u00edficos para el modo individual en recintos *\/\n        .eco-modo-camara-individual { padding: 0 !important; margin: 15px 0 !important; }\n        .eco-modo-camara-individual .eco-tabs-conmutador { display: none !important; }\n        .eco-modo-camara-individual .eco-grid-recintos { grid-template-columns: 1fr !important; max-width: 100% !important; }\n    <\/style>\n\n    <div class=\"eco-wrapper-hibrido eco-modo-camara-individual\" id=\"eco-seccion-webcams-unificada\">\n                \n        <div id=\"eco-webcam-vista-lista\" class=\"eco-vista-bloque eco-activa\">\n            <div class=\"eco-grid-recintos\" id=\"eco-webcams-render-lista\"><\/div>\n        <\/div>\n    <\/div>\n\n    <script type=\"text\/javascript\">\n    window.ecoPlyrInstances = window.ecoPlyrInstances || {};\n    window.ecoHlsInstances = window.ecoHlsInstances || {};\n    var proxyUrlBase = \"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/themes\/kadence-child\/stream-proxy.php\";\n\n   var camaraFiltradaTarget = \"camara_1\";\nvar limiteWebcams = parseInt(\"\") || 0;\nvar webcamsDataCompleta = [\n    { id: 'camara_1', titulo: 'Playa del Sable', lat: 43.4983, lon: -3.5422, file: 'b861783b-ca42-4130-84ab-064bba27c4de.m3u8', tipo: 'playa' },\n    { id: 'camara_2', titulo: 'Playa de la Arena', lat: 43.5029755, lon: -3.5844687, file: '7a893827-b112-4a6a-b7c6-cad7422c4834.m3u8', tipo: 'playa' }\n];\n\nif (window.ecoWebcamsConfig && window.ecoWebcamsConfig.listado) {\n    webcamsDataCompleta = window.ecoWebcamsConfig.listado;\n}\n\n\/\/ Si viene un ID en el shortcode, filtramos el listado para renderizar solo esa c\u00e1mara\nvar webcamsData = camaraFiltradaTarget ? webcamsDataCompleta.filter(c => c.id === camaraFiltradaTarget) : webcamsDataCompleta;\n\n\/\/ Si viene un l\u00edmite en el shortcode, cortamos el listado a las N primeras\nif (limiteWebcams > 0) {\n    webcamsData = webcamsData.slice(0, limiteWebcams);\n}\n\n    \/\/ Icono de clima a partir del c\u00f3digo REAL de OpenWeather (800=despejado, 801-804=nubes, 3xx\/5xx=lluvia...)\n    \/\/ Rayos de sol animados (girando lentamente), reutilizables en cualquier icono con sol\n    function generarRayosSol(cx, cy, rInterior, rExterior, color, numRayos) {\n        numRayos = numRayos || 8;\n        var lineas = '';\n        for (var i = 0; i < numRayos; i++) {\n            var ang = (i * (360 \/ numRayos)) * Math.PI \/ 180;\n            var x1 = cx + rInterior * Math.cos(ang);\n            var y1 = cy + rInterior * Math.sin(ang);\n            var x2 = cx + rExterior * Math.cos(ang);\n            var y2 = cy + rExterior * Math.sin(ang);\n            lineas += `<line x1=\"${x1.toFixed(1)}\" y1=\"${y1.toFixed(1)}\" x2=\"${x2.toFixed(1)}\" y2=\"${y2.toFixed(1)}\" stroke=\"${color}\" stroke-width=\"3\" stroke-linecap=\"round\"\/>`;\n        }\n        return `<g class=\"eco-rayos-sol\">${lineas}<\/g>`;\n    }\n\n    function generarSvgClima(code, esNoche) {\n        var estiloComun = 'width:22px; height:24px; display:block; overflow:visible;';\n        if (code === 800) {\n            if (esNoche) {\n                return '<svg viewBox=\"0 0 24 24\" style=\"' + estiloComun + '\"><circle cx=\"12\" cy=\"12\" r=\"8\" fill=\"#ECEFF1\" stroke=\"#CFD8DC\" stroke-width=\"1.5\"\/><circle cx=\"9\" cy=\"9\" r=\"2\" fill=\"#B0BEC5\" opacity=\"0.4\"\/><\/svg>';\n            }\n            return '<svg viewBox=\"0 0 64 64\" class=\"eco-svg-clima\" style=\"' + estiloComun + '\">' + generarRayosSol(32, 32, 16, 23, '#FFB300') + '<circle cx=\"32\" cy=\"32\" r=\"12\" fill=\"#FFB300\"\/><\/svg>';\n        }\n        if (code === 801) {\n            var sol1 = esNoche ? '' : (generarRayosSol(42, 24, 10, 15, '#FFA000') + '<circle cx=\"42\" cy=\"24\" r=\"8\" fill=\"#FFA000\"\/>');\n            return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\">' + sol1 + '<path d=\"M22 46h22a10 10 0 0 0 3-19.2 11 11 0 0 0-21.2-2.8A10 10 0 0 0 22 46z\" fill=\"#E2E8F0\"\/><\/svg>';\n        }\n        if (code === 802 || code === 803) {\n            var sol2 = esNoche ? '' : (generarRayosSol(44, 22, 9, 13, '#FFB300', 8) + '<circle cx=\"44\" cy=\"22\" r=\"7\" fill=\"#FFB300\" opacity=\"0.8\"\/>');\n            return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\">' + sol2 + '<path d=\"M18 44h26a11 11 0 0 0 3-21.2 12 12 0 0 0-23.2-2.8A11 11 0 0 0 18 44z\" fill=\"#CBD5E1\"\/><\/svg>';\n        }\n        if (code === 804) {\n            return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\"><path d=\"M16 46h32a14 14 0 0 0 4-27.2 16 16 0 0 0-31.2-3.6A14 14 0 0 0 16 46z\" fill=\"#94A3B8\"\/><\/svg>';\n        }\n        if ((code >= 300 && code < 400) || (code >= 500 && code < 600)) {\n            return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\"><path d=\"M18 40h26a11 11 0 0 0 3-21.2 12 12 0 0 0-23.2-2.8A11 11 0 0 0 18 40z\" fill=\"#64748B\"\/><line x1=\"25\" y1=\"46\" x2=\"22\" y2=\"54\" stroke=\"#38BDF8\" stroke-width=\"2.5\" stroke-linecap=\"round\"\/><line x1=\"34\" y1=\"46\" x2=\"31\" y2=\"54\" stroke=\"#38BDF8\" stroke-width=\"2.5\" stroke-linecap=\"round\"\/><\/svg>';\n        }\n        if (code >= 200 && code < 300) {\n            return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\"><path d=\"M18 40h26a11 11 0 0 0 3-21.2 12 12 0 0 0-23.2-2.8A11 11 0 0 0 18 40z\" fill=\"#475569\"\/><line x1=\"28\" y1=\"44\" x2=\"24\" y2=\"54\" stroke=\"#FBBF24\" stroke-width=\"3\" stroke-linecap=\"round\"\/><\/svg>';\n        }\n        if (code >= 600 && code < 700) {\n            return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\"><path d=\"M18 40h26a11 11 0 0 0 3-21.2 12 12 0 0 0-23.2-2.8A11 11 0 0 0 18 40z\" fill=\"#CBD5E1\"\/><circle cx=\"26\" cy=\"50\" r=\"2\" fill=\"#E0F2FE\"\/><circle cx=\"36\" cy=\"52\" r=\"2\" fill=\"#E0F2FE\"\/><\/svg>';\n        }\n        if (code >= 700 && code < 800) {\n            return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\"><path d=\"M10 26h44M10 36h44M10 46h44\" stroke=\"#94A3B8\" stroke-width=\"4\" stroke-linecap=\"round\"\/><\/svg>';\n        }\n        return '<svg viewBox=\"0 0 64 64\" style=\"' + estiloComun + '\"><path d=\"M18 44h26a11 11 0 0 0 3-21.2 12 12 0 0 0-23.2-2.8A11 11 0 0 0 18 44z\" fill=\"#CBD5E1\"\/><\/svg>';\n    }\n\n    \/\/ Icono de temperatura del mar: una ola con cuerpo, sin term\u00f3metro\n    function generarSvgOlaMar() {\n        return '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0284c7\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">'\n            + '<path d=\"M2 15c1.4-1.3 2.8-1.3 4.2 0s2.8 1.3 4.2 0s2.8-1.3 4.2 0s2.8 1.3 4.2 0s2.8-1.3 4.2 0\" fill=\"none\"\/>'\n            + '<path d=\"M2 15c1.4-1.3 2.8-1.3 4.2 0s2.8 1.3 4.2 0s2.8-1.3 4.2 0s2.8 1.3 4.2 0s2.8-1.3 4.2 0v6H2z\" fill=\"#0284c7\" fill-opacity=\"0.18\" stroke=\"none\"\/>'\n            + '<path d=\"M2 19.5c1.4-1.3 2.8-1.3 4.2 0s2.8 1.3 4.2 0s2.8-1.3 4.2 0s2.8 1.3 4.2 0s2.8-1.3 4.2 0\" stroke-width=\"1.5\" opacity=\"0.6\"\/>'\n            + '<path d=\"M4.1 10.8c1.4-1.3 2.8-1.3 4.2 0s2.8 1.3 4.2 0s2.8-1.3 4.2 0\" stroke-width=\"1.4\" opacity=\"0.4\"\/>'\n            + '<\/svg>';\n    }\n\n    \/\/ Icono de oleaje: cambia forma\/color seg\u00fan la altura real (escala tipo Douglas)\n    function generarSvgOleaje(alturaMetros) {\n        if (alturaMetros === null || alturaMetros === undefined || isNaN(alturaMetros)) {\n            return { svg: '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0284c7\" stroke-width=\"2.5\"><path d=\"M2 12h2c1-1 2-1 3 0s2 1 3 0s2 1 3 0s2 1 3 0s2 1 3 0h2\"\/><\/svg>', color: '#0284c7', etiqueta: '' };\n        }\n        var color, etiqueta, amplitud, ondas;\n        if (alturaMetros < 0.3) { color = '#059669'; etiqueta = 'Mar en calma'; amplitud = 1.5; ondas = 3; }\n        else if (alturaMetros < 1) { color = '#0284c7'; etiqueta = 'Marejadilla'; amplitud = 3; ondas = 3; }\n        else if (alturaMetros < 2) { color = '#d97706'; etiqueta = 'Marejada'; amplitud = 4.5; ondas = 2; }\n        else { color = '#dc2626'; etiqueta = 'Fuerte marejada'; amplitud = 6; ondas = 2; }\n\n        var puntos = [];\n        var ancho = 24, centroY = 12, pasos = ondas * 8;\n        for (var i = 0; i <= pasos; i++) {\n            var x = (i \/ pasos) * ancho;\n            var y = centroY + Math.sin((i \/ pasos) * Math.PI * 2 * ondas) * amplitud;\n            puntos.push(x.toFixed(1) + ',' + y.toFixed(1));\n        }\n        var path = 'M' + puntos.join(' L');\n        var svg = '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"' + color + '\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"' + path + '\"\/><\/svg>';\n        return { svg: svg, color: color, etiqueta: etiqueta };\n    }\n\n    \/\/ Luna realista: dibuja el terminador exacto (curva d\u00eda\/noche) seg\u00fan la\n    \/\/ fracci\u00f3n iluminada real, en vez de 4 iconos fijos. waxing=true => se\n    \/\/ ilumina por la derecha (creciente), false => por la izquierda (menguante).\n    function generarSvgLunaFase(fraccionIluminada, waxing, idUnico) {\n        var r = 10;\n        var rx = r * Math.abs(1 - 2 * fraccionIluminada);\n        var s1 = waxing ? 1 : 0;\n        var s2 = fraccionIluminada < 0.5 ? (1 - s1) : s1;\n        var pathIluminado = `M 0,${-r} A ${r},${r} 0 0 ${s1} 0,${r} A ${rx.toFixed(3)},${r} 0 0 ${s2} 0,${-r} Z`;\n        var clipId = 'ecoLunaClip' + idUnico;\n\n        \/\/ Un pu\u00f1ado de \"cr\u00e1teres\" sutiles fijos para dar textura realista\n        var crateres = [\n            {cx: -3.2, cy: -4.5, r: 1.1}, {cx: 2.6, cy: -2.2, r: 0.7}, {cx: -1.4, cy: 1.8, r: 1.3},\n            {cx: 4.1, cy: 3.4, r: 0.6}, {cx: -4.6, cy: 4.6, r: 0.8}, {cx: 1.2, cy: 6.2, r: 0.5}\n        ].map(function(c) { return `<circle cx=\"${c.cx}\" cy=\"${c.cy}\" r=\"${c.r}\" fill=\"#000\" opacity=\"0.07\"\/>`; }).join('');\n\n        return `<svg viewBox=\"-11 -11 22 22\" style=\"width:24px; height:24px; overflow:visible; flex-shrink:0;\">\n            <defs>\n                <clipPath id=\"${clipId}\"><circle cx=\"0\" cy=\"0\" r=\"${r}\"\/><\/clipPath>\n                <radialGradient id=\"ecoLunaLuz${idUnico}\" cx=\"35%\" cy=\"30%\" r=\"75%\">\n                    <stop offset=\"0%\" stop-color=\"#fffdf5\"\/>\n                    <stop offset=\"100%\" stop-color=\"#e8dfc4\"\/>\n                <\/radialGradient>\n            <\/defs>\n            <g clip-path=\"url(#${clipId})\">\n                <circle cx=\"0\" cy=\"0\" r=\"${r}\" fill=\"#232a35\"\/>\n                <path d=\"${pathIluminado}\" fill=\"url(#ecoLunaLuz${idUnico})\"\/>\n                ${crateres}\n            <\/g>\n            <circle cx=\"0\" cy=\"0\" r=\"${r}\" fill=\"none\" stroke=\"#00000022\" stroke-width=\"0.4\"\/>\n        <\/svg>`;\n    }\n\n    function cargarDatoClima(lat, lon, elementoId, camId, tipoCamara) {\n        var proxyClimaBase = \"https:\/\/2026.ecoparquedetrasmiera.com\/wp-content\/themes\/kadence-child\/weather-proxy.php\";\n        var el = document.getElementById(elementoId);\n        \n        fetch(`${proxyClimaBase}?lat=${lat}&lon=${lon}&type=weather&v=${new Date().getTime()}`)\n            .then(r => {\n                if (!r.ok) throw new Error(\"HTTP Error \" + r.status);\n                return r.json();\n            })\n            .then(data => {\n                var weather = data.current_weather || data.current;\n                if (!weather) throw new Error(\"JSON vac\u00edo\");\n                \n                var tempAire = Math.round(weather.temperature || weather.temperature_2m);\n\t\t\t\tvar sensacionTermica = Math.round(weather.feels_like);\n                var code = weather.weathercode || weather.weather_code;\n                var velocidadViento = Math.round(weather.windspeed || weather.wind_speed_10m);\n                var direccionViento = weather.winddirection || weather.wind_direction_10m;\n                \n                var rosaVientos = [\"N\", \"NNE\", \"NE\", \"ENE\", \"E\", \"ESE\", \"SE\", \"SSE\", \"S\", \"SSW\", \"SW\", \"WSW\", \"W\", \"WNW\", \"NW\", \"NNW\"];\n                var indiceViento = Math.floor(((direccionViento + 11.25) % 360) \/ 22.5);\n                var puntoCardinal = rosaVientos[indiceViento] || \"N\";\n                \n                var rotacionFlecha = (direccionViento + 180) % 360;\n                var tiempoActual = new Date(weather.time).getTime();\n                var esNoche = false;\n                var htmlAstro = '';\n                var txtAmanecer = '--:--';\n                var txtAnochecer = '--:--';\n                \n                if (data.daily && data.daily.sunrise && data.daily.sunset) {\n                    var amanecerSec = new Date(data.daily.sunrise[0]);\n                    var anochecerSec = new Date(data.daily.sunset[0]);\n                    txtAmanecer = amanecerSec.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});\n                    txtAnochecer = anochecerSec.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});\n                    esNoche = (tiempoActual < amanecerSec.getTime() || tiempoActual > anochecerSec.getTime());\n                } else {\n                    var horaFija = new Date().getHours();\n                    esNoche = (horaFija < 6 || horaFija > 21);\n                }\n                \n                var indiceUVActual = \"0.0\";\n                var colorUV = \"#6b7a66\";\n\n                if (data.hourly && data.hourly.uv_index && data.hourly.time) {\n                    var timeRefActual = weather.time;\n                    var indexHora = data.hourly.time.indexOf(timeRefActual);\n                    if (indexHora === -1) indexHora = new Date().getHours();\n                    if (data.hourly.uv_index[indexHora] !== undefined) {\n                        var uvVal = parseFloat(data.hourly.uv_index[indexHora]);\n                        indiceUVActual = uvVal.toFixed(1);\n                        if (uvVal >= 3 && uvVal < 6) colorUV = \"#f97316\";\n                        else if (uvVal >= 6 && uvVal < 8) colorUV = \"#ef4444\";\n                        else if (uvVal >= 8) colorUV = \"#a855f7\";\n                    }\n                }\n                \n               var htmlColumnaViento = `\n                    <div style=\"width:50%; display:flex; flex-direction:column; justify-content:center; padding-left:14px; border-left:1px dashed #e2e6e1; box-sizing:border-box;\">\n                        <span style=\"font-size:10px; font-weight:700; color:#6b7a66; text-transform:uppercase; letter-spacing:0.3px; margin-bottom:4px; display:inline-flex; align-items:center; gap:4px;\">\n                            <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#6b7a66\" stroke-width=\"2.5\" style=\"width:12px; height:14px;\"><path d=\"M9.59 4.59A2 2 0 1 1 11 8H2m10.59 11.41A2 2 0 1 0 14 16H2m15.73-8.27A2.5 2.5 0 1 1 19.5 12H2\"\/><\/svg>\n                            VIENTO ACTUAL\n                        <\/span>\n                        <span style=\"font-size:14px; font-weight:800; color:#1a2e16; line-height:1.2;\">${velocidadViento} <span style=\"font-size:11px; font-weight:600; color:#4e584a;\">km\/h<\/span><\/span>\n                        <span style=\"font-size:11px; font-weight:700; color:#4e584a; margin-top:2px; display:inline-flex; align-items:center; gap:6px; line-height:1.2;\">\n                            Dir: <span style=\"color:#1a2e16; font-weight:800;\">${puntoCardinal}<\/span>\n                            <span class=\"eco-flecha-viento-anim\" style=\"--rotacion-viento: ${rotacionFlecha}deg;\">\n                                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#1a2e16\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"5\"\/><polyline points=\"5 12 12 5 19 12\"\/><\/svg>\n                            <\/span>\n                        <\/span>\n                        \n                        <!-- FILA CONJUNTA OPTIMIZADA: Altura controlada para no estirar la izquierda -->\n                        <div style=\"display:flex; flex-wrap:wrap; gap:12px; margin-top:6px; font-size:10.5px; font-weight:600; color:#4e584a; line-height:1.2;\">\n                            <span style=\"display:inline-flex; align-items:center; gap:4px;\">\n                                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0284c7\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:11px; height:11px; flex-shrink:0;\"><path d=\"M12 2.69S5 10.18 5 15a7 7 0 0 0 14 0c0-4.82-7-12.31-7-12.31z\"\/><\/svg>\n                                Hum: <strong style=\"color:#0284c7;\">${weather.humidity ?? 0}%<\/strong>\n                            <\/span>\n                            <span style=\"display:inline-flex; align-items:center; gap:4px;\">\n                                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ff9800\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:11px; height:11px; flex-shrink:0;\"><path d=\"M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z\"\/><\/svg>\n                                Sen. T\u00e9rmica: <strong style=\"color:#1a2e16;\">${sensacionTermica}\u00b0C<\/strong>\n                            <\/span>\n                        <\/div>\n                    <\/div>\n                `;\n\n                if (!esNoche) {\n                    htmlAstro = `\n                        <div class=\"eco-astro-box\" style=\"margin-top:14px; padding:12px 14px; background:#fcfdfc; border:1px solid #e2e6e1; border-radius:12px; font-family:inherit; display:flex; gap:0; box-sizing:border-box; width:100%; align-items:stretch;\">\n                            <div style=\"width:50%; display:flex; flex-direction:column; justify-content:center; gap:5px; padding-right:10px; box-sizing:border-box;\">\n                                <div style=\"display:flex; flex-direction:column; gap:5px; font-size:10px; color:#4e584a; font-weight:700;\">\n                                    \n                                    <!-- AMANECER: Icono de Sol saliendo -->\n                                    <span style=\"display:inline-flex; align-items:center; gap:6px; color:#6b7a66; height:14px; line-height:14px;\">\n                                        <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ff9800\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:13px; height:13px; flex-shrink:0; display:block;\"><path d=\"M12 2v2M4.93 4.93l1.41 1.41M20 12h2M17.66 6.34l1.41-1.41M2 22h20M19 22a7 7 0 0 0-14 0\"\/><\/svg>\n                                        AMANECER: <span style=\"color:#1a2e16; margin-left:auto; font-weight:800;\">${txtAmanecer}<\/span>\n                                    <\/span>\n                                    \n                                    <!-- ATARDECER: Icono de Luna creciente minimalista -->\n                                    <span style=\"display:inline-flex; align-items:center; gap:6px; color:#6b7a66; height:14px; line-height:14px;\">\n                                        <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#7c3aed\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"width:13px; height:13px; flex-shrink:0; display:block;\"><path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9z\"\/><\/svg>\n                                        ATARDECER: <span style=\"color:#1a2e16; margin-left:auto; font-weight:800;\">${txtAnochecer}<\/span>\n                                    <\/span>\n                                    \n                                <\/div>\n                                <div style=\"margin-top:4px; padding-top:5px; border-top:1px dashed #e2e6e1; display:flex; justify-content:space-between; align-items:center; font-size:10px; font-weight:700; color:#6b7a66; height:15px;\">\n                                    <span style=\"display:inline-flex; align-items:center; gap:5px; height:14px;\">\n                                        <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${colorUV}\" stroke-width=\"2.5\" style=\"width:13px; height:13px; flex-shrink:0;\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><path d=\"M12 8v4M12 16h.01\"\/><\/svg>\n                                        \u00cdNDICE UV:\n                                    <\/span>\n                                    <span style=\"color:${colorUV}; font-weight:800; font-size:11px;\">${indiceUVActual}<\/span>\n                                <\/div>\n                            <\/div>\n                            ${htmlColumnaViento}\n                        <\/div>\n                    `;\n                } else {\n                    var faseAPI = (data.daily && data.daily.moon_phase) ? data.daily.moon_phase[0] : 0.5;\n                    \/\/ Fracci\u00f3n real iluminada (0=luna nueva, 1=luna llena), curva continua\n                    var fraccionIluminada = (1 - Math.cos(2 * Math.PI * faseAPI)) \/ 2;\n                    var esCreciente = faseAPI < 0.5;\n                    var nombreFase = \"Fase Lunar\";\n                    var iluminacionEstimada = Math.round(fraccionIluminada * 100) + \"%\";\n\n                    if (faseAPI >= 0.485 && faseAPI <= 0.515) {\n                        nombreFase = \"Luna Llena\";\n                    } else if (faseAPI <= 0.015 || faseAPI >= 0.985) {\n                        nombreFase = \"Luna Nueva\";\n                    } else if (esCreciente) {\n                        nombreFase = \"Luna Creciente\";\n                    } else {\n                        nombreFase = \"Luna Menguante\";\n                    }\n                    var svgLunaFase = generarSvgLunaFase(fraccionIluminada, esCreciente, camId);\n\n                    htmlAstro = `\n                        <div class=\"eco-astro-box\" style=\"margin-top:14px; padding:12px 14px; background:#f9fafb; border:1px solid #e5e7eb; border-radius:12px; font-family:inherit; display:flex; gap:0; box-sizing:border-box; width:100%; align-items:stretch;\">\n                            <div style=\"width:50%; display:flex; align-items:center; gap:10px; padding-right:10px; box-sizing:border-box;\">\n                                <div style=\"flex-shrink:0; display:flex; align-items:center;\">\n                                    ${svgLunaFase}\n                                <\/div>\n                                <div style=\"display:flex; flex-direction:column; justify-content:center;\">\n                                    <span style=\"font-size:11px; font-weight:800; color:#1a2e16; line-height:1.2; white-space:nowrap;\">\n                                        ${nombreFase}\n                                    <\/span>\n                                    <span style=\"font-size:10px; font-weight:600; color:#6b7a66; margin-top:2px;\">Ilum: ${iluminacionEstimada}<\/span>\n                                <\/div>\n                            <\/div>\n                            ${htmlColumnaViento}\n                        <\/div>\n                    `;\n                }\n                \n                if (camId && htmlAstro !== '') {\n                    var contenedorAstro = document.getElementById('astro-lista-' + camId);\n                    if (contenedorAstro) { contenedorAstro.innerHTML = htmlAstro; }\n                }\n\n                var htmlClima;\n                if (el) {\n                    htmlClima = `<a href=\"https:\/\/www.eltiempo.es\/arnuero.html\" target=\"_blank\" rel=\"noopener\" class=\"eco-clima-link-pildora\"><div class=\"eco-clima-flex-render\"><span>${tempAire}\u00b0C<\/span>${generarSvgClima(code, esNoche)}<\/div><\/a>`;\n                    el.innerHTML = htmlClima;\n                }\n\n               \/\/ Avisos oficiales AEMET (color real amarillo\/naranja\/rojo), ya filtrados\n                \/\/ por el proxy seg\u00fan si el punto de esta webcam cae en el pol\u00edgono del aviso.\n                if (camId) {\n                    var contenedorAvisos = document.getElementById('avisos-lista-' + camId);\n                    if (contenedorAvisos) {\n                        if (data.alerts && data.alerts.length > 0) {\n                            var ahoraMs = Date.now();\n                            var iconoAviso = '<svg class=\"aviso-icono\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0zM12 9v4M12 17h.01\"\/><\/svg>';\n\n                            var prefijoDiaAviso = function(fecha) {\n                                var hoy = new Date();\n                                var d0 = new Date(hoy.getFullYear(), hoy.getMonth(), hoy.getDate());\n                                var d1 = new Date(fecha.getFullYear(), fecha.getMonth(), fecha.getDate());\n                                var diffDias = Math.round((d1 - d0) \/ 86400000);\n                                if (diffDias <= 0) return '';\n                                if (diffDias === 1) return 'ma\u00f1ana';\n                                if (diffDias < 7) return fecha.toLocaleDateString('es-ES', {weekday: 'long'});\n                                return fecha.toLocaleDateString('es-ES', {day: 'numeric', month: 'short'});\n                            };\n\n                            var avisoEstaActivo = function(aviso) {\n    var inicioMs = aviso.start ? aviso.start * 1000 : null;\n    var finMs = aviso.end ? aviso.end * 1000 : null;\n    if (inicioMs !== null && ahoraMs < inicioMs) return false; \/\/ todav\u00eda no ha empezado\n    if (finMs !== null && ahoraMs > finMs) return false; \/\/ ya ha terminado\n    return true; \/\/ sin start expl\u00edcito (ya en marcha) o dentro del rango\n};\n\n                            var avisoEmpiezaHoyOManana = function(aviso) {\n    var inicioMs = aviso.start ? aviso.start * 1000 : null;\n    if (inicioMs === null || inicioMs <= ahoraMs) return false;\n    var hoy = new Date();\n    var d0 = new Date(hoy.getFullYear(), hoy.getMonth(), hoy.getDate());\n    var fechaInicio = new Date(inicioMs);\n    var d1 = new Date(fechaInicio.getFullYear(), fechaInicio.getMonth(), fechaInicio.getDate());\n    var diffDias = Math.round((d1 - d0) \/ 86400000);\n    return diffDias === 0 || diffDias === 1; \/\/ m\u00e1s tarde hoy, o ma\u00f1ana\n};\n\n\/\/ Activos ahora, o que empiecen m\u00e1s tarde hoy, o ma\u00f1ana (nunca m\u00e1s lejos)\nvar alertasCandidatas = data.alerts.filter(function(aviso) {\n    return avisoEstaActivo(aviso) || avisoEmpiezaHoyOManana(aviso);\n});\n\n                            \/\/ Si hay activos hoy, ocultamos los de ma\u00f1ana hasta que se desactiven\n                            var hayActivosHoy = alertasCandidatas.some(avisoEstaActivo);\n                            var alertasFinalAviso = hayActivosHoy\n                                ? alertasCandidatas.filter(avisoEstaActivo)\n                                : alertasCandidatas;\n\n                            if (alertasFinalAviso.length > 0) {\n                                var htmlAvisos = alertasFinalAviso.map(function(aviso) {\n                                    var nivel = aviso.nivel || 'amarillo';\n                                    var inicioMs = aviso.start ? aviso.start * 1000 : null;\n                                    var finMs = aviso.end ? aviso.end * 1000 : null;\n                                    var horaInicio = inicioMs ? new Date(inicioMs).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}) : null;\n                                    var horaFin = finMs ? new Date(finMs).toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'}) : null;\n                                    var esProximo = !avisoEstaActivo(aviso);\n\n                                    var horarioTxt = '';\n                                    if (esProximo) {\n                                        var diaInicio = prefijoDiaAviso(new Date(inicioMs));\n                                        if (horaInicio && horaFin) {\n                                            horarioTxt = diaInicio ? `${diaInicio}: ${horaInicio}h-${horaFin}h` : `${horaInicio}h-${horaFin}h`;\n                                        } else if (horaInicio) {\n                                            horarioTxt = diaInicio ? `${diaInicio}: desde las ${horaInicio}h` : `desde las ${horaInicio}h`;\n                                        }\n                                    } else if (horaFin) {\n                                        horarioTxt = `hasta las ${horaFin}h`;\n                                    }\n\n                                    var descHtml = aviso.description ? `<div class=\"aviso-desc\">${aviso.description}<\/div>` : '';\n                                    var nivelClase = esProximo ? 'proximo' : nivel;\n                                    var lineaSuperior = esProximo ? 'Pr\u00f3ximo aviso' : aviso.event;\n                                    var lineaSecundaria = esProximo ? `<div class=\"aviso-subtipo\">${aviso.event}<\/div>` : '';\n\n                                    return `<div class=\"eco-aviso-aemet nivel-${nivelClase}\">\n                                        ${iconoAviso}\n                                        <div class=\"aviso-txt\">\n                                            <div class=\"aviso-fila-superior\">\n                                                <span class=\"aviso-evento\">${lineaSuperior}<\/span>\n                                                ${horarioTxt ? `<span class=\"aviso-horario-txt\">${horarioTxt}<\/span>` : ''}\n                                            <\/div>\n                                            ${lineaSecundaria}\n                                            ${descHtml}\n                                        <\/div>\n                                    <\/div>`;\n                                }).join('');\n                                contenedorAvisos.innerHTML = htmlAvisos;\n                            } else {\n                                contenedorAvisos.innerHTML = '';\n                            }\n                        } else {\n                            contenedorAvisos.innerHTML = '';\n                        }\n                    }\n                }\n\n                if (tipoCamara === 'playa' && camId) {\n                    var urlMar = `${proxyClimaBase}?lat=${lat}&lon=${lon}&type=marine`;\n\n                    fetch(urlMar).then(rm => rm.ok ? rm.json() : { error: 'HTTP ' + rm.status })\n                        .then((dataMar) => {\n                            var tempAgua = 19;\n                            if (dataMar && !dataMar.error && dataMar.current && dataMar.current.sea_surface_temperature !== null && dataMar.current.sea_surface_temperature !== undefined) {\n                                tempAgua = Math.round(dataMar.current.sea_surface_temperature);\n                            }\n\n                            var alturaOleaje = (dataMar && dataMar.current && typeof dataMar.current.altura_oleaje === 'number') ? dataMar.current.altura_oleaje : null;\n                            var oleajeInfo = generarSvgOleaje(alturaOleaje);\n                            var pildoraOleaje = alturaOleaje !== null\n                                ? `<div class=\"eco-clima-flex-render eco-oleaje-pildora\" style=\"border-color:${oleajeInfo.color}33;\" title=\"${oleajeInfo.etiqueta}\"><span style=\"color:${oleajeInfo.color};\">${alturaOleaje.toFixed(1)}m<\/span>${oleajeInfo.svg}<\/div>`\n                                : '';\n\n                            if (el) {\n                                el.innerHTML = htmlClima\n                                    + `<a href=\"https:\/\/www.eltiempo.es\/cantabria\/playas\" target=\"_blank\" rel=\"noopener\" class=\"eco-clima-link-pildora\"><div class=\"eco-clima-flex-render eco-mar-pildora\"><span>${tempAgua}\u00b0C<\/span>${generarSvgOlaMar()}<\/div><\/a>`\n                                    + pildoraOleaje;\n                            }\n\n                            var txtMarea = \"Marea\", horaMareaStr = \"--:--h\", alturaCalculada = \"0.00\", etiquetaSubLabel = \"\", esPleamar = false;\n                            var eventosMarea = (dataMar && Array.isArray(dataMar.eventos)) ? dataMar.eventos : [];\n\n                            \/\/ Si el proxy ya nos da la altura actual real (curva de 5 min oficial),\n                            \/\/ la usamos directamente en vez de interpolar en el cliente.\n                            if (dataMar && dataMar.current && dataMar.current.altura_marea !== null && dataMar.current.altura_marea !== undefined) {\n                                alturaCalculada = dataMar.current.altura_marea.toFixed(2);\n                            }\n\n                            if (eventosMarea.length > 0) {\n                                var ahoraMs = Date.now(), anterior = null, siguiente = null;\n                                for (var i = 0; i < eventosMarea.length; i++) {\n                                    var tsEvento = eventosMarea[i].timestamp * 1000;\n                                    if (tsEvento <= ahoraMs) { anterior = eventosMarea[i]; }\n                                    else { siguiente = eventosMarea[i]; break; }\n                                }\n\n                                if (siguiente) {\n                                    esPleamar = (siguiente.tipo === 'pleamar');\n                                    txtMarea = esPleamar ? 'Pleamar' : 'Bajamar';\n                                    horaMareaStr = siguiente.hora + 'h';\n                                    etiquetaSubLabel = `(${esPleamar ? 'M\u00e1x' : 'M\u00edn'}: ${siguiente.altura.toFixed(2)}m) `;\n\n                                    \/\/ Fallback por si el proxy no trajo altura_marea de la curva de 5 min\n                                    if (alturaCalculada === \"0.00\" && anterior) {\n                                        var t0 = anterior.timestamp * 1000, t1 = siguiente.timestamp * 1000;\n                                        var progreso = (ahoraMs - t0) \/ (t1 - t0);\n                                        var altura = anterior.altura + (siguiente.altura - anterior.altura) * (1 - Math.cos(Math.PI * progreso)) \/ 2;\n                                        alturaCalculada = altura.toFixed(2);\n                                    }\n                                }\n                            }\n\n                            var svgMareaUp = `<span class=\"eco-flecha-marea-anim\"><svg viewBox=\"0 0 24 24\" style=\"width:16px;height:16px;display:block;\"><path d=\"M12 21V3M12 3l-6 6m6-6l6 6\" stroke=\"#0284c7\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"\/><\/svg><\/span>`;\n                            var svgMareaDown = `<span class=\"eco-flecha-marea-anim\"><svg viewBox=\"0 0 24 24\" style=\"width:16px;height:16px;display:block;\"><path d=\"M12 3v18M12 21l-6-6m6 6l6-6\" stroke=\"#0284c7\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"\/><\/svg><\/span>`;\n                            var svgReloj = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#0284c7\" stroke-width=\"2.5\" style=\"width:16px;height:16px;\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><path d=\"M12 6v6l4 2\"\/><\/svg>`;\n\n                            var contenedorMarino = document.getElementById(`marino-lista-${camId}`);\n                            if (contenedorMarino) {\n                                contenedorMarino.innerHTML = `\n                                    <a href=\"https:\/\/ideihm.covam.es\/api-ihm\/getmarea?request=gettide&id=3&format=txt\" target=\"_blank\" rel=\"noopener\" class=\"eco-marino-link-wrap\">\n                                        <div class=\"eco-marino-pildora-unica\">\n                                            <div class=\"eco-marino-seccion\">${(esPleamar ? svgMareaUp : svgMareaDown)}<div class=\"eco-marino-meta\"><span class=\"eco-marino-label\">Siguiente marea<\/span><span class=\"eco-marino-valor\">${txtMarea}<\/span><\/div><\/div>\n                                            <div class=\"eco-marino-separador\"><\/div>\n                                            <div class=\"eco-marino-seccion\">${svgReloj}<div class=\"eco-marino-meta\"><span class=\"eco-marino-hora-valor\">${horaMareaStr}<\/span><span class=\"eco-marino-label-sub\">${etiquetaSubLabel}<\/span><\/div><\/div>\n                                            <div class=\"eco-marino-separador\"><\/div>\n                                            <div class=\"eco-marino-seccion\"><div class=\"eco-marino-meta\"><span class=\"eco-marino-label\">Altura actual<\/span><span class=\"eco-marino-valor\">${alturaCalculada} metros<\/span><\/div><\/div>\n                                        <\/div>\n                                    <\/a>\n                                `;\n                            }\n                        })\n                        .catch(errMar => {\n                            var contMar = document.getElementById(`marino-lista-${camId}`);\n                            if (contMar) contMar.innerHTML = `<span style=\"font-size:10px; color:#ef4444;\">Error Mar: ${errMar.message}<\/span>`;\n                        });\n                }\n            })\n            .catch(err => {\n                if (el) el.innerHTML = `<span style=\"font-size:11px; font-weight:bold; color:#ef4444; background:#fee2e2; padding:4px 8px; border-radius:4px;\">Error: ${err.message}<\/span>`;\n            });\n    }\n\n    function inicializarModuloWebcams() {\n        if (typeof Hls === 'undefined' || typeof Plyr === 'undefined') {\n            setTimeout(inicializarModuloWebcams, 150);\n            return;\n        }\n\n        var contenedorLista = document.getElementById('eco-webcams-render-lista');\n        if (!contenedorLista) {\n            setTimeout(inicializarModuloWebcams, 100);\n            return;\n        }\n\n        var htmlCards = '';\n        webcamsData.forEach(function(cam) {\n            var tienePlaya = (cam.tipo === 'playa');\n            var bloqueMarinoInicial = tienePlaya ? `<div class=\"eco-bloque-marino\" id=\"marino-lista-${cam.id}\"><div class=\"eco-skeleton eco-skeleton-bloque\"><\/div><\/div>` : `<div class=\"eco-bloque-marino\" id=\"marino-lista-${cam.id}\"><\/div>`;\n            var archivoLimpio = cam.file.trim();\n\n            \/\/ Car\u00e1tula (miniatura est\u00e1tica) de la c\u00e1mara: mismo UUID que el .m3u8,\n            \/\/ servida por tendsys en formato jpg. La pasamos por el mismo proxy que\n            \/\/ el v\u00eddeo para evitar bloqueos de referer\/hotlink, con t= para evitar cach\u00e9.\n            var idCaratula = archivoLimpio.replace('.m3u8', '');\n            var urlCaratula = `${proxyUrlBase}?file=${idCaratula}.jpg&t=${Date.now()}`;\n\n            htmlCards += `\n                <div class=\"eco-tarjeta-recinto\" data-entorno=\"${cam.tipo || 'playa'}\">\n                    <div class=\"eco-video-container-lista\" id=\"wrapper-lista-${cam.id}\" data-cam-id=\"${cam.id}\" data-file=\"${archivoLimpio}\" data-poster=\"${urlCaratula}\">\n                        <div class=\"badge-en-vivo\"><span class=\"punto-parpadeo\"><\/span>EN DIRECTO<\/div>\n                        <div class=\"eco-video-placeholder\" style=\"background-image:url('${urlCaratula}'); background-size:cover; background-position:center;\"><\/div>\n                        <button type=\"button\" class=\"eco-play-overlay\" aria-label=\"Reproducir ${cam.titulo}\"><i class=\"fa-solid fa-play\"><\/i><\/button>\n                    <\/div>\n                    <div class=\"eco-tarjeta-cuerpo\">\n                        <div class=\"eco-tarjeta-cabecera-flex\" style=\"display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; width:100%; gap:8px;\">\n                            <h4 class=\"eco-tarjeta-titulo\" style=\"margin:0;\">${cam.titulo}<\/h4>\n                            <div class=\"eco-popup-clima-info\" id=\"clima-lista-${cam.id}\" style=\"display:flex; gap:6px; justify-content:end;\"><div class=\"eco-skeleton eco-skeleton-pildora\"><\/div>${tienePlaya ? `<div class=\"eco-skeleton eco-skeleton-pildora\"><\/div>` : ''}<\/div>\n                        <\/div>\n\n                        <div class=\"eco-avisos-contenedor\" id=\"avisos-lista-${cam.id}\"><\/div>\n                        <div class=\"eco-bloque-astronomico\" id=\"astro-lista-${cam.id}\"><\/div>\n                        \n                        ${bloqueMarinoInicial}\n                    <\/div>\n                <\/div>\n            `;\n        });\n        contenedorLista.innerHTML = htmlCards;\n\n        \/\/ Ya NO se arranca ning\u00fan stream HLS aqu\u00ed: solo se piden los datos ligeros\n        \/\/ de tiempo\/marea\/avisos. El v\u00eddeo de cada c\u00e1mara se crea \u00fanicamente\n        \/\/ cuando el usuario pulsa el bot\u00f3n de play (ver iniciarReproduccionTarjeta).\n        webcamsData.forEach(function(cam) {\n            cargarDatoClima(cam.lat, cam.lon, 'clima-lista-' + cam.id, cam.id, cam.tipo);\n        });\n\n        \/\/ Si se renderiza una sola c\u00e1mara en un recinto, no procesamos la l\u00f3gica de pesta\u00f1as\/mapas\n        if (camaraFiltradaTarget) return;\n\n        var esPortada = document.body.classList.contains('home') || document.body.classList.contains('front-page');\n        var esMovil = window.innerWidth <= 767;\n\n        if (esPortada) {\n            var contenedorMapaArr = document.getElementById('eco-webcam-vista-mapa');\n            if (contenedorMapaArr) contenedorMapaArr.style.display = 'none';\n            var contenedorListaArr = document.getElementById('eco-webcam-vista-lista');\n            if (contenedorListaArr) { contenedorListaArr.style.display = 'block'; contenedorListaArr.classList.add('eco-activa'); }\n        } else {\n            if (esMovil) {\n                var vLista = document.getElementById('eco-webcam-vista-lista');\n                if(vLista) vLista.classList.add('eco-activa');\n            } else {\n                var vMapa = document.getElementById('eco-webcam-vista-mapa');\n                if(vMapa) vMapa.classList.add('eco-activa'); \n            }\n        }\n    }\n\n    \/\/ Arranca el stream HLS de una tarjeta bajo demanda (solo al pulsar play).\n    \/\/ Hasta ese momento no se ha abierto ninguna conexi\u00f3n de streaming: el\n    \/\/ ahorro de datos\/CPU es m\u00e1ximo cuando hay varias c\u00e1maras en la p\u00e1gina.\n    function iniciarReproduccionTarjeta(wrapper) {\n        if (!wrapper || wrapper.dataset.iniciado === '1') return;\n        if (typeof Hls === 'undefined' || typeof Plyr === 'undefined') return;\n        wrapper.dataset.iniciado = '1';\n\n        var camId = wrapper.getAttribute('data-cam-id');\n        var file = wrapper.getAttribute('data-file');\n        var posterUrl = wrapper.getAttribute('data-poster') || '';\n        var streamUrl = `${proxyUrlBase}?file=${file}`;\n\n        \/\/ Mientras el stream real est\u00e1 cargando, dejamos la car\u00e1tula visible\n        \/\/ (con un spinner encima) en vez de dejar la caja en negro.\n        wrapper.classList.add('cargando');\n        var spinner = document.createElement('div');\n        spinner.className = 'eco-video-loading-spinner';\n        wrapper.appendChild(spinner);\n\n        var video = document.createElement('video');\n        video.id = 'video-lista-' + camId;\n        video.controls = false;\n        video.crossOrigin = 'anonymous';\n        video.playsInline = true;\n        video.muted = true;\n        video.autoplay = true;\n        if (posterUrl) video.poster = posterUrl;\n        wrapper.appendChild(video);\n\n        \/\/ Solo cuando llega el primer frame real quitamos la car\u00e1tula\/spinner\n        \/\/ y mostramos el v\u00eddeo, evitando el parpadeo\/negro intermedio.\n        var yaListo = false;\n        function marcarListo() {\n            if (yaListo) return;\n            yaListo = true;\n            if (spinner && spinner.parentNode) spinner.parentNode.removeChild(spinner);\n            wrapper.classList.remove('cargando');\n            wrapper.classList.add('iniciada');\n        }\n        video.addEventListener('playing', marcarListo);\n\n        var hlsCard = new Hls({ maxBufferLength: 4, manifestLoadingMaxRetry: 2, levelLoadingMaxRetry: 2 });\n        hlsCard.loadSource(streamUrl);\n        hlsCard.attachMedia(video);\n        window.ecoHlsInstances[camId] = hlsCard;\n\n        hlsCard.on(Hls.Events.MANIFEST_PARSED, function() {\n            window.ecoPlyrInstances[camId] = new Plyr(video, {\n                controls: ['play', 'mute', 'volume', 'fullscreen'],\n                fullscreen: { enabled: true, fallback: true, iosNative: true }\n            });\n            video.play().catch(function(){});\n        });\n        hlsCard.on(Hls.Events.ERROR, function(event, data) {\n            if (data.fatal) {\n                hlsCard.destroy();\n                wrapper.innerHTML = `<div class=\"eco-camara-caida-aviso\"><svg viewBox=\"0 0 24 24\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0zM12 9v4M12 17h.01\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg><p>C\u00e1mara fuera de servicio.<\/p><\/div>`;\n            }\n        });\n    }\n\n    document.addEventListener('DOMContentLoaded', function() {\n        \/\/ Delegaci\u00f3n de eventos: arranca el v\u00eddeo de una tarjeta solo al pulsar su bot\u00f3n de play\n        document.addEventListener('click', function(e) {\n            var btn = e.target.closest('.eco-play-overlay');\n            if (btn) {\n                var wrapper = btn.closest('.eco-video-container-lista');\n                iniciarReproduccionTarjeta(wrapper);\n            }\n        });\n    });\n\n    if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', inicializarModuloWebcams);\n    } else {\n        inicializarModuloWebcams();\n    }\n    <\/script>\n    \n\n\n\n<style data-wp-block-html=\"css\">\n#eco-seccion-webcams-unificada {\npadding: 0px!important;\n}\n<\/style>\n","protected":false},"excerpt":{"rendered":"<p>La playa del Sable se encuentra en el n\u00facleo de Isla Playa, siendo una playa de car\u00e1cter urbano y familiar. Muy animada en periodo estival y tranquile el resto del a\u00f1o, con fina arena dorada es ideal para familias con ni\u00f1os peque\u00f1os, ya que se encuentra resguardada por un islote rocoso que le hace similar&#8230;<\/p>\n","protected":false},"featured_media":4951,"template":"","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"","_eb_attr":"","_kadence_starter_templates_imported_post":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","_latwm_translated_slug":"","_VenueAddress":"","_VenueCity":"Isla","_VenuePhone":"","_VenueURL":"","_eco_lugar_latitud":"43.4986246","_eco_lugar_longitud":"-3.5422134","_eco_lugar_icono":"playa","_eco_bandera_azul":"si","_eco_q_calidad":"si","_eco_horarios_info":"Abierto 24h","_eco_acceso_libre":"si","_eco_accesibilidad":"si","_eco_enlace_reserva":"","_eco_informacion_contacto":"","_eco_ocultar_sitio":"no","_eco_destacar_en_home":"no"},"categoria_recinto_propio":[21],"class_list":["post-4295","eco_recintos","type-eco_recintos","status-publish","has-post-thumbnail","hentry","categoria_recinto_propio-playas"],"_links":{"self":[{"href":"https:\/\/2026.ecoparquedetrasmiera.com\/en-gb\/wp-json\/wp\/v2\/eco_recintos\/4295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/2026.ecoparquedetrasmiera.com\/en-gb\/wp-json\/wp\/v2\/eco_recintos"}],"about":[{"href":"https:\/\/2026.ecoparquedetrasmiera.com\/en-gb\/wp-json\/wp\/v2\/types\/eco_recintos"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/2026.ecoparquedetrasmiera.com\/en-gb\/wp-json\/wp\/v2\/media\/4951"}],"wp:attachment":[{"href":"https:\/\/2026.ecoparquedetrasmiera.com\/en-gb\/wp-json\/wp\/v2\/media?parent=4295"}],"wp:term":[{"taxonomy":"categoria_recinto_propio","embeddable":true,"href":"https:\/\/2026.ecoparquedetrasmiera.com\/en-gb\/wp-json\/wp\/v2\/categoria_recinto_propio?post=4295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}