Compare commits

...

7 Commits

Author SHA1 Message Date
huyuanxiang 1ffc0e9be6 [add]添加本地JS文件
6 days ago
huyuanxiang 72632f097b [add]添加HTML模板文件
3 weeks ago
huyuanxiang 720866e042 [add]添加HTML模板文件
4 weeks ago
huyuanxiang 106bf38909 [fix]更新脚部菜单导航,并设置最低z-index
1 month ago
huyuanxiang d72526ebee [add]在PHP中添加拦截导航为/zh/zh_CN等中文站内容,添加新页面基础配置
1 month ago
huyuanxiang 6a461052f9 [add]添加从数据库获取产品列表信息
2 months ago
huyuanxiang 5519bdf676 [add]改版首页、添加加入我们、产品列表页面
2 months ago

1
.gitignore vendored

@ -5,6 +5,7 @@ bin-release/
[Bb]in/
wp-admin/
wp-includes/
html-temp/
wp-content/languages/
wp-content/mu-plugins/
wp-content/plugins/

@ -8,4 +8,18 @@ RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

@ -0,0 +1,935 @@
<!DOCTYPE html>
<html lang="en" class="scroll-smooth">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Microgrid | Smart Energy System</title>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#13eca4",
"primary-dark": "#0da670", // Added for contrast on light mode
"background-light": "#f8fcfa",
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
"accent": "#ff6b00"
},
fontFamily: {
"display": ["Montserrat", "sans-serif"],
"sans": ["Montserrat", "sans-serif"],
"mono": ["JetBrains Mono", "Montserrat"],
"inter": ["Inter", "Montserrat"],
},
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0.4) 100%)',
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.15) 0%, rgba(13,166,112,0.08) 50%, rgba(248,252,250,0) 100%)',
},
boxShadow: {
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(255,255,255,0.6)',
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.25), 0 0 0 1px rgba(19,236,164,0.5)',
'glass': '0 8px 32px 0 rgba(13, 166, 112, 0.1)',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
dash: {
'0%': { strokeDashoffset: '1000' },
'100%': { strokeDashoffset: '0' },
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out forwards',
'dash-flow': 'dash 3s linear infinite',
}
},
},
}
</script>
</head>
<body class="bg-liquid-gradient text-background-dark font-sans antialiased overflow-x-hidden selection:bg-primary selection:text-white min-h-screen">
<!-- Three.js Canvas Container -->
<div id="canvas-container" class="fixed inset-0 z-0 pointer-events-none opacity-80"></div>
<div class="fixed inset-0 bg-gradient-to-t from-background-light via-background-light/40 to-transparent z-0 pointer-events-none"></div>
<main class="relative z-10 mx-auto ">
<!-- === Hero Section === -->
<section id="mod-hero" class="min-h-screen flex flex-col justify-center text-center">
<span class="text-primary font-mono text-sm tracking-[0.3em] uppercase mb-6 " data-aos="fade-down">
Smart Energy System
</span>
<h1 class="text-4xl md:text-[2.66rem] leading-tight tracking-tighter text-background-dark mb-8 drop-shadow-sm" data-aos="zoom-in">
INTEGRATED INDEPENDENT
<span class="text-primary">INTELLIGENT.</span>
</h1>
<p class="text-[1rem] text-background-dark/70 font-medium max-w-4xl mx-auto leading-relaxed md:text-center" data-aos="fade-up">
The Next Generation of Microgrid Solutions Empowering industrial parks and zero-carbon communities with seamless, green, and autonomous energy.
</p>
</section>
<!-- === 系统拓扑图模块 === -->
<section id="mod-topology" class="min-h-screen flex flex-col justify-center items-center text-center py-24 relative z-10 overflow-hidden">
<!-- 明亮网格背景 -->
<div class="absolute inset-0 z-0 opacity-[0.4] pointer-events-none hex-bg"></div>
<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>
<style>
.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"); }
.cyber-clip { clip-path: polygon(0 15px, 15px 0, 100% 0, 100% calc(100% - 15px), calc(100% - 15px) 100%, 0 100%); }
.cyber-hub { clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%); }
.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; }
.tilt-card.reset { transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94), border-color 0.4s ease; }
.svg-circuit-line { fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.flow-packet { stroke-dasharray: 15, 150; animation: dashFlow 3s linear infinite; }
@keyframes dashFlow { 0% { stroke-dashoffset: 165; } 100% { stroke-dashoffset: 0; } }
.layer-stats { opacity: 1; transition: opacity 0.3s ease, transform 0.3s ease; transform: translateY(0); }
.layer-text { opacity: 0; pointer-events: none; transition: opacity 0.3s ease, transform 0.3s ease; transform: translateY(10px); }
.tilt-card:hover .layer-stats { opacity: 0; transform: translateY(-10px); pointer-events: none; }
.tilt-card:hover .layer-text { opacity: 1; pointer-events: auto; transform: translateY(0); }
</style>
<div class="relative z-30 mb-20" data-aos="fade-down">
<h2 class="text-4xl md:text-[2.66rem] mb-4 uppercase tracking-[0.2em] text-background-dark flex items-center justify-center gap-4">
CORE ARCHITECTURE OF MICROGRID SYSTEM
</h2>
<div class="flex items-center justify-center gap-4 text-primary font-mono text-xs tracking-[0.4em] ">
<span class="w-8 h-[2px] bg-gradient-to-r from-transparent to-primary-dark"></span>
INTELLIGENT MICROGRID NETWORK
<span class="w-8 h-[2px] bg-gradient-to-l from-transparent to-primary-dark"></span>
</div>
</div>
<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]">
<div class="hidden lg:block absolute inset-0 z-0 pointer-events-none">
<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">
<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" />
<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" />
<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" />
<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;" />
<path d="M 850 250 L 1020 250" class="svg-circuit-line stroke-primary/30" />
<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;" />
</svg>
</div>
<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">
<div class="flex flex-col gap-8 relative z-10">
<!-- Card 1 -->
<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">
<div class="flex items-start justify-between mb-6 relative z-10">
<div class="flex items-center gap-4">
<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">
<span class="material-symbols-outlined text-2xl">&#xec0f;</span>
</div>
<div>
<h3 class="text-xl text-background-dark tracking-wide">Power Gen</h3>
<div class="text-[10px] text-primary font-mono mt-1 ">NODE: GEN_01</div>
</div>
</div>
</div>
<div class="relative h-[80px] w-full">
<div class="layer-stats absolute inset-0 w-full grid grid-cols-2 gap-3 font-mono text-xs">
<div class="bg-primary/5 border border-primary/20 p-3 text-primary flex flex-col justify-center rounded-sm">
<span class="text-background-dark/50 text-[10px] mb-1 ">VOLTAGE OUT</span>
<span class="text-base ">400V DC</span>
</div>
<div class="bg-primary/5 border border-primary/20 p-3 text-primary flex flex-col justify-center rounded-sm">
<span class="text-background-dark/50 text-[10px] mb-1 ">STATUS</span>
<span class="text-base animate-pulse">STABLE</span>
</div>
</div>
<div class="layer-text absolute inset-0 w-full overflow-hidden">
<p class="decrypt-text text-[13px] text-background-dark/70 font-medium leading-relaxed" data-target="Harnessing renewable and conventional energy for consistent supply.">>_ Awaiting command...</p>
</div>
</div>
<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>
</div>
<!-- Card 2 -->
<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">
<div class="flex items-start justify-between mb-6 relative z-10">
<div class="flex items-center gap-4">
<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">
<span class="material-symbols-outlined text-2xl">&#xe1a3;</span>
</div>
<div>
<h3 class="text-xl text-background-dark tracking-wide">Energy Storage</h3>
<div class="text-[10px] text-accent font-mono mt-1 ">NODE: BATT_X</div>
</div>
</div>
</div>
<div class="relative h-[80px] w-full">
<div class="layer-stats absolute inset-0 w-full grid grid-cols-2 gap-3 font-mono text-xs">
<div class="bg-accent/5 border border-accent/20 p-3 text-accent flex flex-col justify-center rounded-sm">
<span class="text-background-dark/50 text-[10px] mb-1 ">CAPACITY</span>
<span class="text-base ">500 kWh</span>
</div>
<div class="bg-accent/5 border border-accent/20 p-3 text-accent flex flex-col justify-center rounded-sm">
<span class="text-background-dark/50 text-[10px] mb-1 ">MODE</span>
<span class="text-base animate-pulse">CHARGE</span>
</div>
</div>
<div class="layer-text absolute inset-0 w-full overflow-hidden">
<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.">>_ Interfacing...</p>
</div>
</div>
<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>
</div>
</div>
<!-- Central Hub -->
<div class="flex justify-center items-center relative z-20 mx-4 py-8 lg:py-0">
<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">
<div class="relative w-32 h-32 flex items-center justify-center mb-8">
<div class="absolute inset-0 rounded-full border border-dashed border-primary-dark/40 animate-[spin_10s_linear_infinite]"></div>
<div class="absolute inset-2 rounded-full border-t-4 border-primary/80 animate-[spin_3s_linear_infinite]"></div>
<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">
<span class="material-symbols-outlined text-primary text-4xl">&#xe322;</span>
</div>
</div>
<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 ">
<span class="w-2 h-2 bg-primary rounded-full animate-ping"></span> CONVERTER
</div>
<h3 class="text-2xl text-background-dark tracking-wide mb-2 z-10 group-hover:text-primary transition-colors">Power Conversion</h3>
<p class="text-[12px] text-background-dark/60 font-mono tracking-widest text-center mt-2 ">AC/DC ⇌ DC/AC<br>EFF: <span class="text-primary">99.1%</span></p>
</div>
</div>
<!-- Card 3 -->
<div class="flex flex-col justify-center relative z-10">
<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">
<div class="flex items-start justify-between mb-6 relative z-10">
<div class="flex items-center gap-4">
<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">
<span class="material-symbols-outlined text-2xl">&#xe7ee;</span>
</div>
<div>
<h3 class="text-xl text-background-dark tracking-wide">Demand Mgt</h3>
<div class="text-[10px] text-background-dark/50 font-mono mt-1 ">NODE: LOAD_END</div>
</div>
</div>
</div>
<div class="relative h-[80px] w-full">
<div class="layer-stats absolute inset-0 w-full grid grid-cols-2 gap-3 font-mono text-xs">
<div class="bg-gray-100 border border-gray-200 p-3 text-background-dark flex flex-col justify-center rounded-sm">
<span class="text-background-dark/50 text-[10px] mb-1 ">REAL POWER</span>
<span class="text-base ">120 kW</span>
</div>
<div class="bg-gray-100 border border-gray-200 p-3 text-background-dark flex flex-col justify-center rounded-sm">
<span class="text-background-dark/50 text-[10px] mb-1 ">POWER FACTOR</span>
<span class="text-base ">0.98</span>
</div>
</div>
<div class="layer-text absolute inset-0 w-full overflow-hidden">
<p class="decrypt-text text-[13px] text-background-dark/70 font-medium leading-relaxed" data-target="Distributing power smartly to meet diverse load requirements.">>_ Connecting...</p>
</div>
</div>
<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>
</div>
</div>
</div>
</div>
</section>
<!-- Features Sections (Glassmorphism & Bright Theme) -->
<section id="mod-security" class="min-h-screen flex items-center">
<div class="max-w-xl bg-white/80 backdrop-blur-xl p-10 border-l-4 border-accent rounded-r-3xl shadow-glass">
<span class="material-symbols-outlined text-5xl text-accent mb-6">&#xe32a;</span>
<h2 class="text-4xl mb-4 text-background-dark">Safe &<br>Reliable</h2>
<p class="text-lg text-background-dark/70 leading-relaxed font-medium">Sustains island operation without disconnection, backed by multi-power redundancy to guarantee zero downtime for critical loads.</p>
</div>
</section>
<section id="mod-efficiency" class="min-h-screen flex items-center justify-end text-right">
<div class="max-w-xl bg-white/80 backdrop-blur-xl p-10 border-r-4 border-primary rounded-l-3xl shadow-glass">
<span class="material-symbols-outlined text-5xl text-primary mb-6">&#xf0cf;</span>
<h2 class="text-4xl mb-4 text-background-dark">Smart &<br>Efficient</h2>
<p class="text-lg text-background-dark/70 leading-relaxed font-medium">Intelligent optimization and dispatch enable peak shaving and valley filling, effectively reducing electricity costs and energy consumption.</p>
</div>
</section>
<section id="mod-netzero" class="min-h-screen flex items-center">
<div class="max-w-xl bg-white/80 backdrop-blur-xl p-10 border-l-4 border-primary-dark rounded-r-3xl shadow-glass">
<span class="material-symbols-outlined text-5xl text-primary mb-6">&#xea35;</span>
<h2 class="text-4xl mb-4 text-background-dark">Green &<br>Low-Carbon</h2>
<p class="text-lg text-background-dark/70 leading-relaxed font-medium">Efficiently absorbs renewable energy and reduces carbon emissions, facilitating the realization of dual-carbon goals.</p>
</div>
</section>
<section id="mod-autonomous" class="min-h-screen flex items-center justify-end text-right">
<div class="max-w-xl bg-white/80 backdrop-blur-xl p-10 border-r-4 border-accent rounded-l-3xl shadow-glass">
<span class="material-symbols-outlined text-5xl text-accent mb-6">&#xe97a;</span>
<h2 class="text-4xl mb-4 text-background-dark">Autonomous &<br>Controllable</h2>
<p class="text-lg text-background-dark/70 leading-relaxed font-medium">Operates independently of the external grid, significantly enhancing energy autonomy and risk resilience.</p>
</div>
</section>
<!-- === Scenarios === -->
<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;">
<h2 class="text-4xl md:text-[2.66rem] mb-12 uppercase tracking-widest text-background-dark mt-10 relative z-30">Applicable Scenarios</h2>
<div class="flex flex-wrap justify-center gap-4 font-mono text-sm max-w-4xl relative z-30 " id="scenario-buttons">
<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">Industrial Parks</button>
<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">Data Centers</button>
<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">Commercial Complexes</button>
<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">Hospitals & Schools</button>
<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">Remote Regions</button>
<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">Islands</button>
<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">Zero-Carbon Communities</button>
<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">New Energy Stations</button>
</div>
<div id="card-wrapper" class="relative mt-12 w-full max-w-5xl h-[450px] z-20" style="transform-style: preserve-3d;">
<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;">
<div class="absolute inset-0 z-0 overflow-hidden">
<img id="card-img" src="" class="w-full h-full object-cover opacity-90" alt="Scenario Image" />
</div>
<!-- Light theme inner gradient -->
<div class="absolute inset-0 bg-gradient-to-t from-white via-white/80 to-transparent z-10"></div>
<div class="absolute bottom-12 left-12 z-20 text-left">
<h3 id="card-title" class="text-4xl font-display text-background-dark mb-4 tracking-tighter"></h3>
<p id="card-desc" class="text-lg text-background-dark/80 max-w-2xl leading-relaxed font-medium"></p>
</div>
</div>
</div>
</section>
<!-- === Contact === -->
<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)]">
<div class="max-w-7xl mx-auto px-6">
<div class="flex items-center gap-4 mb-12" data-aos="fade-right">
<div class="h-[2px] w-12 bg-primary-dark"></div>
<span class="text-primary font-mono text-xs uppercase tracking-[0.4em] ">Get in Touch</span>
</div>
<div class="flex flex-col lg:flex-row lg:items-end lg:justify-between gap-12">
<div data-aos="fade-up" data-aos-delay="100">
<h2 class="text-background-dark/50 text-sm font-mono uppercase tracking-widest mb-2 ">Microgrid Project Leader</h2>
<div class="flex items-baseline gap-6">
<span class="text-5xl tracking-tighter text-background-dark">Yan</span>
</div>
</div>
<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">
<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">
<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>
<div class="relative flex items-center gap-4">
<div class="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center text-primary">
<span class="material-symbols-outlined">&#xe158;</span>
</div>
<div>
<div class="text-background-dark/50 text-[10px] uppercase tracking-widest ">Send Email</div>
<div class="text-background-dark group-hover:text-primary transition-colors">sheyanxin@nenghui.com</div>
</div>
</div>
</a>
<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">
<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>
<div class="relative flex items-center gap-4">
<div class="w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center text-primary">
<span class="material-symbols-outlined">&#xe0b0;</span>
</div>
<div>
<div class="text-background-dark/50 text-[10px] uppercase tracking-widest ">Call Directly</div>
<div class="text-background-dark group-hover:text-primary transition-colors">+86 191 2059 3729</div>
</div>
</div>
</a>
</div>
</div>
</div>
</section>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<!-- JavaScript Logic & Animations -->
<script>
AOS.init({ once: true });
gsap.registerPlugin(ScrollTrigger);
// --- 卡片倾斜与打字机特效 (保持不变) ---
document.addEventListener("DOMContentLoaded", () => {
const cards = document.querySelectorAll('.tilt-card');
cards.forEach(card => {
card.addEventListener('mousemove', e => {
card.classList.remove('reset');
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateX = ((y - centerY) / centerY) * -4;
const rotateY = ((x - centerX) / centerX) * 4;
card.style.setProperty('--rx', `${rotateX}deg`);
card.style.setProperty('--ry', `${rotateY}deg`);
});
card.addEventListener('mouseleave', () => {
card.classList.add('reset');
card.style.setProperty('--rx', `0deg`);
card.style.setProperty('--ry', `0deg`);
const decryptEl = card.querySelector('.decrypt-text');
if(decryptEl) {
decryptEl.dataset.isAnimating = "false";
decryptEl.innerHTML = `>_ Awaiting command...`;
}
});
card.addEventListener('mouseenter', () => {
const decryptEl = card.querySelector('.decrypt-text');
if(!decryptEl || decryptEl.dataset.isAnimating === "true") return;
decryptEl.dataset.isAnimating = "true";
const targetText = decryptEl.getAttribute('data-target');
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%&*';
let iteration = 0;
function decryptFrame() {
if(decryptEl.dataset.isAnimating === "false") return;
decryptEl.innerHTML = targetText.split("").map((letter, index) => {
if(index < iteration) return letter;
return chars[Math.floor(Math.random() * chars.length)];
}).join("") + `<span class="animate-pulse text-primary ml-1">_</span>`;
if(iteration < targetText.length) {
iteration += 1;
setTimeout(() => requestAnimationFrame(decryptFrame), 15);
} else {
decryptEl.dataset.isAnimating = "false";
decryptEl.innerHTML = targetText + `<span class="animate-pulse text-primary ml-1">_</span>`;
}
}
requestAnimationFrame(decryptFrame);
});
});
});
// --- Three.js 亮色主题粒子引擎 ---
const scene = new THREE.Scene();
// 增加雾化效果,让远处的粒子融入背景
scene.fog = new THREE.FogExp2(0xf8fcfa, 0.0015);
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 500;
function updateCameraFOV() {
camera.fov = window.innerWidth < 768 ? 75 : 55;
camera.updateProjectionMatrix();
}
updateCameraFOV();
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('canvas-container').appendChild(renderer.domElement);
const particleCount = window.innerWidth < 768 ? 9000 : 12000;
const geometry = new THREE.BufferGeometry();
const currentPositions = new Float32Array(particleCount * 3);
const renderPositions = new Float32Array(particleCount * 3);
const startPos = new Float32Array(particleCount * 3);
const targetPos = new Float32Array(particleCount * 3);
const colors = new Float32Array(particleCount * 3);
// --- 核心改动:适合亮色背景的粒子颜色 ---
const colorPrimary = new THREE.Color('#09ab75'); // 深翠绿,保证在白底上清晰
const colorAccent = new THREE.Color('#64e8bc'); // 亮绿色用于点缀
const colorGray = new THREE.Color('#94a3b8'); // 蓝灰色替代原有的银白色
for (let i = 0; i < particleCount; i++) {
const mix = Math.random();
const color = colorPrimary.clone().lerp(colorAccent, mix * 0.5);
colors.set([color.r, color.g, color.b], i * 3);
}
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
// 形状生成器 (保持原有计算逻辑)
const shapesGen = {
text: () => {
const canvas = document.createElement('canvas');
canvas.width = 1200; canvas.height = 300;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#000'; ctx.fillRect(0, 0, 1200, 300);
ctx.font = 'bold 200px "Arial", sans-serif';
ctx.fillStyle = '#fff'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
ctx.fillText( window.innerWidth < 768 ? 'NH' :'NENGHUI', 600, 150);
const data = ctx.getImageData(0, 0, 1200, 300).data;
let points = [];
for (let y = 0; y < 300; y += 3) {
for (let x = 0; x < 1200; x += 3) {
if (data[(y * 1200 + x) * 4] > 128) {
points.push({ x: x - 600, y: -(y - 150), z: (Math.random() - 0.5) * 20 });
}
}
}
const arr = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
const p = points[i % points.length];
arr.set([p.x, p.y, p.z], i * 3);
}
return arr;
},
nestedPolyhedron: () => {
const arr = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
const r = i % 2 === 0 ? 100 : 50;
const theta = Math.random() * Math.PI * 2;
const phi = Math.acos(Math.random() * 2 - 1);
let x = r * Math.sin(phi) * Math.cos(theta);
let y = r * Math.sin(phi) * Math.sin(theta);
let z = r * Math.cos(phi);
if (Math.abs(x) > r * 0.7) x = Math.sign(x) * r * 0.7;
arr.set([x, y, z], i * 3);
}
return arr;
},
symbioticLeaf: () => {
const arr = new Float32Array(particleCount * 3);
const leafParticles = Math.floor(particleCount * 0.85);
const carbonParticles = particleCount - leafParticles;
for (let i = 0; i < leafParticles; i++) {
const t = Math.random();
const y = t * 400 - 150;
const widthFactor = Math.sin(t * Math.PI) * (1.2 - 0.2 * t);
const maxWidth = 160;
let x, z;
const isVein = Math.random() < 0.4;
if (isVein) {
if (Math.random() < 0.3) {
x = (Math.random() - 0.5) * 4;
z = (Math.random() - 0.5) * 4;
} else {
const side = Math.random() > 0.5 ? 1 : -1;
const veinT = Math.floor(t * 10) / 10;
x = side * (t - veinT) * 300 + (side * veinT * 20);
x = THREE.MathUtils.clamp(x, -maxWidth * widthFactor, maxWidth * widthFactor);
z = (Math.random() - 0.5) * 10;
}
} else {
const rawX = (Math.random() - 0.5) * 2 * maxWidth * widthFactor;
x = Math.round(rawX / 15) * 15;
z = (Math.random() - 0.5) * 20;
}
const bend = Math.sin(t * Math.PI) * 30;
arr.set([x + bend, y, z], i * 3);
}
for (let i = 0; i < carbonParticles; i++) {
const idx = (leafParticles + i) * 3;
arr.set([
(Math.random() - 0.5) * 300,
-250 - Math.random() * 150,
(Math.random() - 0.5) * 60
], idx);
}
return arr;
},
concentricSphere: () => {
const arr = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
const r = i % 3 === 0 ? 140 : (i % 3 === 1 ? 90 : 40);
const phi = Math.acos(-1 + Math.random() * 2);
const theta = Math.random() * Math.PI * 2;
arr.set([r * Math.sin(phi) * Math.cos(theta), r * Math.sin(phi) * Math.sin(theta), r * Math.cos(phi)], i * 3);
}
return arr;
},
barGraph: () => {
const arr = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
const gridX = Math.floor(Math.random() * 8) - 4;
const gridZ = Math.floor(Math.random() * 8) - 4;
const height = (Math.sin(gridX) + Math.cos(gridZ) + 2) * 40 + 20;
arr.set([gridX * 40 + (Math.random() - 0.5) * 20, Math.random() * height - 100, gridZ * 40 + (Math.random() - 0.5) * 20], i * 3);
}
return arr;
},
shield: () => {
const arr = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
let x = (Math.random() - 0.5) * 200;
let y, z;
let topEdge = 100 + 15 * Math.cos(x * Math.PI / 100);
let bottomEdge = -120 + 220 * Math.pow(Math.abs(x) / 100, 2);
let t = Math.random();
if (Math.random() > 0.6) {
t = Math.random() > 0.5 ? Math.random() * 0.1 : 0.9 + Math.random() * 0.1;
}
y = bottomEdge + t * (topEdge - bottomEdge);
let maxZ = 30 * (1 - Math.pow(Math.abs(x) / 100, 2));
if (Math.abs(x) < 8 || Math.abs(y - 10) < 8) maxZ += 10;
z = (Math.random() - 0.5) * maxZ;
arr.set([x, y, z], i * 3);
}
return arr;
},
torusKnot: () => {
const arr = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
const t = Math.random() * Math.PI * 2;
const p = 2; const q = 3;
const r = 50 * (2 + Math.cos(q * t));
const x = r * Math.cos(p * t);
const y = r * Math.sin(p * t);
const z = 50 * Math.sin(q * t);
const noise = 15;
arr.set([x + (Math.random() - 0.5) * noise, y + (Math.random() - 0.5) * noise, z + (Math.random() - 0.5) * noise], i * 3);
}
return arr;
},
networkNode: () => {
const arr = new Float32Array(particleCount * 3);
const nodes = [
{x: 0, y: 0, z: 0, r: 35},
{x: 120, y: 70, z: 40, r: 15},
{x: -110, y: -80, z: 20, r: 20},
{x: 90, y: -100, z: -40, r: 15},
{x: -100, y: 90, z: -30, r: 18},
{x: 0, y: 130, z: 10, r: 12},
{x: 0, y: -130, z: 0, r: 12}
];
for (let i = 0; i < particleCount; i++) {
const pType = Math.random();
if (pType < 0.5) {
const node = nodes[Math.floor(Math.random() * nodes.length)];
const theta = Math.random() * Math.PI * 2;
const phi = Math.acos((Math.random() * 2) - 1);
const r = node.r * (0.5 + 0.5 * Math.random());
arr.set([
node.x + r * Math.sin(phi) * Math.cos(theta),
node.y + r * Math.sin(phi) * Math.sin(theta),
node.z + r * Math.cos(phi)
], i * 3);
} else {
const targetNode = nodes[1 + Math.floor(Math.random() * (nodes.length - 1))];
const t = Math.random();
const noise = 3;
arr.set([
t * targetNode.x + (Math.random() - 0.5) * noise,
t * targetNode.y + (Math.random() - 0.5) * noise,
t * targetNode.z + (Math.random() - 0.5) * noise
], i * 3);
}
}
return arr;
}
};
const precalculatedShapes = {
text: shapesGen.text(),
nestedPolyhedron: shapesGen.nestedPolyhedron(),
symbioticLeaf: shapesGen.symbioticLeaf(),
concentricSphere: shapesGen.concentricSphere(),
barGraph: shapesGen.barGraph(),
shield: shapesGen.shield(),
torusKnot: shapesGen.torusKnot(),
networkNode: shapesGen.networkNode()
};
currentPositions.set(precalculatedShapes.text);
renderPositions.set(precalculatedShapes.text);
geometry.setAttribute('position', new THREE.BufferAttribute(renderPositions, 3));
// --- 核心改动:必须使用 NormalBlending 才能在白底上显示颜色 ---
const material = new THREE.PointsMaterial({
size: window.innerWidth < 768 ? 3.5 : 4.0,
vertexColors: true,
transparent: true,
opacity: 0.8,
blending: THREE.NormalBlending, // AdditiveBlending 会在白底上完全消失!
sizeAttenuation: true,
depthWrite: false
});
const particles = new THREE.Points(geometry, material);
scene.add(particles);
let time = 0;
let morphData = { progress: 0 };
let currentShapeKey = 'text';
let morphTween = null;
const rotationSpeed = { x: 0, y: 0 };
const waveConfig = { amplitude: 20 };
function morphTo(shapeKey) {
if (currentShapeKey === shapeKey) return;
currentShapeKey = shapeKey;
if (morphTween) morphTween.kill();
const colorAttribute = geometry.attributes.color;
const targetColors = new Float32Array(particleCount * 3);
const leafParticles = Math.floor(particleCount * 0.85);
for (let i = 0; i < particleCount; i++) {
let color;
if (shapeKey === 'symbioticLeaf') {
if (i < leafParticles) {
color = colorPrimary.clone().lerp(colorAccent, Math.random() * 0.2);
} else {
color = colorGray.clone();
}
} else {
color = colorPrimary.clone().lerp(colorAccent, Math.random() * 0.4);
}
targetColors.set([color.r, color.g, color.b], i * 3);
}
gsap.to(colorAttribute.array, {
endArray: targetColors,
duration: 1.5,
ease: "power2.inOut",
onUpdate: () => colorAttribute.needsUpdate = true
});
for (let i = 0; i < currentPositions.length; i++) {
startPos[i] = currentPositions[i];
}
targetPos.set(precalculatedShapes[shapeKey]);
morphData.progress = 0;
morphTween = gsap.to(morphData, {
progress: 1,
duration: 2.0,
ease: "power3.inOut",
onUpdate: () => {
for (let i = 0; i < particleCount * 3; i++) {
currentPositions[i] = startPos[i] + (targetPos[i] - startPos[i]) * morphData.progress;
}
}
});
if (shapeKey === 'text') {
gsap.to(rotationSpeed, { x: 0, y: 0, duration: 1.5 });
const targetX = Math.round(particles.rotation.x / (Math.PI * 2)) * (Math.PI * 2);
const targetY = Math.round(particles.rotation.y / (Math.PI * 2)) * (Math.PI * 2);
gsap.to(particles.rotation, { x: targetX, y: targetY, duration: 2.0 });
} else if (shapeKey === 'shield') {
gsap.to(rotationSpeed, { x: 0, y: 0.002, duration: 1.5 });
const targetX = Math.round(particles.rotation.x / (Math.PI * 2)) * (Math.PI * 2);
gsap.to(particles.rotation, { x: targetX, duration: 2.0 });
} else if (shapeKey === 'symbioticLeaf') {
gsap.to(rotationSpeed, { x: 0.0005, y: 0.001, duration: 1.5 });
} else if (shapeKey === 'barGraph') {
gsap.to(rotationSpeed, { x: 0, y: 0.002, duration: 1.5 });
const targetX = Math.round(particles.rotation.x / (Math.PI * 2)) * (Math.PI * 2);
gsap.to(particles.rotation, { x: targetX + 0.4, duration: 2.0 });
} else {
gsap.to(rotationSpeed, { x: 0.001, y: 0.002, duration: 2.0 });
}
gsap.to(waveConfig, {
duration: 2.0,
amplitude: (shapeKey === 'text') ? 20 : 0
});
}
function animate() {
requestAnimationFrame(animate);
time += 0.02;
const positions = geometry.attributes.position.array;
const colorsArray = geometry.attributes.color.array;
const leafParticles = Math.floor(particleCount * 0.85);
for (let i = 0; i < particleCount; i++) {
let idx = i * 3;
let baseX = currentPositions[idx];
let baseY = currentPositions[idx + 1];
let baseZ = currentPositions[idx + 2];
if (currentShapeKey === 'symbioticLeaf' ) {
if (i < leafParticles) {
if (i % 7 === 0 ) {
if (Math.abs(baseX) < 100) {
const angle = time * 3 + (baseY * 0.02);
const r = 10 * Math.sin(time * 0.5);
positions[idx] = baseX + r * Math.cos(angle);
positions[idx + 1] = baseY;
positions[idx + 2] = baseZ + r * Math.sin(angle);
}
} else {
positions[idx] = baseX + Math.sin(time + baseY * 0.1) * 2;
positions[idx + 1] = baseY;
positions[idx + 2] = baseZ;
}
}
} else if (waveConfig.amplitude > 0.01) {
const phase = baseX * 0.006 + time;
const waveY = Math.sin(phase) * (waveConfig.amplitude * 0.4);
const waveZ = Math.cos(phase * 0.8) * waveConfig.amplitude;
positions[idx] = baseX;
positions[idx + 1] = baseY + waveY;
positions[idx + 2] = baseZ + waveZ;
} else {
positions[idx] = baseX;
positions[idx + 1] = baseY;
positions[idx + 2] = baseZ;
}
if (currentShapeKey === 'symbioticLeaf') {
if (i >= leafParticles) {
let y = baseY + (time * 50) % 200;
let opacity = 1.0;
if (y > -150) {
opacity = THREE.MathUtils.lerp(1.0, 0.0, (y + 150) / 100);
}
if (y > -50) opacity = 0;
positions[idx + 1] = y;
colorsArray[idx] = colorGray.r * opacity;
colorsArray[idx + 1] = colorGray.g * opacity;
colorsArray[idx + 2] = colorGray.b * opacity;
}
}
}
geometry.attributes.position.needsUpdate = true;
if (currentShapeKey === 'symbioticLeaf') {
geometry.attributes.color.needsUpdate = true;
}
particles.rotation.x += rotationSpeed.x;
particles.rotation.y += rotationSpeed.y;
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
updateCameraFOV();
});
const shapeList = ['text', 'shield', 'concentricSphere', 'symbioticLeaf', 'torusKnot', 'networkNode', 'barGraph', 'nestedPolyhedron'];
const sections = ['#mod-hero', '#mod-security', '#mod-efficiency', '#mod-netzero', '#mod-autonomous', '#mod-topology', '#mod-scenarios', '#mod-contact'];
sections.forEach((id, idx) => {
ScrollTrigger.create({
trigger: id,
start: "top 55%",
end: "bottom 45%",
onEnter: () => morphTo(shapeList[idx]),
onEnterBack: () => morphTo(shapeList[idx])
});
});
</script>
<script>
// --- 场景卡片 3D 动画 ---
const scenarioData = {
"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." },
"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." },
"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." },
"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." },
"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." },
"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." },
"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." },
"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." }
};
const scenarioButtons = document.querySelectorAll('.scenario-btn');
const scenarioCard = document.getElementById('scenario-card');
const cardImg = document.getElementById('card-img');
const cardTitle = document.getElementById('card-title');
const cardDesc = document.getElementById('card-desc');
let currentActiveBtn = document.querySelector('.active-scenario');
function updateCardContent(scenarioName) {
if(!scenarioData[scenarioName]) return;
const data = scenarioData[scenarioName];
const tl = gsap.timeline();
tl.to(scenarioCard, { rotationY: 90, opacity: 0, duration: 0.4, ease: "power2.in" })
.call(() => {
cardImg.src = data.img;
cardTitle.innerText = scenarioName;
cardDesc.innerText = data.desc;
})
.fromTo(scenarioCard,
{ rotationY: -90 },
{ rotationY: 0, opacity: 1, duration: 0.6, ease: "back.out(1.7)" }
);
}
scenarioButtons.forEach(btn => {
btn.addEventListener('click', () => {
if (btn === currentActiveBtn) return;
scenarioButtons.forEach(b => {
b.classList.remove('active-scenario', 'bg-primary/10', 'border-primary', 'text-primary', 'shadow-[0_4px_15px_rgba(19,236,164,0.3)]');
b.classList.add('border-primary/20', 'bg-white/80', 'text-background-dark/70');
});
btn.classList.add('active-scenario', 'bg-primary/10', 'border-primary', 'text-primary', 'shadow-[0_4px_15px_rgba(19,236,164,0.3)]');
currentActiveBtn = btn;
updateCardContent(btn.innerText.trim());
});
});
if (currentActiveBtn) {
const data = scenarioData[currentActiveBtn.innerText.trim()];
if (data) {
cardImg.src = data.img;
cardTitle.innerText = currentActiveBtn.innerText.trim();
cardDesc.innerText = data.desc;
}
}
ScrollTrigger.create({
trigger: '#mod-scenarios',
start: "top 60%",
end: "bottom top",
onEnter: () => {
gsap.fromTo(scenarioCard,
{ z: -1000, rotationX: 45, rotationY: -30, opacity: 0, scale: 0.5 },
{ z: 0, rotationX: 0, rotationY: 0, opacity: 1, scale: 1, duration: 1.5, ease: "expo.out" }
);
},
onLeaveBack: () => {
gsap.to(scenarioCard, {
z: -800, rotationX: 20, opacity: 0, scale: 0.7, duration: 0.8, ease: "power2.in"
});
},
onLeave: () => {
gsap.to(scenarioCard, {
y: -200, z: 200, rotationX: -20, opacity: 0, duration: 0.8, ease: "power2.in"
});
},
onEnterBack: () => {
gsap.to(scenarioCard, {
y: 0, z: 0, rotationX: 0, opacity: 1, scale: 1, duration: 1, ease: "back.out(1.2)"
});
}
});
</script>
</body>
</html>

