{"id":4637,"date":"2021-11-01T10:43:25","date_gmt":"2021-11-01T03:43:25","guid":{"rendered":"https:\/\/science4conservation.com\/?page_id=4637"},"modified":"2026-08-24T19:48:56","modified_gmt":"2026-08-24T12:48:56","slug":"perlindungan-sarang-penyu-dan-pemantauan-aktivitas-peneluran","status":"publish","type":"page","link":"https:\/\/science4conservation.com\/en\/konservasi-penyu-belimbing-berbasis-pendekatan-holistik\/pemantauan-penyu-dan-perlindungan-sarang\/perlindungan-sarang-penyu-dan-pemantauan-aktivitas-peneluran\/","title":{"rendered":"Perlindungan Sarang Penyu &#038; Pemantauan Aktivitas Peneluran"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"4637\" class=\"elementor elementor-4637\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-2cf3372 elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"2cf3372\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-no\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1b35e84\" data-id=\"1b35e84\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-c88d183 elementor-widget elementor-widget-image\" data-id=\"c88d183\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img fetchpriority=\"high\" decoding=\"async\" width=\"2480\" height=\"800\" src=\"https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website.jpg\" class=\"attachment-full size-full wp-image-21922\" alt=\"\" srcset=\"https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website.jpg 2480w, https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website-300x97.jpg 300w, https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website-1024x330.jpg 1024w, https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website-768x248.jpg 768w, https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website-1536x495.jpg 1536w, https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website-2048x661.jpg 2048w, https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website-1200x387.jpg 1200w, https:\/\/science4conservation.com\/wp-content\/uploads\/2026\/08\/Header-Website-1980x639.jpg 1980w\" sizes=\"(max-width: 2480px) 100vw, 2480px\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-d6ab6c1 elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"d6ab6c1\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-no\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-702b042\" data-id=\"702b042\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-1358641 elementor-widget elementor-widget-text-editor\" data-id=\"1358641\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><strong>Perlindungan Sarang Penyu &amp; Pemantauan Aktivitas Peneluran<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fb6b24c elementor-widget elementor-widget-text-editor\" data-id=\"fb6b24c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Pemulihan populasi penyu belimbing bertumpu pada produksi tukik yang cukup dari pantai peneluran dan tingkat mortalitas di laut. Oleh sebab itu tim pemantauan penyu dan perlindungan sarang LPPM UNIPA bersama anggota masyarakat lokal berupaya keras untuk meningkatkan jumlah tukik yang dihasilkan dengan melindungi sarang. Pemantauan aktivitas peneluran yang dilakukan secara rutin agar tersedia data-data yang dapat digunakan untuk menyusun strategi-strategi yang mendukung pemulihan populasi penyu belimbing di wilayah ini. Simak kumpulan artikel tentang kegiatan yang kami lakukan di lapang.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7a1cf76 elementor-widget elementor-widget-html\" data-id=\"7a1cf76\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n\r\n<link\r\n    href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:wght@400;500;600&family=Poppins:wght@500;600;700&display=swap\"\r\n    rel=\"stylesheet\"\r\n>\r\n\r\n\r\n<div class=\"custom-news-section\" id=\"customNewsSlider\">\r\n\r\n    <button\r\n        class=\"custom-news-nav custom-news-prev is-hidden\"\r\n        type=\"button\"\r\n        aria-label=\"Berita sebelumnya\"\r\n    >\r\n        &#10094;\r\n    <\/button>\r\n\r\n\r\n    <div class=\"custom-news-track\">\r\n\r\n        <div class=\"custom-news-skeleton initial-skeleton\">\r\n            <div class=\"skeleton-image skeleton-animation\"><\/div>\r\n\r\n            <div class=\"skeleton-content\">\r\n                <div class=\"skeleton-date skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-category skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-title skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-title skeleton-title-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-text-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-button skeleton-animation\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n\r\n        <div class=\"custom-news-skeleton initial-skeleton\">\r\n            <div class=\"skeleton-image skeleton-animation\"><\/div>\r\n\r\n            <div class=\"skeleton-content\">\r\n                <div class=\"skeleton-date skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-category skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-title skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-title skeleton-title-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-text-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-button skeleton-animation\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n\r\n        <div class=\"custom-news-skeleton initial-skeleton\">\r\n            <div class=\"skeleton-image skeleton-animation\"><\/div>\r\n\r\n            <div class=\"skeleton-content\">\r\n                <div class=\"skeleton-date skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-category skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-title skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-title skeleton-title-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-text-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-button skeleton-animation\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n\r\n        <div class=\"custom-news-skeleton initial-skeleton\">\r\n            <div class=\"skeleton-image skeleton-animation\"><\/div>\r\n\r\n            <div class=\"skeleton-content\">\r\n                <div class=\"skeleton-date skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-category skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-title skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-title skeleton-title-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-animation\"><\/div>\r\n                <div class=\"skeleton-text skeleton-text-short skeleton-animation\"><\/div>\r\n\r\n                <div class=\"skeleton-button skeleton-animation\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n\r\n    <\/div>\r\n\r\n\r\n    <button\r\n        class=\"custom-news-nav custom-news-next is-hidden\"\r\n        type=\"button\"\r\n        aria-label=\"Berita berikutnya\"\r\n    >\r\n        &#10095;\r\n    <\/button>\r\n\r\n\r\n    <div\r\n        class=\"custom-news-pagination\"\r\n        aria-label=\"Navigasi halaman berita\"\r\n    ><\/div>\r\n\r\n<\/div>\r\n\r\n\r\n<style>\r\n\r\n.custom-news-section {\r\n    --primary: #1E73BE;\r\n    --primary-dark: #155A96;\r\n    --primary-soft: rgba(30, 115, 190, 0.11);\r\n    --title-color: #152033;\r\n    --text-color: #64748B;\r\n\r\n    position: relative;\r\n\r\n    width: 100%;\r\n\r\n    box-sizing: border-box;\r\n\r\n    padding: 20px 5px 15px;\r\n}\r\n\r\n\r\n\/* TRACK *\/\r\n\r\n.custom-news-track {\r\n    display: flex;\r\n\r\n    align-items: stretch;\r\n\r\n    gap: 24px;\r\n\r\n    width: 100%;\r\n\r\n    overflow-x: auto;\r\n    overflow-y: hidden;\r\n\r\n    scroll-behavior: smooth;\r\n\r\n    scroll-snap-type: x mandatory;\r\n\r\n    scrollbar-width: none;\r\n\r\n    padding: 10px 5px 25px;\r\n\r\n    box-sizing: border-box;\r\n\r\n    touch-action: pan-x;\r\n}\r\n\r\n\r\n.custom-news-track::-webkit-scrollbar {\r\n    display: none;\r\n}\r\n\r\n\r\n\/* CARD *\/\r\n\r\n.custom-news-card {\r\n    flex: 0 0 calc((100% - 72px) \/ 4);\r\n\r\n    min-width: 0;\r\n\r\n    background: #FFFFFF;\r\n\r\n    border-radius: 20px;\r\n\r\n    overflow: hidden;\r\n\r\n    display: flex;\r\n\r\n    flex-direction: column;\r\n\r\n    scroll-snap-align: start;\r\n\r\n    box-shadow:\r\n        0 8px 30px rgba(15, 23, 42, 0.08);\r\n\r\n    transition:\r\n        transform 0.25s ease,\r\n        box-shadow 0.25s ease;\r\n}\r\n\r\n\r\n.custom-news-card:hover {\r\n    transform: translateY(-5px);\r\n\r\n    box-shadow:\r\n        0 15px 38px rgba(15, 23, 42, 0.13);\r\n}\r\n\r\n\r\n\/* FADE IN *\/\r\n\r\n.custom-news-card.news-card-enter {\r\n    animation:\r\n        newsCardEnter\r\n        0.55s\r\n        ease\r\n        both;\r\n}\r\n\r\n\r\n@keyframes newsCardEnter {\r\n\r\n    0% {\r\n        opacity: 0;\r\n        transform: translateY(15px);\r\n    }\r\n\r\n    100% {\r\n        opacity: 1;\r\n        transform: translateY(0);\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* FEATURED IMAGE *\/\r\n\r\n.custom-news-image {\r\n    display: block;\r\n\r\n    width: 100%;\r\n\r\n    aspect-ratio: 1080 \/ 780;\r\n\r\n    background: #E5E7EB;\r\n\r\n    overflow: hidden;\r\n\r\n    flex-shrink: 0;\r\n}\r\n\r\n\r\n.custom-news-image img {\r\n    display: block;\r\n\r\n    width: 100%;\r\n    height: 100%;\r\n\r\n    object-fit: cover;\r\n\r\n    transition: transform 0.4s ease;\r\n}\r\n\r\n\r\n.custom-news-card:hover .custom-news-image img {\r\n    transform: scale(1.04);\r\n}\r\n\r\n\r\n\/* PLACEHOLDER *\/\r\n\r\n.custom-news-placeholder {\r\n    width: 100%;\r\n    height: 100%;\r\n\r\n    display: flex;\r\n\r\n    align-items: center;\r\n    justify-content: center;\r\n\r\n    background:\r\n        linear-gradient(\r\n            135deg,\r\n            #1E73BE,\r\n            #155A96\r\n        );\r\n\r\n    color: #FFFFFF;\r\n\r\n    font-family: 'Poppins', sans-serif;\r\n\r\n    font-size: 18px;\r\n\r\n    font-weight: 600;\r\n}\r\n\r\n\r\n\/* CONTENT *\/\r\n\r\n.custom-news-content {\r\n    flex: 1;\r\n\r\n    display: flex;\r\n\r\n    flex-direction: column;\r\n\r\n    padding: 22px 21px 22px;\r\n\r\n    box-sizing: border-box;\r\n}\r\n\r\n\r\n\/* DATE *\/\r\n\r\n.custom-news-date {\r\n    display: flex;\r\n\r\n    align-items: center;\r\n\r\n    gap: 8px;\r\n\r\n    margin-bottom: 12px;\r\n\r\n    color: var(--text-color);\r\n\r\n    font-family: 'DM Sans', sans-serif;\r\n\r\n    font-size: 14px;\r\n\r\n    line-height: 1.4;\r\n\r\n    font-weight: 500;\r\n}\r\n\r\n\r\n.custom-news-date svg {\r\n    width: 18px;\r\n    height: 18px;\r\n\r\n    min-width: 18px;\r\n\r\n    color: var(--primary);\r\n}\r\n\r\n\r\n\/* CATEGORY *\/\r\n\r\n.custom-news-category {\r\n    display: block;\r\n\r\n    align-self: flex-start;\r\n\r\n    width: fit-content;\r\n\r\n    max-width: 100%;\r\n\r\n    padding: 6px 11px;\r\n\r\n    margin-bottom: 12px;\r\n\r\n    box-sizing: border-box;\r\n\r\n    border-radius: 999px;\r\n\r\n    background: var(--primary-soft);\r\n\r\n    color: var(--primary-dark);\r\n\r\n    font-family: 'DM Sans', sans-serif;\r\n\r\n    font-size: 11px;\r\n\r\n    line-height: 1.3;\r\n\r\n    font-weight: 600;\r\n\r\n    overflow: hidden;\r\n\r\n    cursor: default;\r\n}\r\n\r\n\r\n.custom-news-category-text {\r\n    display: block;\r\n\r\n    width: max-content;\r\n\r\n    white-space: nowrap;\r\n\r\n    transform: translateX(0);\r\n}\r\n\r\n\r\n.custom-news-category.has-overflow:hover\r\n.custom-news-category-text {\r\n    animation:\r\n        categoryMarquee\r\n        var(--marquee-duration, 5s)\r\n        linear\r\n        infinite\r\n        alternate;\r\n}\r\n\r\n\r\n@keyframes categoryMarquee {\r\n\r\n    0% {\r\n        transform: translateX(0);\r\n    }\r\n\r\n    100% {\r\n        transform:\r\n            translateX(\r\n                calc(\r\n                    0px -\r\n                    var(--marquee-distance)\r\n                )\r\n            );\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* TITLE *\/\r\n\r\n.custom-news-title {\r\n    margin: 0 0 11px;\r\n\r\n    font-family: 'Poppins', sans-serif;\r\n\r\n    font-size: 20px;\r\n\r\n    line-height: 1.35;\r\n\r\n    font-weight: 600;\r\n\r\n    display: -webkit-box;\r\n\r\n    -webkit-box-orient: vertical;\r\n\r\n    -webkit-line-clamp: 2;\r\n\r\n    overflow: hidden;\r\n}\r\n\r\n\r\n.custom-news-title a {\r\n    color: var(--title-color);\r\n\r\n    font-family: 'Poppins', sans-serif;\r\n\r\n    font-size: inherit;\r\n\r\n    line-height: inherit;\r\n\r\n    font-weight: inherit;\r\n\r\n    text-decoration: none;\r\n\r\n    transition: color 0.2s ease;\r\n}\r\n\r\n\r\n.custom-news-title a:hover {\r\n    color: var(--primary);\r\n}\r\n\r\n\r\n\/* EXCERPT *\/\r\n\r\n.custom-news-excerpt {\r\n    margin-bottom: 20px;\r\n\r\n    color: var(--text-color);\r\n\r\n    font-family: 'DM Sans', sans-serif;\r\n\r\n    font-size: 14px;\r\n\r\n    line-height: 1.65;\r\n\r\n    font-weight: 400;\r\n\r\n    display: -webkit-box;\r\n\r\n    -webkit-box-orient: vertical;\r\n\r\n    -webkit-line-clamp: 3;\r\n\r\n    overflow: hidden;\r\n}\r\n\r\n\r\n\/* BUTTON *\/\r\n\r\n.custom-news-button-area {\r\n    margin-top: auto;\r\n}\r\n\r\n\r\n.custom-news-button {\r\n    display: inline-flex;\r\n\r\n    align-items: center;\r\n\r\n    justify-content: center;\r\n\r\n    gap: 10px;\r\n\r\n    padding: 11px 21px;\r\n\r\n    background: var(--primary);\r\n\r\n    border-radius: 999px;\r\n\r\n    color: #FFFFFF !important;\r\n\r\n    text-decoration: none !important;\r\n\r\n    font-family: 'Poppins', sans-serif;\r\n\r\n    font-size: 14px;\r\n\r\n    line-height: 1.4;\r\n\r\n    font-weight: 600;\r\n\r\n    transition:\r\n        background 0.2s ease,\r\n        transform 0.2s ease;\r\n}\r\n\r\n\r\n.custom-news-button:hover {\r\n    background: var(--primary-dark);\r\n\r\n    color: #FFFFFF !important;\r\n\r\n    transform: translateY(-2px);\r\n}\r\n\r\n\r\n.custom-news-button-arrow {\r\n    font-family: 'Poppins', sans-serif;\r\n\r\n    font-size: 18px;\r\n\r\n    line-height: 1;\r\n\r\n    transition: transform 0.2s ease;\r\n}\r\n\r\n\r\n.custom-news-button:hover .custom-news-button-arrow {\r\n    transform: translateX(4px);\r\n}\r\n\r\n\r\n\/* NAVIGATION *\/\r\n\r\n.custom-news-nav {\r\n    position: absolute;\r\n\r\n    top: 47%;\r\n\r\n    z-index: 20;\r\n\r\n    width: 56px;\r\n    height: 56px;\r\n\r\n    padding: 0;\r\n\r\n    display: flex;\r\n\r\n    align-items: center;\r\n    justify-content: center;\r\n\r\n    transform: translateY(-50%);\r\n\r\n    border: none;\r\n\r\n    outline: none;\r\n\r\n    border-radius: 50%;\r\n\r\n    background: #FFFFFF;\r\n\r\n    color: var(--primary);\r\n\r\n    font-size: 24px;\r\n\r\n    line-height: 1;\r\n\r\n    cursor: pointer;\r\n\r\n    box-shadow:\r\n        0 10px 28px rgba(15, 23, 42, 0.14);\r\n\r\n    transition:\r\n        background 0.2s ease,\r\n        color 0.2s ease;\r\n}\r\n\r\n\r\n.custom-news-nav:hover {\r\n    background: var(--primary);\r\n\r\n    color: #FFFFFF;\r\n}\r\n\r\n\r\n.custom-news-prev {\r\n    left: -28px;\r\n}\r\n\r\n\r\n.custom-news-next {\r\n    right: -28px;\r\n}\r\n\r\n\r\n.custom-news-nav.is-hidden {\r\n    display: none !important;\r\n}\r\n\r\n\r\n\/* PAGINATION *\/\r\n\r\n.custom-news-pagination {\r\n    display: flex;\r\n\r\n    align-items: center;\r\n\r\n    justify-content: center;\r\n\r\n    flex-wrap: wrap;\r\n\r\n    gap: 8px;\r\n\r\n    min-height: 18px;\r\n\r\n    margin-top: 2px;\r\n}\r\n\r\n\r\n.custom-news-dot {\r\n    width: 8px;\r\n    height: 8px;\r\n\r\n    padding: 0;\r\n\r\n    border: none;\r\n\r\n    border-radius: 999px;\r\n\r\n    background:\r\n        rgba(30, 115, 190, 0.25);\r\n\r\n    cursor: pointer;\r\n\r\n    transition:\r\n        width 0.25s ease,\r\n        background 0.25s ease;\r\n}\r\n\r\n\r\n.custom-news-dot:hover {\r\n    background:\r\n        rgba(30, 115, 190, 0.6);\r\n}\r\n\r\n\r\n.custom-news-dot.is-active {\r\n    width: 24px;\r\n\r\n    background: var(--primary);\r\n}\r\n\r\n\r\n\/* SKELETON *\/\r\n\r\n.custom-news-skeleton {\r\n    flex: 0 0 calc((100% - 72px) \/ 4);\r\n\r\n    min-width: 0;\r\n\r\n    background: #FFFFFF;\r\n\r\n    border-radius: 20px;\r\n\r\n    overflow: hidden;\r\n\r\n    scroll-snap-align: start;\r\n\r\n    box-shadow:\r\n        0 8px 30px rgba(15, 23, 42, 0.06);\r\n}\r\n\r\n\r\n.skeleton-image {\r\n    width: 100%;\r\n\r\n    aspect-ratio: 1080 \/ 780;\r\n}\r\n\r\n\r\n.skeleton-content {\r\n    padding: 22px 21px 22px;\r\n}\r\n\r\n\r\n.skeleton-date {\r\n    width: 42%;\r\n\r\n    height: 13px;\r\n\r\n    margin-bottom: 15px;\r\n\r\n    border-radius: 20px;\r\n}\r\n\r\n\r\n.skeleton-category {\r\n    width: 58%;\r\n\r\n    height: 22px;\r\n\r\n    margin-bottom: 14px;\r\n\r\n    border-radius: 999px;\r\n}\r\n\r\n\r\n.skeleton-title {\r\n    width: 95%;\r\n\r\n    height: 17px;\r\n\r\n    margin-bottom: 9px;\r\n\r\n    border-radius: 20px;\r\n}\r\n\r\n\r\n.skeleton-title-short {\r\n    width: 67%;\r\n\r\n    margin-bottom: 20px;\r\n}\r\n\r\n\r\n.skeleton-text {\r\n    width: 100%;\r\n\r\n    height: 10px;\r\n\r\n    margin-bottom: 9px;\r\n\r\n    border-radius: 20px;\r\n}\r\n\r\n\r\n.skeleton-text-short {\r\n    width: 70%;\r\n\r\n    margin-bottom: 24px;\r\n}\r\n\r\n\r\n.skeleton-button {\r\n    width: 155px;\r\n\r\n    height: 42px;\r\n\r\n    border-radius: 999px;\r\n}\r\n\r\n\r\n\/* SHIMMER *\/\r\n\r\n.skeleton-animation {\r\n    position: relative;\r\n\r\n    overflow: hidden;\r\n\r\n    background: #E5ECEB;\r\n}\r\n\r\n\r\n.skeleton-animation::after {\r\n    content: '';\r\n\r\n    position: absolute;\r\n\r\n    top: 0;\r\n\r\n    left: -160%;\r\n\r\n    width: 140%;\r\n\r\n    height: 100%;\r\n\r\n    background:\r\n        linear-gradient(\r\n            90deg,\r\n            rgba(255, 255, 255, 0),\r\n            rgba(255, 255, 255, 0.85),\r\n            rgba(30, 115, 190, 0.12),\r\n            rgba(255, 255, 255, 0.85),\r\n            rgba(255, 255, 255, 0)\r\n        );\r\n\r\n    animation:\r\n        newsShimmer\r\n        1.25s\r\n        infinite;\r\n}\r\n\r\n\r\n@keyframes newsShimmer {\r\n\r\n    0% {\r\n        left: -160%;\r\n    }\r\n\r\n    100% {\r\n        left: 160%;\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* ERROR *\/\r\n\r\n.custom-news-error {\r\n    width: 100%;\r\n\r\n    padding: 50px 20px;\r\n\r\n    box-sizing: border-box;\r\n\r\n    text-align: center;\r\n\r\n    color: var(--text-color);\r\n\r\n    font-family: 'DM Sans', sans-serif;\r\n\r\n    font-size: 14px;\r\n}\r\n\r\n\r\n\/* TABLET *\/\r\n\r\n@media (max-width: 1024px) {\r\n\r\n    .custom-news-card {\r\n        flex:\r\n            0 0 calc((100% - 24px) \/ 2);\r\n    }\r\n\r\n\r\n    .custom-news-skeleton {\r\n        flex:\r\n            0 0 calc((100% - 24px) \/ 2);\r\n    }\r\n\r\n\r\n    .custom-news-prev {\r\n        left: 8px;\r\n    }\r\n\r\n\r\n    .custom-news-next {\r\n        right: 8px;\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* MOBILE *\/\r\n\r\n@media (max-width: 767px) {\r\n\r\n    .custom-news-section {\r\n        padding: 5px 0 12px;\r\n    }\r\n\r\n\r\n    .custom-news-track {\r\n        gap: 16px;\r\n\r\n        padding: 10px 16px 18px;\r\n    }\r\n\r\n\r\n    .custom-news-card {\r\n        flex: 0 0 87%;\r\n\r\n        border-radius: 17px;\r\n    }\r\n\r\n\r\n    .custom-news-skeleton {\r\n        flex: 0 0 87%;\r\n\r\n        border-radius: 17px;\r\n    }\r\n\r\n\r\n    .custom-news-content {\r\n        padding: 19px 18px 20px;\r\n    }\r\n\r\n\r\n    .skeleton-content {\r\n        padding: 19px 18px 20px;\r\n    }\r\n\r\n\r\n    .custom-news-title {\r\n        font-size: 18px;\r\n    }\r\n\r\n\r\n    .custom-news-nav {\r\n        display: none !important;\r\n    }\r\n\r\n\r\n    .custom-news-pagination {\r\n        padding: 0 16px;\r\n    }\r\n\r\n}\r\n\r\n\r\n\/* REDUCED MOTION *\/\r\n\r\n@media (prefers-reduced-motion: reduce) {\r\n\r\n    .custom-news-track {\r\n        scroll-behavior: auto;\r\n    }\r\n\r\n\r\n    .skeleton-animation::after {\r\n        animation: none;\r\n    }\r\n\r\n\r\n    .custom-news-card.news-card-enter {\r\n        animation: none;\r\n    }\r\n\r\n\r\n    .custom-news-category.has-overflow:hover\r\n    .custom-news-category-text {\r\n        animation: none;\r\n        transform: translateX(0);\r\n    }\r\n\r\n}\r\n\r\n<\/style>\r\n\r\n\r\n<script>\r\n\r\n(function () {\r\n\r\n\r\n    \/* =================================\r\n       UBAH KATEGORI DI SINI SAJA\r\n       ================================= *\/\r\n\r\n    const CATEGORY_NAME =\r\n        'Konservasi Penyu Belimbing Monitoring';\r\n\r\n\r\n    const POSTS_PER_REQUEST =\r\n        4;\r\n\r\n\r\n    \/* ELEMENT *\/\r\n\r\n    const slider =\r\n        document.getElementById(\r\n            'customNewsSlider'\r\n        );\r\n\r\n\r\n    if (!slider) {\r\n        return;\r\n    }\r\n\r\n\r\n    const track =\r\n        slider.querySelector(\r\n            '.custom-news-track'\r\n        );\r\n\r\n\r\n    const prevButton =\r\n        slider.querySelector(\r\n            '.custom-news-prev'\r\n        );\r\n\r\n\r\n    const nextButton =\r\n        slider.querySelector(\r\n            '.custom-news-next'\r\n        );\r\n\r\n\r\n    const pagination =\r\n        slider.querySelector(\r\n            '.custom-news-pagination'\r\n        );\r\n\r\n\r\n    \/* WORDPRESS API *\/\r\n\r\n    const apiLink =\r\n        document.querySelector(\r\n            'link[rel=\"https:\/\/api.w.org\/\"]'\r\n        );\r\n\r\n\r\n    let apiRoot;\r\n\r\n\r\n    if (\r\n        apiLink &&\r\n        apiLink.href\r\n    ) {\r\n\r\n        if (\r\n            apiLink.href.endsWith('\/')\r\n        ) {\r\n\r\n            apiRoot =\r\n                apiLink.href.slice(\r\n                    0,\r\n                    -1\r\n                );\r\n\r\n        } else {\r\n\r\n            apiRoot =\r\n                apiLink.href;\r\n\r\n        }\r\n\r\n    } else {\r\n\r\n        apiRoot =\r\n            window.location.origin +\r\n            '\/wp-json';\r\n\r\n    }\r\n\r\n\r\n    const wpAPI =\r\n        apiRoot +\r\n        '\/wp\/v2';\r\n\r\n\r\n    \/* STATE *\/\r\n\r\n    let categoryID =\r\n        null;\r\n\r\n\r\n    let currentPage =\r\n        1;\r\n\r\n\r\n    let totalPages =\r\n        1;\r\n\r\n\r\n    let loading =\r\n        false;\r\n\r\n\r\n    let autoLoadTimer;\r\n\r\n\r\n    \/* HELPER *\/\r\n\r\n    function stripHTML(html) {\r\n\r\n        const element =\r\n            document.createElement(\r\n                'div'\r\n            );\r\n\r\n\r\n        element.innerHTML =\r\n            html || '';\r\n\r\n\r\n        return (\r\n            element.textContent ||\r\n            element.innerText ||\r\n            ''\r\n        ).trim();\r\n\r\n    }\r\n\r\n\r\n    function escapeHTML(text) {\r\n\r\n        const element =\r\n            document.createElement(\r\n                'div'\r\n            );\r\n\r\n\r\n        element.textContent =\r\n            text || '';\r\n\r\n\r\n        return element.innerHTML;\r\n\r\n    }\r\n\r\n\r\n    function truncateText(\r\n        text,\r\n        max\r\n    ) {\r\n\r\n        if (!text) {\r\n            return '';\r\n        }\r\n\r\n\r\n        if (\r\n            text.length <= max\r\n        ) {\r\n\r\n            return text;\r\n\r\n        }\r\n\r\n\r\n        let result =\r\n            text.substring(\r\n                0,\r\n                max\r\n            );\r\n\r\n\r\n        const lastSpace =\r\n            result.lastIndexOf(\r\n                ' '\r\n            );\r\n\r\n\r\n        if (\r\n            lastSpace > 0\r\n        ) {\r\n\r\n            result =\r\n                result.substring(\r\n                    0,\r\n                    lastSpace\r\n                );\r\n\r\n        }\r\n\r\n\r\n        return (\r\n            result.trim() +\r\n            '...'\r\n        );\r\n\r\n    }\r\n\r\n\r\n    function formatDate(\r\n        dateString\r\n    ) {\r\n\r\n        const date =\r\n            new Date(\r\n                dateString\r\n            );\r\n\r\n\r\n        const months = [\r\n            'Jan',\r\n            'Feb',\r\n            'Mar',\r\n            'Apr',\r\n            'Mei',\r\n            'Jun',\r\n            'Jul',\r\n            'Agu',\r\n            'Sep',\r\n            'Okt',\r\n            'Nov',\r\n            'Des'\r\n        ];\r\n\r\n\r\n        return (\r\n            String(\r\n                date.getDate()\r\n            ).padStart(\r\n                2,\r\n                '0'\r\n            )\r\n            +\r\n            ' '\r\n            +\r\n            months[\r\n                date.getMonth()\r\n            ]\r\n            +\r\n            ' '\r\n            +\r\n            date.getFullYear()\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* NORMALIZE TEXT *\/\r\n\r\n    function normalizeText(\r\n        text\r\n    ) {\r\n\r\n        let result =\r\n            stripHTML(\r\n                text || ''\r\n            )\r\n            .trim()\r\n            .toLowerCase();\r\n\r\n\r\n        const charactersToRemove = [\r\n            '.',\r\n            ',',\r\n            ':',\r\n            ';',\r\n            '!',\r\n            '?',\r\n            '\"',\r\n            \"'\",\r\n            '(',\r\n            ')',\r\n            '[',\r\n            ']',\r\n            '{',\r\n            '}',\r\n            '-',\r\n            '\u2013',\r\n            '\u2014'\r\n        ];\r\n\r\n\r\n        charactersToRemove.forEach(\r\n            function (\r\n                character\r\n            ) {\r\n\r\n                result =\r\n                    result\r\n                        .split(\r\n                            character\r\n                        )\r\n                        .join(\r\n                            ' '\r\n                        );\r\n\r\n            }\r\n        );\r\n\r\n\r\n        while (\r\n            result.includes(\r\n                '  '\r\n            )\r\n        ) {\r\n\r\n            result =\r\n                result.replace(\r\n                    '  ',\r\n                    ' '\r\n                );\r\n\r\n        }\r\n\r\n\r\n        return result.trim();\r\n\r\n    }\r\n\r\n\r\n    \/* SMART EXCERPT *\/\r\n\r\n    function getSmartExcerpt(\r\n        post\r\n    ) {\r\n\r\n        const fallbackExcerpt =\r\n            truncateText(\r\n                stripHTML(\r\n                    post.excerpt &&\r\n                    post.excerpt.rendered\r\n                        ? post.excerpt.rendered\r\n                        : ''\r\n                ),\r\n                150\r\n            );\r\n\r\n\r\n        if (\r\n            !post.content ||\r\n            !post.content.rendered\r\n        ) {\r\n\r\n            return fallbackExcerpt;\r\n\r\n        }\r\n\r\n\r\n        const postTitle =\r\n            normalizeText(\r\n                post.title &&\r\n                post.title.rendered\r\n                    ? post.title.rendered\r\n                    : ''\r\n            );\r\n\r\n\r\n        const container =\r\n            document.createElement(\r\n                'div'\r\n            );\r\n\r\n\r\n        container.innerHTML =\r\n            post.content.rendered;\r\n\r\n\r\n        const paragraphs =\r\n            Array.from(\r\n                container.querySelectorAll(\r\n                    'p'\r\n                )\r\n            );\r\n\r\n\r\n        const ignoredStarts = [\r\n            'seri cerita jejak penjaga bentang laut',\r\n            'cerita lapangan dari para pendamping',\r\n            'dalam seri',\r\n            'penulis',\r\n            'tanggal',\r\n            'oleh',\r\n            'bagikan tulisan',\r\n            'baca juga',\r\n            'share this',\r\n            'image'\r\n        ];\r\n\r\n\r\n        for (\r\n            let i = 0;\r\n            i < paragraphs.length;\r\n            i++\r\n        ) {\r\n\r\n            const text =\r\n                stripHTML(\r\n                    paragraphs[i].innerHTML\r\n                ).trim();\r\n\r\n\r\n            if (\r\n                !text ||\r\n                text.length < 45\r\n            ) {\r\n\r\n                continue;\r\n\r\n            }\r\n\r\n\r\n            const normalizedText =\r\n                normalizeText(\r\n                    text\r\n                );\r\n\r\n\r\n            if (\r\n                !normalizedText\r\n            ) {\r\n\r\n                continue;\r\n\r\n            }\r\n\r\n\r\n            \/*\r\n             * ABAIKAN JIKA PARAGRAF\r\n             * SAMA DENGAN JUDUL\r\n             *\/\r\n\r\n            if (\r\n                postTitle &&\r\n                normalizedText ===\r\n                postTitle\r\n            ) {\r\n\r\n                continue;\r\n\r\n            }\r\n\r\n\r\n            \/*\r\n             * ABAIKAN JIKA JUDUL POST\r\n             * MENGANDUNG TEKS PARAGRAF\r\n             *\/\r\n\r\n            if (\r\n                postTitle &&\r\n                normalizedText.length > 25 &&\r\n                postTitle.includes(\r\n                    normalizedText\r\n                )\r\n            ) {\r\n\r\n                continue;\r\n\r\n            }\r\n\r\n\r\n            \/*\r\n             * ABAIKAN JIKA PARAGRAF\r\n             * HANYA JUDUL DENGAN\r\n             * TAMBAHAN SEDIKIT TEKS\r\n             *\/\r\n\r\n            if (\r\n                postTitle &&\r\n                normalizedText.includes(\r\n                    postTitle\r\n                ) &&\r\n                normalizedText.length <\r\n                postTitle.length + 60\r\n            ) {\r\n\r\n                continue;\r\n\r\n            }\r\n\r\n\r\n            let ignored =\r\n                false;\r\n\r\n\r\n            for (\r\n                let j = 0;\r\n                j < ignoredStarts.length;\r\n                j++\r\n            ) {\r\n\r\n                if (\r\n                    normalizedText.startsWith(\r\n                        ignoredStarts[j]\r\n                    )\r\n                ) {\r\n\r\n                    ignored =\r\n                        true;\r\n\r\n                    break;\r\n\r\n                }\r\n\r\n            }\r\n\r\n\r\n            if (\r\n                ignored\r\n            ) {\r\n\r\n                continue;\r\n\r\n            }\r\n\r\n\r\n            \/*\r\n             * INI PARAGRAF ISI PERTAMA\r\n             * YANG VALID\r\n             *\/\r\n\r\n            return truncateText(\r\n                text,\r\n                150\r\n            );\r\n\r\n        }\r\n\r\n\r\n        return fallbackExcerpt;\r\n\r\n    }\r\n\r\n\r\n    \/* FEATURED IMAGE *\/\r\n\r\n    function getFeaturedImage(\r\n        post\r\n    ) {\r\n\r\n        try {\r\n\r\n            const media =\r\n                post._embedded[\r\n                    'wp:featuredmedia'\r\n                ][0];\r\n\r\n\r\n            const sizes =\r\n                media.media_details &&\r\n                media.media_details.sizes\r\n                    ? media.media_details.sizes\r\n                    : {};\r\n\r\n\r\n            if (\r\n                sizes.medium_large\r\n            ) {\r\n\r\n                return (\r\n                    sizes.medium_large\r\n                        .source_url\r\n                );\r\n\r\n            }\r\n\r\n\r\n            if (\r\n                sizes.medium\r\n            ) {\r\n\r\n                return (\r\n                    sizes.medium\r\n                        .source_url\r\n                );\r\n\r\n            }\r\n\r\n\r\n            if (\r\n                sizes.large\r\n            ) {\r\n\r\n                return (\r\n                    sizes.large\r\n                        .source_url\r\n                );\r\n\r\n            }\r\n\r\n\r\n            return (\r\n                media.source_url ||\r\n                ''\r\n            );\r\n\r\n\r\n        } catch (error) {\r\n\r\n            return '';\r\n\r\n        }\r\n\r\n    }\r\n\r\n\r\n    \/* CATEGORY *\/\r\n\r\n    async function getCategoryID() {\r\n\r\n        const cacheKey =\r\n            'wp_news_category_' +\r\n            encodeURIComponent(\r\n                CATEGORY_NAME\r\n                    .trim()\r\n                    .toLowerCase()\r\n            );\r\n\r\n\r\n        const cachedID =\r\n            localStorage.getItem(\r\n                cacheKey\r\n            );\r\n\r\n\r\n        if (\r\n            cachedID\r\n        ) {\r\n\r\n            return Number(\r\n                cachedID\r\n            );\r\n\r\n        }\r\n\r\n\r\n        const url =\r\n            wpAPI +\r\n            '\/categories' +\r\n            '?per_page=100' +\r\n            '&search=' +\r\n            encodeURIComponent(\r\n                CATEGORY_NAME\r\n            ) +\r\n            '&_fields=id,name,slug';\r\n\r\n\r\n        const response =\r\n            await fetch(\r\n                url\r\n            );\r\n\r\n\r\n        if (\r\n            !response.ok\r\n        ) {\r\n\r\n            throw new Error(\r\n                'Kategori tidak dapat dimuat'\r\n            );\r\n\r\n        }\r\n\r\n\r\n        const categories =\r\n            await response.json();\r\n\r\n\r\n        if (\r\n            !categories.length\r\n        ) {\r\n\r\n            return null;\r\n\r\n        }\r\n\r\n\r\n        const exactCategory =\r\n            categories.find(\r\n                function (\r\n                    category\r\n                ) {\r\n\r\n                    return (\r\n                        category.name\r\n                            .trim()\r\n                            .toLowerCase()\r\n                        ===\r\n                        CATEGORY_NAME\r\n                            .trim()\r\n                            .toLowerCase()\r\n                    );\r\n\r\n                }\r\n            );\r\n\r\n\r\n        const selectedCategory =\r\n            exactCategory ||\r\n            categories[0];\r\n\r\n\r\n        localStorage.setItem(\r\n            cacheKey,\r\n            selectedCategory.id\r\n        );\r\n\r\n\r\n        return selectedCategory.id;\r\n\r\n    }\r\n\r\n\r\n    \/* FETCH POSTS *\/\r\n\r\n    async function fetchPosts(\r\n        page\r\n    ) {\r\n\r\n        const url =\r\n            wpAPI +\r\n            '\/posts' +\r\n            '?per_page=' +\r\n            POSTS_PER_REQUEST +\r\n            '&page=' +\r\n            page +\r\n            '&categories=' +\r\n            categoryID +\r\n            '&orderby=date' +\r\n            '&order=desc' +\r\n            '&_embed=wp:featuredmedia';\r\n\r\n\r\n        const response =\r\n            await fetch(\r\n                url\r\n            );\r\n\r\n\r\n        if (\r\n            !response.ok\r\n        ) {\r\n\r\n            throw new Error(\r\n                'Berita tidak dapat dimuat'\r\n            );\r\n\r\n        }\r\n\r\n\r\n        totalPages =\r\n            Number(\r\n                response.headers.get(\r\n                    'X-WP-TotalPages'\r\n                ) || 1\r\n            );\r\n\r\n\r\n        return (\r\n            await response.json()\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* CREATE CARD *\/\r\n\r\n    function createCard(\r\n        post\r\n    ) {\r\n\r\n        const title =\r\n            stripHTML(\r\n                post.title &&\r\n                post.title.rendered\r\n                    ? post.title.rendered\r\n                    : ''\r\n            );\r\n\r\n\r\n        const excerpt =\r\n            getSmartExcerpt(\r\n                post\r\n            );\r\n\r\n\r\n        const image =\r\n            getFeaturedImage(\r\n                post\r\n            );\r\n\r\n\r\n        const card =\r\n            document.createElement(\r\n                'article'\r\n            );\r\n\r\n\r\n        card.className =\r\n            'custom-news-card news-card-enter';\r\n\r\n\r\n        card.innerHTML = `\r\n\r\n            <a\r\n                href=\"${post.link}\"\r\n                class=\"custom-news-image\"\r\n                aria-label=\"${escapeHTML(title)}\"\r\n            >\r\n\r\n                ${\r\n                    image\r\n\r\n                    ? `\r\n                        <img\r\n                            src=\"${image}\"\r\n                            alt=\"${escapeHTML(title)}\"\r\n                            loading=\"lazy\"\r\n                            decoding=\"async\"\r\n                        >\r\n                    `\r\n\r\n                    : `\r\n                        <div class=\"custom-news-placeholder\">\r\n                            Berita\r\n                        <\/div>\r\n                    `\r\n                }\r\n\r\n            <\/a>\r\n\r\n\r\n            <div class=\"custom-news-content\">\r\n\r\n\r\n                <div class=\"custom-news-date\">\r\n\r\n                    <svg\r\n                        viewBox=\"0 0 24 24\"\r\n                        fill=\"none\"\r\n                        stroke=\"currentColor\"\r\n                        stroke-width=\"1.8\"\r\n                        stroke-linecap=\"round\"\r\n                        stroke-linejoin=\"round\"\r\n                    >\r\n\r\n                        <rect\r\n                            x=\"3\"\r\n                            y=\"5\"\r\n                            width=\"18\"\r\n                            height=\"16\"\r\n                            rx=\"2\"\r\n                        ><\/rect>\r\n\r\n                        <line\r\n                            x1=\"16\"\r\n                            y1=\"3\"\r\n                            x2=\"16\"\r\n                            y2=\"7\"\r\n                        ><\/line>\r\n\r\n                        <line\r\n                            x1=\"8\"\r\n                            y1=\"3\"\r\n                            x2=\"8\"\r\n                            y2=\"7\"\r\n                        ><\/line>\r\n\r\n                        <line\r\n                            x1=\"3\"\r\n                            y1=\"11\"\r\n                            x2=\"21\"\r\n                            y2=\"11\"\r\n                        ><\/line>\r\n\r\n                    <\/svg>\r\n\r\n\r\n                    <span>\r\n                        ${formatDate(post.date)}\r\n                    <\/span>\r\n\r\n                <\/div>\r\n\r\n\r\n                <div\r\n                    class=\"custom-news-category\"\r\n                    title=\"${escapeHTML(CATEGORY_NAME)}\"\r\n                >\r\n\r\n                    <span class=\"custom-news-category-text\">\r\n                        ${escapeHTML(CATEGORY_NAME)}\r\n                    <\/span>\r\n\r\n                <\/div>\r\n\r\n\r\n                <h3 class=\"custom-news-title\">\r\n\r\n                    <a\r\n                        href=\"${post.link}\"\r\n                        title=\"${escapeHTML(title)}\"\r\n                    >\r\n                        ${escapeHTML(title)}\r\n                    <\/a>\r\n\r\n                <\/h3>\r\n\r\n\r\n                ${\r\n                    excerpt\r\n\r\n                    ? `\r\n                        <div class=\"custom-news-excerpt\">\r\n                            ${escapeHTML(excerpt)}\r\n                        <\/div>\r\n                    `\r\n\r\n                    : ''\r\n                }\r\n\r\n\r\n                <div class=\"custom-news-button-area\">\r\n\r\n                    <a\r\n                        href=\"${post.link}\"\r\n                        class=\"custom-news-button\"\r\n                    >\r\n\r\n                        <span>\r\n                            Baca Selengkapnya\r\n                        <\/span>\r\n\r\n                        <span class=\"custom-news-button-arrow\">\r\n                            \u2192\r\n                        <\/span>\r\n\r\n                    <\/a>\r\n\r\n                <\/div>\r\n\r\n\r\n            <\/div>\r\n\r\n        `;\r\n\r\n\r\n        return card;\r\n\r\n    }\r\n\r\n\r\n    \/* CREATE SKELETON *\/\r\n\r\n    function createSkeleton() {\r\n\r\n        const skeleton =\r\n            document.createElement(\r\n                'div'\r\n            );\r\n\r\n\r\n        skeleton.className =\r\n            'custom-news-skeleton loading-next-skeleton';\r\n\r\n\r\n        skeleton.innerHTML = `\r\n\r\n            <div\r\n                class=\"skeleton-image skeleton-animation\"\r\n            ><\/div>\r\n\r\n\r\n            <div class=\"skeleton-content\">\r\n\r\n                <div\r\n                    class=\"skeleton-date skeleton-animation\"\r\n                ><\/div>\r\n\r\n                <div\r\n                    class=\"skeleton-category skeleton-animation\"\r\n                ><\/div>\r\n\r\n                <div\r\n                    class=\"skeleton-title skeleton-animation\"\r\n                ><\/div>\r\n\r\n                <div\r\n                    class=\"skeleton-title skeleton-title-short skeleton-animation\"\r\n                ><\/div>\r\n\r\n                <div\r\n                    class=\"skeleton-text skeleton-animation\"\r\n                ><\/div>\r\n\r\n                <div\r\n                    class=\"skeleton-text skeleton-animation\"\r\n                ><\/div>\r\n\r\n                <div\r\n                    class=\"skeleton-text skeleton-text-short skeleton-animation\"\r\n                ><\/div>\r\n\r\n                <div\r\n                    class=\"skeleton-button skeleton-animation\"\r\n                ><\/div>\r\n\r\n            <\/div>\r\n\r\n        `;\r\n\r\n\r\n        return skeleton;\r\n\r\n    }\r\n\r\n\r\n    \/* CATEGORY MARQUEE *\/\r\n\r\n    function updateCategoryMarquee() {\r\n\r\n        const badges =\r\n            track.querySelectorAll(\r\n                '.custom-news-category'\r\n            );\r\n\r\n\r\n        badges.forEach(\r\n            function (\r\n                badge\r\n            ) {\r\n\r\n                const text =\r\n                    badge.querySelector(\r\n                        '.custom-news-category-text'\r\n                    );\r\n\r\n\r\n                if (\r\n                    !text\r\n                ) {\r\n\r\n                    return;\r\n\r\n                }\r\n\r\n\r\n                badge.classList.remove(\r\n                    'has-overflow'\r\n                );\r\n\r\n\r\n                badge.style.removeProperty(\r\n                    '--marquee-distance'\r\n                );\r\n\r\n\r\n                badge.style.removeProperty(\r\n                    '--marquee-duration'\r\n                );\r\n\r\n\r\n                const style =\r\n                    window.getComputedStyle(\r\n                        badge\r\n                    );\r\n\r\n\r\n                const paddingLeft =\r\n                    parseFloat(\r\n                        style.paddingLeft\r\n                    ) || 0;\r\n\r\n\r\n                const paddingRight =\r\n                    parseFloat(\r\n                        style.paddingRight\r\n                    ) || 0;\r\n\r\n\r\n                const availableWidth =\r\n                    badge.clientWidth -\r\n                    paddingLeft -\r\n                    paddingRight;\r\n\r\n\r\n                const textWidth =\r\n                    text.scrollWidth;\r\n\r\n\r\n                const overflowDistance =\r\n                    textWidth -\r\n                    availableWidth;\r\n\r\n\r\n                if (\r\n                    overflowDistance > 4\r\n                ) {\r\n\r\n                    badge.classList.add(\r\n                        'has-overflow'\r\n                    );\r\n\r\n\r\n                    badge.style.setProperty(\r\n                        '--marquee-distance',\r\n                        overflowDistance +\r\n                        'px'\r\n                    );\r\n\r\n\r\n                    const duration =\r\n                        Math.max(\r\n                            3.5,\r\n                            overflowDistance \/ 22\r\n                        );\r\n\r\n\r\n                    badge.style.setProperty(\r\n                        '--marquee-duration',\r\n                        duration +\r\n                        's'\r\n                    );\r\n\r\n                }\r\n\r\n            }\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* FIRST POSTS *\/\r\n\r\n    function renderFirstPosts(\r\n        posts\r\n    ) {\r\n\r\n        track.innerHTML =\r\n            '';\r\n\r\n\r\n        const fragment =\r\n            document.createDocumentFragment();\r\n\r\n\r\n        posts.forEach(\r\n            function (\r\n                post\r\n            ) {\r\n\r\n                fragment.appendChild(\r\n                    createCard(\r\n                        post\r\n                    )\r\n                );\r\n\r\n            }\r\n        );\r\n\r\n\r\n        track.appendChild(\r\n            fragment\r\n        );\r\n\r\n\r\n        setTimeout(\r\n            function () {\r\n\r\n                updateCategoryMarquee();\r\n\r\n            },\r\n            100\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* ADD SKELETON *\/\r\n\r\n    function addNextSkeletons() {\r\n\r\n        const existing =\r\n            track.querySelectorAll(\r\n                '.loading-next-skeleton'\r\n            );\r\n\r\n\r\n        if (\r\n            existing.length\r\n        ) {\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        const fragment =\r\n            document.createDocumentFragment();\r\n\r\n\r\n        for (\r\n            let i = 0;\r\n            i < POSTS_PER_REQUEST;\r\n            i++\r\n        ) {\r\n\r\n            fragment.appendChild(\r\n                createSkeleton()\r\n            );\r\n\r\n        }\r\n\r\n\r\n        track.appendChild(\r\n            fragment\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* REPLACE SKELETON *\/\r\n\r\n    function replaceSkeletons(\r\n        posts\r\n    ) {\r\n\r\n        const skeletons =\r\n            Array.from(\r\n                track.querySelectorAll(\r\n                    '.loading-next-skeleton'\r\n                )\r\n            );\r\n\r\n\r\n        posts.forEach(\r\n            function (\r\n                post,\r\n                index\r\n            ) {\r\n\r\n                const card =\r\n                    createCard(\r\n                        post\r\n                    );\r\n\r\n\r\n                if (\r\n                    skeletons[index]\r\n                ) {\r\n\r\n                    skeletons[index]\r\n                        .replaceWith(\r\n                            card\r\n                        );\r\n\r\n                } else {\r\n\r\n                    track.appendChild(\r\n                        card\r\n                    );\r\n\r\n                }\r\n\r\n            }\r\n        );\r\n\r\n\r\n        skeletons.forEach(\r\n            function (\r\n                skeleton,\r\n                index\r\n            ) {\r\n\r\n                if (\r\n                    index >=\r\n                    posts.length\r\n                ) {\r\n\r\n                    skeleton.remove();\r\n\r\n                }\r\n\r\n            }\r\n        );\r\n\r\n\r\n        setTimeout(\r\n            function () {\r\n\r\n                updateCategoryMarquee();\r\n\r\n            },\r\n            100\r\n        );\r\n\r\n    }\r\n\r\n\r\n    function removeLoadingSkeletons() {\r\n\r\n        const skeletons =\r\n            track.querySelectorAll(\r\n                '.loading-next-skeleton'\r\n            );\r\n\r\n\r\n        skeletons.forEach(\r\n            function (\r\n                skeleton\r\n            ) {\r\n\r\n                skeleton.remove();\r\n\r\n            }\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* CARD PER SLIDE *\/\r\n\r\n    function cardsPerSlide() {\r\n\r\n        if (\r\n            window.innerWidth <=\r\n            767\r\n        ) {\r\n\r\n            return 1;\r\n\r\n        }\r\n\r\n\r\n        if (\r\n            window.innerWidth <=\r\n            1024\r\n        ) {\r\n\r\n            return 2;\r\n\r\n        }\r\n\r\n\r\n        return 4;\r\n\r\n    }\r\n\r\n\r\n    \/* GET CARDS *\/\r\n\r\n    function getCards() {\r\n\r\n        return Array.from(\r\n            track.querySelectorAll(\r\n                '.custom-news-card'\r\n            )\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* SCROLL AMOUNT *\/\r\n\r\n    function getScrollAmount() {\r\n\r\n        const card =\r\n            track.querySelector(\r\n                '.custom-news-card'\r\n            );\r\n\r\n\r\n        if (\r\n            !card\r\n        ) {\r\n\r\n            return track.clientWidth;\r\n\r\n        }\r\n\r\n\r\n        const gap =\r\n            parseFloat(\r\n                window\r\n                    .getComputedStyle(\r\n                        track\r\n                    )\r\n                    .gap\r\n            ) || 0;\r\n\r\n\r\n        const width =\r\n            card\r\n                .getBoundingClientRect()\r\n                .width;\r\n\r\n\r\n        return (\r\n            (width + gap) *\r\n            cardsPerSlide()\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* HAS MORE POSTS *\/\r\n\r\n    function hasMorePosts() {\r\n\r\n        return (\r\n            currentPage <=\r\n            totalPages\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* CURRENT PAGE *\/\r\n\r\n    function getCurrentVisualPage() {\r\n\r\n        const amount =\r\n            getScrollAmount();\r\n\r\n\r\n        if (\r\n            !amount\r\n        ) {\r\n\r\n            return 0;\r\n\r\n        }\r\n\r\n\r\n        return Math.round(\r\n            track.scrollLeft \/\r\n            amount\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* PAGINATION *\/\r\n\r\n    function updatePagination() {\r\n\r\n        const cards =\r\n            getCards();\r\n\r\n\r\n        if (\r\n            !cards.length\r\n        ) {\r\n\r\n            pagination.innerHTML =\r\n                '';\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        const totalVisualPages =\r\n            Math.ceil(\r\n                cards.length \/\r\n                cardsPerSlide()\r\n            );\r\n\r\n\r\n        const activePage =\r\n            Math.min(\r\n                getCurrentVisualPage(),\r\n                totalVisualPages - 1\r\n            );\r\n\r\n\r\n        pagination.innerHTML =\r\n            '';\r\n\r\n\r\n        for (\r\n            let i = 0;\r\n            i < totalVisualPages;\r\n            i++\r\n        ) {\r\n\r\n            const dot =\r\n                document.createElement(\r\n                    'button'\r\n                );\r\n\r\n\r\n            dot.type =\r\n                'button';\r\n\r\n\r\n            dot.className =\r\n                'custom-news-dot';\r\n\r\n\r\n            dot.setAttribute(\r\n                'aria-label',\r\n                'Buka bagian berita ' +\r\n                (i + 1)\r\n            );\r\n\r\n\r\n            if (\r\n                i ===\r\n                activePage\r\n            ) {\r\n\r\n                dot.classList.add(\r\n                    'is-active'\r\n                );\r\n\r\n            }\r\n\r\n\r\n            dot.addEventListener(\r\n                'click',\r\n                function () {\r\n\r\n                    track.scrollTo({\r\n\r\n                        left:\r\n                            getScrollAmount() *\r\n                            i,\r\n\r\n                        behavior:\r\n                            'smooth'\r\n\r\n                    });\r\n\r\n                }\r\n            );\r\n\r\n\r\n            pagination.appendChild(\r\n                dot\r\n            );\r\n\r\n        }\r\n\r\n    }\r\n\r\n\r\n    \/* ACTIVE DOT *\/\r\n\r\n    function updateActiveDot() {\r\n\r\n        const dots =\r\n            pagination.querySelectorAll(\r\n                '.custom-news-dot'\r\n            );\r\n\r\n\r\n        if (\r\n            !dots.length\r\n        ) {\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        const activePage =\r\n            getCurrentVisualPage();\r\n\r\n\r\n        dots.forEach(\r\n            function (\r\n                dot,\r\n                index\r\n            ) {\r\n\r\n                dot.classList.toggle(\r\n                    'is-active',\r\n                    index === activePage\r\n                );\r\n\r\n            }\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* NAVIGATION *\/\r\n\r\n    function updateNavigation() {\r\n\r\n        if (\r\n            window.innerWidth <=\r\n            767\r\n        ) {\r\n\r\n            prevButton.classList.add(\r\n                'is-hidden'\r\n            );\r\n\r\n\r\n            nextButton.classList.add(\r\n                'is-hidden'\r\n            );\r\n\r\n\r\n            return;\r\n\r\n        }\r\n\r\n\r\n        const maxScroll =\r\n            Math.max(\r\n                0,\r\n                track.scrollWidth -\r\n                track.clientWidth\r\n            );\r\n\r\n\r\n        const atStart =\r\n            track.scrollLeft <=\r\n            8;\r\n\r\n\r\n        const atEnd =\r\n            track.scrollLeft >=\r\n            maxScroll - 8;\r\n\r\n\r\n        prevButton.classList.toggle(\r\n            'is-hidden',\r\n            atStart\r\n        );\r\n\r\n\r\n        nextButton.classList.toggle(\r\n            'is-hidden',\r\n            atEnd &&\r\n            !hasMorePosts() &&\r\n            !loading\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* LOAD NEXT POSTS *\/\r\n\r\n    async function loadNextPosts(\r\n        autoMove\r\n    ) {\r\n\r\n        if (\r\n            loading ||\r\n            !hasMorePosts()\r\n        ) {\r\n\r\n            return false;\r\n\r\n        }\r\n\r\n\r\n        loading =\r\n            true;\r\n\r\n\r\n        addNextSkeletons();\r\n\r\n\r\n        updateNavigation();\r\n\r\n\r\n        if (\r\n            autoMove\r\n        ) {\r\n\r\n            setTimeout(\r\n                function () {\r\n\r\n                    track.scrollBy({\r\n\r\n                        left:\r\n                            getScrollAmount(),\r\n\r\n                        behavior:\r\n                            'smooth'\r\n\r\n                    });\r\n\r\n                },\r\n                30\r\n            );\r\n\r\n        }\r\n\r\n\r\n        try {\r\n\r\n            const posts =\r\n                await fetchPosts(\r\n                    currentPage\r\n                );\r\n\r\n\r\n            replaceSkeletons(\r\n                posts\r\n            );\r\n\r\n\r\n            currentPage++;\r\n\r\n\r\n            setTimeout(\r\n                function () {\r\n\r\n                    updateNavigation();\r\n\r\n                    updatePagination();\r\n\r\n                    updateActiveDot();\r\n\r\n                    updateCategoryMarquee();\r\n\r\n                },\r\n                250\r\n            );\r\n\r\n\r\n            return true;\r\n\r\n\r\n        } catch (\r\n            error\r\n        ) {\r\n\r\n            console.error(\r\n                'News Slider:',\r\n                error\r\n            );\r\n\r\n\r\n            removeLoadingSkeletons();\r\n\r\n\r\n            updateNavigation();\r\n\r\n\r\n            return false;\r\n\r\n\r\n        } finally {\r\n\r\n            loading =\r\n                false;\r\n\r\n\r\n            setTimeout(\r\n                updateNavigation,\r\n                50\r\n            );\r\n\r\n        }\r\n\r\n    }\r\n\r\n\r\n    \/* NEXT *\/\r\n\r\n    nextButton.addEventListener(\r\n        'click',\r\n        async function () {\r\n\r\n            if (\r\n                loading\r\n            ) {\r\n\r\n                return;\r\n\r\n            }\r\n\r\n\r\n            const maxScroll =\r\n                Math.max(\r\n                    0,\r\n                    track.scrollWidth -\r\n                    track.clientWidth\r\n                );\r\n\r\n\r\n            const atEnd =\r\n                track.scrollLeft >=\r\n                maxScroll - 8;\r\n\r\n\r\n            if (\r\n                !atEnd\r\n            ) {\r\n\r\n                track.scrollBy({\r\n\r\n                    left:\r\n                        getScrollAmount(),\r\n\r\n                    behavior:\r\n                        'smooth'\r\n\r\n                });\r\n\r\n\r\n                return;\r\n\r\n            }\r\n\r\n\r\n            if (\r\n                hasMorePosts()\r\n            ) {\r\n\r\n                await loadNextPosts(\r\n                    true\r\n                );\r\n\r\n            }\r\n\r\n        }\r\n    );\r\n\r\n\r\n    \/* PREVIOUS *\/\r\n\r\n    prevButton.addEventListener(\r\n        'click',\r\n        function () {\r\n\r\n            if (\r\n                loading\r\n            ) {\r\n\r\n                return;\r\n\r\n            }\r\n\r\n\r\n            track.scrollBy({\r\n\r\n                left:\r\n                    -getScrollAmount(),\r\n\r\n                behavior:\r\n                    'smooth'\r\n\r\n            });\r\n\r\n        }\r\n    );\r\n\r\n\r\n    \/* SWIPE AND AUTO LOAD *\/\r\n\r\n    track.addEventListener(\r\n        'scroll',\r\n        function () {\r\n\r\n            window.requestAnimationFrame(\r\n                function () {\r\n\r\n                    updateNavigation();\r\n\r\n                    updateActiveDot();\r\n\r\n                }\r\n            );\r\n\r\n\r\n            clearTimeout(\r\n                autoLoadTimer\r\n            );\r\n\r\n\r\n            autoLoadTimer =\r\n                setTimeout(\r\n                    function () {\r\n\r\n                        if (\r\n                            loading ||\r\n                            !hasMorePosts()\r\n                        ) {\r\n\r\n                            return;\r\n\r\n                        }\r\n\r\n\r\n                        const remaining =\r\n                            track.scrollWidth -\r\n                            track.clientWidth -\r\n                            track.scrollLeft;\r\n\r\n\r\n                        const triggerDistance =\r\n                            getScrollAmount() *\r\n                            0.75;\r\n\r\n\r\n                        if (\r\n                            remaining <=\r\n                            triggerDistance\r\n                        ) {\r\n\r\n                            loadNextPosts(\r\n                                false\r\n                            );\r\n\r\n                        }\r\n\r\n                    },\r\n                    150\r\n                );\r\n\r\n        },\r\n        {\r\n            passive: true\r\n        }\r\n    );\r\n\r\n\r\n    \/* RESIZE *\/\r\n\r\n    let resizeTimer;\r\n\r\n\r\n    window.addEventListener(\r\n        'resize',\r\n        function () {\r\n\r\n            clearTimeout(\r\n                resizeTimer\r\n            );\r\n\r\n\r\n            resizeTimer =\r\n                setTimeout(\r\n                    function () {\r\n\r\n                        updateNavigation();\r\n\r\n                        updatePagination();\r\n\r\n                        updateActiveDot();\r\n\r\n                        updateCategoryMarquee();\r\n\r\n                    },\r\n                    150\r\n                );\r\n\r\n        }\r\n    );\r\n\r\n\r\n    if (\r\n        document.fonts &&\r\n        document.fonts.ready\r\n    ) {\r\n\r\n        document.fonts.ready.then(\r\n            function () {\r\n\r\n                updateCategoryMarquee();\r\n\r\n            }\r\n        );\r\n\r\n    }\r\n\r\n\r\n    \/* START *\/\r\n\r\n    async function start() {\r\n\r\n        try {\r\n\r\n            categoryID =\r\n                await getCategoryID();\r\n\r\n\r\n            if (\r\n                !categoryID\r\n            ) {\r\n\r\n                track.innerHTML =\r\n                    '<div class=\"custom-news-error\">Kategori tidak ditemukan.<\/div>';\r\n\r\n\r\n                prevButton.classList.add(\r\n                    'is-hidden'\r\n                );\r\n\r\n\r\n                nextButton.classList.add(\r\n                    'is-hidden'\r\n                );\r\n\r\n\r\n                return;\r\n\r\n            }\r\n\r\n\r\n            const firstPosts =\r\n                await fetchPosts(\r\n                    1\r\n                );\r\n\r\n\r\n            renderFirstPosts(\r\n                firstPosts\r\n            );\r\n\r\n\r\n            currentPage =\r\n                2;\r\n\r\n\r\n            updateNavigation();\r\n\r\n            updatePagination();\r\n\r\n\r\n            setTimeout(\r\n                function () {\r\n\r\n                    updateCategoryMarquee();\r\n\r\n                },\r\n                150\r\n            );\r\n\r\n\r\n            \/*\r\n             * SIAPKAN BERITA BERIKUTNYA\r\n             *\/\r\n\r\n            if (\r\n                hasMorePosts()\r\n            ) {\r\n\r\n                setTimeout(\r\n                    function () {\r\n\r\n                        loadNextPosts(\r\n                            false\r\n                        );\r\n\r\n                    },\r\n                    250\r\n                );\r\n\r\n            }\r\n\r\n\r\n        } catch (\r\n            error\r\n        ) {\r\n\r\n            console.error(\r\n                'News Slider:',\r\n                error\r\n            );\r\n\r\n\r\n            track.innerHTML =\r\n                '<div class=\"custom-news-error\">Berita tidak dapat dimuat.<\/div>';\r\n\r\n\r\n            prevButton.classList.add(\r\n                'is-hidden'\r\n            );\r\n\r\n\r\n            nextButton.classList.add(\r\n                'is-hidden'\r\n            );\r\n\r\n        }\r\n\r\n    }\r\n\r\n\r\n    start();\r\n\r\n\r\n})();\r\n\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Perlindungan Sarang Penyu &amp; Pemantauan Aktivitas Peneluran Pemulihan populasi penyu belimbing bertumpu pada produksi tukik yang cukup dari pantai peneluran dan tingkat mortalitas di laut. Oleh sebab itu tim pemantauan penyu dan perlindungan sarang LPPM UNIPA bersama anggota masyarakat lokal berupaya keras untuk meningkatkan jumlah tukik yang dihasilkan dengan melindungi sarang. Pemantauan aktivitas peneluran yang [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":9649,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_themeisle_gutenberg_block_has_review":false,"footnotes":""},"class_list":["post-4637","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/pages\/4637","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/comments?post=4637"}],"version-history":[{"count":32,"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/pages\/4637\/revisions"}],"predecessor-version":[{"id":23615,"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/pages\/4637\/revisions\/23615"}],"up":[{"embeddable":true,"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/pages\/9649"}],"wp:attachment":[{"href":"https:\/\/science4conservation.com\/en\/wp-json\/wp\/v2\/media?parent=4637"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}