{"id":2023,"date":"2026-03-18T10:18:24","date_gmt":"2026-03-18T02:18:24","guid":{"rendered":"https:\/\/nenghui.com\/?page_id=2023"},"modified":"2026-04-01T17:33:10","modified_gmt":"2026-04-01T09:33:10","slug":"microgrid","status":"publish","type":"page","link":"https:\/\/nenghui.com\/ms\/microgrid\/","title":{"rendered":"Microgrid\u00a0"},"content":{"rendered":"<div class=\"bg-liquid-gradient text-background-dark font-sans antialiased overflow-x-hidden selection:bg-primary selection:text-white min-h-screen\">\n\n    <!-- Three.js Canvas Container -->\n    <div id=\"canvas-container\" class=\"fixed inset-0 z-0 pointer-events-none opacity-80\"><\/div>\n    <div class=\"fixed inset-0 bg-gradient-to-t from-background-light via-background-light\/40 to-transparent z-0 pointer-events-none\"><\/div>\n\n    <main class=\"relative z-10  mx-auto\">\n        \n        <!-- === Hero Section === -->\n        <section id=\"mod-hero\" class=\"min-h-screen flex flex-col justify-center text-center\">\n            <span class=\"text-primary font-mono text-sm tracking-[0.3em] uppercase mb-6\" data-aos=\"fade-down\">\n                Sistem Tenaga Pintar\n            <\/span>\n            <h1 class=\"text-4xl md:text-[2.66rem] leading-tight tracking-tighter text-background-dark mb-8  drop-shadow-sm\" data-aos=\"zoom-in\">\n              BERSEPADU BEBAS \n                <span class=\"text-primary\">PINTAR.<\/span>\n            <\/h1>\n            <p class=\"text-[1rem] text-background-dark\/70 font-medium max-w-4xl mx-auto leading-relaxed md:text-center\" data-aos=\"fade-up\">\n               Generasi Penyelesaian Mikrogrid Seterusnya Memperkasa taman perindustrian dan komuniti sifar karbon dengan tenaga yang lancar, hijau dan autonomi.\n            <\/p>\n        <\/section>\n\n        <!-- === \u7cfb\u7edf\u62d3\u6251\u56fe\u6a21\u5757 === -->\n<section id=\"mod-topology\" class=\"min-h-screen flex flex-col justify-center items-center text-center py-24 relative z-10 overflow-hidden\">\n    \n    <!-- \u660e\u4eae\u7f51\u683c\u80cc\u666f -->\n    <div class=\"absolute inset-0 z-0 opacity-[0.4] pointer-events-none hex-bg\"><\/div>\n    <div class=\"absolute inset-0 z-0 opacity-[0.5] pointer-events-none\" style=\"background-image: linear-gradient(rgba(19,236,164,0.2) 1px, transparent 1px), linear-gradient(90deg, rgba(19,236,164,0.2) 1px, transparent 1px); background-size: 60px 60px; transform: perspective(800px) rotateX(60deg) scale(2.5) translateY(-50px); transform-origin: top center;\"><\/div>\n\n    <style>\n        .hex-bg { background-image: url(\"data:image\/svg+xml,%3Csvg width='24' height='40' viewBox='0 0 24 40' xmlns='http:\/\/www.w3.org\/2000\/svg'%3E%3Cpath d='M0 10L12 3l12 7v14l-12 7-12-7V10z' stroke='rgba(13,166,112,0.1)' fill='none' fill-rule='evenodd'\/%3E%3C\/svg%3E\"); }\n        .cyber-clip { clip-path: polygon(0 15px, 15px 0, 100% 0, 100% calc(100% - 15px), calc(100% - 15px) 100%, 0 100%); }\n        .cyber-hub { clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%); }\n        .tilt-card { transform-style: preserve-3d; will-change: transform; transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale3d(1, 1, 1); transition: transform 0.1s cubic-bezier(0.25, 0.46, 0.45, 0.94), border-color 0.4s ease; }\n        .tilt-card.reset { transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94), border-color 0.4s ease; }\n        .svg-circuit-line { fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }\n        .flow-packet { stroke-dasharray: 15, 150; animation: dashFlow 3s linear infinite; }\n        @keyframes dashFlow { 0% { stroke-dashoffset: 165; } 100% { stroke-dashoffset: 0; } }\n        .layer-stats { opacity: 1; transition: opacity 0.3s ease, transform 0.3s ease; transform: translateY(0); }\n        .layer-text { opacity: 0; pointer-events: none; transition: opacity 0.3s ease, transform 0.3s ease; transform: translateY(10px); }\n        .tilt-card:hover .layer-stats { opacity: 0; transform: translateY(-10px); pointer-events: none; }\n        .tilt-card:hover .layer-text { opacity: 1; pointer-events: auto; transform: translateY(0); }\n    <\/style>\n\n    <div class=\"relative z-30 mb-20\" data-aos=\"fade-down\">\n        <h2 class=\"text-4xl md:text-[2.66rem] mb-4 uppercase tracking-[0.2em] text-background-dark  flex items-center justify-center gap-4\">\n             SENIBINA TERAS SISTEM MIKROGRID\n        <\/h2>\n        <div class=\"flex items-center justify-center gap-4 text-primary font-mono text-xs tracking-[0.4em]\">\n            <span class=\"w-8 h-[2px] bg-gradient-to-r from-transparent to-primary-dark\"><\/span>\n            RANGKAIAN MIKROGRID PINTAR\n            <span class=\"w-8 h-[2px] bg-gradient-to-l from-transparent to-primary-dark\"><\/span>\n        <\/div>\n    <\/div>\n\n    <div class=\"relative w-full max-w-[1400px] mx-auto z-30 flex items-center justify-center px-10 lg:px-20 min-h-[500px]\">\n        \n        <div class=\"hidden lg:block absolute inset-0 z-0 pointer-events-none\">\n            <svg class=\"w-full h-full drop-shadow-[0_0_8px_rgba(19,236,164,0.4)]\" preserveaspectratio=\"xMidYMid meet\" viewbox=\"0 0 1400 500\">\n                <path d=\"M 380 130 L 450 130 Q 480 130 480 160 L 480 250 L 550 250\" class=\"svg-circuit-line stroke-primary\/30\" \/>\n                <path d=\"M 380 130 L 450 130 Q 480 130 480 160 L 480 250 L 550 250\" class=\"svg-circuit-line stroke-primary-dark flow-packet\" \/>\n                <path d=\"M 380 370 L 450 370 Q 480 370 480 340 L 480 250 L 550 250\" class=\"svg-circuit-line stroke-accent\/30\" \/>\n                <path d=\"M 380 370 L 450 370 Q 480 370 480 340 L 480 250 L 550 250\" class=\"svg-circuit-line stroke-accent flow-packet\" style=\"animation-duration: 2.5s; animation-direction: reverse;\" \/>\n                <path d=\"M 850 250 L 1020 250\" class=\"svg-circuit-line stroke-primary\/30\" \/>\n                <path d=\"M 850 250 L 1020 250\" class=\"svg-circuit-line stroke-primary-dark flow-packet\" style=\"stroke-dasharray: 20, 100; animation-duration: 1.5s;\" \/>\n            <\/svg>\n        <\/div>\n\n        <div class=\"grid grid-cols-1 lg:grid-cols-[minmax(300px,1.2fr)_auto_minmax(300px,1.2fr)] gap-8 lg:gap-16 w-full relative z-10 items-center\">\n            \n            <div class=\"flex flex-col gap-8 relative z-10\">\n                <!-- Card 1 -->\n                <div class=\"tilt-card relative bg-white\/70 backdrop-blur-xl border border-white p-8 cyber-clip cursor-pointer hover:border-primary\/50 shadow-glass text-left w-full lg:w-[290px] ml-auto group\">\n                    <div class=\"flex items-start justify-between mb-6 relative z-10\">\n                        <div class=\"flex items-center gap-4\">\n                            <div class=\"w-12 h-12 bg-primary\/10 rounded flex items-center justify-center border border-primary\/30 text-primary group-hover:bg-primary group-hover:text-white transition-colors duration-300 shadow-sm\">\n                                <span class=\"material-symbols-outlined text-2xl\">\uec0f<\/span>\n                            <\/div>\n                            <div>\n                                <h3 class=\"text-xl text-background-dark  tracking-wide\">Penjana Kuasa<\/h3>\n                                <div class=\"text-[10px] text-primary font-mono mt-1\">NOD: GEN_01<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                    <div class=\"relative h-[80px] w-full\">\n                        <div class=\"layer-stats absolute inset-0 w-full grid grid-cols-2 gap-3 font-mono text-xs\">\n                            <div class=\"bg-primary\/5 border border-primary\/20 p-3 text-primary flex flex-col justify-center rounded-sm\">\n                                <span class=\"text-background-dark\/50 text-[10px] mb-1\">VOLTAN KELUAR<\/span>\n                                <span class=\"text-base\">400V DC<\/span>\n                            <\/div>\n                            <div class=\"bg-primary\/5 border border-primary\/20 p-3 text-primary flex flex-col justify-center rounded-sm\">\n                                <span class=\"text-background-dark\/50 text-[10px] mb-1\">STATUS<\/span>\n                                <span class=\"text-base  animate-pulse\">STABIL<\/span>\n                            <\/div>\n                        <\/div>\n                        <div class=\"layer-text absolute inset-0 w-full overflow-hidden\">\n                            <p class=\"decrypt-text text-[13px] text-background-dark\/70 font-medium leading-relaxed\" data-target=\"Harnessing renewable and conventional energy for consistent supply.\">&gt;_ Menunggu arahan\u2026<\/p>\n                        <\/div>\n                    <\/div>\n                    <div class=\"absolute bottom-0 right-0 w-6 h-6 border-b-2 border-r-2 border-primary\/40 group-hover:border-primary-dark transition-colors m-1\"><\/div>\n                <\/div>\n                \n                <!-- Card 2 -->\n                <div class=\"tilt-card relative bg-white\/70 backdrop-blur-xl border border-white p-8 cyber-clip cursor-pointer hover:border-accent\/50 shadow-glass text-left w-full lg:w-[290px] ml-auto group\">\n                    <div class=\"flex items-start justify-between mb-6 relative z-10\">\n                        <div class=\"flex items-center gap-4\">\n                            <div class=\"w-12 h-12 bg-accent\/10 rounded flex items-center justify-center border border-accent\/30 text-accent group-hover:bg-accent group-hover:text-white transition-colors duration-300 shadow-sm\">\n                                <span class=\"material-symbols-outlined text-2xl\">\ue1a3<\/span>\n                            <\/div>\n                            <div>\n                                <h3 class=\"text-xl text-background-dark  tracking-wide\">Penyimpanan Tenaga<\/h3>\n                                <div class=\"text-[10px] text-accent font-mono mt-1\">NOD: BATT_X<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n                    <div class=\"relative h-[80px] w-full\">\n                        <div class=\"layer-stats absolute inset-0 w-full grid grid-cols-2 gap-3 font-mono text-xs\">\n                            <div class=\"bg-accent\/5 border border-accent\/20 p-3 text-accent flex flex-col justify-center rounded-sm\">\n                                <span class=\"text-background-dark\/50 text-[10px] mb-1\">KAPASITI<\/span>\n                                <span class=\"text-base\">500 kWh<\/span>\n                            <\/div>\n                            <div class=\"bg-accent\/5 border border-accent\/20 p-3 text-accent flex flex-col justify-center rounded-sm\">\n                                <span class=\"text-background-dark\/50 text-[10px] mb-1\">MOD<\/span>\n                                <span class=\"text-base  animate-pulse\">CAJ<\/span>\n                            <\/div>\n                        <\/div>\n                        <div class=\"layer-text absolute inset-0 w-full overflow-hidden\">\n                            <p class=\"decrypt-text text-[13px] text-background-dark\/70 font-medium leading-relaxed\" data-target=\"Storing surplus electricity to stabilize the grid day and night.\">&gt;_ Antaramuka\u2026<\/p>\n                        <\/div>\n                    <\/div>\n                    <div class=\"absolute bottom-0 right-0 w-6 h-6 border-b-2 border-r-2 border-accent\/40 group-hover:border-accent transition-colors m-1\"><\/div>\n                <\/div>\n            <\/div>\n\n            <!-- Central Hub -->\n            <div class=\"flex justify-center items-center relative z-20 mx-4 py-8 lg:py-0\">\n                <div class=\"relative flex flex-col items-center justify-center p-12 bg-white\/80 backdrop-blur-2xl border-2 border-white cyber-hub hover:border-primary\/50 transition-all duration-500 w-[300px] h-[360px] shadow-glass group\">\n                    <div class=\"relative w-32 h-32 flex items-center justify-center mb-8\">\n                        <div class=\"absolute inset-0 rounded-full border border-dashed border-primary-dark\/40 animate-[spin_10s_linear_infinite]\"><\/div>\n                        <div class=\"absolute inset-2 rounded-full border-t-4 border-primary\/80 animate-[spin_3s_linear_infinite]\"><\/div>\n                        <div class=\"absolute inset-6 rounded-full bg-white border border-primary\/30 flex items-center justify-center overflow-hidden z-10 group-hover:shadow-[0_0_20px_rgba(19,236,164,0.6)] transition-shadow duration-500\">\n                            <span class=\"material-symbols-outlined text-primary text-4xl\">\ue322<\/span>\n                        <\/div>\n                    <\/div>\n                    <div class=\"bg-primary\/10 border border-primary\/30 px-3 py-1 rounded-full text-primary font-mono text-[10px] mb-4 flex gap-2 items-center tracking-widest\">\n                        <span class=\"w-2 h-2 bg-primary rounded-full animate-ping\"><\/span> PENUKAR\n                    <\/div>\n                    <h3 class=\"text-2xl text-background-dark  tracking-wide mb-2 z-10 group-hover:text-primary transition-colors\">Penukaran Kuasa<\/h3>\n                    <p class=\"text-[12px] text-background-dark\/60 font-mono tracking-widest text-center mt-2\">AC\/DC \u21cc DC\/AC<br>EFF: <span class=\"text-primary\">99.1%<\/span><\/p>\n                <\/div>\n            <\/div>\n\n            <!-- Card 3 -->\n            <div class=\"flex flex-col justify-center relative z-10\">\n                <div class=\"tilt-card relative bg-white\/70 backdrop-blur-xl border border-white p-8 cyber-clip cursor-pointer hover:border-primary-dark\/50 shadow-glass text-left w-full lg:w-[290px] group\">\n                    <div class=\"flex items-start justify-between mb-6 relative z-10\">\n                        <div class=\"flex items-center gap-4\">\n                            <div class=\"w-12 h-12 bg-primary-dark\/10 rounded flex items-center justify-center border border-primary-dark\/30 text-primary group-hover:bg-primary-dark group-hover:text-white transition-colors duration-300 shadow-sm\">\n                                <span class=\"material-symbols-outlined text-2xl\">\ue7ee<\/span>\n                            <\/div>\n                            <div>\n                                <h3 class=\"text-xl text-background-dark  tracking-wide\">Pengurusan Permintaan<\/h3>\n                                <div class=\"text-[10px] text-background-dark\/50 font-mono mt-1\">NOD: MUAT_END<\/div>\n                            <\/div>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"relative h-[80px] w-full\">\n                        <div class=\"layer-stats absolute inset-0 w-full grid grid-cols-2 gap-3 font-mono text-xs\">\n                            <div class=\"bg-gray-100 border border-gray-200 p-3 text-background-dark flex flex-col justify-center rounded-sm\">\n                                <span class=\"text-background-dark\/50 text-[10px] mb-1\">KUASA SEBENAR<\/span>\n                                <span class=\"text-base\">120 kW<\/span>\n                            <\/div>\n                            <div class=\"bg-gray-100 border border-gray-200 p-3 text-background-dark flex flex-col justify-center rounded-sm\">\n                                <span class=\"text-background-dark\/50 text-[10px] mb-1\">FAKTOR KUASA<\/span>\n                                <span class=\"text-base\">0.98<\/span>\n                            <\/div>\n                        <\/div>\n                        <div class=\"layer-text absolute inset-0 w-full overflow-hidden\">\n                            <p class=\"decrypt-text text-[13px] text-background-dark\/70 font-medium leading-relaxed\" data-target=\"Distributing power smartly to meet diverse load requirements.\">&gt;_ Menyambung\u2026<\/p>\n                        <\/div>\n                    <\/div>\n                    <div class=\"absolute bottom-0 right-0 w-6 h-6 border-b-2 border-r-2 border-primary-dark\/40 group-hover:border-primary-dark transition-colors m-1\"><\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/section>\n\n<!-- Features Sections (Glassmorphism & Bright Theme) -->\n        <section id=\"mod-security\" class=\"min-h-screen flex items-center\">\n            <div class=\"max-w-xl bg-white\/80 backdrop-blur-xl p-10 border-l-4 border-accent rounded-r-3xl shadow-glass\">\n                <span class=\"material-symbols-outlined text-5xl text-accent mb-6\">\ue32a<\/span>\n                <h2 class=\"text-4xl  mb-4 text-background-dark\">Selamat &amp;<br>Boleh dipercayai<\/h2>\n                <p class=\"text-lg text-background-dark\/70 leading-relaxed font-medium\">Mengekalkan operasi pulau tanpa pemutusan bekalan, disokong oleh redundansi berbilang kuasa untuk menjamin sifar masa henti untuk beban kritikal.<\/p>\n            <\/div>\n        <\/section>\n\n        <section id=\"mod-efficiency\" class=\"min-h-screen flex items-center justify-end text-right\">\n            <div class=\"max-w-xl bg-white\/80 backdrop-blur-xl p-10 border-r-4 border-primary rounded-l-3xl shadow-glass\">\n                <span class=\"material-symbols-outlined text-5xl text-primary mb-6\">\uf0cf<\/span>\n                <h2 class=\"text-4xl  mb-4 text-background-dark\">Pintar &amp;<br>Cekap<\/h2>\n                <p class=\"text-lg text-background-dark\/70 leading-relaxed font-medium\">Pengoptimuman dan penghantaran pintar membolehkan pencukuran puncak dan pengisian lembah, sekali gus mengurangkan kos elektrik dan penggunaan tenaga dengan berkesan.<\/p>\n            <\/div>\n        <\/section>\n\n        <section id=\"mod-netzero\" class=\"min-h-screen flex items-center\">\n            <div class=\"max-w-xl bg-white\/80 backdrop-blur-xl p-10 border-l-4 border-primary-dark rounded-r-3xl shadow-glass\">\n                <span class=\"material-symbols-outlined text-5xl text-primary mb-6\">\uea35<\/span>\n                <h2 class=\"text-4xl  mb-4 text-background-dark\">Hijau &amp;<br>Rendah Karbon<\/h2>\n                <p class=\"text-lg text-background-dark\/70 leading-relaxed font-medium\">Menyerap tenaga boleh diperbaharui dengan cekap dan mengurangkan pelepasan karbon, memudahkan pencapaian matlamat dwi-karbon.<\/p>\n            <\/div>\n        <\/section>\n\n        <section id=\"mod-autonomous\" class=\"min-h-screen flex items-center justify-end text-right\">\n            <div class=\"max-w-xl bg-white\/80 backdrop-blur-xl p-10 border-r-4 border-accent rounded-l-3xl shadow-glass\">\n                <span class=\"material-symbols-outlined text-5xl text-accent mb-6\">\ue97a<\/span>\n                <h2 class=\"text-4xl  mb-4 text-background-dark\">Autonomi &amp;<br>Boleh dikawal<\/h2>\n                <p class=\"text-lg text-background-dark\/70 leading-relaxed font-medium\">Beroperasi secara bebas daripada grid luaran, meningkatkan autonomi tenaga dan daya tahan risiko dengan ketara.<\/p>\n            <\/div>\n        <\/section>\n\n       <!-- === Scenarios === -->\n       <section id=\"mod-scenarios\" class=\"min-h-[80vh] flex flex-col justify-center items-center text-center pb-20 relative z-10\" style=\"perspective: 2000px;\">\n            <h2 class=\"text-4xl md:text-[2.66rem] mb-12 uppercase tracking-widest text-background-dark  mt-10 relative z-30\">Senario yang Berkenaan<\/h2>\n            \n            <div class=\"flex flex-wrap justify-center gap-4 font-mono text-sm max-w-4xl relative z-30\" id=\"scenario-buttons\">\n                <button class=\"scenario-btn px-6 py-2 border border-primary\/20 bg-white\/80 hover:border-primary-dark hover:text-primary transition-all duration-300 rounded-full shadow-sm text-background-dark\/70\">Taman Perindustrian<\/button>\n                <button class=\"scenario-btn px-6 py-2 border border-primary\/20 bg-white\/80 hover:border-primary-dark hover:text-primary transition-all duration-300 rounded-full shadow-sm text-background-dark\/70\">Pusat Data<\/button>\n                <button class=\"scenario-btn px-6 py-2 border border-primary\/20 bg-white\/80 hover:border-primary-dark hover:text-primary transition-all duration-300 rounded-full shadow-sm text-background-dark\/70\">Kompleks Komersial<\/button>\n                <button class=\"scenario-btn px-6 py-2 border border-primary\/20 bg-white\/80 hover:border-primary-dark hover:text-primary transition-all duration-300 rounded-full shadow-sm text-background-dark\/70\">Hospital &amp; Sekolah<\/button>\n                <button class=\"scenario-btn px-6 py-2 border border-primary\/20 bg-white\/80 hover:border-primary-dark hover:text-primary transition-all duration-300 rounded-full shadow-sm text-background-dark\/70\">Kawasan Terpencil<\/button>\n                <button class=\"scenario-btn px-6 py-2 border border-primary\/20 bg-white\/80 hover:border-primary-dark hover:text-primary transition-all duration-300 rounded-full shadow-sm text-background-dark\/70\">Kepulauan<\/button>\n                <button class=\"scenario-btn active-scenario px-6 py-2 bg-primary\/10 border border-primary text-primary shadow-[0_4px_15px_rgba(19,236,164,0.3)] transition-all duration-300 rounded-full\">Komuniti Sifar Karbon<\/button>\n                <button class=\"scenario-btn px-6 py-2 border border-primary\/20 bg-white\/80 hover:border-primary-dark hover:text-primary transition-all duration-300 rounded-full shadow-sm text-background-dark\/70\">Stesen Tenaga Baharu<\/button>\n            <\/div>\n\n            <div id=\"card-wrapper\" class=\"relative mt-12 w-full max-w-5xl h-[450px] z-20\" style=\"transform-style: preserve-3d;\">\n                <div id=\"scenario-card\" class=\"absolute inset-0 w-full h-full rounded-3xl overflow-hidden border-4 border-white shadow-2xl bg-white opacity-0\" style=\"transform: translateZ(-500px) rotateX(20deg); pointer-events: none;\">\n                    <div class=\"absolute inset-0 z-0 overflow-hidden\">\n                        <img decoding=\"async\" id=\"card-img\" src=\"\" class=\"w-full h-full object-cover opacity-90\" alt=\"Scenario Image\" >\n                    <\/div>\n                    <!-- Light theme inner gradient -->\n                    <div class=\"absolute inset-0 bg-gradient-to-t from-white via-white\/80 to-transparent z-10\"><\/div>\n                    <div class=\"absolute bottom-12 left-12 z-20 text-left\">\n                        <h3 id=\"card-title\" class=\"text-4xl font-display  text-background-dark mb-4 tracking-tighter\"><\/h3>\n                        <p id=\"card-desc\" class=\"text-lg text-background-dark\/80 max-w-2xl leading-relaxed font-medium\"><\/p>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/section>\n\n       <!-- === Contact === -->\n       <section id=\"mod-contact\" class=\"w-full py-24 relative z-10 overflow-hidden bg-white\/50 border-t border-white shadow-[0_-10px_40px_rgba(13,166,112,0.05)]\">\n            <div class=\"max-w-7xl mx-auto px-6\">\n                <div class=\"flex items-center gap-4 mb-12\" data-aos=\"fade-right\">\n                    <div class=\"h-[2px] w-12 bg-primary-dark\"><\/div>\n                    <span class=\"text-primary font-mono text-xs uppercase tracking-[0.4em]\">Hubungi Kami<\/span>\n                <\/div>\n\n                <div class=\"flex flex-col lg:flex-row lg:items-end lg:justify-between gap-12\">\n                    <div data-aos=\"fade-up\" data-aos-delay=\"100\">\n                        <h2 class=\"text-background-dark\/50 text-sm font-mono uppercase tracking-widest mb-2\">Ketua Projek Mikrogrid<\/h2>\n                        <div class=\"flex items-baseline gap-6\">\n                            <span class=\"text-5xl  tracking-tighter text-background-dark\">Yan<\/span>\n                        <\/div>\n                    <\/div>\n\n                    <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 w-full lg:max-w-2xl\" data-aos=\"fade-left\" data-aos-delay=\"200\">\n                        <a href=\"mailto:sheyanxin@nenghui.com\" class=\"group relative p-6 bg-white border border-primary\/20 rounded-2xl overflow-hidden transition-all duration-500 hover:border-primary hover:shadow-lg\">\n                            <div class=\"absolute inset-0 bg-gradient-to-r from-primary\/5 to-transparent translate-x-[-100%] group-hover:translate-x-[0%] transition-transform duration-500\"><\/div>\n                            <div class=\"relative flex items-center gap-4\">\n                                <div class=\"w-12 h-12 rounded-full bg-primary\/10 flex items-center justify-center text-primary\">\n                                    <span class=\"material-symbols-outlined\">\ue158<\/span>\n                                <\/div>\n                                <div>\n                                    <div class=\"text-background-dark\/50 text-[10px] uppercase tracking-widest\">Hantar E-mel<\/div>\n                                    <div class=\"text-background-dark  group-hover:text-primary transition-colors\">sheyanxin@nenghui.com<\/div>\n                                <\/div>\n                            <\/div>\n                        <\/a>\n\n                        <a href=\"tel:8619120593729\" class=\"group relative p-6 bg-white border border-primary\/20 rounded-2xl overflow-hidden transition-all duration-500 hover:border-primary hover:shadow-lg\">\n                            <div class=\"absolute inset-0 bg-gradient-to-r from-primary\/5 to-transparent translate-x-[-100%] group-hover:translate-x-[0%] transition-transform duration-500\"><\/div>\n                            <div class=\"relative flex items-center gap-4\">\n                                <div class=\"w-12 h-12 rounded-full bg-primary\/10 flex items-center justify-center text-primary\">\n                                    <span class=\"material-symbols-outlined\">\ue0b0<\/span>\n                                <\/div>\n                                <div>\n                                    <div class=\"text-background-dark\/50 text-[10px] uppercase tracking-widest\">Hubungi Secara Terus<\/div>\n                                    <div class=\"text-background-dark  group-hover:text-primary transition-colors\">+86 191 2059 3729<\/div>\n                                <\/div>\n                            <\/div>\n                        <\/a>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/section>\n    <\/main>\n\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\"><\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/gsap\/3.12.2\/gsap.min.js\"><\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/gsap\/3.12.2\/ScrollTrigger.min.js\"><\/script>\n    <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/aos\/2.3.4\/aos.js\"><\/script>\n    \n    <!-- JavaScript Logic & Animations -->\n    <script>\n        AOS.init({ once: true });\n        gsap.registerPlugin(ScrollTrigger);\n\n        \/\/ --- \u5361\u7247\u503e\u659c\u4e0e\u6253\u5b57\u673a\u7279\u6548 (\u4fdd\u6301\u4e0d\u53d8) ---\n        document.addEventListener(\"DOMContentLoaded\", () => {\n            const cards = document.querySelectorAll('.tilt-card');\n            cards.forEach(card => {\n                card.addEventListener('mousemove', e => {\n                    card.classList.remove('reset'); \n                    const rect = card.getBoundingClientRect();\n                    const x = e.clientX - rect.left;\n                    const y = e.clientY - rect.top;\n                    const centerX = rect.width \/ 2;\n                    const centerY = rect.height \/ 2;\n                    const rotateX = ((y - centerY) \/ centerY) * -4; \n                    const rotateY = ((x - centerX) \/ centerX) * 4;\n                    card.style.setProperty('--rx', `${rotateX}deg`);\n                    card.style.setProperty('--ry', `${rotateY}deg`);\n                });\n\n                card.addEventListener('mouseleave', () => {\n                    card.classList.add('reset');\n                    card.style.setProperty('--rx', `0deg`);\n                    card.style.setProperty('--ry', `0deg`);\n                    const decryptEl = card.querySelector('.decrypt-text');\n                    if(decryptEl) {\n                        decryptEl.dataset.isAnimating = \"false\";\n                        decryptEl.innerHTML = `>_ Awaiting command...`;\n                    }\n                });\n\n                card.addEventListener('mouseenter', () => {\n                    const decryptEl = card.querySelector('.decrypt-text');\n                    if(!decryptEl || decryptEl.dataset.isAnimating === \"true\") return;\n                    decryptEl.dataset.isAnimating = \"true\";\n                    const targetText = decryptEl.getAttribute('data-target');\n                    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%&*';\n                    let iteration = 0;\n                    function decryptFrame() {\n                        if(decryptEl.dataset.isAnimating === \"false\") return; \n                        decryptEl.innerHTML = targetText.split(\"\").map((letter, index) => {\n                            if(index < iteration) return letter;\n                            return chars[Math.floor(Math.random() * chars.length)];\n                        }).join(\"\") + `<span class=\"animate-pulse text-primary ml-1\">_<\/span>`;\n                        if(iteration < targetText.length) {\n                            iteration += 1; \n                            setTimeout(() => requestAnimationFrame(decryptFrame), 15);\n                        } else {\n                            decryptEl.dataset.isAnimating = \"false\";\n                            decryptEl.innerHTML = targetText + `<span class=\"animate-pulse text-primary ml-1\">_<\/span>`;\n                        }\n                    }\n                    requestAnimationFrame(decryptFrame);\n                });\n            });\n        });\n\n        \/\/ --- Three.js \u4eae\u8272\u4e3b\u9898\u7c92\u5b50\u5f15\u64ce ---\n        const scene = new THREE.Scene();\n        \/\/ \u589e\u52a0\u96fe\u5316\u6548\u679c\uff0c\u8ba9\u8fdc\u5904\u7684\u7c92\u5b50\u878d\u5165\u80cc\u666f\n        scene.fog = new THREE.FogExp2(0xf8fcfa, 0.0015);\n        \n        const camera = new THREE.PerspectiveCamera(60, window.innerWidth \/ window.innerHeight, 1, 2000);\n        camera.position.z = 500;\n\n        function updateCameraFOV() {\n            camera.fov = window.innerWidth < 768 ? 75 : 55;\n            camera.updateProjectionMatrix();\n        }\n        updateCameraFOV();\n\n        const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });\n        renderer.setPixelRatio(window.devicePixelRatio);\n        renderer.setSize(window.innerWidth, window.innerHeight);\n        document.getElementById('canvas-container').appendChild(renderer.domElement);\n\n        const particleCount = window.innerWidth < 768 ? 9000 : 12000; \n        const geometry = new THREE.BufferGeometry();\n        \n        const currentPositions = new Float32Array(particleCount * 3); \n        const renderPositions = new Float32Array(particleCount * 3);  \n        const startPos = new Float32Array(particleCount * 3);\n        const targetPos = new Float32Array(particleCount * 3);\n        const colors = new Float32Array(particleCount * 3);\n\n        \/\/ --- \u6838\u5fc3\u6539\u52a8\uff1a\u9002\u5408\u4eae\u8272\u80cc\u666f\u7684\u7c92\u5b50\u989c\u8272 ---\n        const colorPrimary = new THREE.Color('#09ab75'); \/\/ \u6df1\u7fe0\u7eff\uff0c\u4fdd\u8bc1\u5728\u767d\u5e95\u4e0a\u6e05\u6670\n        const colorAccent = new THREE.Color('#64e8bc');  \/\/ \u4eae\u7eff\u8272\u7528\u4e8e\u70b9\u7f00\n        const colorGray = new THREE.Color('#94a3b8');    \/\/ \u84dd\u7070\u8272\u66ff\u4ee3\u539f\u6709\u7684\u94f6\u767d\u8272\n\n        for (let i = 0; i < particleCount; i++) {\n            const mix = Math.random();\n            const color = colorPrimary.clone().lerp(colorAccent, mix * 0.5);\n            colors.set([color.r, color.g, color.b], i * 3);\n        }\n        geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));\n\n        \/\/ \u5f62\u72b6\u751f\u6210\u5668 (\u4fdd\u6301\u539f\u6709\u8ba1\u7b97\u903b\u8f91)\n        const shapesGen = {\n            text: () => {\n                const canvas = document.createElement('canvas');\n                canvas.width = 1200; canvas.height = 300;\n                const ctx = canvas.getContext('2d');\n                ctx.fillStyle = '#000'; ctx.fillRect(0, 0, 1200, 300);\n                ctx.font = 'bold 200px \"Arial\", sans-serif';\n                ctx.fillStyle = '#fff'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';\n                ctx.fillText( window.innerWidth < 768  ?  'NH' :'NENGHUI', 600, 150);\n                const data = ctx.getImageData(0, 0, 1200, 300).data;\n                let points = [];\n                for (let y = 0; y < 300; y += 3) {\n                    for (let x = 0; x < 1200; x += 3) {\n                        if (data[(y * 1200 + x) * 4] > 128) {\n                            points.push({ x: x - 600, y: -(y - 150), z: (Math.random() - 0.5) * 20 });\n                        }\n                    }\n                }\n                const arr = new Float32Array(particleCount * 3);\n                for (let i = 0; i < particleCount; i++) {\n                    const p = points[i % points.length];\n                    arr.set([p.x, p.y, p.z], i * 3);\n                }\n                return arr;\n            },\n            nestedPolyhedron: () => {\n                const arr = new Float32Array(particleCount * 3);\n                for (let i = 0; i < particleCount; i++) {\n                    const r = i % 2 === 0 ? 100 : 50;\n                    const theta = Math.random() * Math.PI * 2;\n                    const phi = Math.acos(Math.random() * 2 - 1);\n                    let x = r * Math.sin(phi) * Math.cos(theta);\n                    let y = r * Math.sin(phi) * Math.sin(theta);\n                    let z = r * Math.cos(phi);\n                    if (Math.abs(x) > r * 0.7) x = Math.sign(x) * r * 0.7;\n                    arr.set([x, y, z], i * 3);\n                }\n                return arr;\n            },\n            symbioticLeaf: () => {\n                const arr = new Float32Array(particleCount * 3);\n                const leafParticles = Math.floor(particleCount * 0.85);\n                const carbonParticles = particleCount - leafParticles;\n                for (let i = 0; i < leafParticles; i++) {\n                    const t = Math.random();\n                    const y = t * 400 - 150; \n                    const widthFactor = Math.sin(t * Math.PI) * (1.2 - 0.2 * t);\n                    const maxWidth = 160;\n                    let x, z;\n                    const isVein = Math.random() < 0.4;\n                    if (isVein) {\n                        if (Math.random() < 0.3) {\n                            x = (Math.random() - 0.5) * 4;\n                            z = (Math.random() - 0.5) * 4;\n                        } else {\n                            const side = Math.random() > 0.5 ? 1 : -1;\n                            const veinT = Math.floor(t * 10) \/ 10; \n                            x = side * (t - veinT) * 300 + (side * veinT * 20);\n                            x = THREE.MathUtils.clamp(x, -maxWidth * widthFactor, maxWidth * widthFactor);\n                            z = (Math.random() - 0.5) * 10;\n                        }\n                    } else {\n                        const rawX = (Math.random() - 0.5) * 2 * maxWidth * widthFactor;\n                        x = Math.round(rawX \/ 15) * 15; \n                        z = (Math.random() - 0.5) * 20;\n                    }\n                    const bend = Math.sin(t * Math.PI) * 30;\n                    arr.set([x + bend, y, z], i * 3);\n                }\n                for (let i = 0; i < carbonParticles; i++) {\n                    const idx = (leafParticles + i) * 3;\n                    arr.set([\n                        (Math.random() - 0.5) * 300,\n                        -250 - Math.random() * 150,\n                        (Math.random() - 0.5) * 60\n                    ], idx);\n                }\n                return arr;\n            },\n            concentricSphere: () => {\n                const arr = new Float32Array(particleCount * 3);\n                for (let i = 0; i < particleCount; i++) {\n                    const r = i % 3 === 0 ? 140 : (i % 3 === 1 ? 90 : 40);\n                    const phi = Math.acos(-1 + Math.random() * 2);\n                    const theta = Math.random() * Math.PI * 2;\n                    arr.set([r * Math.sin(phi) * Math.cos(theta), r * Math.sin(phi) * Math.sin(theta), r * Math.cos(phi)], i * 3);\n                }\n                return arr;\n            },\n            barGraph: () => {\n                const arr = new Float32Array(particleCount * 3);\n                for (let i = 0; i < particleCount; i++) {\n                    const gridX = Math.floor(Math.random() * 8) - 4;\n                    const gridZ = Math.floor(Math.random() * 8) - 4;\n                    const height = (Math.sin(gridX) + Math.cos(gridZ) + 2) * 40 + 20;\n                    arr.set([gridX * 40 + (Math.random() - 0.5) * 20, Math.random() * height - 100, gridZ * 40 + (Math.random() - 0.5) * 20], i * 3);\n                }\n                return arr;\n            },\n            shield: () => {\n                const arr = new Float32Array(particleCount * 3);\n                for (let i = 0; i < particleCount; i++) {\n                    let x = (Math.random() - 0.5) * 200; \n                    let y, z;\n                    let topEdge = 100 + 15 * Math.cos(x * Math.PI \/ 100);\n                    let bottomEdge = -120 + 220 * Math.pow(Math.abs(x) \/ 100, 2);\n                    let t = Math.random();\n                    if (Math.random() > 0.6) {\n                         t = Math.random() > 0.5 ? Math.random() * 0.1 : 0.9 + Math.random() * 0.1;\n                    }\n                    y = bottomEdge + t * (topEdge - bottomEdge);\n                    let maxZ = 30 * (1 - Math.pow(Math.abs(x) \/ 100, 2));\n                    if (Math.abs(x) < 8 || Math.abs(y - 10) < 8) maxZ += 10;\n                    z = (Math.random() - 0.5) * maxZ;\n                    arr.set([x, y, z], i * 3);\n                }\n                return arr;\n            },\n            torusKnot: () => {\n                const arr = new Float32Array(particleCount * 3);\n                for (let i = 0; i < particleCount; i++) {\n                    const t = Math.random() * Math.PI * 2;\n                    const p = 2; const q = 3; \n                    const r = 50 * (2 + Math.cos(q * t));\n                    const x = r * Math.cos(p * t);\n                    const y = r * Math.sin(p * t);\n                    const z = 50 * Math.sin(q * t);\n                    const noise = 15;\n                    arr.set([x + (Math.random() - 0.5) * noise, y + (Math.random() - 0.5) * noise, z + (Math.random() - 0.5) * noise], i * 3);\n                }\n                return arr;\n            },\n            networkNode: () => {\n                const arr = new Float32Array(particleCount * 3);\n                const nodes = [\n                    {x: 0, y: 0, z: 0, r: 35}, \n                    {x: 120, y: 70, z: 40, r: 15},\n                    {x: -110, y: -80, z: 20, r: 20},\n                    {x: 90, y: -100, z: -40, r: 15},\n                    {x: -100, y: 90, z: -30, r: 18},\n                    {x: 0, y: 130, z: 10, r: 12},\n                    {x: 0, y: -130, z: 0, r: 12}\n                ];\n                for (let i = 0; i < particleCount; i++) {\n                    const pType = Math.random();\n                    if (pType < 0.5) {\n                        const node = nodes[Math.floor(Math.random() * nodes.length)];\n                        const theta = Math.random() * Math.PI * 2;\n                        const phi = Math.acos((Math.random() * 2) - 1);\n                        const r = node.r * (0.5 + 0.5 * Math.random());\n                        arr.set([\n                            node.x + r * Math.sin(phi) * Math.cos(theta),\n                            node.y + r * Math.sin(phi) * Math.sin(theta),\n                            node.z + r * Math.cos(phi)\n                        ], i * 3);\n                    } else {\n                        const targetNode = nodes[1 + Math.floor(Math.random() * (nodes.length - 1))];\n                        const t = Math.random();\n                        const noise = 3;\n                        arr.set([\n                            t * targetNode.x + (Math.random() - 0.5) * noise,\n                            t * targetNode.y + (Math.random() - 0.5) * noise,\n                            t * targetNode.z + (Math.random() - 0.5) * noise\n                        ], i * 3);\n                    }\n                }\n                return arr;\n            }\n        };\n\n        const precalculatedShapes = {\n            text: shapesGen.text(),\n            nestedPolyhedron: shapesGen.nestedPolyhedron(),\n            symbioticLeaf: shapesGen.symbioticLeaf(),\n            concentricSphere: shapesGen.concentricSphere(),\n            barGraph: shapesGen.barGraph(),\n            shield: shapesGen.shield(),\n            torusKnot: shapesGen.torusKnot(),\n            networkNode: shapesGen.networkNode()\n        };\n\n        currentPositions.set(precalculatedShapes.text);\n        renderPositions.set(precalculatedShapes.text);\n        geometry.setAttribute('position', new THREE.BufferAttribute(renderPositions, 3));\n        \n        \/\/ --- \u6838\u5fc3\u6539\u52a8\uff1a\u5fc5\u987b\u4f7f\u7528 NormalBlending \u624d\u80fd\u5728\u767d\u5e95\u4e0a\u663e\u793a\u989c\u8272 ---\n        const material = new THREE.PointsMaterial({\n            size: window.innerWidth < 768 ? 3.5 : 4.0, \n            vertexColors: true,\n            transparent: true,\n            opacity: 0.8,\n            blending: THREE.NormalBlending, \/\/ AdditiveBlending \u4f1a\u5728\u767d\u5e95\u4e0a\u5b8c\u5168\u6d88\u5931\uff01\n            sizeAttenuation: true, \n            depthWrite: false\n        });\n        const particles = new THREE.Points(geometry, material);\n        scene.add(particles);\n\n        let time = 0;\n        let morphData = { progress: 0 };\n        let currentShapeKey = 'text';\n        let morphTween = null; \n        \n        const rotationSpeed = { x: 0, y: 0 };\n        const waveConfig = { amplitude: 20 }; \n\n        function morphTo(shapeKey) {\n            if (currentShapeKey === shapeKey) return;\n            currentShapeKey = shapeKey;\n\n            if (morphTween) morphTween.kill();\n\n            const colorAttribute = geometry.attributes.color;\n            const targetColors = new Float32Array(particleCount * 3);\n            const leafParticles = Math.floor(particleCount * 0.85);\n\n            for (let i = 0; i < particleCount; i++) {\n                let color;\n                if (shapeKey === 'symbioticLeaf') {\n                    if (i < leafParticles) {\n                        color = colorPrimary.clone().lerp(colorAccent, Math.random() * 0.2);\n                    } else {\n                        color = colorGray.clone();\n                    }\n                } else {\n                    color = colorPrimary.clone().lerp(colorAccent, Math.random() * 0.4);\n                }\n                targetColors.set([color.r, color.g, color.b], i * 3);\n            }\n\n            gsap.to(colorAttribute.array, {\n                endArray: targetColors,\n                duration: 1.5,\n                ease: \"power2.inOut\",\n                onUpdate: () => colorAttribute.needsUpdate = true\n            });\n\n            for (let i = 0; i < currentPositions.length; i++) {\n                startPos[i] = currentPositions[i];\n            }\n            targetPos.set(precalculatedShapes[shapeKey]);\n\n            morphData.progress = 0;\n            morphTween = gsap.to(morphData, {\n                progress: 1,\n                duration: 2.0, \n                ease: \"power3.inOut\",\n                onUpdate: () => {\n                    for (let i = 0; i < particleCount * 3; i++) {\n                        currentPositions[i] = startPos[i] + (targetPos[i] - startPos[i]) * morphData.progress;\n                    }\n                }\n            });\n\n            if (shapeKey === 'text') {\n                gsap.to(rotationSpeed, { x: 0, y: 0, duration: 1.5 });\n                const targetX = Math.round(particles.rotation.x \/ (Math.PI * 2)) * (Math.PI * 2);\n                const targetY = Math.round(particles.rotation.y \/ (Math.PI * 2)) * (Math.PI * 2);\n                gsap.to(particles.rotation, { x: targetX, y: targetY, duration: 2.0 });\n            } else if (shapeKey === 'shield') {\n                gsap.to(rotationSpeed, { x: 0, y: 0.002, duration: 1.5 });\n                const targetX = Math.round(particles.rotation.x \/ (Math.PI * 2)) * (Math.PI * 2);\n                gsap.to(particles.rotation, { x: targetX, duration: 2.0 });\n            } else if (shapeKey === 'symbioticLeaf') {\n                gsap.to(rotationSpeed, { x: 0.0005, y: 0.001, duration: 1.5 });\n            } else if (shapeKey === 'barGraph') {\n                gsap.to(rotationSpeed, { x: 0, y: 0.002, duration: 1.5 });\n                const targetX = Math.round(particles.rotation.x \/ (Math.PI * 2)) * (Math.PI * 2);\n                gsap.to(particles.rotation, { x: targetX + 0.4, duration: 2.0 });\n            } else {\n                gsap.to(rotationSpeed, { x: 0.001, y: 0.002, duration: 2.0 });\n            }\n\n            gsap.to(waveConfig, {\n                duration: 2.0,\n                amplitude: (shapeKey === 'text') ? 20 : 0\n            });\n        }\n   \n        function animate() {\n            requestAnimationFrame(animate);\n            time += 0.02; \n\n            const positions = geometry.attributes.position.array;\n            const colorsArray = geometry.attributes.color.array;\n            const leafParticles = Math.floor(particleCount * 0.85);\n\n            for (let i = 0; i < particleCount; i++) {\n                let idx = i * 3;\n                let baseX = currentPositions[idx];\n                let baseY = currentPositions[idx + 1];\n                let baseZ = currentPositions[idx + 2];\n\n                if (currentShapeKey === 'symbioticLeaf' ) {\n                    if (i < leafParticles) {\n                        if (i % 7 === 0 ) {\n                            if (Math.abs(baseX) < 100) {\n                                const angle = time * 3 + (baseY * 0.02);\n                                const r = 10 * Math.sin(time * 0.5);\n                                positions[idx] = baseX + r * Math.cos(angle);\n                                positions[idx + 1] = baseY;\n                                positions[idx + 2] = baseZ + r * Math.sin(angle);\n                            }\n                        } else {\n                            positions[idx] = baseX + Math.sin(time + baseY * 0.1) * 2;\n                            positions[idx + 1] = baseY;\n                            positions[idx + 2] = baseZ;\n                        }\n                    }\n                } else if (waveConfig.amplitude > 0.01) {\n                    const phase = baseX * 0.006 + time; \n                    const waveY = Math.sin(phase) * (waveConfig.amplitude * 0.4);\n                    const waveZ = Math.cos(phase * 0.8) * waveConfig.amplitude;\n                    positions[idx] = baseX;\n                    positions[idx + 1] = baseY + waveY;\n                    positions[idx + 2] = baseZ + waveZ;\n                } else {\n                    positions[idx] = baseX;\n                    positions[idx + 1] = baseY;\n                    positions[idx + 2] = baseZ;\n                }\n\n                if (currentShapeKey === 'symbioticLeaf') {\n                    if (i >= leafParticles) {\n                        let y = baseY + (time * 50) % 200; \n                        let opacity = 1.0;\n\n                        if (y > -150) {\n                            opacity = THREE.MathUtils.lerp(1.0, 0.0, (y + 150) \/ 100);\n                        }\n                        if (y > -50) opacity = 0; \n                        positions[idx + 1] = y;\n                        colorsArray[idx] = colorGray.r * opacity;\n                        colorsArray[idx + 1] = colorGray.g * opacity;\n                        colorsArray[idx + 2] = colorGray.b * opacity;\n                    }\n                }\n            }\n            \n            geometry.attributes.position.needsUpdate = true;\n            if (currentShapeKey === 'symbioticLeaf') {\n                geometry.attributes.color.needsUpdate = true;\n            }\n\n            particles.rotation.x += rotationSpeed.x;\n            particles.rotation.y += rotationSpeed.y;\n            \n            renderer.render(scene, camera);\n        }\n        animate();\n\n        window.addEventListener('resize', () => {\n            camera.aspect = window.innerWidth \/ window.innerHeight;\n            camera.updateProjectionMatrix();\n            renderer.setSize(window.innerWidth, window.innerHeight);\n            updateCameraFOV();\n        });\n\n        const shapeList = ['text', 'shield', 'concentricSphere', 'symbioticLeaf', 'torusKnot', 'networkNode', 'barGraph', 'nestedPolyhedron'];\n        const sections = ['#mod-hero', '#mod-security', '#mod-efficiency', '#mod-netzero', '#mod-autonomous', '#mod-topology', '#mod-scenarios', '#mod-contact'];\n        \n        sections.forEach((id, idx) => {\n            ScrollTrigger.create({\n                trigger: id,\n                start: \"top 55%\",\n                end: \"bottom 45%\",\n                onEnter: () => morphTo(shapeList[idx]),\n                onEnterBack: () => morphTo(shapeList[idx])\n            });\n        });\n\n    <\/script>\n    <script>\n        \/\/ --- \u573a\u666f\u5361\u7247 3D \u52a8\u753b ---\n        const scenarioData = {\n            \"Industrial Parks\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-Industrial-parks.jpg\", desc: \"Optimize energy consumption and reduce operational costs for smart industrial zones with intelligent management.\" },\n            \"Data Centers\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-data-center.jpg\", desc: \"Ensuring continuous mission-critical power supply for data centers with robust and resilient microgrids.\" },\n            \"Commercial Complexes\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-Commercial-complexes.jpg\", desc: \"Optimize operational costs for commercial hubs through intelligent energy distribution and Peak Shaving.\" },\n            \"Hospitals & Schools\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-Hospitals-schools.jpg\", desc: \"Ensuring uninterrupted power supply for critical medical services and secure educational campus environments.\" },\n            \"Remote Regions\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-Remote-regions.jpg\", desc: \"Overcoming geographical barriers with advanced microgrid technology to illuminate the world's remotest corners.\" },\n            \"Islands\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-Islands.jpg\", desc: \"Achieve reliable energy independence for remote islands through sustainable solar and storage systems.\" },\n            \"Zero-Carbon Communities\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-Zero-carbon-communities.jpg\", desc: \"Building a sustainable future for modern living through intelligent and eco-friendly microgrid systems.\" },\n            \"New Energy Stations\": { img: \"https:\/\/nenghui.com\/wp-content\/uploads\/2026\/03\/icrogrid-New-energy-stations.jpg\", desc: \"Enhancing grid stability and renewable integration through advanced storage-based microgrid management systems.\" }\n        };\n\n        const scenarioButtons = document.querySelectorAll('.scenario-btn');\n        const scenarioCard = document.getElementById('scenario-card');\n        const cardImg = document.getElementById('card-img');\n        const cardTitle = document.getElementById('card-title');\n        const cardDesc = document.getElementById('card-desc');\n        \n        let currentActiveBtn = document.querySelector('.active-scenario');\n\n        function updateCardContent(scenarioName) {\n            if(!scenarioData[scenarioName]) return;\n            const data = scenarioData[scenarioName];\n            \n            const tl = gsap.timeline();\n            tl.to(scenarioCard, { rotationY: 90, opacity: 0, duration: 0.4, ease: \"power2.in\" })\n              .call(() => {\n                  cardImg.src = data.img;\n                  cardTitle.innerText = scenarioName;\n                  cardDesc.innerText = data.desc;\n              })\n              .fromTo(scenarioCard, \n                { rotationY: -90 }, \n                { rotationY: 0, opacity: 1, duration: 0.6, ease: \"back.out(1.7)\" }\n              );\n        }\n\n        scenarioButtons.forEach(btn => {\n            btn.addEventListener('click', () => {\n                if (btn === currentActiveBtn) return;\n                \n                scenarioButtons.forEach(b => {\n                    b.classList.remove('active-scenario', 'bg-primary\/10', 'border-primary', 'text-primary', 'shadow-[0_4px_15px_rgba(19,236,164,0.3)]');\n                    b.classList.add('border-primary\/20', 'bg-white\/80', 'text-background-dark\/70');\n                });\n                btn.classList.add('active-scenario', 'bg-primary\/10', 'border-primary', 'text-primary', 'shadow-[0_4px_15px_rgba(19,236,164,0.3)]');\n                \n                currentActiveBtn = btn;\n                updateCardContent(btn.innerText.trim());\n            });\n        });\n\n        if (currentActiveBtn) {\n            const data = scenarioData[currentActiveBtn.innerText.trim()];\n            if (data) {\n                cardImg.src = data.img;\n                cardTitle.innerText = currentActiveBtn.innerText.trim();\n                cardDesc.innerText = data.desc;\n            }\n        }\n\n        ScrollTrigger.create({\n            trigger: '#mod-scenarios',\n            start: \"top 60%\", \n            end: \"bottom top\", \n            onEnter: () => {\n                gsap.fromTo(scenarioCard, \n                    { z: -1000, rotationX: 45, rotationY: -30, opacity: 0, scale: 0.5 },\n                    { z: 0, rotationX: 0, rotationY: 0, opacity: 1, scale: 1, duration: 1.5, ease: \"expo.out\" }\n                );\n            },\n            onLeaveBack: () => {\n                gsap.to(scenarioCard, {\n                    z: -800, rotationX: 20, opacity: 0, scale: 0.7, duration: 0.8, ease: \"power2.in\"\n                });\n            },\n            onLeave: () => {\n                gsap.to(scenarioCard, {\n                    y: -200, z: 200, rotationX: -20, opacity: 0, duration: 0.8, ease: \"power2.in\"\n                });\n            },\n            onEnterBack: () => {\n                gsap.to(scenarioCard, {\n                    y: 0, z: 0, rotationX: 0, opacity: 1, scale: 1, duration: 1, ease: \"back.out(1.2)\"\n                });\n            }\n        });\n\n    <\/script>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Sistem Tenaga Pintar BERSEPADU BEBAS PINTAR. Generasi Seterusnya Penyelesaian Mikrogrid Memperkasa taman perindustrian dan komuniti sifar karbon dengan tenaga yang lancar, hijau dan autonomi. SENIBINA TERAS SISTEM MIKROGRID RANGKAIAN MIKROGRID PINTAR \uec0f NOD Penjana Kuasa: GEN_01 VOLTAN KELUAR 400V DC STATUS STABIL &gt;_ Menunggu arahan\u2026 \ue1a3 NOD Storan Tenaga: BATT_X KAPASITI 500 kWh MOD [\u2026]<\/p>","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-2023","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/pages\/2023","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/comments?post=2023"}],"version-history":[{"count":5,"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/pages\/2023\/revisions"}],"predecessor-version":[{"id":2116,"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/pages\/2023\/revisions\/2116"}],"wp:attachment":[{"href":"https:\/\/nenghui.com\/ms\/wp-json\/wp\/v2\/media?parent=2023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}