@ -0,0 +1,554 @@
<!DOCTYPE html>
<html lang="zh-CN" >
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Global Tech Company | Tailwind Edition</title>
<!-- 项目原有: Google Fonts & Material Icons -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<!-- AOS Animation Library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<!-- Tailwind & Config -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#13eca4",
"background-light": "#f8fcfa",
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
"about-us": "#ff6b00"
},
fontFamily: {
"display": ["Montserrat", "sans-serif"],
"sans": ["Montserrat", "sans-serif"],
"mono": ["JetBrains Mono", "Montserrat"],
"inter": ["Inter", "Montserrat"],
},
borderRadius: {
"DEFAULT": "0.5rem",
"lg": "1rem",
"xl": "1.5rem",
"2xl": "2rem",
"3xl": "3rem",
"full": "9999px"
},
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.1) 0%, rgba(13,166,112,0.05) 50%, rgba(248,252,250,0) 100%)',
'mesh': 'radial-gradient(at 40% 20%, rgba(19,236,164,0.08) 0px, transparent 50%), radial-gradient(at 80% 0%, rgba(16,34,28,0.05) 0px, transparent 50%), radial-gradient(at 0% 50%, rgba(19,236,164,0.05) 0px, transparent 50%)',
},
boxShadow: {
// 将光效统一映射为 primary 颜色 (13eca4 的 RGBA)
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
'glow-lg': '0 10px 30px rgba(19, 236, 164, 0.4)',
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02)',
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.15), 0 0 0 1px rgba(19,236,164,0.3)',
'bento-dark': '0 30px 60px -15px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
scan: {
'0%': { top: '-10%', opacity: '0' },
'10%': { opacity: '1' },
'90%': { opacity: '1' },
'100%': { top: '110%', opacity: '0' },
},
rotateGlobe: {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
dash: {
'0%': { strokeDashoffset: '1000' },
'100%': { strokeDashoffset: '0' },
},
globePulse: {
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
},
// 高级交互动画
pulseGlow: {
'0%': { textShadow: '0 0 10px rgba(19, 236, 164, 0.4)' },
'100%': { textShadow: '0 0 30px #ff6b00' }
},
sweep: { '100%': { left: '200%' } },
cardFlip: {
'0%': { opacity: '0', transform: 'rotateY(-90deg) translateZ(50px)' },
'100%': { opacity: '1', transform: 'rotateY(0deg) translateZ(0)' }
},
floatY: {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-15px)' }
},
textShimmer: {
'0%': { backgroundPosition: '0% 50%' },
'100%': { backgroundPosition: '100% 50%' },
},
blobSpin: {
'0%': { transform: 'rotate(0deg) scale(1)' },
'50%': { transform: 'rotate(180deg) scale(1.1)' },
'100%': { transform: 'rotate(360deg) scale(1)' },
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out forwards',
'scan-slow': 'scan 6s linear infinite',
'spin-slow': 'rotateGlobe 60s linear infinite',
'dash-flow': 'dash 3s linear infinite',
'globe-select': 'globePulse 0.8s ease-out',
'pulse-glow': 'pulseGlow 2s infinite alternate',
'sweep': 'sweep 3s infinite',
'flip-in': 'cardFlip 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards',
'float-1': 'floatY 3s ease-in-out infinite',
'float-2': 'floatY 3s ease-in-out infinite 1s',
'float-3': 'floatY 3s ease-in-out infinite 2s',
'text-shimmer': 'textShimmer 3s ease-out infinite alternate',
'blob-spin': 'blobSpin 20s infinite cubic-bezier(0.4, 0, 0.2, 1)',
}
},
},
}
</script>
<!-- Tailwind 基础样式注入 -->
<style type="text/tailwindcss">
@layer utilities {
/* 滚动揭示动效 */
/* 新增:专门为副标题定制的 3D 荧光挤压动画 */
.text-3d-subtitle {
color: #ff6b00; /* 保持主题色 */
animation: pulse3d 2s infinite alternate;
}
@keyframes pulse3d {
0% {
text-shadow:
/* 左上高光 */
-1px -1px 0px rgba(255, 255, 255, 0.5),
/* 右下厚度 (深翠绿色系) */
1px 1px 0px #ce6c33,
2px 2px 0px #b44914,
3px 3px 0px #75600a,
/* 基础投影 */
4px 4px 10px rgba(0, 0, 0, 0.6),
/* 较弱的呼吸背光 */
0px 0px 10px rgba(224, 114, 12, 0.3);
}
100% {
text-shadow:
-1px -1px 0px rgba(255, 255, 255, 0.7),
1px 1px 0px #cc7e19,
2px 2px 0px #e2d921,
3px 3px 0px #692a05,
5px 5px 15px rgba(0, 0, 0, 0.8),
/* 较强的呼吸背光,模拟能量溢出 */
0px 0px 30px #f2e930,
0px 0px 50px rgba(195, 159, 16, 0.6);
}
}
.text-3d {
text-shadow:
0 1px 0 #e2e8f0, /* 亮银色顶边 */
0 2px 0 #cbd5e1,
0 3px 0 #94a3b8,
0 4px 0 #64748b, /* 逐渐变暗模拟背光面 */
0 5px 0 #475569,
0 6px 0 #334155,
0 8px 10px rgba(0, 0, 0, 0.4), /* 近处接触阴影 */
0 15px 20px rgba(0, 0, 0, 0.3), /* 中距离扩散阴影 */
0 25px 40px rgba(0, 0, 0, 0.8); /* 远距离环境阴影 */
}
.text-3d-ultra {
color: #ffffff;
/* 1. 顶部左侧的亮色高光切割边 */
text-shadow:
-1px -1px 1px rgba(255, 255, 255, 0.3),
/* 2. 右下角 45度 斜向挤压厚度 (融入您的深墨绿环境色) */
1px 1px 0px #0d1e18,
2px 2px 0px #0a1813,
3px 3px 0px #08130e,
4px 4px 0px #060e0a,
5px 5px 0px #040906,
6px 6px 0px #020403,
7px 7px 0px #000000,
/* 3. 接触面的死黑投影 */
8px 8px 15px rgba(0, 0, 0, 0.8),
/* 4. 远距离大范围柔和投影 */
15px 15px 30px rgba(0, 0, 0, 0.6),
/* 5. 核心点睛之笔:在阴影反方向及底部映射出 #13eca4 (Primary) 的环境光晕 */
-5px -5px 30px rgba(19, 236, 164, 0.1),
10px 10px 40px rgba(19, 236, 164, 0.25);
}
/* Tab 状态管控:选中时变为 primary 背景与深色字体 */
#tech-landing-wrapper .tab-content { @apply hidden; }
#tech-landing-wrapper .tab-content.active { @apply grid; }
}
</style>
</head>
<body id="tech-landing-wrapper" class="bg-background-dark text-background-light font-sans w-full leading-relaxed relative">
<!-- 进度条 -->
<!-- <div id="progress-bar" class="fixed top-0 left-0 w-0 h-1 bg-theme-primary z-50 shadow-glow transition-all duration-100"></div> -->
<!-- 模块一:品牌愿景与全球定位 -->
<section data-aos="fade-down" class="h-screen relative flex items-center justify-center text-center overflow-hidden " id="hero-sec">
<!-- 沉浸式背景 (添加3D视差联动) -->
<div id="m1-bg" class="absolute -top-[5%] -left-[5%] w-[110%] h-[110%] -z-10 bg-[url('https://nenghui.com/wp-content/uploads/2026/02/about-us-banner.jpg')] bg-cover bg-center brightness-70 transition-transform duration-100 ease-out"></div>
<!-- 前景文字层 -->
<div id="m1-content" style="transform-style: preserve-3d;" class="relative z-10 pointer-events-none transition-transform duration-100 ease-out reveal">
<h1 data-aos="fade-down" style="transform: translateZ(80px);" class="text-3d-ultra text-4xl md:text-[2.66rem] tracking-widest uppercase text-white drop-shadow-[0_10px_40px_rgba(0,0,0,0.8)] leading-tight mb-4">
From China to the World
</h1>
<!-- 光效能量条,也向前推一点点形成错层 -->
<div class="w-32 h-1 bg-primary mx-auto mb-6 shadow-[0_0_20px_#13eca4] rounded-full" style="transform: translateZ(40px);"></div>
<p data-aos="fade-up" data-aos-delay="150" style="transform: translateZ(20px);" class="text-3d-subtitle text-sm text-about-us mt-4 tracking-[5px]">Empowering a Sustainable Future.</p>
</div>
</section>
<!-- 模块二:创新驱动与技术内核 -->
<section class="max-w-7xl mx-auto px-8 py-24 grid grid-cols-1 md:grid-cols-2 gap-16 items-center">
<div class="reveal" data-aos="fade-right">
<h2 class=" text-4xl md:text-[2.66rem] text-about-us mb-6">Innovation & Engineering Excellence</h2>
<p class="text-[1rem] mb-4">We firmly believe that technology is the sole driving force behind industry transformation. By continuously pushing the boundaries of physics and engineering, we provide cutting-edge solutions to customers worldwide.</p>
<div class="flex flex-col sm:flex-row gap-8 my-8">
<div class="flex-1 bg-black/20 p-6 border-l-4 border-about-us rounded-r-lg shadow-lg relative overflow-hidden group">
<div class="absolute top-0 -left-full w-1/2 h-full bg-gradient-to-r from-transparent via-white/5 to-transparent -skew-x-12 animate-sweep"></div>
<h3 class="font-mono text-4xl mb-2 text-white">100+</h3>
<p class="text-sm tracking-wider uppercase text-about-us/80">Specialized R&D Engineers</p>
</div>
<div class="flex-1 bg-black/20 p-6 border-l-4 border-about-us rounded-r-lg shadow-lg relative overflow-hidden group">
<div class="absolute top-0 -left-full w-1/2 h-full bg-gradient-to-r from-transparent via-white/5 to-transparent -skew-x-12 animate-sweep"></div>
<h3 class="font-mono text-4xl mb-2 text-white">10%+</h3>
<p class="text-sm tracking-wider uppercase text-about-us/80">Annual R&D investment ratio</p>
</div>
</div>
<p class="text-theme-mut text-[1rem]">The core self-developed algorithms and sophisticated hardware architecture undergo ultra-high standard laboratory testing to ensure that every product meets industrial-grade stability standards.</p>
</div>
<!-- 图片网格 (启用 3D Tilt) -->
<div class="grid grid-cols-2 gap-4 perspective-[1000px] reveal delay-1" data-aos="fade-left" data-aos-delay="200">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-pc3.jpg" alt="Circuit Board" class="w-full aspect-square object-cover rounded-xl shadow-2xl translate-z-[20px]" data-tilt data-tilt-max="15" data-tilt-speed="400" data-tilt-glare data-tilt-max-glare="0.4">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-pc2.jpg" alt="Lab Test" class="w-full aspect-square object-cover rounded-xl shadow-2xl translate-z-[20px] mt-8" data-tilt data-tilt-max="15" data-tilt-speed="400" data-tilt-glare data-tilt-max-glare="0.4">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-pc1.jpg" alt="Lab Test" class="w-full aspect-square object-cover rounded-xl shadow-2xl translate-z-[20px] mt-8" data-tilt data-tilt-max="15" data-tilt-speed="400" data-tilt-glare data-tilt-max-glare="0.4">
<img src=" https://nenghui.com/wp-content/uploads/2026/02/about-us-pc4.jpg" alt="Lab Test" class="w-full aspect-square object-cover rounded-xl shadow-2xl translate-z-[20px] mt-8" data-tilt data-tilt-max="15" data-tilt-speed="400" data-tilt-glare data-tilt-max-glare="0.4">
</div>
</section>
<!-- 模块三:精益制造与供应链优势 -->
<section class="py-32 px-8 text-center text-white bg-[url('https://nenghui.com/wp-content/uploads/2026/02/about-us-pc5.jpg')] bg-fixed bg-cover bg-center relative z-0">
<!-- 黑色渐变遮罩 -->
<div class="absolute inset-0 bg-black/40 -z-10"></div>
<h2 data-aos="fade-up" class="text-4xl md:text-[2.66rem] mb-4 relative z-10 reveal">Precision Manufacturing & Supply Chain</h2>
<p data-aos="fade-up" data-aos-delay="150" class="text-[1rem] text-gray-300 relative z-10 reveal delay-1 mb-16">Fully automated robotic arms and Class 100 cleanrooms form an insurmountable competitive advantage.</p>
<!-- 1行3列数据网格 -->
<div class="max-w-6xl mx-auto grid grid-cols-1 md:grid-cols-3 gap-12 relative z-10 reveal delay-2" data-aos="fade-up" data-aos-delay="300">
<!-- 维度1原有的 GW 产能 -->
<div class="flex flex-col items-center justify-center group">
<div class="flex items-baseline gap-2 mb-2">
<div class="counter text-6xl md:text-[8rem] text-about-us leading-none drop-shadow-[0_0_20px_rgba(246,155,0,0.4)]" data-target="17" data-decimals="0" >0</div>
<span class="text-3xl md:text-5xl text-theme-primary drop-shadow-[0_0_20px_var(--glow)] text-about-us">+Years</span>
</div>
<span class="text-sm uppercase tracking-widest text-gray-300 group-hover:text-white transition-colors">Dedicated R&D in Solar & ESS </span>
</div>
<!-- 维度2新增机械臂数量 -->
<div class="flex flex-col items-center justify-center group">
<div class="flex items-baseline gap-2 mb-2">
<div class="counter text-6xl md:text-[8rem] text-about-us leading-none drop-shadow-[0_0_20px_rgba(246,155,0,0.4)]" data-target="10" data-decimals="0">0</div>
<span class="text-3xl md:text-5xl text-theme-primary drop-shadow-[0_0_20px_var(--glow)] text-about-us">GWp+</span>
</div>
<span class="text-sm uppercase tracking-widest text-gray-300 group-hover:text-white transition-colors">Global PV Project Track Record </span>
</div>
<!-- 维度3新增良品率 (带小数位支持) -->
<div class="flex flex-col items-center justify-center group">
<div class="flex items-baseline gap-2 mb-2">
<div class="counter text-6xl md:text-[8rem] text-about-us leading-none drop-shadow-[0_0_20px_rgb(246,155,0,0.4)]" data-target="1.2" data-decimals="1">0</div>
<span class="text-3xl md:text-5xl text-theme-primary drop-shadow-[0_0_20px_var(--glow)] text-about-us">GWp+</span>
</div>
<span class="text-sm uppercase tracking-widest text-gray-300 group-hover:text-white transition-colors">Self-owned & Managed Assets</span>
</div>
</div>
</section>
<!-- 模块四:全球化服务与本土化枢纽 -->
<section class="bg-theme-sec py-24">
<div class="max-w-7xl mx-auto px-8 reveal">
<h2 class="text-4xl md:text-[2.66rem] text-center mb-12 text-white" data-aos="fade-up">Global Hubs & Localized Support</h2>
<div class="flex justify-center gap-4 mb-12 flex-wrap sticky top-[100px] z-10" data-aos="fade-up" data-aos-delay="150">
<button class="backdrop-blur-md p-1.5 rounded-full tab-btn active px-8 py-3 rounded-full border-2 border-[#ff6b00] bg-[#ff6b00] text-white transition-all duration-300 shadow-[0_0_20px_rgba(255,107,0,0.4)] " onclick="switchTab('eu', this)">Europe Hub</button>
<button class="backdrop-blur-md p-1.5 rounded-full tab-btn px-8 py-3 rounded-full border-2 border-theme-mut text-theme-text text-lg transition-all duration-300 hover:-translate-y-1 hover:shadow-glow" onclick="switchTab('asia', this)">Nenghui Middle East</button>
<button class="backdrop-blur-md p-1.5 rounded-full tab-btn px-8 py-3 rounded-full border-2 border-theme-mut text-theme-text text-lg transition-all duration-300 hover:-translate-y-1 hover:shadow-glow" onclick="switchTab('na', this)">Nenghui Thailand</button>
<button class="backdrop-blur-md p-1.5 rounded-full tab-btn px-8 py-3 rounded-full border-2 border-theme-mut text-theme-text text-lg transition-all duration-300 hover:-translate-y-1 hover:shadow-glow" onclick="switchTab('va', this)">Nenghui Cambodia</button>
</div>
<!-- Tab 容器 (使用 Tailwind 群组动画控制) -->
<!-- 欧洲内容 -->
<div id="eu" class="tab-content active grid-cols-1 md:grid-cols-3 gap-8 perspective-[1200px]">
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:0ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub1-1.jpg" alt="Office" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Netherlands Hub </p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:100ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub1-2.jpg" alt="Warehouse" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Belgium Smart Logistics </p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:200ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub1-3.jpg" alt="Team" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg"> Localized Expert Support </p>
</div>
</div>
<!-- 东南亚内容 -->
<div id="asia" class="tab-content grid-cols-1 md:grid-cols-3 gap-8 perspective-[1200px]">
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:0ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub2-1.jpg" alt="Office" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Iraq Hub</p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:100ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub2-2.jpg" alt="Warehouse" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Iraq Smart Logistics Hub</p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:200ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub2-3.jpg" alt="Team" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Localized Technical Support</p>
</div>
</div>
<!-- 北美内容 -->
<div id="na" class="tab-content grid-cols-1 md:grid-cols-3 gap-8 perspective-[1200px]">
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:0ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub3-1.jpg" alt="Office" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Thailand Strategic Hub</p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:100ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub3-2.jpg" alt="Warehouse" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Thailand Strategic Hub</p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:200ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub3-3.jpg" alt="Team" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Expert On-site Support</p>
</div>
</div>
<!-- ddd -->
<div id="va" class="tab-content grid-cols-1 md:grid-cols-3 gap-8 perspective-[1200px]">
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:0ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub4-1.jpg" alt="Office" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Cambodia Branch</p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:100ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub4-2.jpg" alt="Warehouse" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Smart Warehousing & Distribution</p>
</div>
<div class="bg-theme-bg rounded-2xl overflow-hidden shadow-lg animate-flip-in [animation-delay:200ms] hover:-translate-y-3 hover:shadow-2xl transition-all duration-500 group">
<img src="https://nenghui.com/wp-content/uploads/2026/02/about-us-hub4-3.jpg" alt="Team" class="h-64 w-full object-cover group-hover:scale-110 transition-transform duration-500">
<p class="p-6 text-center text-xl m-0 relative z-10 bg-theme-bg">Local Technical Support Team</p>
</div>
</div>
</div>
</section>
<!-- 模块五:可持续发展与企业公民 -->
<section class="bg-[#f0fdf4] py-32 text-center transition-colors duration-1000 text-[#064e3b]">
<div class="max-w-4xl mx-auto px-8">
<h2 class="text-4xl md:text-[2.66rem] mb-6 reveal" data-aos="fade-up">Sustainability & Corporate Responsibility</h2>
<p class="text-[1rem] opacity-80 mb-16 reveal delay-1" data-aos="fade-up" data-aos-delay="150">We are committed to achieving carbon neutrality by 2030. Being green is not an option, but a responsibility ingrained in our DNA: to live in harmony with nature and create a sustainable future.</p>
<div class="flex justify-center gap-12 md:gap-24 mb-16 flex-wrap reveal delay-2" data-aos="fade-up" data-aos-delay="300">
<!-- 图标使用 Primary 色 -->
<div class="flex flex-col items-center gap-4 animate-float-1 group cursor-pointer">
<svg viewBox="0 0 24 24" class="w-16 h-16 stroke-primary fill-none stroke-[1.5] group-hover:scale-110 group-hover:rotate-6 transition-transform duration-300 drop-shadow-md"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" /></svg>
<span class="text-lg ">100% Clean Energy</span>
</div>
<div class="flex flex-col items-center gap-4 animate-float-2 group cursor-pointer">
<svg viewBox="0 0 24 24" class="w-16 h-16 stroke-primary fill-none stroke-[1.5] group-hover:scale-110 group-hover:-rotate-6 transition-transform duration-300 drop-shadow-md"><path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418" /></svg>
<span class="text-lg ">ISO 14001 certification</span>
</div>
<div class="flex flex-col items-center gap-4 animate-float-3 group cursor-pointer">
<svg viewBox="0 0 24 24" class="w-16 h-16 stroke-primary fill-none stroke-[1.5] group-hover:scale-110 group-hover:rotate-6 transition-transform duration-300 drop-shadow-md"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 01-1.043 3.296 3.745 3.745 0 01-3.296 1.043A3.745 3.745 0 0112 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 01-3.296-1.043 3.745 3.745 0 01-1.043-3.296A3.745 3.745 0 013 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 011.043-3.296 3.746 3.746 0 013.296-1.043 A3.746 3.746 0 0112 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 013.296 1.043 3.746 3.746 0 011.043 3.296A3.745 3.745 0 0121 12z" /></svg>
<span class="text-lg ">Zero-waste factory</span>
</div>
</div>
</div>
</section>
<!-- 6. 引入 AOS.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<!-- 7. 交互逻辑 (AOS 初始化与功能脚本) -->
<script>
// --- 初始化 AOS 动画 ---
AOS.init({
duration: 800, // 动画持续时间 800ms
easing: 'ease-out-cubic', // 平滑的缓动函数
once: true, // 是否只动画一次
offset: 100, // 距离视口多远触发
});
// 1. 模板(主题)切换
// function setTheme(themeName) {
// document.documentElement.setAttribute('data-theme', themeName);
// }
// // 2. 顶部阅读进度条
// window.addEventListener('scroll', () => {
// const winScroll = document.body.scrollTop || document.documentElement.scrollTop;
// const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
// const scrolled = (winScroll / height) * 100;
// document.getElementById("progress-bar").style.width = scrolled + "%";
// });
// 3. Tab 切换 + 强制重绘触发 Tailwind flip-in 动画
// function switchTab(tabId, btnElement) {
// document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
// document.querySelectorAll('.tab-content').forEach(content => {
// content.classList.remove('active');
// void content.offsetWidth; // 触发重绘
// });
// btnElement.classList.add('active');
// document.getElementById(tabId).classList.add('active');
// }
// Tab 切换逻辑
function switchTab(tabId, btnElement) {
const wrapper = document.getElementById('tech-landing-wrapper');
const tabs = wrapper.querySelectorAll('.tab-btn');
const contents = wrapper.querySelectorAll('.tab-content');
// 重置所有按钮状态 (Hover 设为 #ff6b00)
tabs.forEach(btn => {
btn.className = "backdrop-blur-md p-1.5 rounded-full tab-btn px-8 py-3 rounded-full border-2 border-silver-accent/30 text-silver-accent transition-all duration-300 hover:-translate-y-1 hover:border-[#ff6b00] hover:text-[#ff6b00] ";
});
// 隐藏内容并重绘
contents.forEach(content => {
content.classList.remove('active');
void content.offsetWidth;
});
// 激活当前选中项 (赋值 #ff6b00)
btnElement.className = "backdrop-blur-md p-1.5 rounded-full tab-btn active px-8 py-3 rounded-full border-2 border-[#ff6b00] bg-[#ff6b00] text-white transition-all duration-300 shadow-[0_0_20px_rgba(255,107,0,0.4)] ";
document.getElementById(tabId).classList.add('active');
}
// 4. 高级非线性缓动数字滚动 (支持多节点与小数点)
const counters = document.querySelectorAll('.counter');
const myCounter = counters[0];
// 如果没有加 ID也可以默认选第一个 document.querySelectorAll('.counter')[0]
if(myCounter) {
const year = 2009
const dynamicValue = (new Date().getFullYear()) - year;
myCounter.setAttribute('data-target', dynamicValue);
}
const counterObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
const el = entry.target;
const target = parseFloat(el.getAttribute('data-target'));
const decimals = parseInt(el.getAttribute('data-decimals')) || 0; // 获取小数位数
let count = 0;
const updateCounter = () => {
// 缓动算法:每次增加剩余距离的 5%
count += (target - count) * 0.05;
// 当距离目标值非常近时小于0.1),直接停在目标值
if (target - count > 0.1) {
el.innerText = count.toFixed(decimals);
requestAnimationFrame(updateCounter);
} else {
el.innerText = target.toFixed(decimals);
}
};
updateCounter();
// 动画执行一次后取消监听该元素
observer.unobserve(el);
}
});
}, { threshold: 0.5 }); // 当元素有 50% 露出时触发
counters.forEach(counter => counterObserver.observe(counter));
// 6. 首屏 3D 鼠标视差位移
const m1 = document.getElementById('hero-sec');
const m1Bg = document.getElementById('m1-bg');
const m1Content = document.getElementById('m1-content');
// 首屏动态 3D 鼠标视差 (平移 + 物理扭转)
if(m1 && m1Bg && m1Content){
m1.addEventListener('mousemove', (e) => {
// 计算鼠标偏离屏幕中心的距离
const xAxis = (window.innerWidth / 2 - e.pageX) / 30;
const yAxis = (window.innerHeight / 2 - e.pageY) / 30;
// 背景反向移动
m1Bg.style.transform = `translate(${-xAxis}px, ${-yAxis}px) scale(1.05)`;
// 前景不仅跟随移动,还根据鼠标位置进行 3D 翻转 (Rotate)
// 除以的数值越大,翻转角度越小越柔和
m1Content.style.transform = `translate(${xAxis}px, ${yAxis}px) rotateY(${-xAxis / 2}deg) rotateX(${yAxis / 2}deg)`;
});
// 鼠标移出时缓慢复位
m1.addEventListener('mouseleave', () => {
m1Bg.style.transform = `translate(0, 0) scale(1.05)`;
m1Content.style.transform = `translate(0px, 0px) rotateY(0deg) rotateX(0deg)`;
});
}
// m1.addEventListener('mousemove', (e) => {
// const x = (window.innerWidth / 2 - e.pageX) / 40;
// const y = (window.innerHeight / 2 - e.pageY) / 40;
// m1Bg.style.transform = `translate(${-x}px, ${-y}px)`; // 背景反向移动
// m1Content.style.transform = `translate(${x}px, ${y}px)`; // 前景正向移动
// });
// m1.addEventListener('mouseleave', () => {
// m1Bg.style.transform = `translate(0, 0)`;
// m1Content.style.transform = `translate(0, 0)`;
// });
// 7. 初始化 3D 图片倾斜
VanillaTilt.init(document.querySelectorAll("[data-tilt]"));
</script>
</body>
</html>

@ -0,0 +1,376 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact & Global Grid - NexEnergy</title>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<!-- AOS Animation Library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<!-- Tailwind & Config -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#13eca4",
"background-light": "#f8fcfa",
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
"about-us": "#ff6b00"
},
fontFamily: {
"display": ["Montserrat", "sans-serif"],
"sans": ["Montserrat", "sans-serif"],
"mono": ["JetBrains Mono", "Montserrat"],
"inter": ["Inter", "Montserrat"],
},
borderRadius: {
"DEFAULT": "0.5rem",
"lg": "1rem",
"xl": "1.5rem",
"2xl": "2rem",
"3xl": "3rem",
"full": "9999px"
},
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.1) 0%, rgba(13,166,112,0.05) 50%, rgba(248,252,250,0) 100%)',
'mesh': 'radial-gradient(at 40% 20%, rgba(19,236,164,0.08) 0px, transparent 50%), radial-gradient(at 80% 0%, rgba(16,34,28,0.05) 0px, transparent 50%), radial-gradient(at 0% 50%, rgba(19,236,164,0.05) 0px, transparent 50%)',
},
boxShadow: {
// 将光效统一映射为 primary 颜色 (13eca4 的 RGBA)
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
'glow-lg': '0 10px 30px rgba(19, 236, 164, 0.4)',
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02)',
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.15), 0 0 0 1px rgba(19,236,164,0.3)',
'bento-dark': '0 30px 60px -15px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
scan: {
'0%': { top: '-10%', opacity: '0' },
'10%': { opacity: '1' },
'90%': { opacity: '1' },
'100%': { top: '110%', opacity: '0' },
},
rotateGlobe: {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
dash: {
'0%': { strokeDashoffset: '1000' },
'100%': { strokeDashoffset: '0' },
},
globePulse: {
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
},
// 高级交互动画
pulseGlow: {
'0%': { textShadow: '0 0 10px rgba(19, 236, 164, 0.4)' },
'100%': { textShadow: '0 0 30px #ff6b00' }
},
sweep: { '100%': { left: '200%' } },
cardFlip: {
'0%': { opacity: '0', transform: 'rotateY(-90deg) translateZ(50px)' },
'100%': { opacity: '1', transform: 'rotateY(0deg) translateZ(0)' }
},
floatY: {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-15px)' }
},
textShimmer: {
'0%': { backgroundPosition: '0% 50%' },
'100%': { backgroundPosition: '100% 50%' },
},
blobSpin: {
'0%': { transform: 'rotate(0deg) scale(1)' },
'50%': { transform: 'rotate(180deg) scale(1.1)' },
'100%': { transform: 'rotate(360deg) scale(1)' },
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out forwards',
'scan-slow': 'scan 6s linear infinite',
'spin-slow': 'rotateGlobe 60s linear infinite',
'dash-flow': 'dash 3s linear infinite',
'globe-select': 'globePulse 0.8s ease-out',
'pulse-glow': 'pulseGlow 2s infinite alternate',
'sweep': 'sweep 3s infinite',
'flip-in': 'cardFlip 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards',
'float-1': 'floatY 3s ease-in-out infinite',
'float-2': 'floatY 3s ease-in-out infinite 1s',
'float-3': 'floatY 3s ease-in-out infinite 2s',
'text-shimmer': 'textShimmer 3s ease-out infinite alternate',
'blob-spin': 'blobSpin 20s infinite cubic-bezier(0.4, 0, 0.2, 1)',
}
},
},
}
</script>
<style type="text/tailwindcss">
@layer utilities {
#contact-us .focus-group:hover > div:not(:hover) {
opacity: 0.6;
transform: scale(0.98);
filter: blur(2px);
}
#contact-us .focus-group > div {
transition: opacity 0.5s ease, transform 0.5s ease, filter 0.5s ease;
}
}
</style>
</head>
<body id="contact-us" class="bg-background-light text-background-dark font-sans selection:bg-primary selection:text-background-dark relative min-h-screen">
<!-- Background Aurora -->
<div class="fixed inset-0 w-full h-full bg-mesh z-1"></div>
<div class="fixed top-[-20%] right-[-10%] w-[60vw] h-[60vw] bg-primary/10 rounded-full blur-[120px] z-2 animate-blob-spin mix-blend-multiply"></div>
<div class="fixed bottom-[-20%] left-[-10%] w-[50vw] h-[50vw] bg-[#0a8257]/5 rounded-full blur-[100px] z-2 animate-blob-spin animation-delay-2000 mix-blend-multiply"></div>
<div class="h-24"></div>
<main class=" mx-auto px-6 pb-32 lg:px-8">
<!-- Hero Section -->
<div class="text-center max-w-5xl mx-auto mb-32 relative z-3" data-aos="zoom-out" data-aos-duration="1200">
<!-- Status Badge -->
<div class="inline-flex items-center gap-3 px-5 py-2.5 rounded-full bg-white/50 backdrop-blur-md border border-black/5 shadow-sm mb-10 transform transition-transform hover:scale-105 cursor-default">
<span class="relative flex h-2.5 w-2.5">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75"></span>
<span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-primary"></span>
</span>
<span class="text-xs font-mono text-background-dark uppercase tracking-[0.2em]">Global Turnkey Delivery</span>
</div>
<h1 class=" text-4xl md:text-[2.66rem] tracking-tighter text-background-dark leading-[0.95] mb-8">
Power a Zero-Carbon <br/>
<span class="text-transparent bg-clip-text bg-gradient-to-r from-background-dark via-primary to-[#0da670] bg-[length:200%_auto] animate-text-shimmer">Future.</span>
</h1>
<p class="text-[1rem] text-background-dark/60 leading-relaxed font-light mt-8 max-w-3xl mx-auto">
From visionary system design and megawatt-scale storage integration to global EPC delivery.<br class="hidden lg:block"/> We build secure and efficient renewable energy foundations for every scenario.
</p>
</div>
<!-- Top Tier: Direct Contact Channels -->
<div class="focus-group grid grid-cols-1 lg:grid-cols-3 gap-6 lg:gap-8 mb-40 relative z-3">
<!-- Channel 1: EPC & Projects (Dark Flagship) -->
<div class="bg-background-dark rounded-[2.5rem] p-10 lg:p-12 shadow-bento-dark border border-white/10 hover:border-primary/50 relative overflow-hidden flex flex-col justify-between"
data-aos="fade-up" data-aos-delay="100">
<div class="absolute -right-20 -bottom-20 w-64 h-64 bg-primary/20 blur-[80px] rounded-full"></div>
<div>
<div class="flex justify-between items-start mb-12">
<div class="w-16 h-16 rounded-2xl bg-white/5 flex items-center justify-center border border-white/10 backdrop-blur-md">
<svg class="w-8 h-8 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>
</div>
<span class="px-4 py-1.5 rounded-full bg-primary/10 text-primary text-xs font-mono tracking-widest uppercase border border-primary/20">EPC & Storage</span>
</div>
<h3 class="text-3xl mb-4 text-white">Global EPC & Partnerships</h3>
<p class="text-white/50 text-lg leading-relaxed mb-12">Explore partnerships for utility-scale storage plants, renewable turnkey projects, and microgrids.</p>
</div>
<a href="mailto:epc-projects@nenghui.com" class="group/btn inline-flex items-center justify-between w-full p-4 rounded-2xl bg-white/5 hover:bg-primary transition-all duration-300 border border-white/10 hover:border-primary">
<span class="text-sm sm:text-base lg:text-[1rem] font-mono font-medium text-white group-hover/btn:text-background-dark transition-colors ">epc-projects@nenghui.com</span>
<div class="w-10 h-10 rounded-full bg-white/10 flex items-center justify-center group-hover/btn:bg-background-dark/10 transition-colors shrink-0 ml-2">
<svg class="w-5 h-5 text-white group-hover/btn:text-background-dark transform group-hover/btn:translate-x-1 group-hover/btn:-translate-y-1 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
</div>
</a>
</div>
<!-- Channel 2: Design & Consulting -->
<div class="bg-white/60 backdrop-blur-xl rounded-[2.5rem] p-10 lg:p-12 shadow-bento hover:shadow-bento-hover transition-all flex flex-col justify-between"
data-aos="fade-up" data-aos-delay="200">
<div>
<div class="w-16 h-16 rounded-2xl bg-white flex items-center justify-center shadow-sm border border-black/5 mb-12">
<svg class="w-8 h-8 text-background-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"></path></svg>
</div>
<h3 class=" text-3xl mb-4 text-background-dark">System Design & Consulting</h3>
<p class="text-background-dark/50 text-lg leading-relaxed mb-12">Get customized storage architecture planning, preliminary microgrid designs, and feasibility assessments.</p>
</div>
<a href="mailto:design-eng@nenghui.com" class="group/btn inline-flex items-center justify-between w-full p-4 rounded-2xl bg-white hover:bg-background-dark transition-all duration-300 border border-black/5">
<span class="text-sm sm:text-base lg:text-lg font-mono font-medium text-background-dark group-hover/btn:text-white transition-colors ">design-eng@nenghui.com</span>
<div class="w-10 h-10 rounded-full bg-pearlescent flex items-center justify-center group-hover/btn:bg-white/10 transition-colors shrink-0 ml-2">
<svg class="w-5 h-5 text-background-dark group-hover/btn:text-white transform group-hover/btn:translate-x-1 group-hover/btn:-translate-y-1 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
</div>
</a>
</div>
<!-- Channel 3: O&M Support -->
<div class="bg-white/60 backdrop-blur-xl rounded-[2.5rem] p-10 lg:p-12 shadow-bento hover:shadow-bento-hover transition-all flex flex-col justify-between"
data-aos="fade-up" data-aos-delay="300">
<div>
<div class="w-16 h-16 rounded-2xl bg-white flex items-center justify-center shadow-sm border border-black/5 mb-12">
<svg class="w-8 h-8 text-background-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
</div>
<h3 class="text-3xl mb-4 text-background-dark">Asset O&M Support</h3>
<p class="text-background-dark/50 text-lg leading-relaxed mb-12">24/7 dedicated channel providing full-lifecycle data monitoring and on-site maintenance support.</p>
</div>
<a href="tel:+8602150896255" class="group/btn inline-flex items-center justify-between w-full p-4 rounded-2xl bg-white hover:bg-background-dark transition-all duration-300 border border-black/5">
<span class="text-lg font-mono font-medium text-background-dark group-hover/btn:text-white transition-colors pl-2">+86 021-50896255</span>
<div class="w-10 h-10 rounded-full bg-pearlescent flex items-center justify-center group-hover/btn:bg-white/10 transition-colors shrink-0">
<svg class="w-5 h-5 text-background-dark group-hover/btn:text-white transform group-hover/btn:translate-x-1 group-hover/btn:-translate-y-1 transition-all" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
</div>
</a>
</div>
</div>
<!-- Second Tier: Global Grid -->
<div class="relative pt-10 z-3" data-aos="fade-up">
<div class="flex flex-col md:flex-row items-baseline justify-between mb-16 gap-6">
<h2 class="text-4xl md:text-[2.66rem] text-background-dark tracking-tight">Global<br/><span class="text-primary">Locations.</span></h2>
<div class="flex items-center gap-4">
<span class="w-2 h-2 rounded-full bg-primary animate-pulse"></span>
<p class="font-mono text-sm text-background-dark/40 tracking-widest uppercase text-right">EPC & Supply Chain<br/>Zero-Carbon Hubs</p>
</div>
</div>
<!-- Bento Grid: 4 columns setup.
Row 1: Shanghai (2) - Europe (1) - Iraq (1)
Row 2: Thailand (2) - Cambodia (2)
-->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 auto-rows-min">
<!-- 1. Shanghai HQ (col-span-2) -->
<div class="lg:col-span-2 group bg-white rounded-[2rem] p-8 lg:p-10 shadow-bento hover:shadow-bento-hover transition-all duration-500 border border-black/5 flex flex-col justify-between overflow-hidden relative min-h-[280px]">
<div class="absolute right-0 bottom-0 opacity-[0.03] w-[300px] h-[300px] bg-[url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAwIDIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAwIDBDNDQuOCAwIDAgNDQuOCAwIDEwMHM0NC44IDEwMCAxMDAgMTAwIDEwMC00NC44IDEwMC0xMDBTMTU1LjIgMCAxMDAgMHptMCAxOTJDNDkuMiAxOTIgOCAxNTAuOCA4IDEwMFM0OS4yIDggMTAwIDggMTkyIDQ5LjIgMTkyIDEwMFMxNTAuOCAxOTIgMTAwIDE5MnoiIGZpbGw9IiMwMDAiLz48L3N2Zz4=')] bg-no-repeat bg-right-bottom transform translate-x-10 translate-y-10 group-hover:scale-110 transition-transform duration-700"></div>
<div class="relative z-10 flex justify-between items-start mb-8">
<div>
<span class="font-mono text-xs text-background-dark/50 px-3 py-1 bg-pearlescent rounded-full uppercase tracking-wider mb-4 inline-block">Headquarters</span>
<h3 class="font-display text-4xl text-background-dark">Shanghai</h3>
</div>
<div class="text-right shrink-0 ml-4">
<p class="font-mono text-3xl font-light text-primary live-clock" data-tz="Asia/Shanghai">00:00</p>
<p class="font-mono text-xs text-background-dark/40 uppercase mt-1">Local Time</p>
</div>
</div>
<div class="relative z-10 flex flex-col md:flex-row justify-between items-end gap-6 mt-auto">
<div class="space-y-2">
<p class="text-background-dark/60 text-sm font-medium">Building 2 Hongqiao International,<br/>No.288 Tongxie Road, Shanghai, China</p>
<div class="flex gap-4 mt-2">
<a href="tel:+8602150896255" class="font-mono text-sm text-background-dark hover:text-primary transition-colors flex items-center gap-1"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"></path></svg> +86 021-50896255</a>
</div>
</div>
<a href="mailto:contact@nenghui.com" class="w-12 h-12 rounded-full bg-background-dark text-white flex items-center justify-center hover:bg-primary transition-colors shrink-0 shadow-lg">
<svg class="w-5 h-5 transform -rotate-45" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
</a>
</div>
</div>
<!-- 2. Europe (col-span-1) -->
<div class="group bg-white rounded-[2rem] p-8 shadow-bento hover:shadow-bento-hover transition-all duration-500 border border-black/5 flex flex-col min-h-[280px]">
<div class="flex justify-between items-start mb-6">
<h3 class="font-display text-2xl text-background-dark">Europe</h3>
<p class="font-mono text-lg font-light text-primary live-clock shrink-0 ml-2" data-tz="Europe/Amsterdam">00:00</p>
</div>
<div class="mt-auto">
<p class="text-background-dark/60 text-sm mb-4 font-medium">Haaksbergweg 75<br/>1101 BR Amsterdam<br/>The Netherlands</p>
<a href="https://wa.me/8613057491520" class="font-mono text-xs text-background-dark hover:text-primary transition-colors block mb-1">WA: +86 13057491520</a>
<a href="mailto:Alli.Yu@nenghui.com" class="font-mono text-xs text-background-dark/60 hover:text-primary transition-colors block ">Alli.Yu@nenghui.com</a>
</div>
</div>
<!-- 3. Iraq (col-span-1) -->
<div class="group bg-white rounded-[2rem] p-8 shadow-bento hover:shadow-bento-hover transition-all duration-500 border border-black/5 flex flex-col min-h-[280px]">
<div class="flex justify-between items-start mb-6">
<h3 class="font-display text-2xl text-background-dark">Iraq</h3>
<p class="font-mono text-lg font-light text-primary live-clock shrink-0 ml-2" data-tz="Asia/Baghdad">00:00</p>
</div>
<div class="mt-auto">
<p class="text-background-dark/60 text-sm mb-4 font-medium">Al-Mansour Jordan St.<br/>BFB (near Baghdad Twr)<br/>Baghdad, Iraq</p>
<a href="https://wa.me/96407889681628" class="font-mono text-xs text-background-dark hover:text-primary transition-colors block mb-1">WA: +964 07889681628</a>
<a href="mailto:Leo@nenghui.com" class="font-mono text-xs text-background-dark/60 hover:text-primary transition-colors block ">Leo@nenghui.com</a>
</div>
</div>
<!-- 5. Cambodia (col-span-2) -->
<div class="lg:col-span-2 group bg-white rounded-[2rem] p-8 lg:p-10 shadow-bento hover:shadow-bento-hover transition-all duration-500 border border-black/5 flex flex-col justify-between md:flex-row md:items-end min-h-[280px]">
<div>
<div class="flex items-center gap-4 mb-6">
<h3 class="font-display text-3xl text-background-dark">Cambodia</h3>
<span class="font-mono text-xs text-background-dark/40 px-3 py-1 bg-pearlescent rounded-full">Operations</span>
</div>
<p class="text-background-dark/70 text-sm font-medium leading-relaxed max-w-md">
Borey Chip Mong Grand Mak271, No 011+013 Street MAIN.ST2,<br/>
Shangkat Chark Ang Re Lue, Khan Mean Chey,<br/>
Phnom Penh, Cambodia
</p>
</div>
<div class="mt-8 md:mt-0 text-left md:text-right shrink-0">
<p class="font-mono text-xl font-light text-primary live-clock mb-3" data-tz="Asia/Phnom_Penh">00:00</p>
<div class="flex flex-col gap-2">
<a href="tel:+855066503722" class="font-mono text-sm text-background-dark hover:text-primary transition-colors">Tel: +855 066503722</a>
<a href="mailto:zhangyi@nenghui.com" class="font-mono text-sm text-background-dark/60 hover:text-primary transition-colors">zhangyi@nenghui.com</a>
</div>
</div>
</div>
<!-- 4. Thailand (col-span-2) -->
<div class="lg:col-span-2 group bg-white rounded-[2rem] p-8 lg:p-10 shadow-bento hover:shadow-bento-hover transition-all duration-500 border border-black/5 flex flex-col justify-between md:flex-row md:items-end min-h-[280px]">
<div>
<div class="flex items-center gap-4 mb-6">
<h3 class="font-display text-3xl text-background-dark">Thailand</h3>
<span class="font-mono text-xs text-background-dark/40 px-3 py-1 bg-pearlescent rounded-full">SEA Hub</span>
</div>
<p class="text-background-dark/60 text-sm font-medium leading-relaxed max-w-sm">9th Floor, 909/9 AIA East Gateway Building,<br/>989 Debaratna Road, Bang Na Nuea, Bang Na,<br/>Bangkok 10260, Thailand</p>
</div>
<div class="mt-8 md:mt-0 text-left md:text-right shrink-0">
<p class="font-mono text-xl font-light text-primary live-clock mb-3" data-tz="Asia/Bangkok">00:00</p>
<div class="flex flex-col gap-2">
<a href="tel:+0980645276" class="font-mono text-sm text-background-dark hover:text-primary transition-colors">Tel: +0980645276</a>
<a href="mailto:james.chen@nenghui.com" class="font-mono text-sm text-background-dark/60 hover:text-primary transition-colors">james.chen@nenghui.com</a>
</div>
</div>
</div>
</div>
</div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<script>
AOS.init({ duration: 900, easing: 'ease-out-cubic', once: true, offset: 50 });
// Live Clocks
function updateGlobalClocks() {
const clocks = document.querySelectorAll('.live-clock');
clocks.forEach(clock => {
const tz = clock.getAttribute('data-tz');
if(!tz) return;
const timeString = new Intl.DateTimeFormat('en-GB', {
timeZone: tz, hour: '2-digit', minute: '2-digit', hour12: false
}).format(new Date());
clock.textContent = timeString;
});
}
updateGlobalClocks();
setInterval(updateGlobalClocks, 60000);
if(typeof VanillaTilt !== 'undefined') {
VanillaTilt.init(document.querySelectorAll("[data-tilt]"));
}
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,678 @@
<!DOCTYPE html>
<html class=" overflow-x-hidden" lang="en">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
<title>Join Us - TechCorp</title>
<!-- Google Fonts & Icons -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<!-- AOS Animation Library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<!-- Tailwind & Config -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#13eca4",
"background-light": "#f8fcfa",
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
"about-us": "#ff6b00"
},
fontFamily: {
"display": ["Montserrat", "sans-serif"],
"sans": ["Montserrat", "sans-serif"],
"mono": ["JetBrains Mono", "Montserrat"],
"inter": ["Inter", "Montserrat"],
},
borderRadius: {
"DEFAULT": "0.5rem",
"lg": "1rem",
"xl": "1.5rem",
"2xl": "2rem",
"3xl": "3rem",
"full": "9999px"
},
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.1) 0%, rgba(13,166,112,0.05) 50%, rgba(248,252,250,0) 100%)',
'mesh': 'radial-gradient(at 40% 20%, rgba(19,236,164,0.08) 0px, transparent 50%), radial-gradient(at 80% 0%, rgba(16,34,28,0.05) 0px, transparent 50%), radial-gradient(at 0% 50%, rgba(19,236,164,0.05) 0px, transparent 50%)',
},
boxShadow: {
// 将光效统一映射为 primary 颜色 (13eca4 的 RGBA)
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
'glow-lg': '0 10px 30px rgba(19, 236, 164, 0.4)',
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02)',
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.15), 0 0 0 1px rgba(19,236,164,0.3)',
'bento-dark': '0 30px 60px -15px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
scan: {
'0%': { top: '-10%', opacity: '0' },
'10%': { opacity: '1' },
'90%': { opacity: '1' },
'100%': { top: '110%', opacity: '0' },
},
rotateGlobe: {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
dash: {
'0%': { strokeDashoffset: '1000' },
'100%': { strokeDashoffset: '0' },
},
globePulse: {
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
},
// 高级交互动画
pulseGlow: {
'0%': { textShadow: '0 0 10px rgba(19, 236, 164, 0.4)' },
'100%': { textShadow: '0 0 30px #ff6b00' }
},
sweep: { '100%': { left: '200%' } },
cardFlip: {
'0%': { opacity: '0', transform: 'rotateY(-90deg) translateZ(50px)' },
'100%': { opacity: '1', transform: 'rotateY(0deg) translateZ(0)' }
},
floatY: {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-15px)' }
},
textShimmer: {
'0%': { backgroundPosition: '0% 50%' },
'100%': { backgroundPosition: '100% 50%' },
},
blobSpin: {
'0%': { transform: 'rotate(0deg) scale(1)' },
'50%': { transform: 'rotate(180deg) scale(1.1)' },
'100%': { transform: 'rotate(360deg) scale(1)' },
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out forwards',
'scan-slow': 'scan 6s linear infinite',
'spin-slow': 'rotateGlobe 60s linear infinite',
'dash-flow': 'dash 3s linear infinite',
'globe-select': 'globePulse 0.8s ease-out',
'pulse-glow': 'pulseGlow 2s infinite alternate',
'sweep': 'sweep 3s infinite',
'flip-in': 'cardFlip 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards',
'float-1': 'floatY 3s ease-in-out infinite',
'float-2': 'floatY 3s ease-in-out infinite 1s',
'float-3': 'floatY 3s ease-in-out infinite 2s',
'text-shimmer': 'textShimmer 3s ease-out infinite alternate',
'blob-spin': 'blobSpin 20s infinite cubic-bezier(0.4, 0, 0.2, 1)',
}
},
},
}
</script>
<!-- Swiper CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<!-- AOS Animation CSS -->
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<style>
html { scroll-behavior: smooth; }
body {
overflow-x: hidden;
width: 100%;
font-family: "Inter", "JetBrains Mono","sans-serif";
}
.swiper-slide {
height: auto;
transform: translateZ(0);
}
.swiper-wrapper {
align-items: stretch;
}
.swiper-scrollbar {
background: rgba(0, 0, 0, 0.06) !important;
height: 6px !important;
border-radius: 999px;
width: 100%;
}
.dark .swiper-scrollbar {
background: rgba(255, 255, 255, 0.1) !important;
}
.swiper-scrollbar-drag {
background: #2b8cee !important;
border-radius: 9999px;
cursor: grab;
}
.swiper-button-disabled {
opacity: 0.3 !important;
cursor: not-allowed !important;
pointer-events: none;
box-shadow: none !important;
filter: grayscale(100%);
transform: none !important;
border-color: transparent !important;
}
.dark .swiper-button-disabled {
opacity: 0.2 !important;
background-color: #1f2937 !important;
}
.search-container:focus-within {
box-shadow: 0 0 0 2px var(--tw-ring-offset-color, #fff), 0 0 0 4px rgba(43, 140, 238, 0.5);
}
.card-image-bg {
transition: transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.group:hover .card-image-bg {
transform: scale(1.1);
}
/* Modal Styles */
.modal-overlay {
opacity: 0;
visibility: hidden;
transition: all 0.3s ease-in-out;
}
.modal-overlay.open {
opacity: 1;
visibility: visible;
}
.modal-container {
transform: translateY(20px) scale(0.95);
opacity: 0;
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.modal-overlay.open .modal-container {
transform: translateY(0) scale(1);
opacity: 1;
}
/* 隐藏滚动条但保留功能 */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
</style>
</head>
<body class="bg-background-light dark:bg-background-dark text-[#111418] dark:text-white font-display antialiased w-screen overflow-x-hidden">
<div class="relative flex h-auto min-h-screen w-full flex-col group/design-root overflow-x-hidden">
<!-- Header -->
<!-- <header class="sticky top-0 z-40 flex items-center justify-between border-b border-solid border-[#e5e7eb] dark:border-gray-800 bg-white/80 dark:bg-[#101922]/80 backdrop-blur-md px-4 sm:px-6 lg:px-10 py-3 transition-all duration-300">
<div class="flex items-center gap-4 text-[#111418] dark:text-white">
<div class="size-8 flex items-center justify-center text-primary flex-shrink-0">
<span class="material-symbols-outlined text-3xl">&#xea25</span>
</div>
<h2 class="text-[#111418] dark:text-white text-lg leading-tight tracking-[-0.015em] truncate">TechCorp</h2>
</div>
<div class="hidden md:flex flex-1 justify-end gap-8">
<div class="flex items-center gap-9">
<a class="text-[#111418] dark:text-gray-200 text-sm font-medium hover:text-primary transition-colors" href="#">Jobs</a>
<a class="text-[#111418] dark:text-gray-200 text-sm font-medium hover:text-primary transition-colors" href="#">Culture</a>
<a class="text-[#111418] dark:text-gray-200 text-sm font-medium hover:text-primary transition-colors" href="#">About Us</a>
</div>
<button class="flex min-w-[84px] items-center justify-center rounded-lg h-10 px-6 bg-primary text-white text-sm hover:bg-blue-600 transition-colors shadow-sm">
Login
</button>
</div>
<div class="md:hidden p-2 -mr-2 cursor-pointer text-[#111418] dark:text-white">
<span class="material-symbols-outlined text-2xl">&#xe5d2;</span>
</div>
</header> -->
<main class="layout-container flex h-full grow flex-col pt-6 sm:pt-10 pb-20 w-full overflow-x-hidden">
<div class="w-full flex flex-1 justify-center">
<div class="layout-content-container flex flex-col w-full max-w-[1400px] flex-1">
<!-- Heading & Search Section -->
<div class="flex flex-col gap-6 px-4 sm:px-6 lg:px-40 mb-6 sm:mb-8 w-full max-w-[100vw] overflow-hidden">
<div class="flex flex-wrap items-end justify-between gap-6">
<div class="flex min-w-full md:min-w-[400px] flex-col gap-3 max-w-2xl" data-aos="fade-right" data-aos-duration="1000">
<h1 class="text-[#111418] dark:text-white text-4xl md:text-[2.66rem] leading-tight tracking-[-0.033em]">
Shape the future <br/><span class="text-primary bg-clip-text text-transparent bg-gradient-to-r from-blue-500 to-cyan-400">with us.</span>
</h1>
<p class="text-[#617589] dark:text-gray-400 text-[1rem] leading-normal max-w-lg mt-1 sm:mt-2">
We are looking for thinkers, makers, and doers to join our high-energy team.
</p>
</div>
<div class="flex flex-col sm:flex-row items-end sm:items-center gap-4 w-full sm:w-auto" data-aos="fade-left" data-aos-delay="200">
<div class="search-container relative w-full sm:w-64 group transition-all duration-300 rounded-full">
<span class="material-symbols-outlined absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 group-focus-within:text-primary transition-colors">&#xe8b6;</span>
<input id="job-search" type="text" placeholder="Search positions..."
class="w-full h-11 sm:h-12 pl-12 pr-4 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-full text-sm outline-none focus:border-primary dark:focus:border-primary transition-colors text-[#111418] dark:text-white shadow-sm"
>
</div>
<div class="hidden sm:flex gap-3">
<button class="swiper-button-prev-custom size-12 rounded-full border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 flex items-center justify-center hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-primary/50 text-[#111418] dark:text-white transition-all duration-300 shadow-sm hover:shadow-md active:scale-95 z-10 group cursor-pointer">
<span class="material-symbols-outlined group-hover:text-primary transition-colors">&#xe5c4;</span>
</button>
<button class="swiper-button-next-custom size-12 rounded-full border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 flex items-center justify-center hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-primary/50 text-[#111418] dark:text-white transition-all duration-300 shadow-sm hover:shadow-md active:scale-95 z-10 group cursor-pointer">
<span class="material-symbols-outlined group-hover:text-primary transition-colors">&#xe5c8;</span>
</button>
</div>
</div>
</div>
</div>
<!-- Job Slider Area -->
<div class="relative w-full min-h-[400px]">
<div class="swiper mySwiper w-full pb-14 !overflow-visible">
<div class="swiper-wrapper" id="jobs-container">
<!-- JS will inject slides here -->
</div>
</div>
<div id="no-results" class="hidden absolute inset-0 flex flex-col items-center justify-center text-center p-8 z-0 mt-12">
<span class="material-symbols-outlined text-5xl sm:text-6xl text-gray-300 dark:text-gray-700 mb-4">&#xea76;</span>
<h3 class="text-lg sm:text-xl text-[#111418] dark:text-white">No positions found</h3>
<p class="text-sm sm:text-base text-[#617589] dark:text-gray-400 mt-2">Try adjusting your search criteria</p>
</div>
</div>
<!-- Progress Section -->
<div class="w-full flex justify-center px-4 sm:px-6 lg:px-40 mt-4 max-w-[100vw]" data-aos="fade-in" data-aos-delay="500">
<div class="w-full flex flex-col gap-4">
<div class="flex justify-between items-end">
<div class="flex flex-col gap-0.5">
<p class="text-[10px] sm:text-xs tracking-[0.15em] text-primary uppercase">Explore</p>
<p class="text-[#111418] dark:text-white text-sm sm:text-base ">Open Positions</p>
</div>
<p class="text-[#617589] dark:text-gray-400 text-sm sm:text-base font-medium tabular-nums font-mono">
<span id="slide-current" class="text-[#111418] dark:text-white text-lg">01</span>
<span class="mx-1 text-gray-300 dark:text-gray-600">/</span>
<span id="slide-total">00</span>
</p>
</div>
<div class="w-full h-1.5 rounded-full bg-gray-100 dark:bg-gray-800 overflow-hidden relative">
<div class="swiper-scrollbar !static !w-full !h-full !bg-transparent"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- [New] Job Detail Modal -->
<div id="job-detail-modal" class="modal-overlay fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/60 backdrop-blur-sm p-0 sm:p-4">
<div class="absolute inset-0 cursor-pointer" onclick="closeJobModal()"></div>
<div class="modal-container relative w-full max-w-2xl bg-white dark:bg-[#1a2632] rounded-t-2xl sm:rounded-2xl shadow-2xl flex flex-col max-h-[90vh] sm:max-h-[85vh] border border-white/10 overflow-hidden">
<!-- Header -->
<div class="flex items-start justify-between p-6 border-b border-gray-100 dark:border-gray-700 bg-white/50 dark:bg-[#1a2632]/50 backdrop-blur-sm sticky top-0 z-10">
<div>
<div class="flex items-center gap-3 mb-2">
<span id="modal-tag" class="inline-flex items-center justify-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-primary/20 text-primary border border-primary/10">Product</span>
<span class="text-xs text-gray-400 font-mono" id="modal-location">Remote</span>
</div>
<h2 id="modal-title" class="text-2xl text-[#111418] dark:text-white leading-tight">Senior Product Designer</h2>
</div>
<button onclick="closeJobModal()" class="size-8 rounded-full bg-gray-100 dark:bg-gray-700 flex items-center justify-center text-gray-500 hover:text-gray-900 dark:text-gray-300 dark:hover:text-white transition-colors">
<span class="material-symbols-outlined text-xl">&#xe5cd;</span>
</button>
</div>
<!-- Body (Scrollable) -->
<!-- [修复] 添加 ID 'modal-body' 用于 JS 控制 -->
<div id="modal-body" class="p-6 overflow-y-auto no-scrollbar flex-1 scroll-smooth">
<div class="prose dark:prose-invert max-w-none">
<div class="mb-6">
<h3 class="text-lg text-[#111418] dark:text-white mb-2">About the Role</h3>
<p id="modal-desc" class="text-[#617589] dark:text-gray-400 text-sm leading-relaxed">
Lead design initiatives across our core products...
</p>
</div>
<div class="mb-6">
<h3 class="text-lg text-[#111418] dark:text-white mb-2">Key Responsibilities</h3>
<ul id="modal-responsibilities" class="list-disc pl-5 text-[#617589] dark:text-gray-400 text-sm leading-relaxed space-y-1"></ul>
</div>
<div class="mb-6">
<h3 class="text-lg text-[#111418] dark:text-white mb-2">Requirements</h3>
<ul id="modal-requirements" class="list-disc pl-5 text-[#617589] dark:text-gray-400 text-sm leading-relaxed space-y-1"></ul>
</div>
</div>
</div>
<!-- Footer -->
<!-- Job Detail Modal Footer (修改部分) -->
<div class="p-5 border-t border-gray-100 dark:border-gray-700 bg-gray-50/80 dark:bg-[#151f28]/80 backdrop-blur-md flex flex-col gap-3">
<!-- 主按钮 -->
<a id="modal-apply-btn" href="#" class="flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg h-12 bg-primary hover:bg-blue-600 text-white text-base transition-all shadow-md active:scale-[0.98] group">
<span class="material-symbols-outlined">&#xe159;</span>
Apply via Email
</a>
<!-- 新增:邮箱文本提示 (兜底方案) -->
<p class="text-center text-xs text-[#617589] dark:text-gray-400">
Or email us directly at
<!-- select-all 允许用户点击一次即可全选邮箱 -->
<span class="text-[#111418] dark:text-white font-mono font-medium select-all cursor-text hover:text-primary transition-colors" id="email-link">zhoushu@nenghui.com</span>
</p>
</div>
</div>
</div>
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script>
// --- Enhanced Data Source ---
const jobsData = [
{
id: 1,
title: "Photovoltaic Field Engineer",
type: "Engineering",
dept: "Eng",
location: "Iraq",
image: "https://nenghui.com/wp-content/uploads/2026/02/job-1.avif",
color: "bg-primary/90 border-white/10 text-white",
desc: "",
responsibilities: ["Responsible for on-site supervision, installation guidance, and problem-solving for photovoltaic and energy storage projects, ensuring construction complies with design specifications and safety standards.",
"Inspect the construction site, coordinate the installation team, and conduct system commissioning and performance testing.",
"Collect on-site data and report project progress, quality issues, and customer feedback.",
"Provide customer training and technical support to ensure normal system operation and customer satisfaction.",
"Responsible for site surveys and technical solution design.",
"xResponsible for after-sales troubleshooting."
],
requirements: [
"Full-time college diploma or above, majoring in electrical engineering or related fields, with basic conversational English skills;",
"At least 1 year of experience in photovoltaic construction, understanding of photovoltaic construction details, and experience in on-site construction guidance;",
"Responsible, meticulous, and with good professional ethics and communication and coordination skills;",
"Able to accept long-term relocation to the Middle East; the company provides accommodation and overseas commercial insurance."
]
},
{
id: 11,
title: "Overseas Sales Manager",
type: "Sales",
dept: "Sale",
location: "ShangHai",
image: "https://nenghui.com/wp-content/uploads/2026/02/job-2.avif",
color: "bg-primary/90 border-white/10 text-white",
desc: "",
responsibilities: ["Develop the commercial and industrial energy storage and large-scale energy storage markets in Europe, identify and secure overseas energy storage orders and projects, and achieve company business goals, in accordance with the company's business strategy.",
"Travel overseas as arranged by the company and as needed to conduct market research and customer visits, track and evaluate customer creditworthiness and purchasing intentions, and establish and maintain a regional customer resource pool.",
"Participate in overseas industry exhibitions and seminars to develop customer resources and expand business channels.",
"Assist the company in organizing overseas product launches and promoting brand marketing.",
],
requirements: [
"Bachelor's degree or above, with preference given to candidates majoring in international trade, English, or German.",
"At least 3 years of experience in the new energy industry trade, with preference given to candidates with experience in electrical, photovoltaic, or lithium battery energy storage related products.",
"Fluent in spoken English and proficient in written communication, including international business emails.",
"Familiar with various international trade terms and risk control, and proficient in using international social media and foreign trade customer acquisition software.",
"Excellent communication and teamwork skills.",
]
},
// {
// id: 2,
// title: "Lead Backend Engineer",
// type: "Engineering",
// dept: "Eng",
// location: "San Francisco",
// image: "https://images.unsplash.com/photo-1555099962-4199c345e5dd?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80",
// color: "bg-emerald-500/20 border-white/10 text-emerald-100",
// desc: "Join our backend team to architect scalable systems that handle millions of requests. You will be responsible for the core infrastructure and API development.",
// responsibilities: ["Design and implement scalable APIs.", "Optimize database performance and queries.", "Mentor junior engineers and review code."],
// requirements: ["Strong proficiency in Python, Go, or Java.", "Experience with distributed systems and microservices.", "Familiarity with AWS or Google Cloud."]
// },
{
id: 3,
title: "Business Development Manager ",
type: "Development",
dept: "Development",
location: "Cambodia",
image: "https://nenghui.com/wp-content/uploads/2026/02/job-3.avif",
color: "bg-purple-500/90 border-white/10 text-purple-100",
desc: "",
responsibilities: ["Develop commercial and industrial photovoltaic (PV) projects within the assigned region, establishing strong client relationships, in accordance with the company's business strategy and development requirements.",
"Handle all necessary procedures for project approval and grid connection, including preliminary data collection, site visits, and initial assessments of compliance and economic feasibility.",
"Establish and improve distribution channels for commercial and industrial PV and energy storage projects within the assigned region, fostering a favorable development environment.",
"Maintain relationships with local government/power grid authorities and relevant departments to promote project cooperation."
],
requirements: ["Bachelor's degree or above, any major, at least 2 years of experience in PV projects; experienced business professionals with large-scale project development experience are preferred.",
"Familiar with the local/industry PV market and proficient in the development process of commercial and industrial power plants.",
"Strong communication and execution skills, and excellent teamwork ability.",
"Keen market insight, existing social or industry client resources, and strong ability to acquire project opportunities/leads are preferred."
]
},
// {
// id: 4,
// title: "Financing Director/Manager",
// type: "Financing",
// dept: "Financing",
// location: "ShangHai",
// image: "https://nenghui.com/wp-content/uploads/2026/02/job-1.avif",
// color: "bg-blue-500/90 border-white/10 text-blue-100",
// desc: "",
// responsibilities: ["Build and deploy machine learning models.", "Perform exploratory data analysis.", "Create data visualizations for stakeholders."],
// requirements: ["Master's or PhD in Statistics, CS, or related field.", "Proficiency in Python, R, and SQL.", "Experience with TensorFlow or PyTorch."]
// }
];
const email = 'zhoushu@nenghui.com'
const emailLink = document.getElementById('email-link');
if (emailLink) {
emailLink.innerText = email;
}
let swiperInstance = null;
const container = document.getElementById('jobs-container');
const noResultsEl = document.getElementById('no-results');
const searchInput = document.getElementById('job-search');
const modal = document.getElementById('job-detail-modal');
function openJobModal(jobId) {
const job = jobsData.find(j => j.id === jobId);
if (!job) return;
// Populate Data
document.getElementById('modal-title').textContent = job.title;
document.getElementById('modal-location').textContent = job.location;
document.getElementById('modal-desc').textContent = job.desc;
const tag = document.getElementById('modal-tag');
tag.textContent = job.type;
tag.className = `inline-flex items-center justify-center px-2.5 py-0.5 rounded-full text-xs font-semibold border ${job.color}`;
const respList = document.getElementById('modal-responsibilities');
respList.innerHTML = job.responsibilities.map(item => `<li>${item}</li>`).join('');
const reqList = document.getElementById('modal-requirements');
reqList.innerHTML = job.requirements.map(item => `<li>${item}</li>`).join('');
const subject = encodeURIComponent(`Application for ${job.title} - [Your Name]`);
const body = encodeURIComponent(`Dear Hiring Team,\n\nI am writing to express my interest in the ${job.title} position.\n\nPlease find my resume attached.\n\nBest regards,\n[Your Name]`);
document.getElementById('modal-apply-btn').href = `mailto:${email}?subject=${subject}&body=${body}`;
// [修复] 强制重置滚动条位置到顶部
document.getElementById('modal-body').scrollTop = 0;
modal.classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeJobModal() {
modal.classList.remove('open');
document.body.style.overflow = '';
}
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('open')) {
closeJobModal();
}
});
function renderJobs(data) {
container.innerHTML = '';
if (data.length === 0) {
noResultsEl.classList.remove('hidden');
return;
} else {
noResultsEl.classList.add('hidden');
}
data.forEach((job, index) => {
const slide = document.createElement('div');
slide.className = 'swiper-slide w-[85vw] sm:w-[320px] md:w-[380px]';
slide.setAttribute('data-aos', 'fade-up');
slide.setAttribute('data-aos-delay', window.innerWidth < 640 ? 0 : (index % 5) * 100);
slide.innerHTML = `
<div class="flex flex-col h-full rounded-xl bg-white dark:bg-[#1a2632] shadow-[0_4px_20px_rgb(0,0,0,0.06)] hover:shadow-[0_20px_40px_rgb(0,0,0,0.1)] dark:shadow-none dark:hover:shadow-[0_20px_40px_rgba(0,0,0,0.4)] overflow-hidden group transition-all duration-300 border border-gray-100 dark:border-gray-800 hover:border-gray-200 dark:hover:border-gray-700">
<div class="h-40 sm:h-48 w-full relative overflow-hidden">
<div class="card-image-bg absolute inset-0 bg-cover bg-center" style='background-image: url("${job.image}");'></div>
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent"></div>
<div class="absolute bottom-4 left-4 z-10">
<span class="inline-flex items-center justify-center px-2.5 py-0.5 sm:px-3 sm:py-1 rounded-full text-xs font-semibold ${job.color} backdrop-blur-md shadow-sm border border-white/10">${job.type}</span>
</div>
</div>
<div class="p-5 sm:p-6 flex flex-col flex-1 gap-3 sm:gap-4">
<div class="flex-1">
<h3 class="text-xl sm:text-2xl text-[#111418] dark:text-white leading-tight mb-2 group-hover:text-primary transition-colors">${job.title}</h3>
<div class="flex items-center gap-2 text-[#617589] dark:text-gray-400 text-xs sm:text-sm mb-3 sm:mb-4">
<span class="material-symbols-outlined text-sm sm:text-base">&#xe0c8;</span><span>${job.location}</span>
<span class="w-1 h-1 bg-gray-300 rounded-full mx-1"></span>
<span class="material-symbols-outlined text-sm sm:text-base">&#xe8b5;</span><span>Full-time</span>
</div>
<p class="text-[#617589] dark:text-gray-400 text-sm line-clamp-2 leading-relaxed">${job.desc}</p>
</div>
<button onclick="openJobModal(${job.id})" class="mt-auto w-full flex items-center justify-center gap-2 rounded-lg h-10 sm:h-12 bg-white dark:bg-gray-800 border-2 border-gray-100 dark:border-gray-700 text-[#111418] dark:text-white text-sm hover:border-primary hover:text-primary dark:hover:border-primary dark:hover:text-primary transition-all duration-300 group/btn active:scale-95">
View Details
</button>
</div>
</div>
`;
container.appendChild(slide);
});
}
function initSwiper() {
if (swiperInstance) {
swiperInstance.destroy(true, true);
}
swiperInstance = new Swiper(".mySwiper", {
slidesPerView: "auto",
centeredSlides: window.innerWidth < 640,
spaceBetween: 16,
grabCursor: true,
speed: 600,
resistance: true,
resistanceRatio: 0.65,
observer: true,
observeParents: true,
breakpoints: {
640: {
centeredSlides: false,
spaceBetween: 24,
}
},
navigation: {
nextEl: ".swiper-button-next-custom",
prevEl: ".swiper-button-prev-custom",
},
scrollbar: {
el: ".swiper-scrollbar",
draggable: true,
snapOnRelease: false,
},
mousewheel: {
forceToAxis: true,
},
keyboard: {
enabled: true,
onlyInViewport: true,
},
on: {
init: function(sw) { updateCounter(sw); },
slideChange: function(sw) { updateCounter(sw); },
slidesLengthChange: function(sw) { updateCounter(sw); },
resize: function(sw) {
sw.params.centeredSlides = window.innerWidth < 640;
sw.update();
}
}
});
}
function updateCounter(sw) {
const currentEl = document.getElementById('slide-current');
const totalEl = document.getElementById('slide-total');
let count = sw.slides.length;
if(count === 0) {
currentEl.textContent = "00";
totalEl.textContent = "00";
return;
}
let current = sw.activeIndex + 1;
currentEl.textContent = String(current).padStart(2, '0');
totalEl.textContent = String(count).padStart(2, '0');
}
searchInput.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase().trim();
const filtered = jobsData.filter(job =>
job.title.toLowerCase().includes(query) ||
job.type.toLowerCase().includes(query)
);
renderJobs(filtered);
initSwiper();
setTimeout(() => { AOS.refresh(); }, 100);
});
document.addEventListener('DOMContentLoaded', () => {
AOS.init({
once: true,
offset: 30,
duration: 800,
easing: 'ease-out-cubic',
});
renderJobs(jobsData);
initSwiper();
});
</script>
</body>
</html>

@ -0,0 +1,894 @@
<!DOCTYPE html>
<html class="light" lang="en">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>Energy Storage - Waterfall Specs View</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700;900&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<!-- AOS Animation Library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<!-- Tailwind & Config -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#13eca4",
"background-light": "#f8fcfa",
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
"about-us": "#ff6b00"
},
fontFamily: {
"display": ["Montserrat", "sans-serif"],
"sans": ["Montserrat", "sans-serif"],
"mono": ["JetBrains Mono", "Montserrat"],
"inter": ["Inter", "Montserrat"],
},
borderRadius: {
"DEFAULT": "0.5rem",
"lg": "1rem",
"xl": "1.5rem",
"2xl": "2rem",
"3xl": "3rem",
"full": "9999px"
},
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.1) 0%, rgba(13,166,112,0.05) 50%, rgba(248,252,250,0) 100%)',
'mesh': 'radial-gradient(at 40% 20%, rgba(19,236,164,0.08) 0px, transparent 50%), radial-gradient(at 80% 0%, rgba(16,34,28,0.05) 0px, transparent 50%), radial-gradient(at 0% 50%, rgba(19,236,164,0.05) 0px, transparent 50%)',
},
boxShadow: {
// 将光效统一映射为 primary 颜色 (13eca4 的 RGBA)
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
'glow-lg': '0 10px 30px rgba(19, 236, 164, 0.4)',
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02)',
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.15), 0 0 0 1px rgba(19,236,164,0.3)',
'bento-dark': '0 30px 60px -15px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
scan: {
'0%': { top: '-10%', opacity: '0' },
'10%': { opacity: '1' },
'90%': { opacity: '1' },
'100%': { top: '110%', opacity: '0' },
},
rotateGlobe: {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
dash: {
'0%': { strokeDashoffset: '1000' },
'100%': { strokeDashoffset: '0' },
},
globePulse: {
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
},
// 高级交互动画
pulseGlow: {
'0%': { textShadow: '0 0 10px rgba(19, 236, 164, 0.4)' },
'100%': { textShadow: '0 0 30px #ff6b00' }
},
sweep: { '100%': { left: '200%' } },
cardFlip: {
'0%': { opacity: '0', transform: 'rotateY(-90deg) translateZ(50px)' },
'100%': { opacity: '1', transform: 'rotateY(0deg) translateZ(0)' }
},
floatY: {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-15px)' }
},
textShimmer: {
'0%': { backgroundPosition: '0% 50%' },
'100%': { backgroundPosition: '100% 50%' },
},
blobSpin: {
'0%': { transform: 'rotate(0deg) scale(1)' },
'50%': { transform: 'rotate(180deg) scale(1.1)' },
'100%': { transform: 'rotate(360deg) scale(1)' },
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out forwards',
'scan-slow': 'scan 6s linear infinite',
'spin-slow': 'rotateGlobe 60s linear infinite',
'dash-flow': 'dash 3s linear infinite',
'globe-select': 'globePulse 0.8s ease-out',
'pulse-glow': 'pulseGlow 2s infinite alternate',
'sweep': 'sweep 3s infinite',
'flip-in': 'cardFlip 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards',
'float-1': 'floatY 3s ease-in-out infinite',
'float-2': 'floatY 3s ease-in-out infinite 1s',
'float-3': 'floatY 3s ease-in-out infinite 2s',
'text-shimmer': 'textShimmer 3s ease-out infinite alternate',
'blob-spin': 'blobSpin 20s infinite cubic-bezier(0.4, 0, 0.2, 1)',
}
},
},
}
</script>
</head>
<body class="bg-background-light dark:bg-background-dark text-[#111318] dark:text-white font-sans transition-colors duration-200 overflow-x-hidden">
<!-- Top Navigation -->
<!-- Main Content Wrapper -->
<style>
/* Custom scrollbar for horizontal scrolling elements */
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
.hide-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
/* Smooth Scrolling */
html {
scroll-behavior: smooth;
}
/* Card Hover Effects */
.product-card {
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative; /* 确保 z-index 生效 */
z-index: 10;
}
.product-card:hover {
transform: translateY(-8px);
z-index: 30; /* 低于 filter 的 40 */
}
</style>
<div class="bg-background-light dark:bg-background-dark text-[#111318] dark:text-white font-sans transition-colors duration-200 pt-[80px] hide-scrollbar">
<main class="max-w-[1280px] mx-auto px-4 sm:px-6 lg:px-8 py-8 flex flex-col flex-1 min-h-screen">
<!-- Page Heading & Intro (布局优化:垂直排列) -->
<div class="max-w-4xl mb-10" data-aos="fade-right" data-aos-delay="200">
<h1 class=" text-[#111318] dark:text-white text-4xl md:text-[2.66rem] leading-tight tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-gray-900 to-gray-600 dark:from-white dark:to-gray-400">
High-Performance Energy Storage
</h1>
<p class="text-[#5f6e8c] dark:text-gray-400 text-[1rem] font-normal leading-relaxed max-w-2xl">
From residential backups to utility-scale grids. Explore our LFP and Solid-State battery solutions designed for maximum efficiency.
</p>
</div>
<!-- Filter Section (全新设计:支持多行展示 + 移动端滑动) -->
<div id="filter-sticky-wrapper" class="sticky top-[80px] z-40 mb-8 transition-all duration-300 -mx-4 px-4 sm:mx-0 sm:px-0 rounded-b-xl">
<!-- Visual Background Container (用于承载背景色和模糊) -->
<div class="absolute inset-0 bg-background-light/95 dark:bg-background-dark/95 backdrop-blur-md transition-opacity duration-300 opacity-90 border-b border-transparent" id="filter-bg"></div>
<!-- Content Container -->
<div class="relative max-w-[1280px] mx-auto py-3">
<!-- Filter Label & Controls -->
<div class="flex items-center justify-between mb-2 px-1">
<span class="text-[10px] font-extrabold tracking-widest text-gray-500 dark:text-gray-400 uppercase flex items-center gap-1">
<span class="material-symbols-outlined text-[14px]">&#xe429;</span>
Filter by Category
</span>
<div class="hidden sm:flex gap-2">
<span class="text-xs text-gray-400 font-mono" id="item-count-display">Showing 5 items</span>
</div>
</div>
<!-- Scroll/Wrap Container -->
<div class="relative group/filters">
<!-- Mobile Left Fade Mask -->
<div class="absolute left-0 top-0 bottom-0 w-8 bg-gradient-to-r from-[#f8fcfa] dark:from-[#10221c] to-transparent z-10 pointer-events-none md:hidden transition-colors duration-300" id="mask-left"></div>
<!-- Buttons Grid -->
<!-- py-2 -my-2: 防止按钮放大被裁剪,同时保持紧凑 -->
<div class="flex overflow-x-auto md:flex-wrap gap-3 py-2 -my-2 px-2 -mx-2 hide-scrollbar scroll-smooth snap-x items-center">
<!-- Chip: All -->
<button onclick="filterSelection('all', this)" class="filter-btn active snap-start shrink-0 relative flex items-center gap-2 pl-4 pr-5 h-10 rounded-full border transition-all duration-300 group" data-filter="all">
<span class=" text-sm tracking-wide">All Systems</span>
<span class="count-badge flex items-center justify-center h-5 min-w-[20px] px-1.5 rounded-full text-[10px] ">5</span>
</button>
<button onclick="filterSelection('residential', this)" class="filter-btn snap-start shrink-0 flex items-center gap-2 pl-4 pr-4 h-10 rounded-full border border-[#e5e7eb] dark:border-[#374151] bg-white dark:bg-[#1f2937] text-[#5f6e8c] dark:text-gray-300 transition-all duration-300 hover:scale-105 active:scale-95 hover:shadow-lg hover:border-primary z-0 hover:z-10" data-filter="residential">
<span class="font-medium text-sm"> Smart Energy Storage Systems</span>
<!-- <span class="text-xs text-gray-400 group-hover:text-primary">5-20kWh</span> -->
</button>
<!--
<button onclick="filterSelection('commercial', this)" class="filter-btn snap-start shrink-0 flex items-center gap-2 pl-4 pr-4 h-10 rounded-full border border-[#e5e7eb] dark:border-[#374151] bg-white dark:bg-[#1f2937] text-[#5f6e8c] dark:text-gray-300 transition-all duration-300 hover:scale-105 active:scale-95 hover:shadow-lg hover:border-primary z-0 hover:z-10" data-filter="commercial">
<span class="font-medium text-sm">Commercial</span>
<span class="text-xs text-gray-400 group-hover:text-primary">50-200kWh</span>
</button>
<button onclick="filterSelection('industrial', this)" class="filter-btn snap-start shrink-0 flex items-center gap-2 pl-4 pr-4 h-10 rounded-full border border-[#e5e7eb] dark:border-[#374151] bg-white dark:bg-[#1f2937] text-[#5f6e8c] dark:text-gray-300 transition-all duration-300 hover:scale-105 active:scale-95 hover:shadow-lg hover:border-primary z-0 hover:z-10" data-filter="industrial">
<span class="font-medium text-sm">Industrial</span>
<span class="text-xs text-gray-400 group-hover:text-primary">MWh+</span>
</button>
<button onclick="filterSelection('portable', this)" class="filter-btn snap-start shrink-0 flex items-center gap-2 pl-4 pr-4 h-10 rounded-full border border-[#e5e7eb] dark:border-[#374151] bg-white dark:bg-[#1f2937] text-[#5f6e8c] dark:text-gray-300 transition-all duration-300 hover:scale-105 active:scale-95 hover:shadow-lg hover:border-primary z-0 hover:z-10" data-filter="portable">
<span class="material-symbols-outlined text-[18px]">&#xea12;</span>
<span class="font-medium text-sm">Portable</span>
</button> -->
</div>
<!-- Mobile Right Fade Mask -->
<div class="absolute right-0 top-0 bottom-0 w-12 bg-gradient-to-l from-[#f8fcfa] dark:from-[#10221c] to-transparent z-10 pointer-events-none md:hidden transition-colors duration-300" id="mask-right"></div>
</div>
</div>
</div>
<!-- Waterfall Grid (Masonry Layout) - 保持原有代码,这里不再重复 -->
<div id="product-grid" class="columns-1 md:columns-2 lg:columns-3 gap-6 space-y-6 pb-12">
<!-- Card 1: Residential Standard
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class="relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:bg-[#111318] flex items-center justify-center p-6 group-hover:bg-primary/5 transition-colors duration-500">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-primary text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
≥93% Efficiency
</div>
<div class="w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="Modern white wall-mounted battery unit" style="background-image: url('https://nenghui.com/wp-content/uploads/2025/12/418372.jpg');"></div>
</div>
<div class="p-6">
<div class="flex justify-between items-start mb-2">
<h3 class="text-xl font-display text-[#111318] dark:text-white group-hover:text-primary transition-colors">NB418L</h3>
<button class="text-gray-400 hover:text-primary transition-colors">
<span class="material-symbols-outlined">&#xe867;</span>
</button>
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Rated Energy</p>
<p class=" dark:text-gray-200">418 kWh</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Cycle Life</p>
<p class=" dark:text-gray-200">8,000 times</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">DoD</p>
<p class=" dark:text-gray-200">95%(25±2℃)0.5P</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Rated Voltage</p>
<p class=" dark:text-gray-200">1331.2Vdc</p>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghui liquid-cooled battery cabinet adopts an advanced cabinet-level liquid cooling and temperature balancing strategy. The cell temperature difference is less than 3°C, which further improves the consistency of cell temperature and extends the battery life. The modular design makes the parallel solution more flexible and can be combined with the centralized PCS to form an ESS with higher energy density, which significantly improves the economy, safety and construction convenience of ESS projects.
</p>
<a href="https://nenghui.com/products/ne418l/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
-->
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class="skeleton-wrapper relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:from-[#333] dark:to-[#111318] flex items-center justify-center p-6 transition-all duration-500 group-hover:from-[#666666] group-hover:to-[#e6fcf5]">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-[#295ca8] text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
≥93% Efficiency
</div>
<div class="lazy-target w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="Liquid-cooled Battery Cabinet 418kWh"
data-bg="https://nenghui.com/wp-content/uploads/2026/02/product-NB418L-scaled.jpg"></div>
</div>
<div class="p-5">
<div class="flex justify-between items-start mb-2">
<h3 class="text-3xl text-[#111318] dark:text-white group-hover:text-primary transition-colors">NB418L</h3>
<!-- <button class="text-gray-400 hover:text-primary transition-colors">
<span class="material-symbols-outlined">bookmark_border</span>
</button> -->
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">System Energy</p>
<p class=" dark:text-gray-200">418 kWh</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Cycle Life</p>
<p class=" dark:text-gray-200">8,000 times</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Thermal Management</p>
<p class=" dark:text-gray-200">Liquid cooling</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Ingress Rating</p>
<p class=" dark:text-gray-200">IP55/IP65</p>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghui all-in-one liquid-cooled ESS cabinet adopts advanced cabinet-level liquid cooling and temperature balancing strategy. The cell temperature difference is less than 3°C, which further improves the consistency of cell temperature and extends the battery life. The modular design makes the parallel solution more flexible and has a higher energy density, which significantly improves the economy, safety and construction convenience of ESS projects.
</p>
<a href="/products/ne418l/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
<!-- Card 2: Industrial High Capacity
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="100">
<div class="relative h-72 w-full bg-gradient-to-b from-[#787878] to-white dark:bg-[#111318] flex items-center justify-center p-6 group-hover:bg-primary/5 transition-colors duration-500">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-primary text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
90% Efficiency
</div>
<div class="w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="Large industrial battery cabinet array" style="background-image: url('https://nenghui.com/wp-content/uploads/2026/02/product-NE233L-scaled.jpg');"></div>
</div>
<div class="p-6">
<h3 class="text-xl font-display text-[#111318] dark:text-white mb-3 group-hover:text-primary transition-colors">NE233L</h3>
<div class="flex flex-wrap gap-2 mb-4">
<span class="inline-flex items-center px-2.5 py-1 rounded bg-blue-50 dark:bg-blue-900/30 text-xs font-medium text-blue-700 dark:text-blue-300 border border-blue-100 dark:border-blue-800">≤75dB</span>
<span class="inline-flex items-center px-2.5 py-1 rounded bg-blue-50 dark:bg-blue-900/30 text-xs font-medium text-blue-700 dark:text-blue-300 border border-blue-100 dark:border-blue-800"> Active liquid cooling</span>
</div>
<div class="space-y-3 mb-6 bg-gray-50 dark:bg-[#1f2937]/50 p-4 rounded-lg">
<div class="flex justify-between items-center border-b border-dashed border-gray-200 dark:border-gray-700 pb-2">
<span class="text-sm text-[#5f6e8c] dark:text-gray-400">Battery System</span>
<span class="text-sm font-mono dark:text-gray-200">232.96kWh/1P260S</span>
</div>
<div class="flex justify-between items-center border-b border-dashed border-gray-200 dark:border-gray-700 pb-2 pt-1">
<span class="text-sm text-[#5f6e8c] dark:text-gray-400">DoD</span>
<span class="text-sm font-mono dark:text-gray-200">95% (25±2℃)</span>
</div>
<div class="flex justify-between items-center pt-1">
<span class="text-sm text-[#5f6e8c] dark:text-gray-400">Cycle Life</span>
<span class="text-sm font-mono dark:text-gray-200">>8000 times</span>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghui all-in-one liquid-cooled ESS cabinet adopts advanced cabinet-level liquid cooling and temperature balancing strategy. The cell temperature difference is less than 3°C, which further improves the consistency of cell temperature and extends the battery life. The modular design makes the parallel solution more flexible and has a higher energy density, which significantly improves the economy, safety and construction convenience of ESS projects.
</p>
<a href="https://nenghui.com/products/ne233l/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>-->
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class=" skeleton-wrapper relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:from-[#333] dark:to-[#111318] flex items-center justify-center p-6 transition-all duration-500 group-hover:from-[#666666] group-hover:to-[#e6fcf5]">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-[#295ca8] text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
≥90% Efficiency
</div>
<div class="lazy-target w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="All-in-one Liquid-cooled ESS Cabinet 233kWh"
data-bg="https://nenghui.com/wp-content/uploads/2026/02/product-NE233L-scaled.jpg"></div>
</div>
<div class="p-5">
<div class="flex justify-between items-start mb-2">
<h3 class="text-3xl text-[#111318] dark:text-white group-hover:text-primary transition-colors">NE233L</h3>
<!-- <button class="text-gray-400 hover:text-primary transition-colors">
<span class="material-symbols-outlined">bookmark_border</span>
</button> -->
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">System Energy</p>
<p class=" dark:text-gray-200">233 kWh</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Cycle Life</p>
<p class=" dark:text-gray-200">8,000 times</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Thermal Management</p>
<p class=" dark:text-gray-200">Liquid cooling</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Ingress Rating</p>
<p class=" dark:text-gray-200">IP55/IP65</p>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghui all-in-one liquid-cooled ESS cabinet adopts advanced cabinet-level liquid cooling and temperature balancing strategy. The cell temperature difference is less than 3°C, which further improves the consistency of cell temperature and extends the battery life. The modular design makes the parallel solution more flexible and has a higher energy density, which significantly improves the economy, safety and construction convenience of ESS projects.
</p>
<a href="/products/ne233l/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
<!-- Card 3: Commercial Mid-Range
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="200">
<div class="relative h-56 w-full bg-gradient-to-b from-[#787878] to-white dark:bg-[#111318] flex items-center justify-center p-6 group-hover:bg-primary/5 transition-colors duration-500">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-primary text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
90% Efficiency
</div>
<div class="w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="Grey commercial battery cabinet" style="background-image: url('https://nenghui.com/wp-content/uploads/2026/01/261.jpg');"></div>
</div>
<div class="p-6">
<h3 class="text-xl font-display text-[#111318] dark:text-white mb-4 group-hover:text-primary transition-colors">NE261L</h3>
<div class="grid grid-cols-2 gap-y-2 gap-x-4 mb-5 text-sm">
<div class="border-l-2 border-primary/30 pl-3">
<p class="text-[#5f6e8c] dark:text-gray-500 text-xs">Battery System</p>
<p class=" dark:text-gray-200">261.25kWh/1P260S</p>
</div>
<div class="border-l-2 border-primary/30 pl-3">
<p class="text-[#5f6e8c] dark:text-gray-500 text-xs">Cycle Life</p>
<p class=" dark:text-gray-200">8.000 times</p>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghui all-in-one liquid-cooled ESS cabinet adopts advanced cabinet-level liquid cooling and temperature balancing strategy. The cell temperature difference is less than 3°C, which further improves the consistency of cell temperature and extends the battery life. The modular design makes the parallel solution more flexible and has a higher energy density, which significantly improves the economy, safety and construction convenience of ESS projects.
</p>
<a href="https://nenghui.com/products/ne261l/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
-->
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class=" skeleton-wrapper relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:from-[#333] dark:to-[#111318] flex items-center justify-center p-6 transition-all duration-500 group-hover:from-[#666666] group-hover:to-[#e6fcf5]">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-[#295ca8] text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
≥90% Efficiency
</div>
<div class="lazy-target w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500"
data-alt="All-in-one Liquid-cooled ESS Cabinet 261kWh"
data-bg="https://nenghui.com/wp-content/uploads/2026/02/product-NE261L-scaled.jpg"></div>
</div>
<div class="p-5">
<div class="flex justify-between items-start mb-2">
<h3 class="text-3xl text-[#111318] dark:text-white group-hover:text-primary transition-colors">NE261L</h3>
<!-- <button class="text-gray-400 hover:text-primary transition-colors">
<span class="material-symbols-outlined">bookmark_border</span>
</button> -->
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">System Energy</p>
<p class=" dark:text-gray-200">261.25kWh</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Cycle Life</p>
<p class=" dark:text-gray-200">8,000 times</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Thermal Management</p>
<p class=" dark:text-gray-200">Liquid cooling</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Ingress Rating</p>
<p class=" dark:text-gray-200">IP55/IP67</p>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghui all-in-one liquid-cooled ESS cabinet adopts advanced cabinet-level liquid cooling and temperature balancing strategy. The cell temperature difference is less than 3°C, which further improves the consistency of cell temperature and extends the battery life. The modular design makes the parallel solution more flexible and has a higher energy density, which significantly improves the economy, safety and construction convenience of ESS projects.
</p>
<a href="/products/ne261l/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
<!-- Card 4: Portable/Modular
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class="relative h-48 w-full bg-gradient-to-b from-[#787878] to-white dark:bg-[#111318] flex items-center justify-center p-6 group-hover:bg-primary/5 transition-colors duration-500">
<div class="w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="Small modular battery block" style="background-image: url('https://nenghui.com/wp-content/uploads/2026/01/upload_1768961014.jpg');"></div>
</div>
<div class="p-6">
<div class="flex items-center gap-2 mb-3">
<h3 class="text-xl font-display text-[#111318] dark:text-white group-hover:text-primary transition-colors">N20HC5000</h3>
<span class="bg-primary/10 text-primary text-[10px] px-2 py-0.5 rounded-full border border-primary/20 animate-pulse">NEW</span>
</div>
<div class="flex items-center gap-4 text-sm mb-4">
<div class="flex items-center gap-1 text-gray-600 dark:text-gray-400">
<span class="material-symbols-outlined text-[18px] text-primary">&#xe1a3;</span>
<span class="font-medium">5015.96kWh</span>
</div>
<div class="flex items-center gap-1 text-gray-600 dark:text-gray-400">
<span class="material-symbols-outlined text-[18px] text-primary">&#xe9b0;</span>
<span class="font-medium">≥93%@25±3℃, 0.5C</span>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghuis N20HC5000 factory-assembled DC battery storage container ships with 12 battery racks on the 5.015MWh 20ft container, power distribution cabinet, fire suppression system and advanced liquid-cooling system. And the module is made up of 1P104S LFP prismatic cells. Each cell undergoes strict quality inspections to ensure high energy density, wide operating temperature range, extended battery life, as well as the highest protection and safety features.
</p>
<a href="https://nenghui.com/products/n20hc5000/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
</button>
</a>
</a>
</div>
</div>-->
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class="skeleton-wrapper relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:from-[#333] dark:to-[#111318] flex items-center justify-center p-6 transition-all duration-500 group-hover:from-[#666666] group-hover:to-[#e6fcf5]">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-[#295ca8] text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
≥93% Efficiency
</div>
<div class="lazy-target w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500"
data-alt="Liquid-cooled ESS Container 5MWh"
data-bg="https://nenghui.com/wp-content/uploads/2026/02/product-N20HC5000-scaled.jpg"></div>
</div>
<div class="p-5">
<div class="flex justify-between items-start mb-2">
<h3 class="text-3xl text-[#111318] dark:text-white group-hover:text-primary transition-colors">N20HC5000</h3>
<!-- <button class="text-gray-400 hover:text-primary transition-colors">
<span class="material-symbols-outlined">bookmark_border</span>
</button> -->
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">System Energy</p>
<p class=" dark:text-gray-200">5 MWh</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Cycle Life</p>
<p class=" dark:text-gray-200">8,000 times</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Thermal Management</p>
<p class=" dark:text-gray-200">Liquid cooling</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider">Ingress Rating</p>
<p class=" dark:text-gray-200">IP55/IP67</p>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
Nenghuis N20HC5000 factory-assembled DC battery storage container ships with 12 battery racks on the 5.015MWh 20ft container, power distribution cabinet, fire suppression system and advanced liquid-cooling system. And the module is made up of 1P104S LFP prismatic cells. Each cell undergoes strict quality inspections to ensure high energy density, wide operating temperature range, extended battery life, as well as the highest protection and safety features.
</p>
<a href="/products/n20hc5000/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
<!-- Card 5: High Performance Residential -->
<div data-category="residential" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="100">
<div class="skeleton-wrapper relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:from-[#333] dark:to-[#111318] flex items-center justify-center p-6 transition-all duration-500 group-hover:from-[#666666] group-hover:to-[#e6fcf5]">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-[#295ca8] text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
≥95% Efficiency
</div>
<div class="lazy-target w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500"
data-alt="Max EV Charging Power: 180kW ESS: 261kWh"
data-bg="https://nenghui.com/wp-content/uploads/2026/03/NH-ICS180-261-2-1.jpg"></div>
</div>
<div class="p-5">
<div class="flex items-center gap-2 mb-3">
<h3 class="text-3xl text-[#111318] dark:text-white group-hover:text-primary transition-colors">NH-ICS180-261</h3>
<span class="bg-primary/10 text-primary text-[10px] px-2 py-0.5 rounded-full border border-primary/20 animate-pulse">NEW</span>
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded border-l-2 border-primary">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase">Max Charging Power</p>
<p class=" dark:text-gray-200">180 kW</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded border-l-2 border-primary">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase">Battery Energy</p>
<p class=" dark:text-gray-200">261.25 kWh</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded border-l-2 border-primary">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase">Grid Integration</p>
<p class=" dark:text-gray-200">Peak Shaving & Load Shifting</p>
</div>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded border-l-2 border-primary">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase">Reliability & Safety</p>
<p class=" dark:text-gray-200">IP55 / Pack-level Fire Suppression</p>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
<!-- Our premium solid-state solution offering higher energy density and improved safety profile in a slimmer form factor. -->
Nenghui ESS-Charger integrated charging and storage solution combines DC fast charging with a built-in 261 kWh battery. It enables peak shaving and load shifting to reduce grid impact and enhances operational flexibility. It delivers efficient and reliable fast charging (1*180kw or 2*90kw) while maintaining compatibility with multiple global charging standards. An intelligent operation platform supports OCPP integration, real-time load balancing, and remote monitoring, ensuring optimized asset utilization and seamless coordination with the overall power system.
</p>
<a href="/products/nh-ics180-261/">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
</button>
</a>
</div>
</div>
<!-- Card 6: Containerized Solution
<div data-category="industrial" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="200">
<div class="relative h-60 w-full bg-gradient-to-b from-[#787878] to-white dark:bg-[#111318] flex items-center justify-center p-6 group-hover:bg-primary/5 transition-colors duration-500">
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-primary text-xs px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
98.8% Efficiency
</div>
<div class="w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="Large containerized battery storage unit" style="background-image: url('https://lh3.googleusercontent.com/aida-public/AB6AXuAwajVWtqZGN-Iy3zMuc5cgi5QmTCusR3tJKi3-TUU3KyVWshtIWyQq9SAcyl649TG4HCD1B-6mu94RKdIOoEJ9yw7WPsRr55702m2_UCQ1dpxnzjo5M_Kpj_Agqpq64T2mHWJT9pH0fSKDp3He51zUqY5KKve-tPXY3qFPbbmr6sBfcQL52sgERLQbWsykn0TvizQqZ3_Xq0nrnbb6vIQG26Z6q7zJJYRvFqwaUdS1fGBn95-1WPVY_ry1j4J7wZWsI0mvcb7M2-g');"></div>
</div>
<div class="p-6">
<h3 class="text-xl font-display text-[#111318] dark:text-white mb-3 group-hover:text-primary transition-colors">MegaContainer 20ft</h3>
<div class="space-y-3 mb-6 bg-gray-50 dark:bg-[#1f2937]/50 p-4 rounded-lg">
<div class="flex justify-between items-center border-b border-dashed border-gray-200 dark:border-gray-700 pb-2">
<span class="text-sm text-[#5f6e8c] dark:text-gray-400">Total Capacity</span>
<span class="text-sm font-mono dark:text-gray-200">2.4 MWh</span>
</div>
<div class="flex justify-between items-center border-b border-dashed border-gray-200 dark:border-gray-700 pb-2 pt-1">
<span class="text-sm text-[#5f6e8c] dark:text-gray-400">Dimensions</span>
<span class="text-sm font-mono dark:text-gray-200">20' x 8' x 8.6'</span>
</div>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6">
Turnkey energy storage in a standard shipping container footprint. Pre-assembled and tested for rapid deployment.
</p>
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
</button>
</div>
</div>-->
</div>
<!-- Load More Section
<div class="flex justify-center pt-8 pb-16" data-aos="zoom-in" data-aos-offset="50">
<button class="relative group flex items-center justify-center px-8 py-3 rounded-full bg-primary/10 hover:bg-primary/20 dark:bg-primary/20 dark:hover:bg-primary/30 transition-all duration-300 active:scale-95">
<div class="absolute inset-0 rounded-full border border-primary opacity-20 animate-pulse group-hover:opacity-40"></div>
<span class="text-primary text-sm tracking-wide group-hover:scale-105 transition-transform">LOAD MORE PRODUCTS</span>
</button>
</div>-->
</main>
</div>
<script>
// --- Core Filtering Logic ---
function filterSelection(category, clickedBtn) {
// 1. Update Button Visuals
// 1. Update Button Visuals
updateButtonStyles(clickedBtn);
// 2. Scroll to Top Logic (新增核心代码)
const grid = document.getElementById('product-grid');
const stickyWrapper = document.getElementById('filter-sticky-wrapper');
// 计算偏移量:导航栏高度(64px) + 筛选栏当前高度 + 一点缓冲(20px)
// 这里的 64 对应 tailwind 的 h-16
const headerOffset = 64 + (stickyWrapper ? stickyWrapper.offsetHeight : 60);
const targetPosition = grid.getBoundingClientRect().top + window.scrollY - headerOffset - 20;
// 只有当用户当前滚动位置 大于 目标位置时(即在列表下方),才向上滚动
if (window.scrollY > targetPosition) {
window.scrollTo({
top: targetPosition,
behavior: 'smooth'
});
}
// 3. Filter Cards (保持原有逻辑,增加一点延时让滚动先开始,视觉更流畅)
let visibleCount = 0;
// 使用 setTimeout 稍微延后一点 DOM 操作,防止滚动时的掉帧
setTimeout(() => {
productCards.forEach(card => {
const cardCategory = card.getAttribute('data-category');
const isMatch = (category === 'all' || cardCategory === category);
if (isMatch) {
card.classList.remove('hidden');
// 强制重绘动画:移除 class 再添加
card.classList.remove('aos-animate');
setTimeout(() => card.classList.add('aos-animate'), 50); // 重新触发上浮动画
visibleCount++;
} else {
card.classList.add('hidden');
}
});
// 4. Update UI & AOS
updateItemCount(visibleCount);
// 这一点很重要:内容高度变了,必须刷新 AOS 定位
setTimeout(() => {
AOS.refresh();
}, 300); // 稍微长一点的延时,确保 CSS transition 完成
}, 100);
}
// Helper: Update Button Styles
function updateButtonStyles(activeBtn) {
filterBtns.forEach(btn => {
// Reset all to inactive
btn.className = btn.className.replace(activeClass, "").replace(inactiveClass, ""); // Clean up
btn.classList.add(...inactiveClass.split(" ")); // Add inactive base
// Reset badge styles
const badge = btn.querySelector('.count-badge');
if(badge) {
badge.className = "count-badge hidden"; // Hide badge on inactive
}
});
// Set active button
activeBtn.classList.remove(...inactiveClass.split(" "));
activeBtn.classList.add(...activeClass.split(" "));
// Show badge on active
const activeBadge = activeBtn.querySelector('.count-badge');
if(activeBadge) {
activeBadge.className = "count-badge flex items-center justify-center h-5 min-w-[20px] px-1.5 rounded-full bg-white/20 dark:bg-black/10 text-[10px] ml-auto";
}
}
// --- Configuration ---
const activeClass = "bg-[#111318] dark:bg-white text-white dark:text-[#111318] border-transparent shadow-lg shadow-gray-200 dark:shadow-none ring-2 ring-offset-2 ring-transparent";
const inactiveClass = "bg-white dark:bg-[#1f2937] text-[#5f6e8c] dark:text-gray-300 border-[#e5e7eb] dark:border-[#374151]";
// Select DOM elements
const filterBtns = document.querySelectorAll('.filter-btn');
const productCards = document.querySelectorAll('.product-card');
const searchInput = document.querySelector('input[type="text"]');
const itemCountDisplay = document.getElementById('item-count-display');
const loadMoreBtn = document.querySelector('.load-more-btn');
// Helper: Update Count Text
function updateItemCount(count) {
if(itemCountDisplay) {
itemCountDisplay.textContent = `Showing ${count} items`;
}
}
// --- Search Logic ---
if(searchInput) {
searchInput.addEventListener('keyup', (e) => {
const searchTerm = e.target.value.toLowerCase();
let visibleCount = 0;
// When searching, we reset the category filter visually to 'All' usually,
// but for simplicity, we search within the currently visible items or global.
// Here let's search globally.
productCards.forEach(card => {
const title = card.querySelector('h3').textContent.toLowerCase();
const specs = card.textContent.toLowerCase();
if (title.includes(searchTerm) || specs.includes(searchTerm)) {
card.classList.remove('hidden');
visibleCount++;
} else {
card.classList.add('hidden');
}
});
updateItemCount(visibleCount);
AOS.refresh();
});
}
// --- Load More Logic (Simulation) ---
// Note: Add class 'load-more-btn' to your "Load More" button in HTML
const loadBtn = document.querySelector('button.group'); // Selecting the load more button
if(loadBtn) {
// loadBtn.addEventListener('click', function() {
// const btnContent = this.innerHTML;
// // 1. Loading State
// this.innerHTML = `<span class="material-symbols-outlined animate-spin mr-2">progress_activity</span> Loading...`;
// this.disabled = true;
// // 2. Simulate Network Delay
// setTimeout(() => {
// // 3. Clone the first 2 visible cards to simulate new data
// const container = document.querySelector('.columns-1');
// const visibleCards = Array.from(productCards).filter(c => !c.classList.contains('hidden'));
// if(visibleCards.length > 0) {
// // Clone first two found
// for(let i=0; i < Math.min(2, visibleCards.length); i++) {
// const clone = visibleCards[i].cloneNode(true);
// // Update AOS delay for staggering
// clone.setAttribute('data-aos-delay', (i * 100).toString());
// container.appendChild(clone);
// }
// // Re-query cards so future filters work on new items
// // Note: In a real app you'd append to the 'productCards' NodeList or use an array
// // For this static demo, new items won't be filterable unless we re-query DOM.
// }
// // 4. Reset Button
// this.innerHTML = btnContent;
// this.disabled = false;
// // 5. Refresh Animations
// AOS.refresh();
// }, 1500);
// });
}
document.addEventListener('DOMContentLoaded', () => {
AOS.init({
duration: 800, // 动画持续时间
once: true, // 动画只触发一次,防止回滚时重复触发
offset: 100, // 触发偏移量
easing: 'ease-out-cubic', // 缓动函数
});
const stickyEl = document.getElementById('filter-sticky-wrapper');
const filterBg = document.getElementById('filter-bg');
// 1. 创建 Sentinel (哨兵元素)
const sentinel = document.createElement('div');
sentinel.setAttribute('id', 'sticky-sentinel');
// 把它插入到 sticky 元素的前面
stickyEl.parentNode.insertBefore(sentinel, stickyEl);
// 2. 配置 Observer
// rootMargin: -70px (对应 top-16 的 64px 加上一点缓冲)
// 意思是:当哨兵元素触碰到顶部以下 70px 的位置时触发
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
// 如果哨兵看不见了 (entry.isIntersecting === false),说明 sticky 元素已经吸顶
if (!entry.isIntersecting && entry.boundingClientRect.top < 0) {
// 吸顶状态样式
filterBg.classList.add('border-gray-200', 'dark:border-gray-800', 'shadow-sm');
filterBg.classList.remove('border-transparent');
} else {
// 非吸顶状态样式
filterBg.classList.remove('border-gray-200', 'dark:border-gray-800', 'shadow-sm');
filterBg.classList.add('border-transparent');
}
});
}, {
threshold: 0,
rootMargin: '-72px 0px 0px 0px' // 64px header + 8px buffer
});
observer.observe(sentinel);
updateButtonStyles(document.querySelector('[data-filter="all"]'));
updateItemCount(productCards.length);
})
</script>
</body>
</html>

@ -0,0 +1,774 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact & Global Grid - Nenghui</title>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<!-- AOS Animation Library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<!-- Tailwind & Config -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#13eca4",
"background-light": "#f8fcfa",
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
"about-us": "#ff6b00"
},
fontFamily: {
"display": ["Montserrat", "sans-serif"],
"sans": ["Montserrat", "sans-serif"],
"mono": ["JetBrains Mono", "Montserrat"],
"inter": ["Inter", "Montserrat"],
},
borderRadius: {
"DEFAULT": "0.5rem",
"lg": "1rem",
"xl": "1.5rem",
"2xl": "2rem",
"3xl": "3rem",
"full": "9999px"
},
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.1) 0%, rgba(13,166,112,0.05) 50%, rgba(248,252,250,0) 100%)',
'mesh': 'radial-gradient(at 40% 20%, rgba(19,236,164,0.08) 0px, transparent 50%), radial-gradient(at 80% 0%, rgba(16,34,28,0.05) 0px, transparent 50%), radial-gradient(at 0% 50%, rgba(19,236,164,0.05) 0px, transparent 50%)',
},
boxShadow: {
// 将光效统一映射为 primary 颜色 (13eca4 的 RGBA)
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
'glow-lg': '0 10px 30px rgba(19, 236, 164, 0.4)',
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02)',
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.15), 0 0 0 1px rgba(19,236,164,0.3)',
'bento-dark': '0 30px 60px -15px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
scan: {
'0%': { top: '-10%', opacity: '0' },
'10%': { opacity: '1' },
'90%': { opacity: '1' },
'100%': { top: '110%', opacity: '0' },
},
rotateGlobe: {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' },
},
dash: {
'0%': { strokeDashoffset: '1000' },
'100%': { strokeDashoffset: '0' },
},
globePulse: {
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
},
// 高级交互动画
pulseGlow: {
'0%': { textShadow: '0 0 10px rgba(19, 236, 164, 0.4)' },
'100%': { textShadow: '0 0 30px #ff6b00' }
},
sweep: { '100%': { left: '200%' } },
cardFlip: {
'0%': { opacity: '0', transform: 'rotateY(-90deg) translateZ(50px)' },
'100%': { opacity: '1', transform: 'rotateY(0deg) translateZ(0)' }
},
floatY: {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-15px)' }
},
textShimmer: {
'0%': { backgroundPosition: '0% 50%' },
'100%': { backgroundPosition: '100% 50%' },
},
blobSpin: {
'0%': { transform: 'rotate(0deg) scale(1)' },
'50%': { transform: 'rotate(180deg) scale(1.1)' },
'100%': { transform: 'rotate(360deg) scale(1)' },
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out forwards',
'scan-slow': 'scan 6s linear infinite',
'spin-slow': 'rotateGlobe 60s linear infinite',
'dash-flow': 'dash 3s linear infinite',
'globe-select': 'globePulse 0.8s ease-out',
'pulse-glow': 'pulseGlow 2s infinite alternate',
'sweep': 'sweep 3s infinite',
'flip-in': 'cardFlip 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards',
'float-1': 'floatY 3s ease-in-out infinite',
'float-2': 'floatY 3s ease-in-out infinite 1s',
'float-3': 'floatY 3s ease-in-out infinite 2s',
'text-shimmer': 'textShimmer 3s ease-out infinite alternate',
'blob-spin': 'blobSpin 20s infinite cubic-bezier(0.4, 0, 0.2, 1)',
}
},
},
}
</script>
<!-- Tailwind 基础样式注入 -->
<style type="text/tailwindcss">
@layer utilities {
/* contact us */
#contact-us .focus-group:hover > div:not(:hover) {
opacity: 0.6;
transform: scale(0.98);
filter: blur(2px);
}
#contact-us .focus-group > div {
transition: opacity 0.5s ease, transform 0.5s ease, filter 0.5s ease;
}
/* about-us */
/* 新增:专门为副标题定制的 3D 荧光挤压动画 */
.text-3d-subtitle {
color: #ff6b00; /* 保持主题色 */
animation: pulse3d 2s infinite alternate;
}
@keyframes pulse3d {
0% {
text-shadow:
/* 左上高光 */
-1px -1px 0px rgba(255, 255, 255, 0.5),
/* 右下厚度 (深翠绿色系) */
1px 1px 0px #ce6c33,
2px 2px 0px #b44914,
3px 3px 0px #75600a,
/* 基础投影 */
4px 4px 10px rgba(0, 0, 0, 0.6),
/* 较弱的呼吸背光 */
0px 0px 10px rgba(224, 114, 12, 0.3);
}
100% {
text-shadow:
-1px -1px 0px rgba(255, 255, 255, 0.7),
1px 1px 0px #cc7e19,
2px 2px 0px #e2d921,
3px 3px 0px #692a05,
5px 5px 15px rgba(0, 0, 0, 0.8),
/* 较强的呼吸背光,模拟能量溢出 */
0px 0px 30px #f2e930,
0px 0px 50px rgba(195, 159, 16, 0.6);
}
}
.text-3d {
text-shadow:
0 1px 0 #e2e8f0, /* 亮银色顶边 */
0 2px 0 #cbd5e1,
0 3px 0 #94a3b8,
0 4px 0 #64748b, /* 逐渐变暗模拟背光面 */
0 5px 0 #475569,
0 6px 0 #334155,
0 8px 10px rgba(0, 0, 0, 0.4), /* 近处接触阴影 */
0 15px 20px rgba(0, 0, 0, 0.3), /* 中距离扩散阴影 */
0 25px 40px rgba(0, 0, 0, 0.8); /* 远距离环境阴影 */
}
.text-3d-ultra {
color: #ffffff;
/* 1. 顶部左侧的亮色高光切割边 */
text-shadow:
-1px -1px 1px rgba(255, 255, 255, 0.3),
/* 2. 右下角 45度 斜向挤压厚度 (融入您的深墨绿环境色) */
1px 1px 0px #0d1e18,
2px 2px 0px #0a1813,
3px 3px 0px #08130e,
4px 4px 0px #060e0a,
5px 5px 0px #040906,
6px 6px 0px #020403,
7px 7px 0px #000000,
/* 3. 接触面的死黑投影 */
8px 8px 15px rgba(0, 0, 0, 0.8),
/* 4. 远距离大范围柔和投影 */
15px 15px 30px rgba(0, 0, 0, 0.6),
/* 5. 核心点睛之笔:在阴影反方向及底部映射出 #13eca4 (Primary) 的环境光晕 */
-5px -5px 30px rgba(19, 236, 164, 0.1),
10px 10px 40px rgba(19, 236, 164, 0.25);
}
/* Tab 状态管控:选中时变为 primary 背景与深色字体 */
#tech-landing-wrapper .tab-content { @apply hidden; }
#tech-landing-wrapper .tab-content.active { @apply grid; }
}
</style>
<style>
</style>
</head>
<body class="bg-[#fcfdfd] text-slate-800 font-sans overflow-x-hidden selection:bg-primary selection:text-white cursor-default">
<style>
.text-mask-bg {
background-image: url('https://nenghui.com/wp-content/uploads/2026/03/contact-us_emc4.avif');
background-size: cover; background-position: center; background-attachment: fixed;
-webkit-background-clip: text; color: transparent;
}
.acc-item { flex: 1; transition: flex 0.6s cubic-bezier(0.25, 1, 0.5, 1); }
.acc-item:hover { flex: 2.5; }
.acc-img { opacity: 0; transform: scale(1.1); transition: opacity 0.6s ease, transform 0.8s ease; mix-blend-mode: multiply; }
.acc-item:hover .acc-img { opacity: 0.45; transform: scale(1); }
.img-reveal { transition: transform 2s cubic-bezier(0.16, 1, 0.3, 1); }
.group:hover .img-reveal { transform: scale(1.05); }
::-webkit-scrollbar { display: none; }
/* 1. 呼吸环境光 (亮色版:使用纯白遮罩压暗背景图) */
.ambient-bg {
position: fixed; inset: 0; z-index: 0;
background-image: url('https://nenghui.com/wp-content/uploads/2026/03/contact-us_epc5.avif');
background-size: cover; background-position: center;
opacity: 0.35; filter: grayscale(30%) blur(10px);
animation: breathe 30s infinite alternate ease-in-out;
will-change: transform;
pointer-events: none;
}
.ambient-overlay {
position: fixed; inset: 0; z-index: 1;
background: linear-gradient(to bottom, rgba(252, 253, 253, 0.9), rgba(252, 253, 253, 0.98));
}
@keyframes breathe { 0% { transform: scale(1); } 100% { transform: scale(1.05); } }
/* 2. 生长连接线 (亮色版:加深颜色以增加对比度) */
.connector-wrap {
position: relative; width: 100%; height: 20vh;
display: flex; justify-content: center; z-index: 10;
}
.connector-line {
position: absolute; top: 0; width: 2px; height: 0%;
background: linear-gradient(to bottom, transparent, #0fa373 50%, #d95a00);
box-shadow: 0 5px 15px rgba(15, 163, 115, 0.2);
will-change: height;
}
.connector-dot {
position: absolute; bottom: 0; left: 50%; transform: translate(-50%, 50%);
width: 8px; height: 8px; border-radius: 50%;
background: #ff6b00;
box-shadow: 0 0 15px 4px rgba(255, 107, 0, 0.4);
opacity: 0; transition: opacity 0.2s;
}
/* 3. 擦除文字样式 (亮色版巨变!) */
.scrub-container { position: relative; z-index: 20; padding: 10vh 0 20vh 0; }
.scrub-block {
min-height: 50vh; display: flex; flex-direction: column; justify-content: center;
max-w-[1000px]; margin: 0 auto; padding: 0 5%;
}
/* 单词弹起特效:未激活状态 */
.scrub-word {
display: inline-block; margin-right: 0.25em; margin-bottom: 0.1em;
/* 浅色背景下,未读文字用非常淡的灰色 */
color: rgba(148, 163, 184, 0.25);
transition: color 0.4s ease, text-shadow 0.4s ease, transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
will-change: color, transform;
transform: translateY(8px) scale(0.98);
}
/* 单词弹起特效:已激活状态 (变为极黑/主题色,而不是发光) */
.scrub-word.highlighted {
color: #595959; /* slate-900 深黑 */
text-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); /* 淡淡的投影,让字显得有厚度 */
transform: translateY(0) scale(1);
}
/* 品牌色词汇高亮 (加深以对抗白底) */
.scrub-word.highlighted-primary { color: #108c60; text-shadow: 0 4px 15px rgba(16, 140, 96, 0.2); transform: translateY(0) scale(1); }
.scrub-word.highlighted-orange { color: #d95a00; text-shadow: 0 4px 15px rgba(217, 90, 0, 0.2); transform: translateY(0) scale(1); }
.scrub-word.highlighted-slate { color: #475569; text-shadow: 0 4px 10px rgba(0,0,0,0.05); transform: translateY(0) scale(1); }
/* 4. 手写签名区定制 */
/* @import url('https://fonts.googleapis.com/css2?family=Betania+Patmos+GDL:wght@400;700&family=Dancing+Script:wght@500;700&display=swap'); */
.handwriting-font { font-family: 'Liu Jian Mao Cao', cursive; }
.handwriting-font-word {
/* font-family: 'Sacramento', cursive; */
}
.signature-path {
stroke-dasharray: 1000; stroke-dashoffset: 1000;
transition: stroke-dashoffset 2s cubic-bezier(0.16, 1, 0.3, 1) 0.5s; /* 加0.5s延迟,等字亮完再画线 */
}
/* 当外层触发 AOS 动画时画线 */
.signature-reveal.aos-animate .signature-path { stroke-dashoffset: 0; }
/* 封面图极其缓慢的呼吸缩放 */
@keyframes breatheHero {
0% { transform: scale(1.05); }
100% { transform: scale(1.15); }
}
.animate-breathe-hero {
animation: breatheHero 20s infinite alternate ease-in-out;
will-change: transform;
}
/* 播放按钮的高级心跳波纹 */
@keyframes pingSlow {
0% { transform: scale(1); opacity: 0.8; }
100% { transform: scale(2); opacity: 0; }
}
.animate-ping-slow {
animation: pingSlow 3s cubic-bezier(0, 0, 0.2, 1) infinite;
}
</style>
<!-- 1. 首屏:全屏呼吸封面与视频触发区 -->
<!-- 1. 首屏:全屏呼吸封面与视频触发区 -->
<section class="h-[90vh] flex flex-col justify-center items-center relative z-20 px-6 overflow-hidden">
<!-- 视频封面背景 -->
<div class="absolute inset-0 z-0 overflow-hidden">
<div class="w-full h-full bg-[url('https://nenghui.com/wp-content/uploads/2026/03/contact-us_emc4.avif')] bg-cover bg-center animate-breathe-hero scale-105"></div>
<div class="absolute inset-0 bg-white/40 backdrop-blur-[2px]"></div>
</div>
<div class="relative z-10 text-center flex flex-col items-center" data-aos="zoom-in" data-aos-duration="1500">
<span class="text-primary font-mono tracking-widest uppercase text-sm mb-6 block drop-shadow-md">Our Story</span>
<h1 class="text-4xl md:text-[2.66rem] text-slate-900 tracking-tighter mb-10 drop-shadow-lg">
Engineered<br/><span class="text-primary italic">Harmony.</span>
</h1>
<!-- 播放按钮组 -->
<div class="relative group cursor-pointer mt-4" id="play-video-btn">
<!-- 脉冲波纹 -->
<div class="absolute inset-0 bg-primary/30 rounded-full animate-ping-slow scale-50"></div>
<div class="absolute inset-0 bg-[#ff6b00]/20 rounded-full animate-ping-slow scale-25" style="animation-delay: 1s;"></div>
<!-- 实体按钮 -->
<div class="relative w-24 h-24 md:w-20 md:h-20 bg-white rounded-full flex items-center justify-center shadow-[0_15px_35px_rgba(0,0,0,0.15)] group-hover:scale-110 transition-transform duration-500 border border-slate-100">
<span class="material-symbols-outlined text-4xl md:text-5xl text-primary translate-x-1 group-hover:text-[#ff6b00] transition-colors">&#xe037;</span>
</div>
</div>
<p class="text-sm text-slate-600 font-mono tracking-widest uppercase mt-8 ">Watch the Film</p>
</div>
</section>
<!-- 2. 全屏视频弹窗 (响应式等比例) -->
<div id="video-modal" class="fixed inset-0 z-[99999] bg-black/95 backdrop-blur-xl opacity-0 pointer-events-none transition-opacity duration-500 flex items-center justify-center">
<!-- 关闭按钮 (移出视频框,固定在屏幕右上角,防止被视频遮挡) -->
<button id="close-video-btn" class="absolute top-6 right-6 md:top-10 md:right-10 w-12 h-12 md:w-16 md:h-16 bg-white/10 hover:bg-primary rounded-full flex items-center justify-center text-white hover:text-black transition-all duration-300 z-50">
<span class="material-symbols-outlined text-2xl md:text-3xl">&#xe5cd;</span>
</button>
<!-- 视频容器: max-w 控制最大宽度, w-full 保证不溢出屏幕, aspect-video 强制 16:9 等比例缩放 -->
<div class="w-full max-w-[90vw] md:max-w-5xl lg:max-w-6xl px-4 md:px-0 relative transform scale-95 transition-transform duration-500 delay-100" id="video-container">
<div class="aspect-video bg-black rounded-xl md:rounded-2xl overflow-hidden shadow-2xl relative w-full flex items-center justify-center">
<!-- 真正的 HTML5 Video 标签 -->
<video
id="brand-video"
class="w-full h-full object-contain bg-black"
controls
playsinline
preload="none"
poster="https://nenghui.com/wp-content/uploads/2026/03/contact-us_epc5.avif">
<source src="https://nenghui.com/wp-content/uploads/2026/03/888-SH-NHET-001-final-2026030620.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
</div>
</div>
<!-- 固定背景与亮色遮罩 -->
<div class="ambient-bg"></div>
<!-- <div class="ambient-overlay"></div> -->
<!-- 核心文字排版区 -->
<div class="scrub-container relative container mx-auto">
<!-- 🚀 序言:总裁寄语 (修改为适配浅色背景) -->
<div class="scrub-block text-center w-full max-w-4xl" style="min-height: 80vh;">
<span class="text-[#108c60] font-mono tracking-widest text-sm mb-10 block uppercase ">Prologue</span>
<!-- <h2 class="text-3xl md:text-5xl lg:text-6xl font-display leading-tight tracking-tighter mb-16 data-scrub-target">
<span data-color="slate">Wings of Evolution:</span> Our Journey from Roots to the Future.
</h2> -->
<div class="space-y-6 text-xl md:text-2xl font-light italic leading-relaxed text-left mx-auto max-w-2xl text-slate-800 handwriting-font-word">
<p class="data-scrub-target"><span data-color="orange">Nenghui</span> is radiant as an eagle—always evolving</p>
<p class="data-scrub-target md:pl-8"><span data-color="primary">Nenghui</span> began with deep roots in the Electric power industry</p>
<p class="data-scrub-target"><span data-color="orange">Nenghui</span> excels at Engineering and design</p>
<p class="data-scrub-target md:pl-12"><span data-color="primary">Nenghui</span> is now focused on clean energy</p>
<p class="data-scrub-target">We strive to offer Efficient, worthy products and services</p>
<div class="pt-8">
<p class="data-scrub-target ">Nenghui stands by our partners,</p>
<p class="data-scrub-target md:pl-6">side by side,</p>
<p class="data-scrub-target md:pl-12">hand in hand,</p>
<p class="data-scrub-target md:pl-16"><span data-color="orange">heart to heart.</span></p>
</div>
</div>
<!-- 手写签名区 (适配浅色) -->
<div class="mt-20 flex flex-col items-center justify-center signature-reveal" data-aos="fade-up" data-aos-offset="100">
<p class="text-slate-400 font-mono text-sm tracking-widest uppercase mb-4">------------ Always side by side</p>
<div class="relative inline-block text-center">
<span data-no-translation class="handwriting-font text-5xl md:text-7xl text-slate-900 relative z-10 tracking-wide">
罗传奎
</span>
<!-- 画线变成更深的绿色以在白底上显现 -->
<svg class="absolute bottom-[-5px] left-[-10%] w-[120%] h-6 z-0 pointer-events-none" viewBox="0 0 200 20" preserveAspectRatio="none">
<path class="signature-path" d="M 5,15 Q 50,-5 195,15" fill="transparent" stroke="#108c60" stroke-width="2.5" stroke-linecap="round"/>
</svg>
</div>
<p class="text-slate-500 font-mono text-xs uppercase tracking-widest mt-6 ">Chairman of the Board</p>
</div>
</div>
<div class="connector-wrap"><div class="connector-line"><div class="connector-dot"></div></div></div>
<!-- 区块 1: 使命 -->
<div class="scrub-block text-left md:pr-[15%]">
<span class="text-[#108c60] font-mono tracking-widest text-sm mb-8 block uppercase ">The Mission</span>
<h2 class="text-4xl md:text-[2.66rem] leading-[1.8] leading-tight tracking-tight data-scrub-target">
We exist to bridge the gap between todays energy needs and tomorrows green reality, delivering intelligent, reliable, and life-changing power solutions to the global community.
<!-- To democratize clean energy for global industries. We turn dormant commercial assets into powerful engines of sustainability, making the <span data-color="primary">zero-carbon transition</span> an effortless and highly profitable upgrade. -->
</h2>
</div>
<div class="connector-wrap"><div class="connector-line"><div class="connector-dot"></div></div></div>
<!-- 区块 2: 愿景 -->
<div class="scrub-block text-right md:pl-[15%]">
<span class="text-[#d95a00] font-mono tracking-widest text-sm mb-8 block uppercase ">The Vision</span>
<h2 class=" leading-[1.8] text-4xl md:text-[2.66rem] leading-tight tracking-tight data-scrub-target">
To power a world where sustainable energy flows without borders, enriching every life it touches.
</h2>
</div>
<div class="connector-wrap"><div class="connector-line"><div class="connector-dot"></div></div></div>
<!-- 区块 3: 价值观 1 -->
<div class="scrub-block text-left md:pr-[15%]">
<span class="text-slate-400 font-mono tracking-widest text-sm mb-8 block uppercase ">The Values</span>
<h2 class="leading-[1.8] text-4xl md:text-[2.66rem] leading-tight tracking-tight data-scrub-target">
Empathy in Innovation · Global Responsibility · Trust-Based Partnership · Stewardship of the Planet.
<!-- <span data-color="primary">Obsessive Rigor.</span> From blueprint to grid sync, our engineering is uncompromising, ensuring absolute safety and peak energy yield. -->
</h2>
</div>
</div>
<!-- 3. 价值观 (极简手风琴伸缩) -->
<section class="mt-10 py-20 bg-[#f4f7f6]">
<div class="container mx-auto px-6">
<h2 class="text-4xl md:text-[2.66rem] text-slate-900 mb-16 text-center" data-aos="fade-up">What Drives Us</h2>
<div class="flex flex-col md:flex-row h-auto md:h-[500px] gap-4" data-aos="fade-up" data-aos-delay="200">
<div class="acc-item relative rounded-[2rem] bg-white border border-slate-200 p-10 overflow-hidden group cursor-default shadow-sm hover:shadow-xl">
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/store01.jpg')] bg-cover bg-center acc-img pointer-events-none"></div>
<div class="relative z-10 flex flex-col h-full">
<span class="material-symbols-outlined text-4xl text-primary mb-6">&#xea3b;</span>
<h3 class="text-3xl text-slate-900 mb-4">A Vision for a Net-Zero World</h3>
<p class="text-slate-600 mt-auto leading-relaxed">We are driven by the urgency of decarbonization, delivering smarter, cleaner energy solutions to empower sustainable communities across the globe.</p>
</div>
</div>
<div class="acc-item relative rounded-[2rem] bg-white border border-slate-200 p-10 overflow-hidden group cursor-default shadow-sm hover:shadow-xl">
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/store02.jpg')] bg-cover bg-center acc-img pointer-events-none"></div>
<div class="relative z-10 flex flex-col h-full">
<span class="material-symbols-outlined text-4xl text-[#ff6b00] mb-6">&#xebcb;</span>
<h3 class="text-3xl text-slate-900 mb-4">Innovation Beyond Boundaries</h3>
<p class="text-slate-600 mt-auto leading-relaxed">From high-efficiency PV and energy storage to revolutionary heavy-truck swapping AGVs, we redefine whats possible in the modern energy landscape.</p>
</div>
</div>
<div class="acc-item relative rounded-[2rem] bg-white border border-slate-200 p-10 overflow-hidden group cursor-default shadow-sm hover:shadow-xl">
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/store03.png')] bg-cover bg-center acc-img pointer-events-none"></div>
<div class="relative z-10 flex flex-col h-full">
<span class="material-symbols-outlined text-4xl text-blue-500 mb-6">&#xf39b;</span>
<h3 class="text-3xl text-slate-900 mb-4">Excellence Through Partnership</h3>
<p class="text-slate-600 mt-auto leading-relaxed">With deep roots in EPC and technical services, we build bankable, long-term value for our partners from Europe to Southeast Asia and beyond.</p>
</div>
</div>
</div>
</div>
</section>
<!-- 4. 发展史 (悬浮图文视差) -->
<!-- 4. 发展史 (宽银幕视差版 - 长文案升级) -->
<section class="py-40 bg-[#fff] relative z-20 overflow-hidden">
<div class="container mx-auto px-6">
<div class="text-center mb-32" data-aos="fade-up">
<span class="text-slate-400 font-mono tracking-widest uppercase text-sm mb-4 block">The Journey</span>
<h2 class="text-4xl md:text-[2.66rem] text-slate-900">Milestones of Nenghui.</h2>
</div>
<div class="max-w-6xl mx-auto space-y-40">
<!-- 2009: The Genesis -->
<div class="flex flex-col md:flex-row items-center gap-16 group relative" data-aos="fade-up">
<div class="absolute -top-16 left-0 text-[10rem] md:text-[15rem] font-display font-black text-slate-900 opacity-5 pointer-events-none z-[11] transition-transform group-hover:-translate-y-4 duration-700">2009</div>
<div class="w-full md:w-5/12 text-left md:text-right relative z-10 pt-10">
<span class="text-primary font-mono text-2xl mb-2 block">2009</span>
<h4 class="text-3xl text-slate-900 mb-6">The Genesis of Innovation</h4>
<p class="text-sm text-slate-500 leading-[2] font-light">Founded by visionary alumni from Tsinghua University and Shanghai Jiao Tong University, Nenghui was established with a mission to redefine energy. This year marked our strategic pivot into the Renewable Energy sector, laying the foundation for a sustainable global future.</p>
</div>
<div class="w-full md:w-7/12 rounded-[2.5rem] overflow-hidden aspect-[4/3] relative shadow-xl z-10">
<!-- 象征起源/初升太阳的光伏图 -->
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/contact-us_emc4.avif')] bg-cover bg-center img-reveal"></div>
</div>
</div>
<!-- 2012: Accelerating -->
<div class="flex flex-col md:flex-row-reverse items-center gap-16 group relative" data-aos="fade-up">
<div class="absolute -top-16 right-0 text-[10rem] md:text-[15rem] font-display font-black text-slate-900 opacity-5 pointer-events-none z-[11] transition-transform group-hover:-translate-y-4 duration-700">2012</div>
<div class="w-full md:w-5/12 text-left relative z-10 pt-10">
<span class="text-[#ff6b00] font-mono text-2xl mb-2 block">2012</span>
<h4 class="text-3xl text-slate-900 mb-6">Accelerating the Transition</h4>
<p class="text-sm text-slate-500 leading-[2] font-light">This was a year of breakthroughs. By powering the National "Golden Sun" projects, Nenghui proved its technical prowess on the grandest stage. We transformed our corporate structure to empower our people through equity incentives and welcomed strategic partners to our board. This synergy triggered an unprecedented 500% growth rate, officially establishing Nenghui as a high-growth leader.</p>
</div>
<div class="w-full md:w-7/12 rounded-[2.5rem] overflow-hidden aspect-[4/3] relative shadow-xl z-10">
<!-- 象征高速增长/巨大工程阵列的图片 -->
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/store05.jpg')] bg-cover bg-center img-reveal"></div>
</div>
</div>
<!-- 2017: Empowering -->
<div class="flex flex-col md:flex-row items-center gap-16 group relative" data-aos="fade-up">
<div class="absolute -top-16 left-0 text-[10rem] md:text-[15rem] font-display font-black text-slate-900 opacity-5 pointer-events-none z-[11] transition-transform group-hover:-translate-y-4 duration-700">2017</div>
<div class="w-full md:w-5/12 text-left md:text-right relative z-10 pt-10">
<span class="text-primary font-mono text-2xl mb-2 block">2017</span>
<h4 class="text-3xl text-slate-900 mb-6">Empowering Through Intelligence</h4>
<p class="text-sm text-slate-500 leading-[2] font-light">This year, Nenghui redefined efficiency by introducing our Smart O&M Platform, bringing digital precision to renewable energy. Our commitment to high-quality assets saw our self-operated solar portfolio soar to 50MW, eventually crossing the landmark of 100 million kWh in total energy output. We aren't just building plants; we are powering a smarter world.</p>
</div>
<div class="w-full md:w-7/12 rounded-[2.5rem] overflow-hidden aspect-[4/3] relative shadow-xl z-10">
<!-- 象征智能调度/数据平台的工业控制中心或发光线路图 -->
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/store06.jpg')] bg-cover bg-center img-reveal"></div>
</div>
</div>
<!-- 2021: IPO & Energy Storage -->
<div class="flex flex-col md:flex-row-reverse items-center gap-16 group relative" data-aos="fade-up">
<div class="absolute -top-16 right-0 text-[10rem] md:text-[15rem] font-display font-black text-slate-900 opacity-5 pointer-events-none z-[11] transition-transform group-hover:-translate-y-4 duration-700">2021</div>
<div class="w-full md:w-5/12 text-left relative z-10 pt-10">
<span class="text-[#ff6b00] font-mono text-2xl mb-2 block">2021</span>
<h4 class="text-3xl text-slate-900 mb-6">A Landmark Year of Growth</h4>
<p class="text-sm text-slate-500 leading-[2] font-light">Nenghui reached a historic milestone with our IPO on the Shenzhen Stock Exchange(STOCK CODE:301046.SZ), fueling our global expansion. We expanded our technological frontier into Energy Storage, while solidifying a unique "Four-in-One" business model. This synergy of R&D, smart manufacturing, technical expertise, and strategic investment ensures our sustained leadership.</p>
</div>
<div class="w-full md:w-7/12 rounded-[2.5rem] overflow-hidden aspect-[4/3] relative shadow-xl z-10">
<!-- 象征金融/扩张/储能集装箱的高级感图片 -->
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/store07.jpg')] bg-cover bg-center img-reveal"></div>
</div>
</div>
<!-- 2022: Scaling New Horizons -->
<div class="flex flex-col md:flex-row items-center gap-16 group relative" data-aos="fade-up">
<div class="absolute -top-16 left-0 text-[10rem] md:text-[15rem] font-display font-black text-slate-900 opacity-5 pointer-events-none z-[11] transition-transform group-hover:-translate-y-4 duration-700">2022</div>
<div class="w-full md:w-5/12 text-left md:text-right relative z-10 pt-10">
<span class="text-primary font-mono text-2xl mb-2 block">2022</span>
<h4 class="text-3xl text-slate-900 mb-6">Scaling New Horizons</h4>
<p class="text-sm text-slate-500 leading-[2] leading-relaxed font-light">Nenghui Tech accelerated its mission on two fronts. Our Residential and C&I Solar business reached new heights, supported by our innovative PV Cloud Platform. Simultaneously, we entered the "Fast Lane" of green transportation by releasing the First-of-its-kind Trackless Battery Swapping AGV. These achievements solidified our reputation as a pioneer in integrated energy solutions.</p>
</div>
<div class="w-full md:w-7/12 rounded-[2.5rem] overflow-hidden aspect-[4/3] relative shadow-xl z-10">
<!-- 象征创新/自动化制造/云平台的未来感图片 -->
<div class="absolute inset-0 bg-[url('https://nenghui.com/wp-content/uploads/2026/03/store08.jpg')] bg-cover bg-center img-reveal"></div>
</div>
</div>
</div>
</div>
</section>
<!-- AOS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
/* ==========================================
========================================== */
const playBtn = document.getElementById('play-video-btn');
const closeBtn = document.getElementById('close-video-btn');
const videoModal = document.getElementById('video-modal');
const videoContainer = document.getElementById('video-container');
const brandVideo = document.getElementById('brand-video'); // 获取原生的 video 元素
if (playBtn && closeBtn && videoModal) {
// 打开弹窗
playBtn.addEventListener('click', () => {
videoModal.classList.remove('opacity-0', 'pointer-events-none');
videoModal.classList.add('opacity-100', 'pointer-events-auto');
// 容器放大特效
setTimeout(() => {
videoContainer.classList.remove('scale-95');
videoContainer.classList.add('scale-100');
}, 50);
// 弹窗打开后,稍微延迟一下触发自动播放,体验更佳
if(brandVideo) {
setTimeout(() => {
brandVideo.play();
}, 400);
}
});
//
const closeModal = () => {
videoModal.classList.remove('opacity-100', 'pointer-events-auto');
videoModal.classList.add('opacity-0', 'pointer-events-none');
videoContainer.classList.remove('scale-100');
videoContainer.classList.add('scale-95');
if(brandVideo) {
// 1. 暂停视频
brandVideo.pause();
// 2. 将视频进度归零(下次打开又从头看)
brandVideo.currentTime = 0;
}
};
closeBtn.addEventListener('click', closeModal);
// (不点到视频本身)
videoModal.addEventListener('click', (e) => {
if(e.target === videoModal || e.target === videoContainer) closeModal();
});
//
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && videoModal.classList.contains('opacity-100')) {
closeModal();
}
});
}
if(typeof AOS !== 'undefined') AOS.init({ duration: 1000, once: true });
// 1. 文字切分逻辑
const targets = document.querySelectorAll('.data-scrub-target');
let allWords = [];
targets.forEach(target => {
const childNodes = Array.from(target.childNodes);
target.innerHTML = '';
childNodes.forEach(node => {
if (node.nodeType === Node.TEXT_NODE) {
const words = node.textContent.split(/\s+/).filter(w => w.trim().length > 0);
words.forEach(word => {
const span = document.createElement('span');
span.className = 'scrub-word';
span.textContent = word + ' ';
target.appendChild(span);
allWords.push(span);
});
} else if (node.nodeType === Node.ELEMENT_NODE) {
const specificColor = node.getAttribute('data-color');
const words = node.textContent.split(/\s+/).filter(w => w.trim().length > 0);
words.forEach(word => {
const span = document.createElement('span');
span.className = 'scrub-word';
if(specificColor === 'primary') span.dataset.highlightClass = 'highlighted-primary';
else if(specificColor === 'orange') span.dataset.highlightClass = 'highlighted-orange';
else if(specificColor === 'slate') span.dataset.highlightClass = 'highlighted'; // 默认变成深灰
span.textContent = word + ' ';
target.appendChild(span);
allWords.push(span);
});
}
});
});
// 获取元素
const connectors = document.querySelectorAll('.connector-wrap');
// 将触发线定义在屏幕高度的 45% (视线聚焦处)
const textTriggerLineY = window.innerHeight * 0.75;
// 2. 统一滚动引擎
const handleScroll = () => {
const windowHeight = window.innerHeight;
// 【A】处理文字的点亮与弹起
allWords.forEach(word => {
const wordRect = word.getBoundingClientRect();
const wordCenterY = wordRect.top + (wordRect.height / 2);
if (wordCenterY < textTriggerLineY) {
const highlightClass = word.dataset.highlightClass || 'highlighted';
word.classList.add(highlightClass);
} else {
const highlightClass = word.dataset.highlightClass || 'highlighted';
word.classList.remove(highlightClass);
}
});
// 【B】处理区块间短线的物理生长
connectors.forEach(wrap => {
const rect = wrap.getBoundingClientRect();
const line = wrap.querySelector('.connector-line');
const dot = wrap.querySelector('.connector-dot');
// 线条提前开始生长 (屏幕 65% 位置),在屏幕 40% 位置生长满
const startTrigger = windowHeight * 0.65;
const endTrigger = windowHeight * 0.40;
let progress = 0;
if (rect.top < endTrigger) {
progress = 1;
}
else if (rect.top <= startTrigger ) {
if ( rect.bottom >= endTrigger) {
progress = (startTrigger - rect.top) / (startTrigger - endTrigger);
}
}
progress = Math.max(0, Math.min(1, progress));
line.style.height = `${progress * 100}%`;
// 控制底部发光圆点的显示/隐藏
if (progress > 0.05) {
dot.style.opacity = '1';
} else {
dot.style.opacity = '0';
}
});
};
let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
window.requestAnimationFrame(() => {
handleScroll();
ticking = false;
});
ticking = true;
}
}, { passive: true });
handleScroll(); //
});
</script>
</body>
</html>

@ -0,0 +1,106 @@
<?php
/**
* The template for displaying 404 pages (Not Found)
* Theme: NENGHUI Energy - Borderless Digital Space & 3D Typography
*/
// 强制修改标题
add_filter('pre_get_document_title', function() { return '404'; }, 9999);
add_filter('wp_title', function() { return '404'; }, 9999);
get_header(); ?>
<style>
:root {
--nh-primary: #13eca4;
--nh-dark: #121010;
--nh-bg-light: #f8fcfa;
}
/* 确保主背景通透大气 */
.nh-404-canvas {
min-height: 100vh;
background: #f8fcfa; /* 使用你定义的背景底色 */
background: linear-gradient(135deg, #f8fcfa 0%, #f0f7f5 50%, #dcfce7 60%);
font-family: 'Inter', sans-serif;
color: var(--nh-dark);
position: relative;
overflow: hidden;
}
.font-display { font-family: 'Space Grotesk', sans-serif; }
/* * 核心视觉3D 立体悬浮数字 404
* 利用多层 text-shadow 营造绿色霓虹的厚度感
*/
.text-3d-glow {
color: white; /* 亮色前景 */
/* 1层核心亮绿霓虹 */
text-shadow: 0 1px 0 #b3f3db,
0 2px 0 #83f0ca,
0 3px 0 #54eeb8,
0 4px 0 #13eca4, /* 主色层 */
/* 2层向下的柔和深色投影 */
0 6px 1px rgba(0,0,0,0.1),
0 0 5px rgba(0,0,0,0.1),
/* 3层绿色氛围发光 (Neon Glow) */
0 1px 15px rgba(19, 236, 164, 0.4),
0 3px 25px rgba(19, 236, 164, 0.2);
}
/* 微动效 */
@keyframes float-soft {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.floating-text {
animation: float-soft 5s ease-in-out infinite;
}
</style>
<main class="nh-404-canvas relative flex items-center justify-center p-8 overflow-hidden">
<div class="fixed inset-0 pointer-events-none z-0">
<div class="absolute -top-[10%] -left-[10%] w-[50%] h-[50%] bg-primary/5 rounded-full blur-[150px] animate-blob-spin"></div>
<div class="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-teal-200/20 rounded-full blur-[120px]"></div>
</div>
<div class="relative z-10 w-full max-w-4xl text-center" data-aos="fade-up" data-aos-duration="1200">
<div class="flex flex-col items-center mb-24">
<h1 class="text-3d-glow font-display text-[150px] md:text-[200px] font-black tracking-tighter leading-none floating-text">
404
</h1>
</div>
<div class="space-y-6 mb-24 flex flex-col items-center">
<h2 class="font-display text-3xl text-background-dark tracking-tight leading-tight max-w-lg">
Oops! That page can't be found.
</h2>
<p>You might have typed in the wrong address or the page has moved.</p>
</div>
<div class="flex flex-col sm:flex-row items-center justify-center gap-8 mt-12 w-full sm:w-auto">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>"
class="w-full sm:w-auto px-16 h-16 bg-primary text-background-dark font-bold rounded-full flex items-center justify-center shadow-lg shadow-primary/20 hover:shadow-primary/40 hover:scale-105 transition-all duration-300 text-xs uppercase tracking-[0.2em]">
Go Homepage
</a>
<a href="<?php echo esc_url( home_url( '/contact-us/' ) ); ?>"
class="w-full sm:w-auto px-16 h-16 bg-white/60 backdrop-blur-md border border-primary/10 text-background-dark font-bold rounded-full flex items-center justify-center hover:bg-white transition-all duration-300 text-xs uppercase tracking-[0.2em]">
Contact Us
</a>
</div>
</div>
</main>
<script>
// 最终保险JS 强制修改标题
document.title = "Shanghai Nenghui Energy: Innovative ESS Solutions";
</script>
<?php get_footer(); ?>

@ -0,0 +1,611 @@
# Nenghui Energy Theme - 短代码使用文档
本文档提供了 Nenghui Energy 主题中所有可用短代码的详细说明和使用示例。
## 目录
1. [产品相关短代码](#产品相关短代码)
2. [新闻相关短代码](#新闻相关短代码)
3. [关于页面短代码](#关于页面短代码)
4. [联系页面短代码](#联系页面短代码)
5. [通用组件短代码](#通用组件短代码)
6. [EPC相关短代码](#epc相关短代码)
---
## 产品相关短代码
### `nenghui_products_list` - 产品列表
显示产品列表,支持分类筛选和分页。
**基本用法:**
```php
[nenghui_products_list]
```
**完整参数:**
```php
[nenghui_products_list
per_page="6"
category="residential"
order="date"
orderby="DESC"
category_order=""]
```
**参数说明:**
- `per_page` - 每页显示的产品数量默认6
- `category` - 筛选特定分类(留空显示所有)
- `order` - 排序方式默认date
- `orderby` - 排序字段默认DESC
- `category_order` - 自定义分类排序
**产品自定义字段:**
- `cate_type` - 产品分类(必需)
- `cate_type_value` - 分类显示名称
- `efficiency` - 效率值≥93% Efficiency
- `is_new` - 是否为新产品true/false
- `attr_key` - 属性名称(逗号分隔)
- `attr_value` - 属性值(逗号分隔)
- `_product_banner_url` - 产品横幅图片URL
- `_usage_scenario_data` - 使用场景数据包含bottom_text
**示例:**
```php
// 显示所有产品每页9个
[nenghui_products_list per_page="9"]
// 只显示residential分类的产品
[nenghui_products_list category="residential"]
// 自定义排序
[nenghui_products_list order="title" orderby="ASC"]
```
---
### `nenghui_products_banner` - 产品横幅
显示产品页面横幅。
**基本用法:**
```php
[nenghui_products_banner]
```
或简化版本:
```php
[products_banner]
```
---
### `nenghui_warehousing_distribution` - 仓储配送
显示仓储配送信息。
**基本用法:**
```php
[nenghui_warehousing_distribution]
```
或简化版本:
```php
[warehousing_distribution]
```
---
## 新闻相关短代码
### `nenghui_news` - 新闻列表
显示新闻文章列表。
**基本用法:**
```php
[nenghui_news]
```
**完整参数:**
```php
[nenghui_news
title="最新资讯"
category_id="1"
posts_count="6"
order_by="date"
order="DESC"]
```
**参数说明:**
- `title` - 模块标题
- `category_id` - 分类ID
- `posts_count` - 显示文章数量
- `order_by` - 排序字段
- `order` - 排序方向
---
### `nenghui_news_grid` - 新闻网格
以网格布局显示新闻。
**基本用法:**
```php
[nenghui_news_grid]
```
---
## 关于页面短代码
### `nenghui_about_nav` - 关于导航
显示关于页面的导航菜单。
**基本用法:**
```php
[nenghui_about_nav]
```
**自定义参数:**
```php
[nenghui_about_nav menu_id="123"]
```
**参数说明:**
- `menu_id` - 指定菜单ID留空使用自定义器设置的默认菜单
---
### `nenghui_about_company` - 关于公司
显示公司介绍信息。
**基本用法:**
```php
[nenghui_about_company]
```
**自定义参数:**
```php
[nenghui_about_company show_animation="true"]
```
**参数说明:**
- `show_animation` - 是否显示动画效果
---
### `nenghui_development_history` - 发展历程
显示公司发展历程时间线。
**基本用法:**
```php
[nenghui_development_history]
```
**自定义参数:**
```php
[nenghui_development_history show_animation="true"]
```
---
### `nenghui_certification_gallery` - 认证画廊
显示公司认证证书画廊。
**基本用法:**
```php
[nenghui_certification_gallery]
```
**自定义参数:**
```php
[nenghui_certification_gallery
columns="5"
lightbox="true"
animation="true"]
```
**参数说明:**
- `columns` - 每行显示列数1-6
- `lightbox` - 是否启用灯箱效果
- `animation` - 是否启用动画效果
---
### `nenghui_technical_service` - 技术服务
显示技术服务信息。
**基本用法:**
```php
[nenghui_technical_service]
```
**自定义参数:**
```php
[nenghui_technical_service
title="可靠的技术服务"
subtitle="提升客户体验"]
```
---
### `black_about_company_banner` - 关于公司横幅
显示关于页面的横幅。
**基本用法:**
```php
[black_about_company_banner]
```
---
### `nenghui_black_about_info` - 关于信息
显示公司详细信息。
**基本用法:**
```php
[nenghui_black_about_info]
```
或简化版本:
```php
[black_about_info]
```
---
### `business_process` - 业务流程
显示业务流程图。
**基本用法:**
```php
[business_process]
```
---
## 联系页面短代码
### `nenghui_contact_form` - 联系表单
显示联系表单。
**基本用法:**
```php
[nenghui_contact_form]
```
**自定义参数:**
```php
[nenghui_contact_form form_id="1" show_animation="true"]
```
**参数说明:**
- `form_id` - 表单ID
- `show_animation` - 是否显示动画效果
---
### `nenghui_contact_map` - 联系地图
显示联系地图。
**基本用法:**
```php
[nenghui_contact_map]
```
---
### `nenghui_overseas_services` - 海外服务
显示海外服务信息。
**基本用法:**
```php
[nenghui_overseas_services]
```
---
## 通用组件短代码
### `nenghui_banner` - 轮播横幅
显示轮播横幅。
**基本用法:**
```php
[nenghui_banner]
```
**自定义参数:**
```php
[nenghui_banner autoplay="true"]
```
**参数说明:**
- `autoplay` - 是否自动播放
---
### `nenghui_futures` - 未来展望
显示未来展望内容。
**基本用法:**
```php
[nenghui_futures]
```
**自定义参数:**
```php
[nenghui_futures title="未来展望" show_animation="true"]
```
---
### `nenghui_tabs` - 选项卡
显示选项卡内容。
**基本用法:**
```php
[nenghui_tabs]
```
**自定义参数:**
```php
[nenghui_tabs tabs_count="3" show_animation="true"]
```
---
### `nenghui_flowchart_tabs` - 流程图选项卡
显示流程图选项卡。
**基本用法:**
```php
[nenghui_flowchart_tabs]
```
---
### `nenghui_banner_title` - 标题横幅
显示带标题的横幅。
**基本用法:**
```php
[nenghui_banner_title title="关于我们" description="我们致力于提供最优质的服务"]
```
**完整参数:**
```php
[nenghui_banner_title
title="关于我们"
description="我们致力于提供最优质的服务"
bg_image="https://example.com/image.jpg"
height="70vh"
overlay_opacity="0.6"
show_animation="true"]
```
**参数说明:**
- `title` - 标题
- `description` - 描述
- `bg_image` - 背景图片URL
- `height` - 高度支持px、vh、%
- `overlay_opacity` - 遮罩透明度0-1
- `show_animation` - 是否显示动画
---
### `black_maps` - 黑色地图
显示交互式地图。
**基本用法:**
```php
[black_maps]
```
**自定义参数:**
```php
[black_maps height="100vh" show_loading="true"]
```
**参数说明:**
- `height` - 地图高度
- `show_loading` - 是否显示加载动画
---
### `nenghui_video` - 视频
显示视频播放器。
**基本用法:**
```php
[nenghui_video video_url="https://example.com/video.mp4"]
```
**完整参数:**
```php
[nenghui_video
video_url="https://example.com/video.mp4"
cover_image="https://example.com/cover.jpg"
title="我们的企业视频"
description="了解我们的产品和服务"
play_button_text="立即播放"
show_overlay="true"
overlay_opacity="0.5"
height="80vh"
autoplay="false"
muted="true"
controls="true"]
```
**参数说明:**
- `video_url` - 视频URL必需
- `cover_image` - 封面图片URL
- `title` - 视频标题
- `description` - 视频描述
- `play_button_text` - 播放按钮文字
- `show_overlay` - 是否显示遮罩
- `overlay_opacity` - 遮罩透明度
- `height` - 视频高度
- `autoplay` - 是否自动播放
- `muted` - 是否静音
- `controls` - 是否显示控制栏
---
### `nenghui_download_center` - 下载中心
显示下载中心。
**基本用法:**
```php
[nenghui_download_center]
```
---
### `nenghui_faq` - 常见问题
显示常见问题列表。
**基本用法:**
```php
[nenghui_faq]
```
---
### `nenghui_cases` - 案例展示
显示案例展示。
**基本用法:**
```php
[nenghui_cases]
```
---
## EPC相关短代码
### `nenghui_epc` - EPC解决方案
显示EPC解决方案。
**基本用法:**
```php
[nenghui_epc]
```
**自定义参数:**
```php
[nenghui_epc
title="EPC Solutions"
subtitle="Beyond Hardware: Total EPC Solutions from NengHui Design Institute"
bg_image="https://example.com/epc-bg.jpg"]
```
---
### `nenghui_epc_banner` - EPC横幅
显示EPC横幅。
**基本用法:**
```php
[nenghui_epc_banner]
```
---
## 使用技巧
### 1. 在页面编辑器中使用
在WordPress页面编辑器中直接输入短代码即可
```
[nenghui_products_list per_page="9"]
```
### 2. 在模板文件中使用
在主题模板文件中使用 `do_shortcode()` 函数:
```php
<?php echo do_shortcode('[nenghui_products_list per_page="9"]'); ?>
```
### 3. 组合使用多个短代码
可以在同一个页面中使用多个短代码:
```
[nenghui_banner_title title="我们的产品"]
[nenghui_products_list per_page="9"]
[nenghui_contact_form]
```
### 4. 响应式设计
所有短代码都支持响应式设计,会自动适应不同屏幕尺寸。
### 5. 深色模式
所有短代码都支持深色模式,会自动根据系统设置切换主题。
## 常见问题
### Q: 短代码不显示怎么办?
A: 请确保:
1. 短代码名称拼写正确
2. 主题已正确激活
3. 没有PHP错误检查调试日志
### Q: 如何自定义短代码样式?
A: 可以通过以下方式自定义:
1. 在自定义器中修改相关设置
2. 使用CSS覆盖默认样式
3. 修改对应的模板文件
### Q: 短代码参数不生效怎么办?
A: 请确保:
1. 参数名称拼写正确
2. 参数值格式正确
3. 没有特殊字符冲突
### Q: 如何添加新的短代码?
A: 可以在 `inc/shortcode.php` 文件中添加新的短代码函数,参考现有短代码的实现方式。
## 技术支持
如需技术支持,请联系开发团队或查看主题文档。
---
**文档版本:** 1.0
**最后更新:** 2026-02-09
**主题版本:** nenghui-energy-theme-4

@ -2,7 +2,7 @@
/* feature-module 模块 */
.feature-module {
width: 100%;
max-width: 1300px;
max-width: 1320px;
margin: 40px auto;
overflow: hidden;
background-color: #fff;

@ -4,7 +4,7 @@
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "calibri","PingFang SC", Arial, sans-serif;
/* font-family: "calibri","PingFang SC", Arial, sans-serif; */
}
/* 链接样式 */
@ -213,7 +213,7 @@ img {
}
}
/*
/*
* Banner
*/
@ -250,7 +250,7 @@ img {
.banner-title {
font-size: 3rem;
font-weight: bold;
margin-bottom: 1rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
@ -289,22 +289,22 @@ img {
.nenghui-banner {
height: 400px;
}
.banner-title {
font-size: 2rem;
}
.banner-description {
font-size: 1rem;
}
.banner-btn {
padding: 10px 25px;
font-size: 1rem;
}
}
/*
/*
* Futures
*/
@ -416,7 +416,7 @@ img {
animation-name: fadeInUp;
}
/*
/*
* News
*/
.news-container {
@ -434,8 +434,7 @@ img {
}
.news-title {
font-size: 48px;
font-weight: bold;
font-size: 42px;
color: #333;
letter-spacing: 2px;
}
@ -564,9 +563,9 @@ img {
}
}
/*
* Tabs
/*
* Tabs
*/
.nenghui-container {
max-width: 80%;
@ -721,7 +720,7 @@ img {
padding: 40px 15px;
border-radius: 20px;
}
.main-content {
gap: 40px;
padding: 40px;
@ -733,7 +732,7 @@ img {
padding: 30px 15px;
border-radius: 15px;
}
.main-content {
flex-direction: column;
padding: 30px 20px;
@ -756,7 +755,7 @@ img {
font-size: 13px;
padding: 10px 18px;
}
.tab-image {
height: 250px;
}
@ -766,49 +765,51 @@ img {
.nenghui-container {
padding: 20px 10px;
}
.main-content {
padding: 20px 15px;
}
.main-title {
font-size: 28px;
}
.nenghui-tab {
font-size: 12px;
padding: 8px 16px;
}
.learn-more-btn {
padding: 12px 24px;
font-size: 14px;
}
.tab-image {
height: 200px;
}
}
/*
/*
* Footer
*/
.main-footer {
background-color: #fff !important;
padding: 60px 0 30px;
border-top: 1px solid #e9ecef;
position: relative;
z-index: 1;
}
.footer-container {
max-width: 1300px;
max-width: 1320px;
margin: 0 auto;
padding: 0 20px;
}
.footer-main {
display: grid;
grid-template-columns: 1fr 3fr 1fr;
gap: 0;
grid-template-columns: 1fr auto;
gap: 10px;
margin-bottom: 40px;
}
@ -834,6 +835,65 @@ img {
display: flex;
gap: 15px;
}
/* 社交图标基础样式 (适配浅色背景) */
.social-btn {
position: relative;
width: 42px;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
/* 默认状态:深色图标,浅色背景 */
background: #ffffff; /* 纯白背景 */
border: 1px solid rgba(13, 27, 23, 0.1); /* 极淡的深色边框 */
color: #0d1b17; /* 深绿色/黑色图标,确保可见性 */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); /* 轻微阴影增加层次感 */
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
overflow: hidden;
}
/* --- 悬停通用效果 --- */
.social-btn:hover {
transform: translateY(-4px); /* 上浮 */
color: #ffffff; /* 图标反白 */
border-color: transparent;
}
/* --- 品牌色定义 (悬停时触发) --- */
/* LinkedIn Blue */
.social-btn.linkedin:hover {
background: #0077b5;
box-shadow: 0 10px 20px -5px rgba(0, 119, 181, 0.4);
}
/* Facebook Blue */
.social-btn.facebook:hover {
background: #1877f2;
box-shadow: 0 10px 20px -5px rgba(24, 119, 242, 0.4);
}
/* X (Twitter) Black */
.social-btn.twitter:hover {
background: #000000;
box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.3);
}
/* YouTube Red */
.social-btn.youtube:hover {
background: #ff0000;
box-shadow: 0 10px 20px -5px rgba(255, 0, 0, 0.4);
}
/* --- 点击反馈 --- */
.social-btn:active {
transform: translateY(-1px);
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.social-link {
display: flex;
@ -879,7 +939,6 @@ img {
.footer-nav-title {
font-size: 16px;
font-weight: 600;
color: #333;
margin: 0 0 20px 0;
text-transform: uppercase;
@ -1003,12 +1062,12 @@ img {
gap: 40px;
text-align: center;
}
.footer-nav {
grid-template-columns: repeat(2, 1fr);
gap: 40px;
}
.footer-subscribe {
align-items: center;
}
@ -1019,16 +1078,16 @@ img {
padding: 40px 0 20px;
margin-top: 60px;
}
.article-content {
width: 90%;
padding: 20px 10px;
}
.footer-container {
padding: 0 15px;
}
.footer-main {
gap: 30px;
}
@ -1036,22 +1095,22 @@ img {
.footer-logo {
justify-content: center;
}
.footer-nav {
grid-template-columns: 1fr;
gap: 30px;
}
.footer-bottom {
flex-direction: column;
text-align: center;
gap: 15px;
}
.footer-links {
gap: 20px;
}
.subscribe-form {
max-width: 100%;
}
@ -1061,22 +1120,22 @@ img {
.footer-links {
gap: 10px;
}
.footer-social {
justify-content: center;
}
.subscribe-form {
flex-direction: column;
gap: 10px;
}
.subscribe-input {
border-radius: 4px;
border-right: 1px solid #dee2e6;
}
.subscribe-btn {
border-radius: 4px;
}
}
}

File diff suppressed because one or more lines are too long

@ -1,6 +1,120 @@
// 这是自定义JS文件用于覆盖主题默认JS文件
/**
* AdvancedImageLoader
* 通用图片加载管理器支持懒加载预加载骨架屏控制
*/
class AdvancedImageLoader {
constructor(options = {}) {
this.options = Object.assign({
rootMargin: '200px 0px', // 提前 200px 开始加载
threshold: 0.01, // 只要露出 1% 就加载
selector: '.lazy-target',// 需要懒加载的目标选择器
skeletonClass: 'skeleton-pulse', // 骨架屏动画类名
loadedClass: 'loaded', // 加载完成后的 CSS 类名
}, options);
this.observer = null;
this.init();
}
init() {
if ('IntersectionObserver' in window) {
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.loadImage(entry.target);
observer.unobserve(entry.target);
}
});
}, {
rootMargin: this.options.rootMargin,
threshold: this.options.threshold
});
}
this.scan();
}
/**
* 扫描 DOM寻找未加载的图片并加入观察队列
* 注意在动态渲染如搜索翻页后必须调用此方法
*/
scan() {
const elements = document.querySelectorAll(`${this.options.selector}:not(.${this.options.loadedClass})`);
elements.forEach(el => {
// 如果浏览器不支持 Observer直接加载
if (!this.observer) {
this.loadImage(el);
} else {
this.observer.observe(el);
}
});
}
/**
* 核心加载逻辑
* @param {HTMLElement} el 目标 DOM 元素
*/
loadImage(el) {
const bgSrc = el.getAttribute('data-bg');
const imgSrc = el.getAttribute('data-src');
// 寻找外层包裹的骨架屏容器(如果有)
const skeleton = el.closest('.skeleton-wrapper');
if (!bgSrc && !imgSrc) return;
// 1. 创建内存对象进行预加载 (Preload)
const loader = new Image();
loader.onload = () => {
// 2. 图片下载完毕,更新 DOM
if (bgSrc) {
el.style.backgroundImage = `url("${bgSrc}")`;
}
if (imgSrc) {
el.setAttribute('src', imgSrc);
}
// 3. 触发 CSS 动画 (Fade-in)
// 使用 requestAnimationFrame 确保样式重绘顺滑
requestAnimationFrame(() => {
el.classList.add(this.options.loadedClass);
});
// 4. 关闭骨架屏动画
if (skeleton) {
skeleton.classList.remove(this.options.skeletonClass);
// 可选:加载完成后移除背景色,或者保留作为底色
// skeleton.style.backgroundColor = 'transparent';
}
};
loader.onerror = () => {
console.warn('Image load failed:', bgSrc || imgSrc);
// 即使失败也移除动画,避免一直闪烁
if (skeleton) skeleton.classList.remove(this.options.skeletonClass);
};
// 开始下载
loader.src = bgSrc || imgSrc;
}
/**
* 手动强制预加载一组图片不等待进入视口
* 适用于轮播图的首屏图片模态框弹出前的图片
* @param {Array} urls 图片链接数组
*/
static preloadBatch(urls) {
urls.forEach(url => {
const img = new Image();
img.src = url;
});
}
}
document.addEventListener('DOMContentLoaded', function() {
// 加载图片,支持懒加载、预加载、骨架屏控制
window.ImageLoader = new AdvancedImageLoader();
// 菜单切换
const menuToggle = document.querySelector('.menu-toggle');
const navMenu = document.querySelector('.nav-menu');
@ -122,125 +236,125 @@ document.addEventListener('DOMContentLoaded', function() {
let lastScroll = 0;
const nav = document.querySelector('.main-nav');
window.addEventListener('scroll', function() {
const currentScroll = window.pageYOffset;
// window.addEventListener('scroll', function() {
// const currentScroll = window.pageYOffset;
// 到顶部时显示导航栏并清除背景和阴影
if (currentScroll <= 0) {
nav.classList.remove('scrolled');
nav.style.transform = 'translateY(0)';
nav.style.backgroundColor = '';
nav.style.boxShadow = '';
// 设置主菜单项颜色为白色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#333';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
} else if (currentScroll > 80) {
// 滚动超过80px时添加背景和阴影
nav.classList.add('scrolled');
nav.style.backgroundColor = '#fff';
nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 1)';
// 设置主菜单项颜色为黑色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#000';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
if (currentScroll > lastScroll) {
// 向下滚动时显示导航栏
nav.style.transform = 'translateY(0)';
} else {
// 向上滚动时隐藏导航栏
nav.style.transform = 'translateY(-100%)';
}
} else {
// 滚动在0-80px之间时清除背景和阴影
nav.classList.remove('scrolled');
nav.style.backgroundColor = '';
nav.style.boxShadow = '';
nav.style.transform = 'translateY(0)';
// 设置主菜单项颜色为白色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#333';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
}
// // 到顶部时显示导航栏并清除背景和阴影
// if (currentScroll <= 0) {
// nav.classList.remove('scrolled');
// nav.style.transform = 'translateY(0)';
// nav.style.backgroundColor = '';
// nav.style.boxShadow = '';
// // 设置主菜单项颜色为白色
// const menuLinks = nav.querySelectorAll('.menu-items > li > a');
// menuLinks.forEach(link => {
// link.style.color = '#333';
// });
// // 确保下拉菜单项保持黑色
// const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
// subMenuLinks.forEach(link => {
// link.style.color = '#333';
// });
// } else if (currentScroll > 80) {
// // 滚动超过80px时添加背景和阴影
// nav.classList.add('scrolled');
// nav.style.backgroundColor = '#fff';
// nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 1)';
// // 设置主菜单项颜色为黑色
// const menuLinks = nav.querySelectorAll('.menu-items > li > a');
// menuLinks.forEach(link => {
// link.style.color = '#000';
// });
// // 确保下拉菜单项保持黑色
// const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
// subMenuLinks.forEach(link => {
// link.style.color = '#333';
// });
// if (currentScroll > lastScroll) {
// // 向下滚动时显示导航栏
// nav.style.transform = 'translateY(0)';
// } else {
// // 向上滚动时隐藏导航栏
// nav.style.transform = 'translateY(-100%)';
// }
// } else {
// // 滚动在0-80px之间时清除背景和阴影
// nav.classList.remove('scrolled');
// nav.style.backgroundColor = '';
// nav.style.boxShadow = '';
// nav.style.transform = 'translateY(0)';
// // 设置主菜单项颜色为白色
// const menuLinks = nav.querySelectorAll('.menu-items > li > a');
// menuLinks.forEach(link => {
// link.style.color = '#333';
// });
// // 确保下拉菜单项保持黑色
// const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
// subMenuLinks.forEach(link => {
// link.style.color = '#333';
// });
// }
lastScroll = currentScroll;
});
// lastScroll = currentScroll;
// });
// 鼠标移入移出导航栏效果
nav.addEventListener('mouseenter', function() {
nav.classList.add('scrolled');
nav.style.backgroundColor = '#fff';
nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
// 设置菜单项颜色为黑色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#000';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
});
// nav.addEventListener('mouseenter', function() {
// nav.classList.add('scrolled');
// nav.style.backgroundColor = '#fff';
// nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
// // 设置菜单项颜色为黑色
// const menuLinks = nav.querySelectorAll('.menu-items > li > a');
// menuLinks.forEach(link => {
// link.style.color = '#ddd';
// });
// // 确保下拉菜单项保持黑色
// const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
// subMenuLinks.forEach(link => {
// link.style.color = '#333';
// });
// });
nav.addEventListener('mouseleave', function() {
const currentScroll = window.pageYOffset;
// 根据当前滚动位置决定是否保持背景色
if (currentScroll <= 80) {
nav.classList.remove('scrolled');
nav.style.backgroundColor = '';
nav.style.boxShadow = '';
// nav.addEventListener('mouseleave', function() {
// const currentScroll = window.pageYOffset;
// // 根据当前滚动位置决定是否保持背景色
// if (currentScroll <= 80) {
// nav.classList.remove('scrolled');
// nav.style.backgroundColor = '';
// nav.style.boxShadow = '';
// 设置菜单项颜色为白色
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#333';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
}
});
// // 设置菜单项颜色为白色
// const menuLinks = nav.querySelectorAll('.menu-items > li > a');
// menuLinks.forEach(link => {
// link.style.color = '#333';
// });
// // 确保下拉菜单项保持黑色
// const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
// subMenuLinks.forEach(link => {
// link.style.color = '#333';
// });
// }
// });
// 为有子菜单的项目添加特殊处理
const menuItemsWithChildren = nav.querySelectorAll('.menu-item-has-children');
menuItemsWithChildren.forEach(function(item) {
item.addEventListener('mouseenter', function() {
// 确保导航栏有背景色以便下拉菜单显示
nav.classList.add('scrolled');
nav.style.backgroundColor = '#fff';
nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
const menuLinks = nav.querySelectorAll('.menu-items > li > a');
menuLinks.forEach(link => {
link.style.color = '#000';
});
// 确保下拉菜单项保持黑色
const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
subMenuLinks.forEach(link => {
link.style.color = '#333';
});
});
});
// const menuItemsWithChildren = nav.querySelectorAll('.menu-item-has-children');
// menuItemsWithChildren.forEach(function(item) {
// item.addEventListener('mouseenter', function() {
// // 确保导航栏有背景色以便下拉菜单显示
// nav.classList.add('scrolled');
// nav.style.backgroundColor = '#fff';
// nav.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
// const menuLinks = nav.querySelectorAll('.menu-items > li > a');
// menuLinks.forEach(link => {
// link.style.color = '#333';
// });
// // 确保下拉菜单项保持黑色
// const subMenuLinks = nav.querySelectorAll('.sub-menu li a');
// subMenuLinks.forEach(link => {
// link.style.color = '#333';
// });
// });
// });
// 窗口大小改变时重置菜单状态
window.addEventListener('resize', function() {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -5,73 +5,85 @@
<!-- Logo 和公司信息 -->
<div class="footer-brand">
<div class="footer-logo">
<img src="https://nenghui.com/wp-content/uploads/2025/11/logo-2.png" alt="<?php bloginfo('name'); ?>" style=" height: 32px;" class="logo-img">
</div>
<div class="footer-social">
<a href="https://www.linkedin.com/company/nenghuitech" class="social-link linkedin" aria-label="LinkedIn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
</svg>
</a>
<a href="https://www.facebook.com/nenghuitech" class="social-link facebook" aria-label="Facebook">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
</svg>
</a>
<a href="https://x.com/NenghuiTech" class="social-link twitter" aria-label="Twitter">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
</a>
<h3 class="text-[#111318] dark:text-white text-3xl md:text-2xl leading-tight tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-gray-900 to-gray-600 dark:from-white dark:to-gray-400"> Follow NENGHUI</h3>
<!-- <img src="https://nenghui.com/wp-content/uploads/2025/11/logo-2.png" alt="<?php bloginfo('name'); ?>" style=" height: 32px;" class="logo-img"> -->
</div>
<div class="footer-social flex items-center gap-4">
<!-- LinkedIn -->
<a href="https://www.linkedin.com/company/nenghuitech" class="social-btn group linkedin" aria-label="LinkedIn">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
</svg>
</a>
<!-- Facebook -->
<a href="https://www.facebook.com/nenghuitech" class="social-btn group facebook" aria-label="Facebook">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
</svg>
</a>
<!-- X (Twitter) -->
<a href="https://x.com/NenghuiTech" class="social-btn group twitter" aria-label="Twitter">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
</a>
<!-- YouTube -->
<a href="https://www.youtube.com/@NenghuiTech" class="social-btn group youtube" aria-label="YouTube">
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/>
</svg>
</a>
</div>
</div>
<!-- 导航菜单区域 -->
<div class="footer-nav">
<div class="footer-nav-column">
<h3 class="footer-nav-title">Products</h3>
<h3 class="footer-nav-title">ABOUT US</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/products/ne418l/">NB418L</a></li>
<li><a href="https://nenghui.com/products/ne233l/">NE233L</a></li>
<li><a href="https://nenghui.com/products/ne261l/">NE261L</a></li>
<li><a href="https://nenghui.com/products/n20hc5000/">N20HC5000</a></li>
<li><a href="https://nenghui.com/products/nh-ics180-261/">NH-ICS180-261</a></li>
<li><a href="/about-us">Company Profile</a></li>
<li><a href="/contact-us">Contact Nenghui</a></li>
<li><a href="/honor">Certifications & Accreditations</a></li>
<li><a href="/news">News</a></li>
</ul>
</div>
<div class="footer-nav-column">
<h3 class="footer-nav-title">Support</h3>
<h3 class="footer-nav-title">PRODUCTS & SOLUTIONS</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/download-center/">Download Center</a></li>
<li><a href="https://nenghui.com/support/">Service</a></li>
<li><a href="https://nenghui.com/faq/">FAQ</a></li>
<li><a href="/pros/">Products</a></li>
<li><a href="/epc-solutions">EPC & Energy Solutions</a></li>
<li><a href="/microgrid">Microgrids</a></li>
</ul>
</div>
<div class="footer-nav-column">
<h3 class="footer-nav-title">ABOUT US</h3>
<h3 class="footer-nav-title">CAREER</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/about-us/">Company Profile</a></li>
<li><a href="https://nenghui.com/honor/">Certifications & Accreditations</a></li>
<li><a href="https://nenghui.com/oem/">OEM</a></li>
<li><a href="/join-us/">Join Us</a></li>
</ul>
</div>
<div class="footer-nav-column">
<h3 class="footer-nav-title">Contact us</h3>
<div class="footer-nav-column">
<h3 class="footer-nav-title">SERVICE & SUPPURT</h3>
<ul class="footer-nav-list">
<li><a href="https://nenghui.com/contact-us/">Contact us</a></li>
<li><a href="/download-center/">Download Center</a></li>
<li><a href="/support/">Service</a></li>
<li><a href="/faq/">FAQ</a></li>
</ul>
</div>
</div>
<!-- 订阅区域 -->
<div class="footer-subscribe">
<!-- <div class="footer-subscribe">
<?php echo do_shortcode('[fluentform id="3"]'); ?>
</div>
</div> -->
</div>
<!-- 分隔线 -->
@ -102,6 +114,8 @@
<?php wp_footer(); ?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<script>
AOS.init({
duration: 800, // 动画持续时间
@ -111,5 +125,157 @@
});
</script>
</footer>
<!--
核心修复 1: 外层容器添加 pointer-events-none
这确保了容器本身不会阻挡鼠标,鼠标可以穿透空白区域点击到底层页面
-->
<div class="fixed bottom-8 right-8 z-[90] flex flex-col-reverse items-end gap-4 group/widget pointer-events-none">
<!-- 1. Toggle Button -->
<!--
核心修复 2: 按钮添加 pointer-events-auto
因为外层禁用了交互,这里必须显式开启,否则按钮也点不动了
-->
<button id="support-btn" onclick="toggleSupportMenu()" class="pointer-events-auto relative size-16 bg-primary text-[#0d1b17] rounded-full shadow-[0_10px_30px_rgba(19,236,164,0.3)] flex items-center justify-center transition-all duration-500 hover:scale-110 hover:shadow-[0_0_40px_rgba(19,236,164,0.5)] z-50 border border-white/20 cursor-pointer">
<div class="absolute inset-0 rounded-full border border-white/40 opacity-0 scale-50 transition-all duration-1000 ease-out group-hover/widget:scale-150 group-hover/widget:opacity-100 animate-[ping_2s_infinite]"></div>
<div class="relative w-full h-full flex items-center justify-center">
<span id="icon-chat" translate="no" class="material-symbols-outlined notranslate text-3xl transition-all duration-300 rotate-0 opacity-100 absolute">&#xf0e2;</span>
<span id="icon-close" translate="no" class="material-symbols-outlined notranslate text-3xl transition-all duration-300 absolute text-white opacity-0 -rotate-90 scale-50">&#xe5cd;</span>
</div>
</button>
<!-- 2. Menu Items -->
<!--
核心修复 3: 菜单容器默认 pointer-events-none
这样在隐藏状态下,它完全不可点击,不会遮挡。
JS 打开时会动态改为 pointer-events-auto
-->
<div id="support-menu" class="flex flex-col gap-3 items-end pointer-events-none">
<!-- Live Chat -->
<!-- <a href="#" class="menu-item-card flex items-center gap-3 bg-white/90 backdrop-blur-xl pl-6 pr-2 py-2 rounded-full shadow-[0_10px_40px_rgba(0,0,0,0.1)] border border-white hover:bg-primary hover:border-primary hover:text-[#0d1b17] group/item transition-all duration-300 origin-bottom-right opacity-0 translate-y-4 translate-x-4 scale-90">
<span class="text-xs font-bold text-[#0d1b17] uppercase tracking-wider group-hover/item:text-[#0d1b17]">Live Chat</span>
<div class="size-10 rounded-full bg-[#13eca4]/20 text-[#00a884] group-hover/item:bg-white group-hover/item:text-[#0d1b17] flex items-center justify-center transition-colors">
<span class="material-symbols-outlined text-xl">&#xe0b7;</span>
</div>
</a> -->
<!-- WhatsApp -->
<a href="javascript:void(0);" class="menu-item-card flex items-center gap-3 bg-white/90 backdrop-blur-xl pl-6 pr-2 py-2 rounded-full shadow-[0_10px_40px_rgba(0,0,0,0.1)] border border-white hover:bg-[#07C160] hover:border-[#07C160] hover:text-white group/item transition-all duration-300 origin-bottom-right opacity-0 translate-y-4 translate-x-4 scale-90">
<div class="flex flex-col items-end leading-tight">
<span class="text-[10px] font-bold text-[#0d1b17]/50 uppercase tracking-widest group-hover/item:text-white/70">WHATSAPP</span>
<span class="text-sm font-bold text-[#0d1b17] group-hover/item:text-white">13718570501</span>
</div>
<div class="size-10 rounded-full bg-[#07C160]/10 text-[#07C160] group-hover/item:bg-white/20 group-hover/item:text-white flex items-center justify-center transition-colors">
<svg viewBox="0 0 24 24" fill="currentColor" class="w-5 h-5">
<path d="M18.8 13.9c-.3-.1-.5-.2-.7-.3.7-1.1 1.2-2.3 1.2-3.6 0-3.6-3.4-6.5-7.6-6.5S4 6.4 4 10c0 2.2 1.3 4.2 3.4 5.4-.1.6-.4 1.4-1 2.2 1.5.1 2.8-.5 3.6-1.1.6.2 1.2.3 1.8.3.1 3.2 3 5.8 6.6 5.8 1.5 0 2.9-.5 4.1-1.3.7.5 1.8 1 3.1.9-.5-.7-.8-1.5-.9-2 .9-1 1.4-2.1 1.4-3.4 0-1.2-.6-2.4-1.9-3.4-.6.3-1.2.5-1.8.5z"></path>
</svg>
</div>
</a>
<!-- Email -->
<a href="mailto:info@nenghui.com" class="menu-item-card flex items-center gap-3 bg-white/90 backdrop-blur-xl pl-6 pr-2 py-2 rounded-full shadow-[0_10px_40px_rgba(0,0,0,0.1)] border border-white hover:bg-blue-500 hover:border-blue-500 hover:text-white group/item transition-all duration-300 origin-bottom-right opacity-0 translate-y-4 translate-x-4 scale-90">
<div class="flex flex-col items-end leading-tight">
<span class="text-[10px] font-bold text-[#0d1b17]/50 uppercase tracking-widest group-hover/item:text-white/70">Email Us</span>
<span class="text-sm font-bold text-[#0d1b17] group-hover/item:text-white">contact@nenghui.com</span>
</div>
<div class="size-10 rounded-full bg-blue-100 text-blue-600 group-hover/item:bg-white/20 group-hover/item:text-white flex items-center justify-center transition-colors">
<span class="material-symbols-outlined text-xl">&#xe158;</span>
</div>
</a>
<!-- Phone -->
<a href="tel:+867561234567" class="menu-item-card flex items-center gap-3 bg-white/90 backdrop-blur-xl pl-6 pr-2 py-2 rounded-full shadow-[0_10px_40px_rgba(0,0,0,0.1)] border border-white hover:bg-[#0d1b17] hover:border-[#0d1b17] hover:text-white group/item transition-all duration-300 origin-bottom-right opacity-0 translate-y-4 translate-x-4 scale-90">
<div class="flex flex-col items-end leading-tight">
<span class="text-[10px] font-bold text-[#0d1b17]/50 uppercase tracking-widest group-hover/item:text-white/70">Call Now</span>
<span class="text-sm font-bold text-[#0d1b17] group-hover/item:text-white">+86 02150896255</span>
</div>
<div class="size-10 rounded-full bg-gray-100 text-gray-600 group-hover/item:bg-white/20 group-hover/item:text-white flex items-center justify-center transition-colors">
<span class="material-symbols-outlined text-xl">&#xe0b0;</span>
</div>
</a>
</div>
</div>
<script>
let isMenuOpen = false;
function toggleSupportMenu() {
isMenuOpen = !isMenuOpen;
const menu = document.getElementById('support-menu');
const items = document.querySelectorAll('.menu-item-card');
const iconChat = document.getElementById('icon-chat');
const iconClose = document.getElementById('icon-close');
const btn = document.getElementById('support-btn');
if (isMenuOpen) {
// 打开时:启用菜单点击
menu.classList.remove('pointer-events-none');
menu.classList.add('pointer-events-auto');
// 按钮动画
iconChat.classList.add('opacity-0', 'rotate-90', 'scale-50');
iconClose.classList.remove('opacity-0', '-rotate-90', 'scale-50');
iconClose.classList.add('rotate-0', 'scale-100');
btn.classList.add('bg-[#0d1b17]', 'rotate-90');
btn.classList.remove('bg-primary');
// 菜单项动画
items.forEach((item, index) => {
setTimeout(() => {
item.classList.remove('opacity-0', 'translate-y-4', 'translate-x-4', 'scale-90');
}, index * 60);
});
} else {
// 关闭时:禁用菜单点击(核心!)
menu.classList.remove('pointer-events-auto');
menu.classList.add('pointer-events-none');
// 按钮动画复原
iconChat.classList.remove('opacity-0', 'rotate-90', 'scale-50');
iconClose.classList.add('opacity-0', '-rotate-90', 'scale-50');
iconClose.classList.remove('rotate-0', 'scale-100');
btn.classList.remove('bg-[#0d1b17]', 'rotate-90');
btn.classList.add('bg-primary');
// 菜单项隐藏
items.forEach((item, index) => {
item.classList.add('opacity-0', 'translate-y-4', 'translate-x-4', 'scale-90');
});
}
}
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 设定目标网址
var targetUrl = "https://cn.nenghui.com";
// 设定中文语言的代码 (通常是 zh_CN 或 zh请根据你的设置调整)
// 你可以在 TranslatePress 设置 -> Advanced 标签页中查看 Language Code
var langCode = "zh";
// 查找所有 TranslatePress 语言切换器中的中文链接
// 这涵盖了浮动栏、菜单和短代码形式的切换器
var cnLinks = document.querySelectorAll('a[href*="/' + langCode + '/"], a[data-trp-untranslated-slug="' + langCode + '"]');
console.log(cnLinks);
cnLinks.forEach(function(link) {
// // 方法 A: 直接修改 href 属性 (鼠标悬停时左下角会显示新地址)
// link.href = targetUrl;
// // 方法 B (可选): 如果 TranslatePress 强制通过 JS 跳转,可以使用点击事件拦截
link.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
window.location.href = targetUrl;
});
});
});
</script>
</body>
</html>

@ -334,4 +334,211 @@ class Nenghui_Walker_Nav_Menu extends Walker_Nav_Menu {
}
}
function get_post_meta_by_key($key, $cate_type) {
global $wpdb;
$table = $wpdb->postmeta;
$result = $wpdb->get_var($wpdb->prepare(
"SELECT meta_value FROM $table WHERE meta_key = %s AND post_id IN (
SELECT post_id FROM $table WHERE meta_key = 'cate_type' AND meta_value LIKE %s
) LIMIT 1",
$key,
'%' . $wpdb->esc_like($cate_type) . '%'
));
return $result;
}
add_action('wp_ajax_load_more_products', 'load_more_products_callback');
add_action('wp_ajax_nopriv_load_more_products', 'load_more_products_callback');
function load_more_products_callback() {
check_ajax_referer('load_more_products_nonce', 'nonce');
$offset = intval($_POST['offset']);
$per_page = intval($_POST['per_page']);
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$meta_query = array();
if (!empty($category) && $category !== 'all') {
$meta_query[] = array(
'key' => 'cate_type',
'value' => $category,
'compare' => 'LIKE'
);
}
$query_args = array(
'post_type' => 'products',
'posts_per_page' => $per_page,
'offset' => $offset,
'meta_query' => $meta_query,
'post_status' => 'publish'
);
$products_query = new WP_Query($query_args);
$products = array();
if ($products_query->have_posts()) {
while ($products_query->have_posts()) {
$products_query->the_post();
$post_id = get_the_ID();
$cate_type = get_post_meta($post_id, 'cate_type', true);
$cover_image = get_the_post_thumbnail_url($post_id, 'product-cover-medium');
if (empty($cover_image)) {
$cover_image = get_post_meta($post_id, '_product_banner_url', true);
}
if (empty($cover_image)) {
$cover_image = get_template_directory_uri() . '/assets/images/products-1.webp';
}
$usage_scenario_data = get_post_meta($post_id, '_usage_scenario_data', true);
$description = '';
if (!empty($usage_scenario_data) && isset($usage_scenario_data['bottom_text'])) {
$description = $usage_scenario_data['bottom_text'];
}
$attr_keys = get_post_meta($post_id, 'attr_key', true);
$attr_values = get_post_meta($post_id, 'attr_value', true);
$attr_keys_array = !empty($attr_keys) ? explode(',', $attr_keys) : array();
$attr_values_array = !empty($attr_values) ? explode(',', $attr_values) : array();
$attrs = array();
for ($i = 0; $i < min(4, count($attr_keys_array)); $i++) {
if (isset($attr_keys_array[$i]) && isset($attr_values_array[$i])) {
$attrs[] = array(
'key' => trim($attr_keys_array[$i]),
'value' => trim($attr_values_array[$i])
);
}
}
$efficiency = get_post_meta($post_id, 'efficiency', true);
$is_new = get_post_meta($post_id, 'is_new', true);
$is_new_value = filter_var($is_new, FILTER_VALIDATE_BOOLEAN);
ob_start();
?>
<div data-category="<?php echo esc_attr($cate_type); ?>" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class="skeleton-wrapper relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:from-[#333] dark:to-[#111318] flex items-center justify-center p-6 transition-all duration-500 group-hover:from-[#666666] group-hover:to-[#e6fcf5]">
<?php if (!empty($is_new)): ?>
<div class="absolute top-4 left-4 bg-primary text-white text-xs font-bold px-2.5 py-1 rounded shadow-sm z-10">
NEW
</div>
<?php endif; ?>
<?php if (!empty($efficiency)): ?>
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-primary text-xs font-bold px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
<?php echo esc_html($efficiency); ?>
</div>
<?php endif; ?>
<div class="lazy-target w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="<?php echo esc_attr(get_the_title()); ?>" data-bg="<?php echo esc_url($cover_image); ?>" style="background-image: url('<?php echo esc_url($cover_image); ?>');"></div>
</div>
<div class="p-5">
<div class="flex justify-between items-start mb-2">
<div class="flex items-center gap-2">
<h3 class="text-xl font-bold font-display text-[#111318] dark:text-white group-hover:text-primary transition-colors"><?php echo esc_html(get_the_title()); ?></h3>
<?php if ($is_new_value): ?>
<span class="bg-primary/10 text-primary text-[10px] font-bold px-2 py-0.5 rounded-full border border-primary/20 animate-pulse">NEW</span>
<?php endif; ?>
</div>
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<?php foreach ($attrs as $attr): ?>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded <?php echo $is_new_value ? 'border-l-2 border-primary' : ''; ?>">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider"><?php echo esc_html($attr['key']); ?></p>
<p class="font-semibold dark:text-gray-200"><?php echo esc_html($attr['value']); ?></p>
</div>
<?php endforeach; ?>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
<?php echo wp_kses_post($description); ?>
</p>
<a href="<?php echo esc_url(get_permalink()); ?>" class="product-detail-link">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm font-bold hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
<?php
$products[] = array(
'html' => ob_get_clean()
);
}
wp_reset_postdata();
}
wp_send_json_success(array('products' => $products));
}
// 拦截导航
// 关键修改:将钩子从 'template_redirect' 提前到 'init',并保持优先级 1
add_action( 'init', 'custom_redirect_chinese_to_cn_domain', 1 );
function custom_redirect_chinese_to_cn_domain() {
// 忽略后台请求和 AJAX 请求,避免误杀管理员操作
if ( is_admin() || ( defined('DOING_AJAX') && DOING_AJAX ) ) {
return;
}
$target_domain = 'https://cn.nenghui.com';
$current_uri = $_SERVER['REQUEST_URI'];
$is_chinese_request = false;
$matched_reason = '';
// ==========================================
// 🛠️ 调试模式开关 (测试完毕后请改为 false)
// ==========================================
$debug_mode = false;
// 1. 嗅探 A严格的正则匹配匹配 /zh/, /zh_CN, /zh-cn/ 等
// 解释:(?:^|/) 开头或斜杠; (zh|zh_CN|zh-CN|zh-cn|cn) 语言代码; (/|\?|$) 结尾、参数或斜杠
if ( preg_match( '#(?:^|/)(zh|zh_CN|zh-CN|zh-cn|cn)(/|\?|$)#i', $current_uri, $matches ) ) {
$is_chinese_request = true;
$matched_reason = "URL 路径匹配成功 (检测到: " . $matches[1] . ")";
}
// 2. 嗅探 B检查 GET 参数 (?lang=zh_CN)
if ( isset( $_GET['lang'] ) && in_array( strtolower($_GET['lang']), ['zh_cn', 'zh-cn', 'zh', 'cn'] ) ) {
$is_chinese_request = true;
$matched_reason = "URL 参数匹配成功 (?lang=" . $_GET['lang'] . ")";
}
// ==========================================
// 🖥️ 可视化调试输出
// ==========================================
if ( $debug_mode && $is_chinese_request ) {
// 如果开启了调试且匹配成功,直接输出并终止
echo "<div style='background:#111; color:#13eca4; padding:30px; font-family:monospace; border:2px solid #ff6b00; margin:20px; border-radius:10px; z-index:99999; position:relative;'>";
echo "<h2 style='color:#fff; border-bottom:1px solid #333; padding-bottom:10px;'>🚀 路由跳转调试面板 (Init Hook)</h2>";
echo "<p><strong>当前请求的 URI:</strong> " . esc_html($current_uri) . "</p>";
echo "<p style='color:#ff6b00;'><strong>状态:</strong> 🟢 匹配成功!准备执行跳转。</p>";
echo "<p><strong>触发原因:</strong> " . esc_html($matched_reason) . "</p>";
echo "<p><strong>目标地址:</strong> " . esc_html(trailingslashit($target_domain)) . "</p>";
echo "<p style='margin-top:20px; color:#aaa;'><em>提示:关闭 \$debug_mode 即可真正执行 301 跳转。</em></p>";
echo "</div>";
exit;
} elseif ( $debug_mode && isset($_GET['test_redirect']) ) {
// 增加一个强制调试入口。输入 http://localhost:82/?test_redirect=1 查看未匹配原因
echo "<div style='background:#111; color:#f44336; padding:30px; font-family:monospace; border:2px solid #333; margin:20px; border-radius:10px;'>";
echo "<h2>🔴 未匹配到中文特征</h2>";
echo "<p>当前 URI: " . esc_html($current_uri) . "</p>";
echo "</div>";
exit;
}
// ==========================================
// 🚀 正式执行跳转逻辑
// ==========================================
if ( $is_chinese_request && !$debug_mode ) {
// 统一跳转到国内站首页
$final_url = trailingslashit( $target_domain );
// 必须使用 wp_safe_redirect 或 header 并在前置 hook 提前输出
wp_redirect( $final_url, 301 );
exit;
}
}
?>

@ -10,11 +10,12 @@
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;700;900&family=Liu Jian Mao Cao:wght@400;700&family=Montserrat:wght@400;500;700;800;900&family=Inter:wght@400;500;700;800;900&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.css" />
<!-- AOS Animation Library -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vanilla-tilt/1.7.2/vanilla-tilt.min.js"></script>
<!-- Tailwind & Config -->
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<script id="tailwind-config">
@ -28,10 +29,15 @@
"background-dark": "#10221c",
"pearlescent": "#f0f7f5",
"silver-accent": "#e2e8f0",
"about-us": "#ff6b00",
"primary-dark": "#0da670", // Added for contrast on light mode
"accent": "#ff6b00"
},
fontFamily: {
"display": ["Space Grotesk", "sans-serif"],
"sans": ["Space Grotesk", "sans-serif"],
"display": ["Montserrat", "sans-serif"],
"sans": ["Montserrat", "sans-serif"],
"mono": ["JetBrains Mono", "Montserrat"],
"inter": ["Inter", "Montserrat"],
},
borderRadius: {
"DEFAULT": "0.5rem",
@ -44,6 +50,17 @@
backgroundImage: {
'liquid-gradient': 'linear-gradient(135deg, #f8fcfa 0%, #e8f5f1 50%, #dcfce7 100%)',
'glass-gradient': 'linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.3) 100%)',
'aurora': 'linear-gradient(135deg, rgba(19,236,164,0.1) 0%, rgba(13,166,112,0.05) 50%, rgba(248,252,250,0) 100%)',
'mesh': 'radial-gradient(at 40% 20%, rgba(19,236,164,0.08) 0px, transparent 50%), radial-gradient(at 80% 0%, rgba(16,34,28,0.05) 0px, transparent 50%), radial-gradient(at 0% 50%, rgba(19,236,164,0.05) 0px, transparent 50%)',
},
boxShadow: {
// 将光效统一映射为 primary 颜色 (13eca4 的 RGBA)
'glow': '0 0 20px rgba(19, 236, 164, 0.4)',
'glow-lg': '0 10px 30px rgba(19, 236, 164, 0.4)',
'bento': '0 20px 40px -15px rgba(0,0,0,0.05), 0 0 0 1px rgba(0,0,0,0.02)',
'bento-hover': '0 30px 60px -20px rgba(19,236,164,0.15), 0 0 0 1px rgba(19,236,164,0.3)',
'bento-dark': '0 30px 60px -15px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.1)',
},
keyframes: {
fadeIn: {
@ -68,6 +85,29 @@
'0%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
'50%': { boxShadow: '0 0 50px rgba(19,236,164,0.4)', transform: 'scale(1.02)' },
'100%': { boxShadow: '0 0 0px rgba(19,236,164,0)' },
},
// 高级交互动画
pulseGlow: {
'0%': { textShadow: '0 0 10px rgba(19, 236, 164, 0.4)' },
'100%': { textShadow: '0 0 30px #ff6b00' }
},
sweep: { '100%': { left: '200%' } },
cardFlip: {
'0%': { opacity: '0', transform: 'rotateY(-90deg) translateZ(50px)' },
'100%': { opacity: '1', transform: 'rotateY(0deg) translateZ(0)' }
},
floatY: {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-15px)' }
},
textShimmer: {
'0%': { backgroundPosition: '0% 50%' },
'100%': { backgroundPosition: '100% 50%' },
},
blobSpin: {
'0%': { transform: 'rotate(0deg) scale(1)' },
'50%': { transform: 'rotate(180deg) translate(-80%, 50%) scale(1.1)' },
'100%': { transform: 'rotate(360deg) translate(0) scale(1)' },
}
},
animation: {
@ -75,18 +115,113 @@
'scan-slow': 'scan 6s linear infinite',
'spin-slow': 'rotateGlobe 60s linear infinite',
'dash-flow': 'dash 3s linear infinite',
'globe-select': 'globePulse 0.8s ease-out'
'globe-select': 'globePulse 0.8s ease-out',
'pulse-glow': 'pulseGlow 2s infinite alternate',
'sweep': 'sweep 3s infinite',
'flip-in': 'cardFlip 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards',
'float-1': 'floatY 3s ease-in-out infinite',
'float-2': 'floatY 3s ease-in-out infinite 1s',
'float-3': 'floatY 3s ease-in-out infinite 2s',
'text-shimmer': 'textShimmer 3s ease-out infinite alternate',
'blob-spin': 'blobSpin 20s infinite cubic-bezier(0.4, 0, 0.2, 1)',
}
},
},
}
</script>
<!-- Tailwind 基础样式注入 -->
<style type="text/tailwindcss">
@layer utilities {
/* contact us */
#contact-us .focus-group:hover > div:not(:hover) {
opacity: 0.6;
transform: scale(0.98);
filter: blur(2px);
}
#contact-us .focus-group > div {
transition: opacity 0.5s ease, transform 0.5s ease, filter 0.5s ease;
}
/* about-us */
/* 新增:专门为副标题定制的 3D 荧光挤压动画 */
.text-3d-subtitle {
color: #ff6b00; /* 保持主题色 */
animation: pulse3d 2s infinite alternate;
}
@keyframes pulse3d {
0% {
text-shadow:
/* 左上高光 */
-1px -1px 0px rgba(255, 255, 255, 0.5),
/* 右下厚度 (深翠绿色系) */
1px 1px 0px #ce6c33,
2px 2px 0px #b44914,
3px 3px 0px #75600a,
/* 基础投影 */
4px 4px 10px rgba(0, 0, 0, 0.6),
/* 较弱的呼吸背光 */
0px 0px 10px rgba(224, 114, 12, 0.3);
}
100% {
text-shadow:
-1px -1px 0px rgba(255, 255, 255, 0.7),
1px 1px 0px #cc7e19,
2px 2px 0px #e2d921,
3px 3px 0px #692a05,
5px 5px 15px rgba(0, 0, 0, 0.8),
/* 较强的呼吸背光,模拟能量溢出 */
0px 0px 30px #f2e930,
0px 0px 50px rgba(195, 159, 16, 0.6);
}
}
.text-3d {
text-shadow:
0 1px 0 #e2e8f0, /* 亮银色顶边 */
0 2px 0 #cbd5e1,
0 3px 0 #94a3b8,
0 4px 0 #64748b, /* 逐渐变暗模拟背光面 */
0 5px 0 #475569,
0 6px 0 #334155,
0 8px 10px rgba(0, 0, 0, 0.4), /* 近处接触阴影 */
0 15px 20px rgba(0, 0, 0, 0.3), /* 中距离扩散阴影 */
0 25px 40px rgba(0, 0, 0, 0.8); /* 远距离环境阴影 */
}
.-ultra {
color: #ffffff;
/* 1. 顶部左侧的亮色高光切割边 */
text-shadow:
-1px -1px 1px rgba(255, 255, 255, 0.3),
/* 2. 右下角 45度 斜向挤压厚度 (融入您的深墨绿环境色) */
1px 1px 0px #0d1e18,
2px 2px 0px #0a1813,
3px 3px 0px #08130e,
4px 4px 0px #060e0a,
5px 5px 0px #040906,
6px 6px 0px #020403,
7px 7px 0px #000000,
/* 3. 接触面的死黑投影 */
8px 8px 15px rgba(0, 0, 0, 0.8),
/* 4. 远距离大范围柔和投影 */
15px 15px 30px rgba(0, 0, 0, 0.6),
/* 5. 核心点睛之笔:在阴影反方向及底部映射出 #13eca4 (Primary) 的环境光晕 */
-5px -5px 30px rgba(19, 236, 164, 0.1),
10px 10px 40px rgba(19, 236, 164, 0.25);
}
/* Tab 状态管控:选中时变为 primary 背景与深色字体 */
#tech-landing-wrapper .tab-content { @apply hidden; }
#tech-landing-wrapper .tab-content.active { @apply grid; }
}
</style>
</head>
<body <?php body_class(); ?>>
<nav class="main-nav">
<div class="nav-container">
<div class="nav-logo">
<a href="<?php echo home_url(); ?>">
<div class="nav-logo flex items-center">
<a class="flex flex-col" href="<?php echo home_url(); ?>">
<?php
$logo = get_theme_mod('site_logo');
if ($logo): ?>
@ -94,7 +229,12 @@
<?php else: ?>
<img src="https://nenghui.com/wp-content/uploads/2025/11/logo-2.png" alt="logo">
<?php endif; ?>
<p data-no-translation class="text-[12px] text-[#517bb9] text-justify pl-1 max-w-[12rem] hover:text-normal">Cleaner Energy. Greater Value. </p>
</a>
<a href="https://cn.nenghui.com/" class="ml-[2rem] text-[#295ca8] cursor-pointer relative group hover:text-[#295ca8]" data-no-translation>
中国版
<div class="absolute bottom-0 left-0 w-0 h-[2px] bg-[#295ca8] transition-all duration-300 group-hover:w-full"></"></div>
</a>
</div>
<button class="menu-toggle" aria-label="菜单">

@ -1693,4 +1693,30 @@ function nenghui_business_process_shortcode($atts) {
return $output;
}
add_shortcode('business_process', 'nenghui_business_process_shortcode');
add_shortcode('business_process', 'nenghui_business_process_shortcode');
function nenghui_products_list_shortcode($atts) {
if (!is_array($atts)) {
$atts = array();
}
$atts = shortcode_atts(array(
'id' => 'nenghui-products-list-shortcode',
'class' => '',
'per_page' => '20',
'category' => '',
'order' => 'date',
'orderby' => 'DESC',
'category_order' => ''
), $atts);
ob_start();
global $products_list_shortcode_atts;
$products_list_shortcode_atts = $atts;
include get_template_directory() . '/template-parts/blocks/block-products-list.php';
return ob_get_clean();
}
add_shortcode('nenghui_products_list', 'nenghui_products_list_shortcode');

@ -14,16 +14,59 @@
* {
margin:0;
padding:0;
font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-family: "Montserrat", "Space Grotesk", "Inter", "JetBrains Mono", "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
box-sizing: border-box;
}
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(19, 236, 164, 0.2); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: rgba(19, 236, 164, 0.4); }
.hide-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.hide-scrollbar::-webkit-scrollbar { display: none; }
/* 懒加载图 */
/* 1. 图片初始状态:透明 */
.lazy-target {
opacity: 0;
transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1); /* 平滑淡入 */
will-change: opacity;
}
/* 2. 加载完成状态:不透明 (由 JS 添加 .loaded 类) */
.lazy-target.loaded {
opacity: 1;
}
/* 3. 骨架屏容器:灰色背景 */
.skeleton-wrapper {
background-color: #13eca4; /* Tailwind gray-200 */
position: relative;
overflow: hidden;
/* 确保容器有高度否则图片没加载时高度为0 */
min-height: 100px;
}
.dark .skeleton-wrapper {
background-color: #374151; /* Tailwind gray-700 */
}
/* 4. 骨架屏呼吸动画 */
.skeleton-pulse {
animation: pulse-bg 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse-bg {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
table{
width: 100%!important;
max-width: 100%!important;
}
}
/* 防止横向滚动条 */
html, body {
overflow-x: hidden;
/* overflow-x: hidden; */
overflow: initial;
max-width: 100%;
}
body {
@ -46,8 +89,8 @@
}
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
color: #333;
margin-bottom: 1rem;
/* color: #333; */
/* margin-bottom: 1rem; */
transition: all 0.3s ease;
}
h2{
@ -89,10 +132,10 @@
border-radius: 0 0 10px 10px;
padding: 20px;
}
/* 导航菜单样式 */
.main-nav {
position: fixed;
position: sticky;
top: 0;
left: 0;
right: 0;
@ -100,11 +143,11 @@
z-index: 1000;
transition: transform 0.3s ease;
background-color: #fff;;
}
.nav-container {
max-width: 80%;
max-width: 1320px;
margin: 0 auto;
padding: 0 20px;
height: 100%;
@ -117,13 +160,13 @@
display: flex;
align-items: center;
height: 100%;
padding: 10px;
border-radius: 0 0 10px 10px;
/* padding: 10px; */
/* border-radius: 0 0 10px 10px; */
}
.nav-logo a {
display: flex;
align-items: center;
align-items: flex-start;
text-decoration: none;
}
@ -158,21 +201,22 @@
display: flex;
align-items: center;
position: relative;
cursor: pointer;
}
.menu-items li a {
color: #333;
text-decoration: none;
font-size: 1rem;
font-weight: 500;
padding: 8px 0;
border-radius: 4px;
transition: all 0.3s ease;
}
.menu-items li a:hover {
background: rgba(0, 0, 0, 0.05);
color: #000;
.menu-items li a:hover, .menu-items li.menu-item-has-children > a:hover {
/* background: rgba(0, 0, 0, 0.05); */
font-weight: normal;
color: #007cba !important;;
}
/* 下拉菜单样式 */
@ -183,7 +227,7 @@
.menu-items li.menu-item-has-children > a .dropdown-arrow {
font-size: 0.7rem;
margin-left: 8px;
padding: 10px 0 10px 10px;
transition: transform 0.3s ease;
display: inline-block;
color: inherit;
@ -306,7 +350,7 @@
display: block;
width: 25px;
height: 2px;
background: #fff;
background: #333;
margin: 5px 0;
transition: all 0.3s ease;
}
@ -316,7 +360,7 @@
}
/* 响应式设计 */
@media screen and (max-width: 768px) {
@media screen and (max-width: 1225px) {
.menu-toggle {
display: block;
}
@ -430,7 +474,7 @@
}
.menu-items li.menu-item-has-children > a .dropdown-arrow {
transform: rotate(0deg);
/* transform: rotate(0deg); */
}
.menu-items li.menu-item-has-children.mobile-open > a .dropdown-arrow {
@ -463,11 +507,11 @@
form.fluent_form_3 .ff-btn-submit:not(.ff_btn_no_style) {
width: 100% !important;
}
form.fluent_form_1 .ff-btn-submit:not(.ff_btn_no_style){
width: 100%;
}
form.fluent_form_1 .ff-btn-submit:not(.ff_btn_no_style){
width: 100%;
}
}
/* 文章卡片网格布局 */
.content-area {
max-width: 1200px;
@ -569,4 +613,4 @@
}
.accordion-body{
color: #000000!important;
}
}

@ -102,7 +102,7 @@ for ($i = 0; $i < 4; $i++) {
align-items: flex-start;
gap: 60px;
width: 100%;
max-width: 1300px;
max-width: 1320px;
margin: 0 auto;
padding: 0 20px;
justify-content: space-between;

@ -267,7 +267,7 @@ $overlay_opacity = is_numeric($overlay_opacity) ? $overlay_opacity : '0.4';
position: relative;
z-index: 3;
width: 100%;
max-width: 1300px;
max-width: 1320px;
padding: 0 20px;
}
@ -278,7 +278,6 @@ $overlay_opacity = is_numeric($overlay_opacity) ? $overlay_opacity : '0.4';
/* 文字样式 */
.nenghui-banner-title .banner-title {
font-size: clamp(2.5rem, 5vw, 4rem);
font-weight: 700;
line-height: 1.2;
margin: 0 0 1.5rem 0;
letter-spacing: 3px;
@ -293,7 +292,7 @@ $overlay_opacity = is_numeric($overlay_opacity) ? $overlay_opacity : '0.4';
color: #ffffff;
text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.5);
font-weight: 300;
max-width: 1300px;
max-width: 1320px;
}
/* 动画效果 */
.nenghui-banner-title.has-animation {

@ -139,7 +139,6 @@ $news_query = new WP_Query($query_args);
.news-title {
font-size: 36px;
font-weight: bold;
color: #333;
margin: 0;
}
@ -178,7 +177,6 @@ $news_query = new WP_Query($query_args);
.news-card-title {
font-size: 16px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
line-height: 1.4;
@ -189,7 +187,7 @@ $news_query = new WP_Query($query_args);
}
.news-card-description {
font-size: 14px;
font-size: 12px;
color: #666;
line-height: 1.6;
display: -webkit-box;

@ -0,0 +1,889 @@
<?php
if (!defined('ABSPATH')) {
exit;
}
global $products_list_shortcode_atts;
$atts = $products_list_shortcode_atts;
$per_page = intval($atts['per_page']);
$category = sanitize_text_field($atts['category']);
$order = sanitize_text_field($atts['order']);
$orderby = sanitize_text_field($atts['orderby']);
$category_order = sanitize_text_field($atts['category_order']);
$meta_query = array();
if (!empty($category) && $category !== 'all') {
$meta_query[] = array(
'key' => 'cate_type',
'value' => $category,
'compare' => 'LIKE'
);
}
$query_args = array(
'post_type' => 'products',
'posts_per_page' => $per_page,
'paged' => get_query_var('paged') ? get_query_var('paged') : 1,
'meta_query' => $meta_query,
'order' => $order,
'orderby' => $orderby,
'post_status' => 'publish'
);
$products_query = new WP_Query($query_args);
$all_products_args = array(
'post_type' => 'products',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$all_products = get_posts($all_products_args);
$unique_cate_types = array();
foreach ($all_products as $product) {
$cate_type = get_post_meta($product->ID, 'cate_type', true);
if (!empty($cate_type)) {
$cate_types = explode(',', $cate_type);
foreach ($cate_types as $type) {
$type = trim($type);
if (!empty($type) && !in_array($type, $unique_cate_types)) {
$unique_cate_types[] = $type;
}
}
}
}
if (!empty($category_order)) {
$category_order_array = explode(',', $category_order);
$category_order_array = array_map('trim', $category_order_array);
$unique_cate_types = array_filter($unique_cate_types, function($type) use ($category_order_array) {
return in_array($type, $category_order_array);
});
$unique_cate_types = array_intersect($category_order_array, $unique_cate_types);
}
$total_products = count($all_products);
?>
<style>
/* Custom scrollbar for horizontal scrolling elements */
.hide-scrollbar::-webkit-scrollbar {
display: none;
}
.hide-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
/* Smooth Scrolling */
html {
scroll-behavior: smooth;
}
/* Card Hover Effects */
.product-card {
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
position: relative; /* 确保 z-index 生效 */
z-index: 10;
margin-top: 8px;
}
.product-card:hover {
transform: translateY(-8px);
z-index: 30; /* 低于 filter 的 40 */
}
</style>
<main class="max-w-[1280px] mx-auto px-4 sm:px-6 lg:px-8 py-8 flex flex-col flex-1 min-h-screen">
<div class="max-w-4xl mb-10" data-aos="fade-right" data-aos-delay="200">
<h1 class="font-display text-[#111318] dark:text-white text-4xl md:text-5xl font-black leading-tight tracking-tight mb-4 bg-clip-text text-transparent bg-gradient-to-r from-gray-900 to-gray-600 dark:from-white dark:to-gray-400">
High-Performance Energy Storage
</h1>
<p class="text-[#5f6e8c] dark:text-gray-400 text-lg font-normal leading-relaxed max-w-2xl">
From residential backups to utility-scale grids. Explore our LFP and Solid-State battery solutions designed for maximum efficiency.
</p>
</div>
<div id="filter-sticky-wrapper" class="sticky top-[80px] z-40 mb-8 transition-all duration-300 -mx-4 px-4 sm:mx-0 sm:px-0 rounded-b-xl">
<div class="absolute inset-0 bg-background-light/95 dark:bg-background-dark/95 backdrop-blur-md transition-opacity duration-300 opacity-90 border-b border-transparent" id="filter-bg"></div>
<div class="relative max-w-[1280px] mx-auto py-3">
<div class="flex items-center justify-between mb-2 px-1">
<span class="text-[10px] font-extrabold tracking-widest text-gray-500 dark:text-gray-400 uppercase flex items-center gap-1">
<span class="material-symbols-outlined text-[14px]">&#xe429;</span>
Filter by Category
</span>
<div class="hidden sm:flex gap-2">
<span class="text-xs text-gray-400 font-mono" id="item-count-display">Showing <?php echo esc_html($total_products); ?> items</span>
</div>
</div>
<div class="relative group/filters">
<div class="absolute left-0 top-0 bottom-0 w-8 bg-gradient-to-r from-[#f8fcfa] dark:from-[#10221c] to-transparent z-10 pointer-events-none md:hidden transition-colors duration-300" id="mask-left"></div>
<div class="flex overflow-x-auto md:flex-wrap gap-3 py-2 -my-2 px-2 -mx-2 hide-scrollbar scroll-smooth snap-x items-center">
<button onclick="filterSelection('all', this)" class="filter-btn active snap-start shrink-0 relative flex items-center gap-2 pl-4 pr-5 h-10 rounded-full border transition-all duration-300 group" data-filter="all">
<span class="font-bold text-sm tracking-wide">All Systems</span>
<span class="count-badge flex items-center justify-center h-5 min-w-[20px] px-1.5 rounded-full text-[10px] font-bold"><?php echo esc_html($total_products); ?></span>
</button>
<?php foreach ($unique_cate_types as $cate_type): ?>
<?php
$cate_type_value = get_post_meta_by_key('cate_type_value', $cate_type);
$display_name = !empty($cate_type_value) ? $cate_type_value : $cate_type;
$count = 0;
foreach ($all_products as $product) {
$product_cate_type = get_post_meta($product->ID, 'cate_type', true);
if (!empty($product_cate_type) && strpos($product_cate_type, $cate_type) !== false) {
$count++;
}
}
?>
<button onclick="filterSelection('<?php echo esc_js($cate_type); ?>', this)" class="filter-btn snap-start shrink-0 flex items-center gap-2 pl-4 pr-4 h-10 rounded-full border border-[#e5e7eb] dark:border-[#374151] bg-white dark:bg-[#1f2937] text-[#5f6e8c] dark:text-gray-300 transition-all duration-300 hover:scale-105 active:scale-95 hover:shadow-lg hover:border-primary z-0 hover:z-10" data-filter="<?php echo esc_attr($cate_type); ?>">
<span class="font-medium text-sm"><?php echo esc_html($display_name); ?></span>
</button>
<?php endforeach; ?>
</div>
<div class="absolute right-0 top-0 bottom-0 w-12 bg-gradient-to-l from-[#f8fcfa] dark:from-[#10221c] to-transparent z-10 pointer-events-none md:hidden transition-colors duration-300" id="mask-right"></div>
</div>
</div>
</div>
<div id="initial-loader" class="py-12 w-full">
<div class="flex flex-col items-center justify-center space-y-4 w-full">
<div class="relative flex-shrink-0">
<div class="w-16 h-16 border-4 border-primary/20 border-t-primary rounded-full animate-spin"></div>
<div class="absolute inset-0 flex items-center justify-center">
<span class="material-symbols-outlined text-2xl text-primary animate-pulse">&#xe9d0;</span>
</div>
</div>
<div class="text-center">
<p class="text-gray-500 dark:text-gray-400 font-medium">Loading products...</p>
<p class="text-gray-400 dark:text-gray-500 text-sm mt-1">Please wait</p>
</div>
</div>
</div>
<div id="product-grid" class="columns-1 md:columns-2 lg:columns-3 gap-6 pb-12">
<?php if ($products_query->have_posts()): ?>
<?php while ($products_query->have_posts()): $products_query->the_post(); ?>
<?php
$post_id = get_the_ID();
$cate_type = get_post_meta($post_id, 'cate_type', true);
$cover_image = get_the_post_thumbnail_url($post_id, 'product-cover-medium');
if (empty($cover_image)) {
$cover_image = get_post_meta($post_id, '_product_banner_url', true);
}
if (empty($cover_image)) {
$cover_image = get_template_directory_uri() . '/assets/images/products-1.webp';
}
$usage_scenario_data = get_post_meta($post_id, '_usage_scenario_data', true);
$description = '';
if (!empty($usage_scenario_data) && isset($usage_scenario_data['bottom_text'])) {
$description = $usage_scenario_data['bottom_text'];
}
$attr_keys = get_post_meta($post_id, 'attr_key', true);
$attr_values = get_post_meta($post_id, 'attr_value', true);
$attr_keys_array = !empty($attr_keys) ? explode(',', $attr_keys) : array();
$attr_values_array = !empty($attr_values) ? explode(',', $attr_values) : array();
$attrs = array();
for ($i = 0; $i < min(4, count($attr_keys_array)); $i++) {
if (isset($attr_keys_array[$i]) && isset($attr_values_array[$i])) {
$attrs[] = array(
'key' => trim($attr_keys_array[$i]),
'value' => trim($attr_values_array[$i])
);
}
}
$efficiency = get_post_meta($post_id, 'efficiency', true);
$is_new = get_post_meta($post_id, 'is_new', true);
$is_new_value = filter_var($is_new, FILTER_VALIDATE_BOOLEAN);
?>
<div data-category="<?php echo esc_attr($cate_type); ?>" class="product-card break-inside-avoid bg-white dark:bg-card-dark rounded-xl overflow-hidden border border-[#e5e7eb] dark:border-[#2a3441] shadow-sm hover:shadow-card-hover hover:border-primary/40 group" data-aos="fade-up" data-aos-delay="0">
<div class="skeleton-wrapper relative h-64 w-full bg-gradient-to-b from-[#787878] to-white dark:from-[#333] dark:to-[#111318] flex items-center justify-center p-6 transition-all duration-500 group-hover:from-[#666666] group-hover:to-[#e6fcf5]">
<?php if (!empty($is_new)): ?>
<div class="absolute top-4 left-4 bg-primary text-white text-xs font-bold px-2.5 py-1 rounded shadow-sm z-10">
NEW
</div>
<?php endif; ?>
<?php if (!empty($efficiency)): ?>
<div class="absolute top-4 right-4 bg-white/90 dark:bg-[#2a3441]/90 backdrop-blur text-primary text-xs font-bold px-2.5 py-1 rounded shadow-sm border border-primary/10 z-10">
<?php echo esc_html($efficiency); ?>
</div>
<?php endif; ?>
<div class="lazy-target w-full h-full bg-center bg-no-repeat bg-contain transform group-hover:scale-105 transition-transform duration-500" data-alt="<?php echo esc_attr(get_the_title()); ?>" data-bg="<?php echo esc_url($cover_image); ?>" style="background-image: url('<?php echo esc_url($cover_image); ?>');"></div>
</div>
<div class="p-5">
<div class="flex justify-between items-start mb-2">
<div class="flex items-center gap-2">
<h3 class="text-xl font-bold font-display text-[#111318] dark:text-white group-hover:text-primary transition-colors"><?php echo esc_html(get_the_title()); ?></h3>
<?php if ($is_new_value): ?>
<span class="bg-primary/10 text-primary text-[10px] font-bold px-2 py-0.5 rounded-full border border-primary/20 animate-pulse">NEW</span>
<?php endif; ?>
</div>
</div>
<div class="grid grid-cols-2 gap-y-3 gap-x-4 mb-5 text-sm">
<?php foreach ($attrs as $attr): ?>
<div class="bg-gray-50 dark:bg-[#1f2937] p-2 rounded <?php echo $is_new_value ? 'border-l-2 border-primary' : ''; ?>">
<p class="text-[#5f6e8c] dark:text-gray-500 text-[10px] uppercase tracking-wider"><?php echo esc_html($attr['key']); ?></p>
<p class="font-semibold dark:text-gray-200"><?php echo esc_html($attr['value']); ?></p>
</div>
<?php endforeach; ?>
</div>
<p class="text-[#5f6e8c] dark:text-gray-400 text-sm leading-relaxed mb-6 line-clamp-4">
<?php echo wp_kses_post($description); ?>
</p>
<a href="<?php echo esc_url(get_permalink()); ?>" class="product-detail-link">
<button class="w-full flex items-center justify-center gap-2 h-11 rounded-lg bg-[#f0f1f5] dark:bg-[#2a3441] text-[#111318] dark:text-white text-sm font-bold hover:bg-[#e0e2e8] dark:hover:bg-[#374151] transition-all group-hover:bg-primary group-hover:text-white group-hover:shadow-glow">
<span>View Datasheet</span>
<span class="material-symbols-outlined text-[18px] group-hover:translate-x-1 transition-transform">&#xe5c8;</span>
</button>
</a>
</div>
</div>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else: ?>
<div class="col-span-full text-center py-12">
<p class="text-gray-500 dark:text-gray-400">No products found.</p>
</div>
<?php endif; ?>
</div>
<?php if ($products_query->max_num_pages > 1): ?>
<div class="flex justify-center pt-8 pb-16" data-aos="zoom-in" data-aos-offset="50">
<button id="load-more-btn" class="relative group flex items-center justify-center px-8 py-3 rounded-full bg-primary/10 hover:bg-primary/20 dark:bg-primary/20 dark:hover:bg-primary/30 transition-all duration-300 active:scale-95" data-page="1" data-max-pages="<?php echo esc_attr($products_query->max_num_pages); ?>" data-per-page="<?php echo esc_attr($per_page); ?>">
<div class="absolute inset-0 rounded-full border border-primary opacity-20 animate-pulse group-hover:opacity-40"></div>
<span class="text-primary font-bold text-sm tracking-wide group-hover:scale-105 transition-transform">LOAD MORE PRODUCTS</span>
</button>
</div>
<?php endif; ?>
</main>
<script>
/**
* 产品列表状态管理器
* 负责管理产品列表的状态保存、恢复和清理
*/
const ProductListStateManager = {
// 状态键名常量
KEYS: {
GRID_HTML: 'products_grid_html',
SCROLL_POSITION: 'products_scroll_position',
CURRENT_PAGE: 'products_current_page',
CURRENT_CATEGORY: 'products_current_category',
LOAD_MORE_VISIBLE: 'products_load_more_visible',
NAVIGATED_FROM_LIST: 'products_navigated_from_list',
TIMESTAMP: 'products_state_timestamp'
},
// 状态过期时间30分钟
EXPIRY_TIME: 30 * 60 * 1000,
/**
* 保存当前状态
*/
save: function() {
console.log('[StateManager] Saving state...');
const grid = document.getElementById('product-grid');
const loadMoreBtn = document.getElementById('load-more-btn');
if (!grid) {
console.error('[StateManager] Grid element not found!');
return false;
}
console.log('[StateManager] Current global variables:', {
'window.currentPage': window.currentPage,
'window.currentCategory': window.currentCategory,
'currentPage (local)': currentPage,
'currentCategory (local)': currentCategory
});
const state = {
GRID_HTML: grid.innerHTML,
SCROLL_POSITION: window.scrollY,
CURRENT_PAGE: window.currentPage || currentPage || 1,
CURRENT_CATEGORY: window.currentCategory || currentCategory || 'all',
LOAD_MORE_VISIBLE: loadMoreBtn ? loadMoreBtn.style.display !== 'none' : false,
NAVIGATED_FROM_LIST: 'true',
TIMESTAMP: Date.now()
};
console.log('[StateManager] State to save:', state);
// 保存到 sessionStorage - 直接遍历 state 对象
Object.keys(state).forEach(key => {
const storageKey = this.KEYS[key.toUpperCase()] || this.KEYS[key];
const value = state[key];
console.log('[StateManager] Saving key:', key, '->', storageKey, '=', value);
if (value !== undefined && storageKey) {
sessionStorage.setItem(storageKey, typeof value === 'object' ? JSON.stringify(value) : value);
}
});
console.log('[StateManager] State saved:', {
productCount: grid.querySelectorAll('.product-card').length,
currentPage: state.currentPage,
currentCategory: state.currentCategory,
scrollPosition: state.scrollPosition,
loadMoreVisible: state.loadMoreVisible
});
return true;
},
/**
* 恢复状态
* @returns {boolean} 是否成功恢复
*/
restore: function() {
console.log('[StateManager] Restoring state...');
const gridHtml = sessionStorage.getItem(this.KEYS.GRID_HTML);
const navigatedFromList = sessionStorage.getItem(this.KEYS.NAVIGATED_FROM_LIST);
const timestamp = sessionStorage.getItem(this.KEYS.TIMESTAMP);
// 检查状态是否存在且未过期
if (!gridHtml || navigatedFromList !== 'true') {
console.log('[StateManager] No valid state to restore');
return false;
}
// 检查状态是否过期
if (timestamp && (Date.now() - parseInt(timestamp)) > this.EXPIRY_TIME) {
console.log('[StateManager] State expired, clearing...');
this.clear();
return false;
}
const grid = document.getElementById('product-grid');
if (!grid) {
console.error('[StateManager] Grid element not found!');
return false;
}
// 恢复产品列表
grid.innerHTML = gridHtml;
grid.style.display = 'block';
// 隐藏初始加载器
const initialLoader = document.getElementById('initial-loader');
if (initialLoader) {
initialLoader.style.display = 'none';
}
// 恢复全局变量和局部变量
window.currentPage = parseInt(sessionStorage.getItem(this.KEYS.CURRENT_PAGE)) || 1;
window.currentCategory = sessionStorage.getItem(this.KEYS.CURRENT_CATEGORY) || 'all';
// 同步更新局部变量
currentPage = window.currentPage;
currentCategory = window.currentCategory;
console.log('[StateManager] Restored variables:', {
'window.currentPage': window.currentPage,
'window.currentCategory': window.currentCategory,
'currentPage (local)': currentPage,
'currentCategory (local)': currentCategory
});
// 恢复加载更多按钮状态
const loadMoreBtn = document.getElementById('load-more-btn');
const loadMoreVisible = sessionStorage.getItem(this.KEYS.LOAD_MORE_VISIBLE) === 'true';
if (loadMoreBtn) {
const loadMoreContainer = loadMoreBtn.parentElement;
if (loadMoreVisible) {
loadMoreBtn.style.display = 'flex';
loadMoreBtn.disabled = false;
if (loadMoreContainer) loadMoreContainer.style.display = 'flex';
} else {
loadMoreBtn.style.display = 'none';
if (loadMoreContainer) loadMoreContainer.style.display = 'none';
}
}
// 恢复分类按钮样式
const savedCategory = sessionStorage.getItem(this.KEYS.CURRENT_CATEGORY);
if (savedCategory) {
const activeBtn = document.querySelector(`[data-filter="${savedCategory}"]`);
if (activeBtn) {
updateButtonStyles(activeBtn);
}
}
// 更新产品计数
const visibleCount = grid.querySelectorAll('.product-card').length;
updateItemCount(visibleCount);
// 刷新动画和图片
if (typeof AOS !== 'undefined') {
AOS.refresh();
}
if (typeof window.ImageLoader !== 'undefined' && typeof window.ImageLoader.scan === 'function') {
window.ImageLoader.scan();
}
console.log('[StateManager] State restored:', {
productCount: visibleCount,
currentPage: window.currentPage,
currentCategory: window.currentCategory
});
return true;
},
/**
* 恢复滚动位置
*/
restoreScrollPosition: function() {
const scrollPosition = sessionStorage.getItem(this.KEYS.SCROLL_POSITION);
if (scrollPosition) {
setTimeout(() => {
console.log('[StateManager] Restoring scroll position:', scrollPosition);
window.scrollTo({
top: parseInt(scrollPosition),
behavior: 'auto'
});
}, 100);
}
},
/**
* 清除所有状态
*/
clear: function() {
console.log('[StateManager] Clearing all state...');
Object.values(this.KEYS).forEach(key => {
sessionStorage.removeItem(key);
});
},
/**
* 检查是否有有效的状态
* @returns {boolean}
*/
hasValidState: function() {
const gridHtml = sessionStorage.getItem(this.KEYS.GRID_HTML);
const navigatedFromList = sessionStorage.getItem(this.KEYS.NAVIGATED_FROM_LIST);
const timestamp = sessionStorage.getItem(this.KEYS.TIMESTAMP);
console.log('[StateManager] Checking valid state:', {
gridHtml: gridHtml,
navigatedFromList: navigatedFromList,
timestamp: timestamp
});
if (!gridHtml || navigatedFromList !== 'true') {
return false;
}
// 检查是否过期
if (timestamp && (Date.now() - parseInt(timestamp)) > this.EXPIRY_TIME) {
this.clear();
return false;
}
return true;
}
};
// 全局变量
let currentCategory = 'all';
let currentPage = 1;
let perPage = 6;
let originalLoadMoreBtnContent = '';
const activeClass = "bg-[#111318] dark:bg-white text-white dark:text-[#111318] border-transparent shadow-lg shadow-gray-200 dark:shadow-none ring-2 ring-offset-2 ring-transparent";
const inactiveClass = "bg-white dark:bg-[#1f2937] text-[#5f6e8c] dark:text-gray-300 border-[#e5e7eb] dark:border-[#374151]";
/**
* 保存当前状态(兼容旧代码)
* @returns {boolean} 是否成功保存
*/
function saveState() {
return ProductListStateManager.save();
}
function updateButtonStyles(activeBtn) {
const filterBtns = document.querySelectorAll('.filter-btn');
filterBtns.forEach(btn => {
btn.className = btn.className.replace(activeClass, "").replace(inactiveClass, "");
btn.classList.add(...inactiveClass.split(" "));
const badge = btn.querySelector('.count-badge');
if(badge) {
badge.className = "count-badge hidden";
}
});
activeBtn.classList.remove(...inactiveClass.split(" "));
activeBtn.classList.add(...activeClass.split(" "));
const activeBadge = activeBtn.querySelector('.count-badge');
if(activeBadge) {
activeBadge.className = "count-badge flex items-center justify-center h-5 min-w-[20px] px-1.5 rounded-full bg-white/20 dark:bg-black/10 text-[10px] font-bold ml-auto";
}
}
function updateItemCount(count) {
const itemCountDisplay = document.getElementById('item-count-display');
if(itemCountDisplay) {
itemCountDisplay.textContent = `Showing ${count} items`;
}
}
function loadProducts(category, page = 1, append = false) {
const grid = document.getElementById('product-grid');
const loadMoreBtn = document.getElementById('load-more-btn');
const initialLoader = document.getElementById('initial-loader');
currentCategory = category;
window.currentCategory = category;
if (!append) {
if (initialLoader) {
initialLoader.style.display = 'flex';
}
grid.style.display = 'none';
grid.innerHTML = '';
} else if (loadMoreBtn) {
loadMoreBtn.innerHTML = `
<div class="flex items-center gap-2">
<span class="material-symbols-outlined animate-spin">&#xe9d0;</span>
<span>Loading...</span>
</div>
`;
loadMoreBtn.disabled = true;
}
const offset = (page - 1) * perPage;
console.log('[loadProducts] Request parameters:', {
category: category,
page: page,
perPage: perPage,
offset: offset,
append: append,
'currentPage (local)': currentPage,
'window.currentPage': window.currentPage
});
fetch('<?php echo admin_url('admin-ajax.php'); ?>', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'load_more_products',
offset: offset,
per_page: perPage,
category: category,
nonce: '<?php echo wp_create_nonce('load_more_products_nonce'); ?>'
})
})
.then(response => response.json())
.then(data => {
console.log('AJAX response:', data);
console.log('Append mode:', append);
if (data.success) {
console.log('Data success is true');
if (!append) {
grid.innerHTML = '';
grid.style.display = 'block';
if (initialLoader) {
initialLoader.style.display = 'none';
}
currentPage = 1;
window.currentPage = 1;
sessionStorage.setItem('products_current_page', 1);
sessionStorage.setItem('products_current_category', category);
}
data = data.data || {};
console.log('Products data:', data.products);
if (data.products && data.products.length > 0) {
console.log('Has products, adding to grid');
data.products.forEach(product => {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = product.html;
const newCard = tempDiv.firstElementChild;
newCard.setAttribute('data-aos-delay', '0');
grid.appendChild(newCard);
});
if (typeof AOS !== 'undefined') {
AOS.refresh();
}
if (typeof window.ImageLoader !== 'undefined' && typeof window.ImageLoader.scan === 'function') {
window.ImageLoader.scan();
}
console.log('About to scroll, append:', append);
if (!append) {
console.log('Executing scroll logic');
setTimeout(() => {
const stickyWrapper = document.getElementById('filter-sticky-wrapper');
const headerOffset = 64 + (stickyWrapper ? stickyWrapper.offsetHeight : 60);
const gridRect = grid.getBoundingClientRect();
const targetPosition = gridRect.top + window.scrollY - headerOffset - 20;
console.log('Scrolling to position:', targetPosition, 'Current scroll:', window.scrollY, 'Grid top:', gridRect.top);
window.scrollTo({
top: targetPosition,
behavior: 'auto'
});
}, 150);
} else {
console.log('Skipping scroll, append mode');
}
const visibleCount = grid.querySelectorAll('.product-card').length;
updateItemCount(visibleCount);
console.log('Visible products:', visibleCount);
if (loadMoreBtn) {
const loadMoreContainer = loadMoreBtn.parentElement;
if (loadMoreContainer) {
loadMoreContainer.style.display = 'flex';
}
if (data.products.length < perPage) {
loadMoreBtn.style.display = 'none';
const loadMoreContainer = loadMoreBtn.parentElement;
if (loadMoreContainer) {
loadMoreContainer.style.display = 'none';
}
// 更新当前页码并保存状态
currentPage = page;
window.currentPage = page;
window.currentCategory = currentCategory;
sessionStorage.setItem('products_current_page', page);
console.log('Hide load more button - no more products, saving state');
saveState();
} else {
loadMoreBtn.style.display = 'flex';
loadMoreBtn.innerHTML = originalLoadMoreBtnContent;
loadMoreBtn.disabled = false;
currentPage = page;
window.currentPage = page;
window.currentCategory = currentCategory;
sessionStorage.setItem('products_current_page', page);
console.log('Show load more button - current page:', currentPage);
saveState();
}
}
} else if (!append) {
grid.style.display = 'block';
if (initialLoader) {
initialLoader.style.display = 'none';
}
grid.innerHTML = '<div class="col-span-full text-center py-12"><p class="text-gray-500 dark:text-gray-400">No products found.</p></div>';
updateItemCount(0);
if (loadMoreBtn) {
loadMoreBtn.style.display = 'none';
const loadMoreContainer = loadMoreBtn.parentElement;
if (loadMoreContainer) {
loadMoreContainer.style.display = 'none';
}
}
}
}
})
.catch(error => {
console.error('Error loading products:', error);
const initialLoader = document.getElementById('initial-loader');
if (!append) {
grid.style.display = 'block';
if (initialLoader) {
initialLoader.style.display = 'none';
}
grid.innerHTML = '<div class="col-span-full text-center py-12"><p class="text-red-500">Error loading products. Please try again.</p></div>';
}
if (loadMoreBtn && append) {
loadMoreBtn.innerHTML = originalLoadMoreBtnContent;
loadMoreBtn.disabled = false;
}
});
}
function filterSelection(category, clickedBtn) {
currentCategory = category;
window.currentCategory = category;
updateButtonStyles(clickedBtn);
const grid = document.getElementById('product-grid');
const loadMoreBtn = document.getElementById('load-more-btn');
if (loadMoreBtn) {
const loadMoreContainer = loadMoreBtn.parentElement;
if (loadMoreContainer) {
loadMoreContainer.style.display = 'flex';
}
}
loadProducts(category, 1, false);
}
document.addEventListener('DOMContentLoaded', function() {
const initialLoader = document.getElementById('initial-loader');
const grid = document.getElementById('product-grid');
window.currentPage = 1;
window.currentCategory = 'all';
if (initialLoader && grid) {
setTimeout(() => {
initialLoader.style.display = 'none';
if (typeof AOS !== 'undefined') {
AOS.refresh();
}
if (typeof window.ImageLoader !== 'undefined' && typeof window.ImageLoader.scan === 'function') {
window.ImageLoader.scan();
}
}, 500);
}
const loadMoreBtn = document.getElementById('load-more-btn');
if (loadMoreBtn) {
perPage = parseInt(loadMoreBtn.getAttribute('data-per-page')) || 6;
originalLoadMoreBtnContent = loadMoreBtn.innerHTML;
loadMoreBtn.addEventListener('click', function() {
const nextPage = currentPage + 1;
console.log('[Load More Button] Clicked:', {
'currentPage (local)': currentPage,
'window.currentPage': window.currentPage,
'nextPage': nextPage,
'currentCategory': currentCategory,
'window.currentCategory': window.currentCategory
});
loadProducts(currentCategory, nextPage, true);
});
}
/**
* 页面显示事件处理
* 处理从产品详情页返回的情况
*/
window.addEventListener('pageshow', function(event) {
console.log('[pageshow] Event triggered, persisted:', event.persisted);
// 检查是否有有效的状态需要恢复
if (ProductListStateManager.hasValidState()) {
console.log('[pageshow] Valid state found, restoring...');
// 恢复状态
const restored = ProductListStateManager.restore();
if (restored) {
// 恢复滚动位置
ProductListStateManager.restoreScrollPosition();
// 清除导航标记,避免重复恢复
sessionStorage.removeItem(ProductListStateManager.KEYS.NAVIGATED_FROM_LIST);
console.log('[pageshow] State restored successfully');
}
} else {
console.log('[pageshow] No valid state to restore');
// 如果不是从产品详情页返回,清除所有状态
console.log('[pageshow] Not navigated from list, clearing all states');
if (!ProductListStateManager.hasValidState()) {
ProductListStateManager.clear();
// 滚动到顶部
setTimeout(() => {
window.scrollTo({ top: 0, behavior: 'auto' });
}, 100);
}
}
});
const stickyEl = document.getElementById('filter-sticky-wrapper');
const filterBg = document.getElementById('filter-bg');
if (stickyEl && filterBg) {
const sentinel = document.createElement('div');
sentinel.setAttribute('id', 'sticky-sentinel');
stickyEl.parentNode.insertBefore(sentinel, stickyEl);
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (!entry.isIntersecting && entry.boundingClientRect.top < 0) {
filterBg.classList.add('border-gray-200', 'dark:border-gray-800', 'shadow-sm');
filterBg.classList.remove('border-transparent');
} else {
filterBg.classList.remove('border-gray-200', 'dark:border-gray-800', 'shadow-sm');
filterBg.classList.add('border-transparent');
}
});
}, {
threshold: 0,
rootMargin: '-72px 0px 0px 0px'
});
observer.observe(sentinel);
}
const navigatedFromList = sessionStorage.getItem('products_navigated_from_list');
const savedGridHtml = sessionStorage.getItem('products_grid_html');
const savedCategory = sessionStorage.getItem('products_current_category');
console.log('DOMContentLoaded - navigatedFromList:', navigatedFromList, 'savedGridHtml:', !!savedGridHtml);
if (navigatedFromList === 'true' && savedGridHtml) {
console.log('From product detail with saved HTML, skipping DOMContentLoaded initialization');
return;
}
if (navigatedFromList !== 'true' && !savedGridHtml) {
console.log('Normal page load - setting default button and clearing cache');
updateButtonStyles(document.querySelector('[data-filter="all"]'));
sessionStorage.clear();
} else if (savedCategory) {
console.log('Restoring category button:', savedCategory);
const activeBtn = document.querySelector(`[data-filter="${savedCategory}"]`);
if (activeBtn) {
updateButtonStyles(activeBtn);
}
}
if (!savedGridHtml) {
updateItemCount(document.querySelectorAll('.product-card').length);
}
document.addEventListener('click', function(event) {
const target = event.target;
console.log('[Click Event] Target:', target.tagName, target.className);
const link = target.closest('.product-detail-link');
if (link) {
console.log('[Click Event] Product detail link clicked:', link.href);
event.preventDefault();
event.stopPropagation();
console.log('[Click Event] Saving state before navigation...');
const saved = ProductListStateManager.save();
console.log('[Click Event] State saved, navigating to:', link.href);
window.location.href = link.href;
}
}, true);
});
</script>

@ -31,7 +31,7 @@ if (empty($banner_url)) {
</div>
</div>
<!-- 产品详情内容 -->
<div class="container mt-5">
<div class="container mt-5" style="margin: 1rem auto; ">
<?php
// 获取产品特性显示开关
$show_features = get_post_meta(get_the_ID(), '_show_product_features', true);

Loading…
Cancel
Save