使用heroui完成对页面的重构

This commit is contained in:
2026-01-29 16:23:10 +08:00
parent 2377e2dda2
commit d265126035
24 changed files with 5360 additions and 1121 deletions

View File

@@ -1,10 +1,14 @@
'use client';
import Image from 'next/image';
import { Link, Button } from '@heroui/react';
import { useLanguage } from '@/contexts/LanguageContext';
import { useTheme } from '@/contexts/ThemeContext';
export default function Footer() {
const { t } = useLanguage();
const { theme } = useTheme();
const isDark = theme === 'dark';
const socialIcons = [
{ src: '/component-12.svg', alt: 'Twitter', width: 24, height: 24 },
@@ -14,7 +18,9 @@ export default function Footer() {
];
return (
<footer className="bg-white border-t border-[#e5e7eb] w-full flex flex-col items-center">
<footer className={`w-full flex flex-col items-center border-t ${
isDark ? 'bg-[#0a0a0a] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}>
{/* Main Footer Content */}
<div className="w-full max-w-[1440px] px-6 py-20 flex flex-row gap-8">
@@ -27,12 +33,15 @@ export default function Footer() {
alt="AssetX Logo"
width={160}
height={40}
style={{
filter: isDark ? 'invert(1) brightness(1.2)' : 'none'
}}
/>
</div>
{/* Address */}
<div
className="text-[#9ca1af] text-left font-inter"
className="text-[#9ca1af] text-left font-domine"
style={{
fontSize: '14px',
lineHeight: '150%',
@@ -45,19 +54,24 @@ export default function Footer() {
</div>
{/* Social Icons */}
<div className="flex flex-row gap-4 items-center">
<div className="flex flex-row gap-2 items-center">
{socialIcons.map((icon, index) => (
<div
<Button
key={index}
className="cursor-pointer hover:opacity-70 transition-opacity"
isIconOnly
variant="light"
className="min-w-10 w-10 h-10"
>
<Image
src={icon.src}
alt={icon.alt}
width={icon.width}
height={icon.height}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
</Button>
))}
</div>
</div>
@@ -68,29 +82,29 @@ export default function Footer() {
{/* Products Column */}
<div className="flex flex-col gap-4 w-[178.67px]">
<h3
className="text-[#111827] font-inter"
className={`font-domine font-bold text-base ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 700
lineHeight: '150%'
}}
>
{t('footer.products')}
</h3>
<div className="flex flex-col gap-2">
{[1, 2, 3, 4, 5].map((num) => (
<a
<Link
key={num}
href="#"
className="text-[#9ca1af] hover:text-[#111827] transition-colors font-inter cursor-pointer"
className={`font-domine text-sm ${
isDark ? 'text-[#9ca1af] hover:text-[#fafafa]' : 'text-[#9ca1af] hover:text-[#111827]'
}`}
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
lineHeight: '150%'
}}
>
{t(`footer.product${num}`)}
</a>
</Link>
))}
</div>
</div>
@@ -98,29 +112,29 @@ export default function Footer() {
{/* Resources Column */}
<div className="flex flex-col gap-4 w-[178.67px]">
<h3
className="text-[#111827] font-inter"
className={`font-domine font-bold text-base ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 700
lineHeight: '150%'
}}
>
{t('footer.resources')}
</h3>
<div className="flex flex-col gap-2">
{[1, 2, 3, 4, 5].map((num) => (
<a
<Link
key={num}
href="#"
className="text-[#9ca1af] hover:text-[#111827] transition-colors font-inter cursor-pointer"
className={`font-domine text-sm ${
isDark ? 'text-[#9ca1af] hover:text-[#fafafa]' : 'text-[#9ca1af] hover:text-[#111827]'
}`}
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
lineHeight: '150%'
}}
>
{t(`footer.resource${num}`)}
</a>
</Link>
))}
</div>
</div>
@@ -128,29 +142,29 @@ export default function Footer() {
{/* Company Column */}
<div className="flex flex-col gap-4 w-[178.67px]">
<h3
className="text-[#111827] font-inter"
className={`font-domine font-bold text-base ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 700
lineHeight: '150%'
}}
>
{t('footer.company')}
</h3>
<div className="flex flex-col gap-2">
{[1, 2, 3, 4].map((num) => (
<a
<Link
key={num}
href="#"
className="text-[#9ca1af] hover:text-[#111827] transition-colors font-inter cursor-pointer"
className={`font-domine text-sm ${
isDark ? 'text-[#9ca1af] hover:text-[#fafafa]' : 'text-[#9ca1af] hover:text-[#111827]'
}`}
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
lineHeight: '150%'
}}
>
{t(`footer.company${num}`)}
</a>
</Link>
))}
</div>
</div>
@@ -158,43 +172,34 @@ export default function Footer() {
</div>
{/* Bottom Section - Copyright and Legal Links */}
<div className="w-full max-w-[1440px] border-t border-[#f3f4f6] px-6 py-8 flex flex-row items-center justify-between">
<div className={`w-full max-w-[1440px] border-t px-6 py-8 flex flex-row items-center justify-between ${
isDark ? 'border-[#27272a]' : 'border-[#f3f4f6]'
}`}>
{/* Copyright */}
<div
className="text-[#9ca1af] font-inter"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
}}
>
<div className="text-[#9ca1af] font-domine text-sm" style={{ lineHeight: '150%' }}>
{t('footer.copyright')}
</div>
{/* Legal Links */}
<div className="flex flex-row gap-6">
<a
<Link
href="#"
className="text-[#9ca1af] hover:text-[#111827] transition-colors font-inter cursor-pointer"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
}}
className={`font-domine text-sm ${
isDark ? 'text-[#9ca1af] hover:text-[#fafafa]' : 'text-[#9ca1af] hover:text-[#111827]'
}`}
style={{ lineHeight: '150%' }}
>
{t('footer.privacy')}
</a>
<a
</Link>
<Link
href="#"
className="text-[#9ca1af] hover:text-[#111827] transition-colors font-inter cursor-pointer"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
}}
className={`font-domine text-sm ${
isDark ? 'text-[#9ca1af] hover:text-[#fafafa]' : 'text-[#9ca1af] hover:text-[#111827]'
}`}
style={{ lineHeight: '150%' }}
>
{t('footer.terms')}
</a>
</Link>
</div>
</div>
</footer>

View File

@@ -2,6 +2,7 @@
import { useState, useEffect } from 'react';
import Image from 'next/image';
import { Button } from '@heroui/react';
import { useLanguage } from '@/contexts/LanguageContext';
export default function HeroButtons() {
@@ -9,10 +10,7 @@ export default function HeroButtons() {
const [mounted, setMounted] = useState(false);
useEffect(() => {
console.log('HeroButtons mounted');
// 延迟一些时间后再触发按钮动画,形成渐进效果
const timer = setTimeout(() => {
console.log('HeroButtons animation starting');
setMounted(true);
}, 500);
return () => clearTimeout(timer);
@@ -24,63 +22,34 @@ export default function HeroButtons() {
style={{
transform: mounted ? 'translateY(0)' : 'translateY(3rem)',
opacity: mounted ? 1 : 0,
transition: 'all 1s ease-out'
transition: 'transform 1s ease-out, opacity 1s ease-out'
}}
suppressHydrationWarning
>
{/* .component-82 - Start Investing Button */}
<button
className="bg-white flex flex-row gap-2 items-center justify-center flex-shrink-0 h-[60px] relative overflow-hidden hover:bg-[#f3f4f6] transition-colors select-none"
style={{
borderRadius: '4px',
padding: '0px 32px'
}}
{/* Start Investing Button */}
<Button
size="lg"
className="bg-white text-[#111827] font-bold text-lg h-[60px] px-8"
endContent={
<Image
src="/component-10.svg"
alt="Arrow"
width={20}
height={20}
className="flex-shrink-0"
/>
}
>
{/* .text4 */}
<div
className="text-[#111827] text-center relative flex items-center justify-center font-inter"
style={{
fontSize: '18px',
lineHeight: '150%',
fontWeight: 700
}}
>
{t('hero.startInvesting')}
</div>
{t('hero.startInvesting')}
</Button>
{/* .component-1 - Arrow icon */}
<Image
src="/component-10.svg"
alt="Arrow"
width={20}
height={20}
className="flex-shrink-0 w-5 h-5 relative overflow-visible"
style={{ aspectRatio: 1 }}
/>
</button>
{/* .component-9 - Read the Whitepaper Button */}
<button
className="border border-white/20 flex flex-row gap-2 items-center justify-center self-stretch flex-shrink-0 relative overflow-hidden hover:bg-white/70 hover:border-white/60 transition-all select-none"
style={{
background: 'rgba(255, 255, 255, 0.1)',
borderRadius: '4px',
padding: '12px 32px',
backdropFilter: 'blur(30px)'
}}
{/* Read the Whitepaper Button */}
<Button
size="lg"
variant="bordered"
className="border-white/20 bg-white/10 text-white font-bold text-lg h-[60px] px-8 backdrop-blur-[30px] hover:bg-white/20 hover:border-white/40"
>
{/* .text5 */}
<div
className="text-[#fcfcfd] text-center relative flex items-center justify-center font-inter"
style={{
fontSize: '18px',
lineHeight: '150%',
fontWeight: 700
}}
>
{t('hero.readWhitepaper')}
</div>
</button>
{t('hero.readWhitepaper')}
</Button>
</div>
);
}

View File

@@ -6,8 +6,7 @@ import HeroButtons from './HeroButtons';
export default function HeroSection() {
return (
<section className="relative w-full" style={{ overflow: 'hidden' }} suppressHydrationWarning>
{/* Background Video */}
<section className="relative w-full" style={{ overflow: 'hidden' }}>
<video
autoPlay
loop
@@ -26,7 +25,6 @@ export default function HeroSection() {
<source src="/hero-background.mp4" type="video/mp4" />
</video>
{/* .header - 背景容器 */}
<div
className="flex flex-col items-start justify-center flex-shrink-0 relative"
style={{
@@ -35,13 +33,10 @@ export default function HeroSection() {
minHeight: '670px',
zIndex: 1
}}
suppressHydrationWarning
>
{/* .frame-21 - 主内容容器 */}
<div className="flex flex-col gap-[60px] flex-shrink-0 w-[926px] relative">
<HeroTitle />
<HeroButtons />
</div>
</div>
</section>

View File

@@ -8,9 +8,7 @@ export default function HeroTitle() {
const [mounted, setMounted] = useState(false);
useEffect(() => {
console.log('HeroTitle mounted');
const timer = setTimeout(() => {
console.log('HeroTitle animation starting');
setMounted(true);
}, 400);
return () => clearTimeout(timer);
@@ -22,13 +20,10 @@ export default function HeroTitle() {
style={{
transform: mounted ? 'translateY(0)' : 'translateY(3rem)',
opacity: mounted ? 1 : 0,
transition: 'all 1s ease-out'
transition: 'transform 1s ease-out, opacity 1s ease-out'
}}
suppressHydrationWarning
>
{/* .frame-22 - 标题容器 */}
<div className="flex flex-col gap-4 items-start justify-start self-stretch flex-shrink-0 relative">
{/* .yield-bearing-asset */}
<div
className="text-[#fcfcfd] text-left relative self-stretch font-domine"
style={{
@@ -41,7 +36,6 @@ export default function HeroTitle() {
{t('hero.title1')}
</div>
{/* .on-chain */}
<div
className="text-[#fcfcfd] text-left relative w-[926px] h-[100px] font-domine"
style={{
@@ -55,7 +49,6 @@ export default function HeroTitle() {
</div>
</div>
{/* Description text */}
<div
className="text-[#fcfcfd] text-left relative w-[488px] flex items-center justify-start font-domine"
style={{

View File

@@ -2,7 +2,9 @@
import { useState, useEffect, useRef } from 'react';
import Image from 'next/image';
import { Card, CardBody, Chip } from '@heroui/react';
import { useLanguage } from '@/contexts/LanguageContext';
import { useTheme } from '@/contexts/ThemeContext';
// 数字增长动画Hook
function useCountUp(end: number, duration: number = 1500, startRangePercent: number = 0.75) {
@@ -10,7 +12,7 @@ function useCountUp(end: number, duration: number = 1500, startRangePercent: num
const [count, setCount] = useState(end);
const elementRef = useRef<HTMLDivElement>(null);
const startValueRef = useRef<number>(end);
const animationRef = useRef<number | null>(null);
const timerRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
setMounted(true);
@@ -24,6 +26,11 @@ function useCountUp(end: number, duration: number = 1500, startRangePercent: num
const observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting) {
// 清除之前可能存在的 timer
if (timerRef.current) {
clearInterval(timerRef.current);
}
const start = startValueRef.current;
const startTime = Date.now();
@@ -39,14 +46,15 @@ function useCountUp(end: number, duration: number = 1500, startRangePercent: num
if (progress === 1) {
setCount(end);
clearInterval(timer);
timerRef.current = null;
}
}, 16);
animationRef.current = timer as unknown as number;
return () => clearInterval(timer);
timerRef.current = timer;
} else {
if (animationRef.current) {
clearInterval(animationRef.current);
if (timerRef.current) {
clearInterval(timerRef.current);
timerRef.current = null;
}
setCount(startValueRef.current);
}
@@ -58,7 +66,12 @@ function useCountUp(end: number, duration: number = 1500, startRangePercent: num
observer.observe(elementRef.current);
}
return () => observer.disconnect();
return () => {
if (timerRef.current) {
clearInterval(timerRef.current);
}
observer.disconnect();
};
}, [end, duration, mounted]);
return { count, elementRef };
@@ -66,11 +79,11 @@ function useCountUp(end: number, duration: number = 1500, startRangePercent: num
export default function HowItWorksSection() {
const { t } = useLanguage();
const { theme } = useTheme();
const [animate, setAnimate] = useState(false);
const [activeStep, setActiveStep] = useState(1); // 默认第1步激活
const [activeStep, setActiveStep] = useState(1);
const sectionRef = useRef<HTMLElement>(null);
// 数字动画
const investAmount = useCountUp(100000, 1500, 0.85);
const earnAmount = useCountUp(5150, 1500, 0.85);
@@ -92,6 +105,8 @@ export default function HowItWorksSection() {
return () => observer.disconnect();
}, []);
const isDark = theme === 'dark';
const steps = [
{
number: 1,
@@ -116,36 +131,31 @@ export default function HowItWorksSection() {
return (
<section
ref={sectionRef}
className="bg-[#f9fafb] flex flex-col items-center justify-center flex-shrink-0 w-full relative"
className={`flex flex-col items-center justify-center flex-shrink-0 w-full relative border-y ${
isDark ? 'bg-[#0a0a0a] border-[#27272a]' : 'bg-[#f9fafb] border-[#e5e7eb]'
}`}
style={{
borderStyle: 'solid',
borderColor: '#e5e7eb',
borderWidth: '1px 0px',
padding: '80px 0px'
}}
>
{/* .container20 - Main container */}
<div className="flex flex-row items-start justify-between flex-shrink-0 relative w-[1440px]">
{/* Left Side - Steps (.container21) */}
<div className="flex flex-col gap-10 items-start justify-start flex-shrink-0 relative w-[520px]">
{/* Title (.heading-2) */}
<div className="flex flex-col items-start justify-start flex-shrink-0 relative">
<h2
className="text-[#111827] text-left relative font-inter"
className={`text-left relative font-domine text-5xl font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
fontSize: '48px',
lineHeight: '120%',
letterSpacing: '-0.01em',
fontWeight: 700
letterSpacing: '-0.01em'
}}
>
{t('how.title')}
</h2>
</div>
{/* Steps Container (.frame-34) */}
<div className="flex flex-col gap-6 items-start justify-start flex-shrink-0 relative">
{steps.map((step, index) => {
@@ -156,64 +166,54 @@ export default function HowItWorksSection() {
key={step.number}
onClick={() => setActiveStep(step.number)}
className={`flex flex-row gap-6 items-start justify-start flex-shrink-0 relative cursor-pointer transition-all duration-300 ease-out hover:opacity-80 ${
animate
? 'translate-x-0 opacity-100'
: '-translate-x-12 opacity-0'
animate ? 'translate-x-0 opacity-100' : '-translate-x-12 opacity-0'
}`}
style={{
transitionDelay: `${index * 150}ms`
}}
>
{/* Number and Line Container */}
<div className="pt-2 flex flex-col items-center justify-start self-stretch flex-shrink-0 relative">
{/* Number Badge */}
{isActive ? (
// Active step (black background)
<div
className="bg-[#111827] rounded-[999px] flex items-center justify-center flex-shrink-0 w-8 h-[21.63px] relative transition-all duration-300"
className={`rounded-full flex items-center justify-center flex-shrink-0 w-8 h-[21.63px] transition-all duration-300 ${
isDark ? 'bg-white' : 'bg-[#111827]'
}`}
style={{
padding: '0.31px 0px 1.32px 0px'
}}
>
<span
className="text-[#fcfcfd] text-center relative flex items-center justify-center font-inter transition-all duration-300"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 700
}}
className={`text-center text-sm font-bold font-domine transition-all duration-300 ${
isDark ? 'text-[#0a0a0a]' : 'text-[#fcfcfd]'
}`}
>
{step.number}
</span>
</div>
) : (
// Inactive step (border)
<div
className="bg-[#f9fafb] rounded-[9999px] border-2 border-[#d1d5db] flex items-center justify-center flex-shrink-0 w-8 h-[24.5px] relative transition-all duration-300"
className={`rounded-full border-2 flex items-center justify-center flex-shrink-0 w-8 h-[24.5px] transition-all duration-300 ${
isDark ? 'bg-[#0a0a0a] border-[#3f3f46]' : 'bg-[#f9fafb] border-[#d1d5db]'
}`}
>
<span
className="text-[#9ca1af] text-center relative flex items-center justify-center font-inter transition-all duration-300"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 700
}}
className={`text-center text-sm font-bold font-domine transition-all duration-300 ${
isDark ? 'text-[#71717a]' : 'text-[#9ca1af]'
}`}
>
{step.number}
</span>
</div>
)}
{/* Connecting Line */}
{step.hasLine && (
<div className="pt-6 flex flex-col items-start justify-center flex-1 w-[2px] relative">
<div className="bg-[#e5e7eb] flex-1 w-[2px] relative" />
<div className={`flex-1 w-[2px] ${isDark ? 'bg-[#27272a]' : 'bg-[#e5e7eb]'}`} />
</div>
)}
</div>
{/* Text Content */}
<div
className="flex flex-col gap-2 items-start justify-start flex-1 relative"
style={{
@@ -221,23 +221,23 @@ export default function HowItWorksSection() {
}}
>
<h3
className="text-left relative flex items-center justify-start font-inter transition-all duration-300"
className="text-left text-3xl font-semibold font-domine transition-all duration-300"
style={{
fontSize: '28px',
lineHeight: '130%',
letterSpacing: '-0.005em',
fontWeight: 600,
color: isActive ? '#111827' : '#6b7280'
color: isActive
? (isDark ? '#fafafa' : '#111827')
: (isDark ? '#52525b' : '#6b7280')
}}
>
{step.title}
</h3>
<p
className="text-[#9ca1af] text-left relative self-stretch flex items-center justify-start font-inter"
className={`text-left text-base font-domine ${
isDark ? 'text-[#71717a]' : 'text-[#9ca1af]'
}`}
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
lineHeight: '150%'
}}
>
{step.description}
@@ -249,61 +249,61 @@ export default function HowItWorksSection() {
</div>
</div>
{/* Right Side - Dynamic Cards Container */}
<div
className="calculator-card-container flex flex-col items-start justify-start flex-shrink-0 w-[558px] relative"
style={{
height: '439px'
}}
>
{/* Step 1: Deposit & Mint WUSD Card */}
<>
{/* Coin Images Container - Rotated Card */}
<div
className={`bg-[#111827] rounded-[16px] flex flex-row gap-4 items-start justify-start h-[162px] absolute z-0 transition-all duration-700 ease-out ${
animate && activeStep === 1 ? 'opacity-100' : 'opacity-0'
}`}
style={{
padding: '25px 25px 1px 25px',
left: '205.43px',
top: '15.96px',
boxShadow: '0px 25px 50px -12px rgba(0, 0, 0, 0.25)',
transformOrigin: '0 0',
transform: animate && activeStep === 1
? 'rotate(6.535deg) scale(1, 1) translateX(0)'
: 'rotate(6.535deg) scale(1, 1) translateX(3rem)',
transitionDelay: activeStep === 1 ? '200ms' : '0ms',
pointerEvents: activeStep === 1 ? 'auto' : 'none'
}}
>
{/* USDC Logo */}
<Image
src="/usd-coin-usdc-logo-10.svg"
alt="USDC"
width={64}
height={64}
className="flex-shrink-0"
/>
{/* WUSD Logo */}
<div className="flex-shrink-0 w-[66px] h-[66px] relative">
<div className="absolute inset-0 rounded-full bg-gradient-to-br from-green-400 to-emerald-500" />
<Card
className={`h-[162px] absolute z-0 transition-all duration-700 ease-out ${
animate && activeStep === 1 ? 'opacity-100' : 'opacity-0'
} ${
isDark ? 'bg-white border-[#e5e7eb]' : 'bg-[#111827] border-transparent'
}`}
shadow="lg"
style={{
padding: '25px 25px 1px 25px',
left: '205.43px',
top: '15.96px',
transformOrigin: '0 0',
transform: animate && activeStep === 1
? 'rotate(6.535deg) scale(1, 1) translateX(0)'
: 'rotate(6.535deg) scale(1, 1) translateX(3rem)',
transitionDelay: activeStep === 1 ? '200ms' : '0ms',
pointerEvents: activeStep === 1 ? 'auto' : 'none'
}}
>
<Image
src="/image-220.png"
alt="WUSD"
width={66}
height={66}
className="absolute inset-0 rounded-full"
src="/usd-coin-usdc-logo-10.svg"
alt="USDC"
width={64}
height={64}
className="flex-shrink-0"
/>
</div>
</div>
{/* Calculator Card */}
<div
className={`bg-white/85 backdrop-blur-md rounded-[24px] border border-[#e5e7eb] p-8 absolute left-0 top-[99px] w-full shadow-lg z-10 transition-all duration-700 ease-out ${
<div className="flex-shrink-0 w-[66px] h-[66px] relative">
<div className="absolute inset-0 rounded-full bg-gradient-to-br from-green-400 to-emerald-500" />
<Image
src="/image-220.png"
alt="WUSD"
width={66}
height={66}
className="absolute inset-0 rounded-full"
/>
</div>
</Card>
<Card
className={`absolute left-0 top-[99px] w-full z-10 transition-all duration-700 ease-out ${
animate && activeStep === 1 ? 'opacity-100' : 'opacity-0'
} ${
isDark ? 'bg-[#18181b]/85 border-[#27272a]' : 'bg-white/85 border-[#e5e7eb]'
}`}
shadow="lg"
style={{
backdropFilter: 'blur(12px)',
transform: animate && activeStep === 1
? 'rotate(-3deg) translateX(0)'
: 'rotate(-3deg) translateX(3rem)',
@@ -313,112 +313,109 @@ export default function HowItWorksSection() {
}}
>
{/* Header */}
<div className="flex flex-row items-center justify-between mb-6">
<div className="flex flex-row gap-3 items-center">
<div className="bg-[#111827] rounded-[12px] w-10 h-10 flex items-center justify-center">
<CardBody className="p-8">
<div className="flex flex-row items-center justify-between mb-6">
<div className="flex flex-row gap-3 items-center">
<div className={`rounded-xl w-10 h-10 flex items-center justify-center ${
isDark ? 'bg-white' : 'bg-[#111827]'
}`}>
<Image
src="/icon1.svg"
alt="Portfolio"
width={24}
height={24}
style={{
filter: isDark ? 'none' : 'invert(1)'
}}
/>
</div>
<span
className={`font-domine text-base font-medium ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
>
{t('how.simulator.title')}
</span>
</div>
<Chip className="bg-green-50 text-green-600 font-bold" size="sm">
+5.2% APY
</Chip>
</div>
<div className="mb-4">
<div className="flex flex-col gap-2">
<span
className={`font-domine text-sm ${
isDark ? 'text-[#71717a]' : 'text-[#9ca1af]'
}`}
>
{t('how.simulator.invest')}
</span>
<span
ref={investAmount.elementRef}
className={`font-domine text-3xl font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
lineHeight: '120%',
letterSpacing: '-0.01em'
}}
>
${investAmount.count.toLocaleString()}
</span>
</div>
<div className={`mt-4 h-2 rounded-full relative ${
isDark ? 'bg-[#27272a]' : 'bg-[#e5e7eb]'
}`}>
<div className={`absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-4 h-4 rounded-full ${
isDark ? 'bg-white' : 'bg-[#111827]'
}`} />
</div>
</div>
<div className={`mt-6 pt-6 border-t ${
isDark ? 'border-[#27272a]' : 'border-[#e5e7eb]'
}`}>
<span
className={`font-domine text-sm block mb-2 ${
isDark ? 'text-[#71717a]' : 'text-[#9ca1af]'
}`}
>
{t('how.simulator.earn')}
</span>
<div className="flex flex-row gap-2 items-center">
<Image
src="/icon1.svg"
alt="Portfolio"
src="/icon2.svg"
alt="Earn"
width={24}
height={24}
/>
<span
ref={earnAmount.elementRef}
className="text-green-600 font-domine text-3xl font-bold"
style={{
lineHeight: '120%',
letterSpacing: '-0.01em'
}}
>
+${earnAmount.count.toLocaleString()}
</span>
</div>
<span
className="text-[#111827] font-inter"
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 500
}}
>
{t('how.simulator.title')}
</span>
</div>
<div className="bg-green-50 rounded-lg px-3 py-1">
<span className="text-green-600 font-inter text-sm font-bold">+5.2% APY</span>
</div>
</div>
{/* Investment Amount */}
<div className="mb-4">
<div className="flex flex-col gap-2">
<span
className="text-[#9ca1af] font-inter"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
}}
>
{t('how.simulator.invest')}
</span>
<span
ref={investAmount.elementRef}
className="text-[#111827] font-inter"
style={{
fontSize: '32px',
lineHeight: '120%',
letterSpacing: '-0.01em',
fontWeight: 700
}}
>
${investAmount.count.toLocaleString()}
</span>
</div>
{/* Range Slider */}
<div className="mt-4 h-2 bg-[#e5e7eb] rounded-full relative">
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-4 h-4 bg-[#111827] rounded-full" />
</div>
</div>
{/* Earnings */}
<div className="mt-6 pt-6 border-t border-[#e5e7eb]">
<span
className="text-[#9ca1af] font-inter block mb-2"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
}}
>
{t('how.simulator.earn')}
</span>
<div className="flex flex-row gap-2 items-center">
<Image
src="/icon2.svg"
alt="Earn"
width={24}
height={24}
/>
<span
ref={earnAmount.elementRef}
className="text-green-600 font-inter"
style={{
fontSize: '32px',
lineHeight: '120%',
letterSpacing: '-0.01em',
fontWeight: 700
}}
>
+${earnAmount.count.toLocaleString()}
</span>
</div>
</div>
</div>
</CardBody>
</Card>
</>
{/* Step 2: Dual Investment Options Card */}
<div
className={`bg-white rounded-[16px] border border-[#f3f4f6] p-6 flex flex-col gap-6 absolute left-0 top-[99px] w-full transition-all duration-700 ease-out ${
animate && activeStep === 2
? 'opacity-100'
: 'opacity-0'
<Card
className={`absolute left-0 top-[99px] w-full transition-all duration-700 ease-out ${
animate && activeStep === 2 ? 'opacity-100' : 'opacity-0'
} ${
isDark ? 'bg-[#18181b] border-[#27272a]' : 'bg-white border-[#f3f4f6]'
}`}
shadow="lg"
style={{
boxShadow: '0px 25px 50px -12px rgba(0, 0, 0, 0.25)',
transform: animate && activeStep === 2
? 'rotate(3deg) translateX(0)'
: 'rotate(3deg) translateX(3rem)',
@@ -427,71 +424,90 @@ export default function HowItWorksSection() {
pointerEvents: activeStep === 2 ? 'auto' : 'none'
}}
>
{/* Header */}
<CardBody className="p-6 flex flex-col gap-6">
<div
className="border-b border-[#f3f4f6] pb-4 flex flex-row items-center justify-between w-full"
className={`border-b pb-4 flex flex-row items-center justify-between w-full ${
isDark ? 'border-[#27272a]' : 'border-[#f3f4f6]'
}`}
>
<span className="text-[#000000] font-inter text-[18px] font-bold leading-7">
<span className={`font-domine text-lg font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#000000]'
}`}>
Fund Market
</span>
<span className="text-[#059669] font-inter text-[16px] font-bold leading-6">
<span className="text-[#059669] font-domine text-base font-bold">
Connect Wallet
</span>
</div>
{/* Investment Options Container */}
<div className="flex flex-col gap-4 w-full">
{/* Option 1 - Active */}
<div className="bg-[#f9fafb] rounded-[12px] border border-[#f3f4f6] p-4 flex flex-row gap-4 items-center h-24">
{/* Icon */}
<div className="bg-[#000000] rounded-full w-12 h-12 flex items-center justify-center flex-shrink-0">
<span className="text-white font-inter text-[16px] font-bold">O</span>
<div className={`rounded-xl border p-4 flex flex-row gap-4 items-center h-24 ${
isDark ? 'bg-[#27272a] border-[#3f3f46]' : 'bg-[#f9fafb] border-[#f3f4f6]'
}`}>
<div className={`rounded-full w-12 h-12 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-white' : 'bg-[#000000]'
}`}>
<span className={`font-domine text-base font-bold ${
isDark ? 'text-[#000000]' : 'text-white'
}`}>O</span>
</div>
{/* Text Placeholders */}
<div className="flex flex-col gap-2 flex-1">
<div className="bg-[#e5e7eb] rounded h-4 w-24" />
<div className="bg-[#f3f4f6] rounded h-3 w-16" />
<div className={`rounded h-4 w-24 ${
isDark ? 'bg-[#3f3f46]' : 'bg-[#e5e7eb]'
}`} />
<div className={`rounded h-3 w-16 ${
isDark ? 'bg-[#52525b]' : 'bg-[#f3f4f6]'
}`} />
</div>
{/* APY Info */}
<div className="flex flex-col gap-2 items-end flex-shrink-0">
<div className="bg-[#e5e7eb] rounded h-4 w-20" />
<span className="text-[#059669] font-inter text-[16px] font-bold leading-6">
<div className={`rounded h-4 w-20 ${
isDark ? 'bg-[#3f3f46]' : 'bg-[#e5e7eb]'
}`} />
<span className="text-[#059669] font-domine text-base font-bold">
APY 30.2%
</span>
</div>
</div>
{/* Option 2 - Inactive */}
<div className="bg-[#f9fafb] rounded-[12px] border border-[#f3f4f6] p-4 flex flex-row gap-4 items-center h-24 opacity-60">
{/* Icon */}
<div className="bg-[#d1d5db] rounded-full w-12 h-12 flex-shrink-0" />
<div className={`rounded-xl border p-4 flex flex-row gap-4 items-center h-24 opacity-60 ${
isDark ? 'bg-[#27272a] border-[#3f3f46]' : 'bg-[#f9fafb] border-[#f3f4f6]'
}`}>
<div className={`rounded-full w-12 h-12 flex-shrink-0 ${
isDark ? 'bg-[#52525b]' : 'bg-[#d1d5db]'
}`} />
{/* Text Placeholders */}
<div className="flex flex-col gap-2 flex-1">
<div className="bg-[#e5e7eb] rounded h-4 w-32" />
<div className="bg-[#f3f4f6] rounded h-3 w-20" />
<div className={`rounded h-4 w-32 ${
isDark ? 'bg-[#3f3f46]' : 'bg-[#e5e7eb]'
}`} />
<div className={`rounded h-3 w-20 ${
isDark ? 'bg-[#52525b]' : 'bg-[#f3f4f6]'
}`} />
</div>
{/* APY Info */}
<div className="flex flex-col gap-2 items-end flex-shrink-0">
<div className="bg-[#e5e7eb] rounded h-4 w-20" />
<span className="text-[#059669] font-inter text-[16px] font-bold leading-6">
<div className={`rounded h-4 w-20 ${
isDark ? 'bg-[#3f3f46]' : 'bg-[#e5e7eb]'
}`} />
<span className="text-[#059669] font-domine text-base font-bold">
APY 15.2%
</span>
</div>
</div>
</div>
</div>
</CardBody>
</Card>
{/* Step 3: Earn & Boost Card */}
<div
className={`bg-white rounded-[16px] border border-[#f3f4f6] p-6 flex flex-col gap-6 absolute left-0 top-[99px] w-[520px] transition-all duration-700 ease-out ${
<Card
className={`absolute left-0 top-[99px] w-[520px] transition-all duration-700 ease-out ${
animate && activeStep === 3 ? 'opacity-100' : 'opacity-0'
} ${
isDark ? 'bg-[#18181b] border-[#27272a]' : 'bg-white border-[#f3f4f6]'
}`}
shadow="lg"
style={{
boxShadow: '0px 25px 50px -12px rgba(0, 0, 0, 0.25)',
transform: animate && activeStep === 3
? 'rotate(3deg) translateX(0)'
: 'rotate(3deg) translateX(3rem)',
@@ -501,12 +517,16 @@ export default function HowItWorksSection() {
pointerEvents: activeStep === 3 ? 'auto' : 'none'
}}
>
{/* Header */}
<div className="border-b border-[#f3f4f6] pb-[17px] flex flex-row items-center justify-between" style={{ width: '470px', height: '45px' }}>
<span className="text-[#000000] font-inter text-[18px] font-bold leading-7">
<CardBody className="p-6 flex flex-col gap-6">
<div className={`border-b pb-[17px] flex flex-row items-center justify-between ${
isDark ? 'border-[#27272a]' : 'border-[#f3f4f6]'
}`} style={{ width: '470px', height: '45px' }}>
<span className={`font-domine text-lg font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#000000]'
}`}>
Defi
</span>
<span className="text-[#059669] font-inter text-[16px] font-bold leading-6">
<span className="text-[#059669] font-domine text-base font-bold">
+5.2% APY
</span>
</div>
@@ -536,10 +556,10 @@ export default function HowItWorksSection() {
>
<div className="bg-[#f9fafb] rounded-[12px] border border-[#f3f4f6] p-4 flex flex-col gap-4 items-center absolute" style={{ width: '134.91px', height: '165.18px', left: '0px', top: '0px' }}>
<div className="bg-[#000000] rounded-full w-12 h-12 flex items-center justify-center flex-shrink-0">
<span className="text-white font-inter text-[16px] font-bold leading-6">O</span>
<span className="text-white font-domine text-[16px] font-bold leading-6">O</span>
</div>
<span
className="text-[#000000] font-inter text-[16px] font-bold text-center"
className="text-[#000000] font-domine text-[16px] font-bold text-center"
style={{ width: '124px', height: '17px', transform: 'rotate(-3deg)', transformOrigin: '0 0', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
+10% APY
@@ -548,7 +568,7 @@ export default function HowItWorksSection() {
className="bg-[#000000] rounded-lg px-4 py-2 flex items-center justify-center"
style={{ transform: 'rotate(-3deg)', transformOrigin: '0 0' }}
>
<span className="text-white font-inter text-[12px] font-bold leading-4">
<span className="text-white font-domine text-[12px] font-bold leading-4">
Boost
</span>
</div>
@@ -569,10 +589,10 @@ export default function HowItWorksSection() {
>
<div className="bg-[#f9fafb] rounded-[12px] border border-[#f3f4f6] p-4 flex flex-col gap-4 items-center absolute" style={{ width: '134.91px', height: '165.18px', left: '0px', top: '0px' }}>
<div className="bg-[#000000] rounded-full w-12 h-12 flex items-center justify-center flex-shrink-0">
<span className="text-white font-inter text-[16px] font-bold leading-6">O</span>
<span className="text-white font-domine text-[16px] font-bold leading-6">O</span>
</div>
<span
className="text-[#000000] font-inter text-[16px] font-bold text-center"
className="text-[#000000] font-domine text-[16px] font-bold text-center"
style={{ width: '124px', height: '17px', transform: 'rotate(-3deg)', transformOrigin: '0 0', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
+10% APY
@@ -581,7 +601,7 @@ export default function HowItWorksSection() {
className="bg-[#000000] rounded-lg px-4 py-2 flex items-center justify-center"
style={{ transform: 'rotate(-3deg)', transformOrigin: '0 0' }}
>
<span className="text-white font-inter text-[12px] font-bold leading-4">
<span className="text-white font-domine text-[12px] font-bold leading-4">
Boost
</span>
</div>
@@ -602,10 +622,10 @@ export default function HowItWorksSection() {
>
<div className="bg-[#f9fafb] rounded-[12px] border border-[#f3f4f6] p-4 flex flex-col gap-4 items-center absolute" style={{ width: '134.91px', height: '165.18px', left: '0px', top: '0px' }}>
<div className="bg-[#000000] rounded-full w-12 h-12 flex items-center justify-center flex-shrink-0">
<span className="text-white font-inter text-[16px] font-bold leading-6">O</span>
<span className="text-white font-domine text-[16px] font-bold leading-6">O</span>
</div>
<span
className="text-[#000000] font-inter text-[16px] font-bold text-center"
className="text-[#000000] font-domine text-[16px] font-bold text-center"
style={{ width: '124px', height: '17px', transform: 'rotate(-3deg)', transformOrigin: '0 0', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
+10% APY
@@ -614,7 +634,7 @@ export default function HowItWorksSection() {
className="bg-[#000000] rounded-lg px-4 py-2 flex items-center justify-center"
style={{ transform: 'rotate(-3deg)', transformOrigin: '0 0' }}
>
<span className="text-white font-inter text-[12px] font-bold leading-4">
<span className="text-white font-domine text-[12px] font-bold leading-4">
Boost
</span>
</div>
@@ -635,10 +655,10 @@ export default function HowItWorksSection() {
>
<div className="bg-[#f9fafb] rounded-[12px] border border-[#f3f4f6] p-4 flex flex-col gap-4 items-center absolute" style={{ width: '134.91px', height: '165.18px', left: '0px', top: '0px' }}>
<div className="bg-[#000000] rounded-full w-12 h-12 flex items-center justify-center flex-shrink-0">
<span className="text-white font-inter text-[16px] font-bold leading-6">O</span>
<span className="text-white font-domine text-[16px] font-bold leading-6">O</span>
</div>
<span
className="text-[#000000] font-inter text-[16px] font-bold text-center"
className="text-[#000000] font-domine text-[16px] font-bold text-center"
style={{ width: '124px', height: '17px', transform: 'rotate(-3deg)', transformOrigin: '0 0', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
Get USDC
@@ -647,7 +667,7 @@ export default function HowItWorksSection() {
className="bg-[#000000] rounded-lg px-4 py-2 flex items-center justify-center"
style={{ transform: 'rotate(-3deg)', transformOrigin: '0 0' }}
>
<span className="text-white font-inter text-[12px] font-bold leading-4">
<span className="text-white font-domine text-[12px] font-bold leading-4">
SWAP
</span>
</div>
@@ -668,10 +688,10 @@ export default function HowItWorksSection() {
>
<div className="bg-[#f9fafb] rounded-[12px] border border-[#f3f4f6] p-4 flex flex-col gap-4 items-center absolute" style={{ width: '134.91px', height: '165.18px', left: '0px', top: '0px' }}>
<div className="bg-[#000000] rounded-full w-12 h-12 flex items-center justify-center flex-shrink-0">
<span className="text-white font-inter text-[16px] font-bold leading-6">O</span>
<span className="text-white font-domine text-[16px] font-bold leading-6">O</span>
</div>
<span
className="text-[#000000] font-inter text-[16px] font-bold text-center"
className="text-[#000000] font-domine text-[16px] font-bold text-center"
style={{ width: '124px', height: '17px', transform: 'rotate(-3deg)', transformOrigin: '0 0', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
>
10% APY
@@ -680,14 +700,15 @@ export default function HowItWorksSection() {
className="bg-[#000000] rounded-lg px-4 py-2 flex items-center justify-center"
style={{ transform: 'rotate(-3deg)', transformOrigin: '0 0' }}
>
<span className="text-white font-inter text-[12px] font-bold leading-4">
<span className="text-white font-domine text-[12px] font-bold leading-4">
LP
</span>
</div>
</div>
</div>
</div>
</div>
</CardBody>
</Card>
</div>
</div>

View File

@@ -2,14 +2,26 @@
import { useState, useEffect } from 'react';
import Image from 'next/image';
import {
Navbar as HeroNavbar,
NavbarBrand,
NavbarContent,
NavbarItem,
Button,
Dropdown,
DropdownTrigger,
DropdownMenu,
DropdownItem
} from '@heroui/react';
import ProductMenu from './ProductMenu';
import ResourceMenu from './ResourceMenu';
import { useLanguage } from '@/contexts/LanguageContext';
import { useTheme } from '@/contexts/ThemeContext';
export default function Navbar() {
const [scrolled, setScrolled] = useState(false);
const { language, setLanguage, t } = useLanguage();
const [showLangMenu, setShowLangMenu] = useState(false);
const { theme, toggleTheme } = useTheme();
const [showProductMenu, setShowProductMenu] = useState(false);
const [showResourceMenu, setShowResourceMenu] = useState(false);
const [animate, setAnimate] = useState(false);
@@ -24,7 +36,6 @@ export default function Navbar() {
}, []);
useEffect(() => {
// 页面加载后触发动画
requestAnimationFrame(() => {
requestAnimationFrame(() => {
setAnimate(true);
@@ -35,9 +46,6 @@ export default function Navbar() {
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
const target = e.target as Element;
if (showLangMenu && !target.closest('.language-selector')) {
setShowLangMenu(false);
}
if (showProductMenu && !target.closest('.product-menu-container')) {
setShowProductMenu(false);
}
@@ -48,158 +56,239 @@ export default function Navbar() {
document.addEventListener('click', handleClickOutside);
return () => document.removeEventListener('click', handleClickOutside);
}, [showLangMenu, showProductMenu, showResourceMenu]);
}, [showProductMenu, showResourceMenu]);
const toggleLanguage = (lang: 'zh' | 'en') => {
setLanguage(lang);
setShowLangMenu(false);
};
const isDark = theme === 'dark';
return (
<>
<nav className={`fixed top-0 left-0 right-0 z-50 px-10 py-5 flex items-center justify-between transition-all duration-300 ${
scrolled
? 'bg-white/70 backdrop-blur-[50px] shadow-sm'
: 'bg-white/90 backdrop-blur-[50px]'
}`}>
{/* Logo Section */}
<div
className="flex-1 transition-all duration-1000 ease-out"
<HeroNavbar
maxWidth="full"
style={{
transform: animate ? 'translateY(0)' : 'translateY(-3rem)',
opacity: animate ? 1 : 0
backgroundColor: isDark
? scrolled ? 'rgba(10, 10, 10, 0.7)' : 'rgba(10, 10, 10, 0.9)'
: scrolled ? 'rgba(255, 255, 255, 0.7)' : 'rgba(255, 255, 255, 0.9)',
backdropFilter: 'blur(50px)',
borderBottom: isDark
? scrolled ? '1px solid #27272a' : '1px solid #18181b'
: '1px solid transparent',
transition: 'background-color 0.3s ease-out, border-color 0.3s ease-out'
}}
classNames={{
wrapper: "px-10 py-2"
}}
suppressHydrationWarning
>
<Image
src="/logo0.svg"
alt="Logo"
width={160}
height={40}
priority
/>
</div>
{/* Logo */}
<NavbarBrand>
<div
style={{
transform: animate ? 'translateY(0)' : 'translateY(-3rem)',
opacity: animate ? 1 : 0,
transition: 'transform 1s ease-out, opacity 1s ease-out'
}}
>
<Image
src="/logo0.svg"
alt="Logo"
width={160}
height={40}
priority
style={{
filter: isDark ? 'invert(1) brightness(1.2)' : 'none',
transition: 'filter 0.3s ease-out'
}}
/>
</div>
</NavbarBrand>
{/* Navigation Menu */}
<div className="flex items-center gap-12">
<div className="flex items-center gap-6">
{/* Product - Active */}
<div className="product-menu-container">
<div
className={`rounded-lg px-4 py-2 h-9 flex items-center justify-center cursor-pointer transition-colors select-none ${
showProductMenu ? 'bg-[#f3f4f6]' : 'bg-transparent hover:bg-[#f3f4f6]'
{/* Center Menu */}
<NavbarContent className="hidden sm:flex gap-6" justify="center">
{/* Product */}
<NavbarItem className="product-menu-container">
<Button
variant="light"
className={`font-bold text-sm select-none ${
showProductMenu
? isDark ? 'text-[#fafafa] bg-[#27272a]' : 'text-[#111827] bg-[#f3f4f6]'
: isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'
}`}
onClick={() => {
onPress={() => {
setShowProductMenu(!showProductMenu);
setShowResourceMenu(false);
}}
>
<span className={`font-bold text-sm leading-[150%] font-inter ${
showProductMenu ? 'text-[#111827]' : 'text-[#4b5563]'
}`}>
{t('nav.product')}
</span>
</div>
</div>
{t('nav.product')}
</Button>
</NavbarItem>
{/* Community */}
<div className="bg-transparent rounded-lg px-4 py-2 h-9 flex items-center justify-center hover:bg-[#f3f4f6] transition-colors cursor-pointer select-none">
<span className="text-[#4b5563] font-bold text-sm leading-[150%] font-inter">
<NavbarItem>
<Button
variant="light"
className={`font-bold text-sm select-none ${
isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'
}`}
>
{t('nav.community')}
</span>
</div>
</Button>
</NavbarItem>
{/* Resource */}
<div className="resource-menu-container">
<div
className={`rounded-lg px-4 py-2 h-9 flex items-center justify-center cursor-pointer transition-colors select-none ${
showResourceMenu ? 'bg-[#f3f4f6]' : 'bg-transparent hover:bg-[#f3f4f6]'
<NavbarItem className="resource-menu-container">
<Button
variant="light"
className={`font-bold text-sm select-none ${
showResourceMenu
? isDark ? 'text-[#fafafa] bg-[#27272a]' : 'text-[#111827] bg-[#f3f4f6]'
: isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'
}`}
onClick={() => {
onPress={() => {
setShowResourceMenu(!showResourceMenu);
setShowProductMenu(false);
}}
>
<span className={`font-bold text-sm leading-[150%] font-inter ${
showResourceMenu ? 'text-[#111827]' : 'text-[#4b5563]'
}`}>
{t('nav.resource')}
</span>
</div>
</div>
</div>
</div>
{t('nav.resource')}
</Button>
</NavbarItem>
</NavbarContent>
{/* Launch App Button & Language Selector */}
<div className="flex-1 flex justify-end items-center gap-4">
<div
style={{
transform: animate ? 'translateY(0)' : 'translateY(-3rem)',
opacity: animate ? 1 : 0,
transition: 'transform 1s ease-out 200ms, opacity 1s ease-out 200ms'
}}
suppressHydrationWarning
>
<div className="bg-[#111827] rounded-lg px-5 py-2.5 h-10 flex items-center justify-center overflow-hidden cursor-pointer hover:scale-105 select-none transition-transform duration-300">
<span className="text-[#fcfcfd] font-bold text-sm leading-[150%] font-inter">
{t('nav.launchApp')}
</span>
</div>
</div>
{/* Language Selector */}
<div className="relative language-selector">
<div
className="flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-[#f3f4f6] transition-colors cursor-pointer select-none"
onClick={() => setShowLangMenu(!showLangMenu)}
>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 18.3333C14.6024 18.3333 18.3333 14.6024 18.3333 10C18.3333 5.39763 14.6024 1.66667 10 1.66667C5.39763 1.66667 1.66667 5.39763 1.66667 10C1.66667 14.6024 5.39763 18.3333 10 18.3333Z" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M1.66667 10H18.3333" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M10 1.66667C12.0844 3.94863 13.269 6.91003 13.3333 10C13.269 13.09 12.0844 16.0514 10 18.3333C7.91561 16.0514 6.73104 13.09 6.66667 10C6.73104 6.91003 7.91561 3.94863 10 1.66667Z" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<span className="text-[#4b5563] font-inter text-sm font-bold">
{language === 'zh' ? '中文' : 'EN'}
</span>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4.5L6 7.5L9 4.5" stroke="#4B5563" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
</div>
{/* Dropdown Menu */}
{showLangMenu && (
<div className="absolute right-0 mt-2 w-32 bg-white rounded-lg shadow-lg border border-[#e5e7eb] overflow-hidden z-50">
<div
className={`px-4 py-2.5 hover:bg-[#f3f4f6] cursor-pointer transition-colors select-none ${
language === 'zh' ? 'bg-[#f3f4f6]' : ''
}`}
onClick={() => toggleLanguage('zh')}
{/* Right Content */}
<NavbarContent justify="end" className="gap-4">
{/* Launch App Button */}
<NavbarItem>
<div
style={{
transform: animate ? 'translateY(0)' : 'translateY(-3rem)',
opacity: animate ? 1 : 0,
transition: 'transform 1s ease-out 200ms, opacity 1s ease-out 200ms'
}}
>
<Button
className="font-bold text-sm"
style={{
backgroundColor: isDark ? '#ffffff' : '#111827',
color: isDark ? '#0a0a0a' : '#fafafa',
transition: 'background-color 0.3s ease-out, color 0.3s ease-out'
}}
onPress={() => {}}
>
<span className="text-[#111827] font-inter text-sm font-medium"></span>
</div>
<div
className={`px-4 py-2.5 hover:bg-[#f3f4f6] cursor-pointer transition-colors select-none ${
language === 'en' ? 'bg-[#f3f4f6]' : ''
}`}
onClick={() => toggleLanguage('en')}
>
<span className="text-[#111827] font-inter text-sm font-medium">English</span>
</div>
{t('nav.launchApp')}
</Button>
</div>
)}
</div>
</div>
</nav>
<ProductMenu
isOpen={showProductMenu}
onClose={() => setShowProductMenu(false)}
language={language}
/>
<ResourceMenu
isOpen={showResourceMenu}
onClose={() => setShowResourceMenu(false)}
language={language}
/>
</NavbarItem>
{/* Theme Toggle */}
<NavbarItem>
<Button
isIconOnly
variant="light"
onPress={toggleTheme}
className="transition-colors"
>
<div className="relative w-5 h-5">
{/* Moon icon */}
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="absolute inset-0 transition-all duration-300"
style={{
opacity: isDark ? 1 : 0,
transform: isDark ? 'rotate(0deg) scale(1)' : 'rotate(-90deg) scale(0.5)'
}}
>
<path d="M17.5 10.8333C17.3833 12.2083 16.875 13.4792 16.0625 14.5208C15.25 15.5625 14.1875 16.3333 12.9792 16.7292C11.7708 17.125 10.4792 17.125 9.27083 16.7292C8.0625 16.3333 7 15.5625 6.1875 14.5208C5.375 13.4792 4.86667 12.2083 4.75 10.8333C4.63333 9.45833 4.91667 8.08333 5.5625 6.875C6.20833 5.66667 7.1875 4.6875 8.375 4.04167C9.5625 3.39583 10.9167 3.125 12.2917 3.25C11.2083 4.45833 10.625 6.04167 10.625 7.70833C10.625 9.375 11.2083 10.9583 12.2917 12.1667C13.375 13.375 14.8333 14.0417 16.375 14.0417C16.7917 14.0417 17.2083 14 17.5 10.8333Z" stroke={isDark ? '#a1a1aa' : '#4B5563'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
{/* Sun icon */}
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="absolute inset-0 transition-all duration-300"
style={{
opacity: isDark ? 0 : 1,
transform: isDark ? 'rotate(90deg) scale(0.5)' : 'rotate(0deg) scale(1)'
}}
>
<path d="M10 2.5V4.16667M10 15.8333V17.5M17.5 10H15.8333M4.16667 10H2.5M15.3033 4.69667L14.1667 5.83333M5.83333 14.1667L4.69667 15.3033M15.3033 15.3033L14.1667 14.1667M5.83333 5.83333L4.69667 4.69667M13.3333 10C13.3333 11.8409 11.8409 13.3333 10 13.3333C8.15905 13.3333 6.66667 11.8409 6.66667 10C6.66667 8.15905 8.15905 6.66667 10 6.66667C11.8409 6.66667 13.3333 8.15905 13.3333 10Z" stroke={isDark ? '#a1a1aa' : '#4B5563'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
</div>
</Button>
</NavbarItem>
{/* Language Selector */}
<NavbarItem>
<Dropdown
classNames={{
content: isDark ? 'bg-[#18181b] border-none shadow-lg min-w-[120px] w-[120px]' : 'bg-white border-none shadow-lg min-w-[120px] w-[120px]'
}}
>
<DropdownTrigger>
<Button
variant="light"
className={`font-bold text-sm ${
isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'
}`}
startContent={
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 18.3333C14.6024 18.3333 18.3333 14.6024 18.3333 10C18.3333 5.39763 14.6024 1.66667 10 1.66667C5.39763 1.66667 1.66667 5.39763 1.66667 10C1.66667 14.6024 5.39763 18.3333 10 18.3333Z" stroke={isDark ? '#a1a1aa' : '#4B5563'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M1.66667 10H18.3333" stroke={isDark ? '#a1a1aa' : '#4B5563'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M10 1.66667C12.0844 3.94863 13.269 6.91003 13.3333 10C13.269 13.09 12.0844 16.0514 10 18.3333C7.91561 16.0514 6.73104 13.09 6.66667 10C6.73104 6.91003 7.91561 3.94863 10 1.66667Z" stroke={isDark ? '#a1a1aa' : '#4B5563'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
}
endContent={
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4.5L6 7.5L9 4.5" stroke={isDark ? '#a1a1aa' : '#4B5563'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
}
>
{language === 'zh' ? '中文' : 'EN'}
</Button>
</DropdownTrigger>
<DropdownMenu
aria-label="Language selection"
onAction={(key) => setLanguage(key as 'zh' | 'en')}
selectedKeys={new Set([language])}
classNames={{
list: "py-2"
}}
itemClasses={{
base: "py-3 flex items-center justify-center"
}}
>
<DropdownItem
key="zh"
className={isDark ? 'text-[#fafafa] hover:bg-[#27272a] text-center' : 'text-[#111827] text-center'}
>
</DropdownItem>
<DropdownItem
key="en"
className={isDark ? 'text-[#fafafa] hover:bg-[#27272a] text-center' : 'text-[#111827] text-center'}
>
English
</DropdownItem>
</DropdownMenu>
</Dropdown>
</NavbarItem>
</NavbarContent>
</HeroNavbar>
{/* Custom Menus */}
<ProductMenu
isOpen={showProductMenu}
onClose={() => setShowProductMenu(false)}
language={language}
/>
<ResourceMenu
isOpen={showResourceMenu}
onClose={() => setShowResourceMenu(false)}
language={language}
/>
</>
);
}

View File

@@ -2,6 +2,7 @@
import Image from 'next/image';
import { useState, useEffect } from 'react';
import { useTheme } from '@/contexts/ThemeContext';
interface ProductMenuProps {
isOpen: boolean;
@@ -10,6 +11,8 @@ interface ProductMenuProps {
}
export default function ProductMenu({ isOpen, onClose, language }: ProductMenuProps) {
const { theme } = useTheme();
const isDark = theme === 'dark';
const [isVisible, setIsVisible] = useState(false);
const [isClosing, setIsClosing] = useState(false);
@@ -93,7 +96,9 @@ export default function ProductMenu({ isOpen, onClose, language }: ProductMenuPr
/>
{/* Menu */}
<div className={`fixed left-1/2 -translate-x-1/2 bg-white rounded-2xl shadow-xl border border-[#e5e7eb] p-6 z-50 ${isClosing ? 'animate-slide-up' : 'animate-slide-down'}`}
<div className={`fixed left-1/2 -translate-x-1/2 rounded-2xl shadow-xl border p-6 z-50 transition-colors ${
isDark ? 'bg-[#18181b] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
} ${isClosing ? 'animate-slide-up' : 'animate-slide-down'}`}
style={{ width: '1080px', top: '90px' }}
>
<div className="flex flex-row gap-8">
@@ -101,60 +106,78 @@ export default function ProductMenu({ isOpen, onClose, language }: ProductMenuPr
<div className="flex flex-col gap-2 w-[340px]">
{/* Section Title */}
<div className="px-4 py-2">
<span className="text-[#9ca1af] font-inter text-xs font-medium tracking-wider">
<span className="text-[#9ca1af] font-domine text-xs font-medium tracking-wider">
{t.coreYieldAssets}
</span>
</div>
{/* AX-Fund Card */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#111827] rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#f9fafb]' : 'bg-[#111827]'
}`}>
<Image
src="/environment-rainbow0.svg"
alt="AX-Fund"
width={24}
height={24}
style={{
filter: isDark ? 'invert(1)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1 flex-1">
<div className="flex items-center gap-2">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#f9fafb]' : 'text-[#111827]'
}`}>
{t.axFund}
</span>
<div className="bg-green-50 rounded px-2 py-0.5">
<span className="text-green-600 font-inter text-xs font-medium">
<span className="text-green-600 font-domine text-xs font-medium">
{t.axFundBadge}
</span>
</div>
</div>
<p className="text-[#9ca1af] font-inter text-xs leading-relaxed">
<p className="text-[#9ca1af] font-domine text-xs leading-relaxed">
{t.axFundDesc}
</p>
</div>
</div>
{/* AX-Pool Card */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/environment-planet0.svg"
alt="AX-Pool"
width={24}
height={24}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1 flex-1">
<div className="flex items-center gap-2">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#f9fafb]' : 'text-[#111827]'
}`}>
{t.axPool}
</span>
<div className="bg-blue-50 rounded px-2 py-0.5">
<span className="text-blue-600 font-inter text-xs font-medium">
<span className="text-blue-600 font-domine text-xs font-medium">
{t.axPoolBadge}
</span>
</div>
</div>
<p className="text-[#9ca1af] font-inter text-xs leading-relaxed">
<p className="text-[#9ca1af] font-domine text-xs leading-relaxed">
{t.axPoolDesc}
</p>
</div>
@@ -164,7 +187,9 @@ export default function ProductMenu({ isOpen, onClose, language }: ProductMenuPr
{/* Middle Column - Image + Platforms */}
<div className="flex flex-col gap-6 flex-1 min-w-[380px]">
{/* Image */}
<div className="bg-[#f9fafb] rounded-xl p-3 flex items-center justify-center">
<div className={`rounded-xl p-3 flex items-center justify-center ${
isDark ? 'bg-[#374151]' : 'bg-[#f9fafb]'
}`}>
<Image
src="/image-270.png"
alt="Product Showcase"
@@ -177,66 +202,93 @@ export default function ProductMenu({ isOpen, onClose, language }: ProductMenuPr
{/* Platforms & Protocols */}
<div className="flex flex-col gap-2">
<div className="px-4 py-2">
<span className="text-[#9ca1af] font-inter text-xs font-medium tracking-wider">
<span className="text-[#9ca1af] font-domine text-xs font-medium tracking-wider">
{t.platformsProtocols}
</span>
</div>
<div className="flex flex-col gap-2">
{/* Launchpad */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#111827] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#f9fafb]' : 'bg-[#111827]'
}`}>
<Image
src="/component-20.svg"
alt="Launchpad"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.launchpad}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.launchpadDesc}
</p>
</div>
</div>
{/* DeFi Market */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-21.svg"
alt="DeFi Market"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.defiMarket}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.defiMarketDesc}
</p>
</div>
</div>
{/* Token Factory */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/vuesax-linear-buy-crypto1.svg"
alt="Token Factory"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.tokenFactory}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.tokenFactoryDesc}
</p>
</div>
@@ -248,46 +300,64 @@ export default function ProductMenu({ isOpen, onClose, language }: ProductMenuPr
{/* Right Column - Infrastructure */}
<div className="flex flex-col gap-2 w-[280px]">
<div className="px-4 py-2">
<span className="text-[#9ca1af] font-inter text-xs font-medium tracking-wider">
<span className="text-[#9ca1af] font-domine text-xs font-medium tracking-wider">
{t.infrastructure}
</span>
</div>
<div className="flex flex-col gap-2">
{/* Asset Cockpit */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/navigation-map0.svg"
alt="Asset Cockpit"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.assetCockpit}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.assetCockpitDesc}
</p>
</div>
</div>
{/* Oracle Network */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-10.svg"
alt="Oracle Network"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.oracleNetwork}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.oracleNetworkDesc}
</p>
</div>
@@ -297,12 +367,16 @@ export default function ProductMenu({ isOpen, onClose, language }: ProductMenuPr
</div>
{/* Bottom Border */}
<div className="border-t border-[#f3f4f6] mt-6 pt-4 flex items-center justify-between">
<div className="text-[#9ca1af] font-inter text-sm">
<div className={`border-t mt-6 pt-4 flex items-center justify-between ${
isDark ? 'border-[#27272a]' : 'border-[#f3f4f6]'
}`}>
<div className="text-[#9ca1af] font-domine text-sm">
<span className="font-medium">{t.latestAudit}</span>
<span className="ml-1 text-[#111827] font-bold">{t.auditInfo}</span>
<span className={`ml-1 font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>{t.auditInfo}</span>
</div>
<div className="text-green-600 font-inter text-sm font-bold cursor-pointer hover:opacity-70 transition-opacity">
<div className="text-green-600 font-domine text-sm font-bold cursor-pointer hover:opacity-70 transition-opacity">
{t.viewDocs}
</div>
</div>

View File

@@ -1,15 +1,21 @@
'use client';
import { HeroUIProvider } from '@heroui/react';
import { LanguageProvider } from '@/contexts/LanguageContext';
import { ThemeProvider } from '@/contexts/ThemeContext';
import TransitionWrapper from './TransitionWrapper';
import { ReactNode } from 'react';
export default function Providers({ children }: { children: ReactNode }) {
return (
<LanguageProvider>
<TransitionWrapper>
{children}
</TransitionWrapper>
</LanguageProvider>
<HeroUIProvider>
<ThemeProvider>
<LanguageProvider>
<TransitionWrapper>
{children}
</TransitionWrapper>
</LanguageProvider>
</ThemeProvider>
</HeroUIProvider>
);
}

View File

@@ -2,6 +2,7 @@
import Image from 'next/image';
import { useState, useEffect } from 'react';
import { useTheme } from '@/contexts/ThemeContext';
interface ResourceMenuProps {
isOpen: boolean;
@@ -10,6 +11,8 @@ interface ResourceMenuProps {
}
export default function ResourceMenu({ isOpen, onClose, language }: ResourceMenuProps) {
const { theme } = useTheme();
const isDark = theme === 'dark';
const [isVisible, setIsVisible] = useState(false);
const [isClosing, setIsClosing] = useState(false);
@@ -101,7 +104,9 @@ export default function ResourceMenu({ isOpen, onClose, language }: ResourceMenu
/>
{/* Menu */}
<div className={`fixed left-1/2 -translate-x-1/2 bg-white rounded-2xl shadow-xl border border-[#e5e7eb] p-6 z-50 ${isClosing ? 'animate-slide-up' : 'animate-slide-down'}`}
<div className={`fixed left-1/2 -translate-x-1/2 rounded-2xl shadow-xl border p-6 z-50 transition-colors ${
isDark ? 'bg-[#18181b] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
} ${isClosing ? 'animate-slide-up' : 'animate-slide-down'}`}
style={{ width: '1080px', top: '90px' }}
>
<div className="flex flex-row gap-8">
@@ -109,53 +114,71 @@ export default function ResourceMenu({ isOpen, onClose, language }: ResourceMenu
<div className="flex flex-col gap-2 w-[340px]">
{/* Section Title */}
<div className="px-4 py-2">
<span className="text-[#9ca1af] font-inter text-xs font-medium tracking-wider">
<span className="text-[#9ca1af] font-domine text-xs font-medium tracking-wider">
{t.docLearning}
</span>
</div>
{/* Docs Card */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#111827] rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#374151] hover:border-[#4b5563]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#f9fafb]' : 'bg-[#111827]'
}`}>
<Image
src="/icon-book.svg"
alt="Docs"
width={24}
height={24}
style={{
filter: isDark ? 'invert(1)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1 flex-1">
<div className="flex items-center gap-2">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.docs}
</span>
<div className="bg-green-50 rounded px-2 py-0.5">
<span className="text-green-600 font-inter text-xs font-medium">
<span className="text-green-600 font-domine text-xs font-medium">
{t.docsBadge}
</span>
</div>
</div>
<p className="text-[#9ca1af] font-inter text-xs leading-relaxed">
<p className="text-[#9ca1af] font-domine text-xs leading-relaxed">
{t.docsDesc}
</p>
</div>
</div>
{/* Trust & Security Card */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#374151] hover:border-[#4b5563]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-12 h-12 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#374151]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-11.svg"
alt="Trust & Security"
width={24}
height={24}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1 flex-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.trustSecurity}
</span>
<p className="text-[#9ca1af] font-inter text-xs leading-relaxed">
<p className="text-[#9ca1af] font-domine text-xs leading-relaxed">
{t.trustSecurityDesc}
</p>
</div>
@@ -165,7 +188,9 @@ export default function ResourceMenu({ isOpen, onClose, language }: ResourceMenu
{/* Middle Column - Image + Help & Support */}
<div className="flex flex-col gap-6 flex-1 min-w-[380px]">
{/* Image */}
<div className="bg-[#f9fafb] rounded-xl p-3 flex items-center justify-center">
<div className={`rounded-xl p-3 flex items-center justify-center ${
isDark ? 'bg-[#374151]' : 'bg-[#f9fafb]'
}`}>
<Image
src="/image-280.png"
alt="Resource Showcase"
@@ -178,66 +203,93 @@ export default function ResourceMenu({ isOpen, onClose, language }: ResourceMenu
{/* Help & Support */}
<div className="flex flex-col gap-2">
<div className="px-4 py-2">
<span className="text-[#9ca1af] font-inter text-xs font-medium tracking-wider">
<span className="text-[#9ca1af] font-domine text-xs font-medium tracking-wider">
{t.helpSupport}
</span>
</div>
<div className="flex flex-col gap-2">
{/* Learning Center */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-12.svg"
alt="Learning Center"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.learningCenter}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.learningCenterDesc}
</p>
</div>
</div>
{/* Community Forum */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/communication-chat-conversation0.svg"
alt="Community Forum"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.communityForum}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.communityForumDesc}
</p>
</div>
</div>
{/* Contact Support */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-13.svg"
alt="Contact Support"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.contactSupport}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.contactSupportDesc}
</p>
</div>
@@ -249,86 +301,122 @@ export default function ResourceMenu({ isOpen, onClose, language }: ResourceMenu
{/* Right Column - Company */}
<div className="flex flex-col gap-2 w-[280px]">
<div className="px-4 py-2">
<span className="text-[#9ca1af] font-inter text-xs font-medium tracking-wider">
<span className="text-[#9ca1af] font-domine text-xs font-medium tracking-wider">
{t.company}
</span>
</div>
<div className="flex flex-col gap-2">
{/* About Team */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-14.svg"
alt="About Team"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.aboutTeam}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.aboutTeamDesc}
</p>
</div>
</div>
{/* Careers */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-20-dark.svg"
alt="Careers"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.careers}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.careersDesc}
</p>
</div>
</div>
{/* Contact Us */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-21.svg"
alt="Contact Us"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.contactUs}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.contactUsDesc}
</p>
</div>
</div>
{/* Press & Media */}
<div className="bg-transparent hover:bg-[#f9fafb] border border-transparent hover:border-[#e5e7eb] rounded-xl p-3 flex gap-2 cursor-pointer transition-all">
<div className="bg-[#f3f4f6] rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0">
<div className={`bg-transparent border border-transparent rounded-xl p-3 flex gap-2 cursor-pointer transition-all ${
isDark ? 'hover:bg-[#27272a] hover:border-[#3f3f46]' : 'hover:bg-[#f9fafb] hover:border-[#e5e7eb]'
}`}>
<div className={`rounded-xl w-8 h-8 flex items-center justify-center flex-shrink-0 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f3f4f6]'
}`}>
<Image
src="/component-22.svg"
alt="Press & Media"
width={16}
height={16}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-1">
<span className="text-[#111827] font-inter text-sm font-bold">
<span className={`font-domine text-sm font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>
{t.pressMedia}
</span>
<p className="text-[#9ca1af] font-inter text-xs">
<p className="text-[#9ca1af] font-domine text-xs">
{t.pressMediaDesc}
</p>
</div>
@@ -338,16 +426,24 @@ export default function ResourceMenu({ isOpen, onClose, language }: ResourceMenu
</div>
{/* Bottom Border */}
<div className="border-t border-[#f3f4f6] mt-6 pt-4 flex items-center justify-between">
<div className="text-[#9ca1af] font-inter text-sm">
<div className={`border-t mt-6 pt-4 flex items-center justify-between ${
isDark ? 'border-[#27272a]' : 'border-[#f3f4f6]'
}`}>
<div className="text-[#9ca1af] font-domine text-sm">
<span className="font-medium">{t.latestAudit}</span>
<span className="ml-1 text-[#111827] font-bold">{t.auditInfo}</span>
<span className={`ml-1 font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}>{t.auditInfo}</span>
</div>
<div className="flex gap-4">
<div className="text-[#9ca1af] font-inter text-sm cursor-pointer hover:text-[#111827] transition-colors">
<div className={`text-[#9ca1af] font-domine text-sm cursor-pointer transition-colors ${
isDark ? 'hover:text-[#fafafa]' : 'hover:text-[#111827]'
}`}>
{t.privacyPolicy}
</div>
<div className="text-[#9ca1af] font-inter text-sm cursor-pointer hover:text-[#111827] transition-colors">
<div className={`text-[#9ca1af] font-domine text-sm cursor-pointer transition-colors ${
isDark ? 'hover:text-[#fafafa]' : 'hover:text-[#111827]'
}`}>
{t.termsOfService}
</div>
</div>

View File

@@ -2,12 +2,14 @@
import { useState, useEffect, useRef } from 'react';
import Image from 'next/image';
import { Card, CardBody } from '@heroui/react';
import { useLanguage } from '@/contexts/LanguageContext';
export default function SecuritySection() {
const { t } = useLanguage();
const [animate, setAnimate] = useState(false);
const sectionRef = useRef<HTMLElement>(null);
const [cardHovers, setCardHovers] = useState<{[key: number]: {x: number, y: number} | null}>({});
useEffect(() => {
const currentRef = sectionRef.current;
@@ -27,6 +29,67 @@ export default function SecuritySection() {
return () => observer.disconnect();
}, []);
const handleCardMouseMove = (e: React.MouseEvent<HTMLDivElement>, index: number) => {
const rect = e.currentTarget.getBoundingClientRect();
const x = ((e.clientX - rect.left) / rect.width) * 100;
const y = ((e.clientY - rect.top) / rect.height) * 100;
setCardHovers(prev => ({...prev, [index]: {x, y}}));
};
const handleCardMouseLeave = (index: number) => {
setCardHovers(prev => ({...prev, [index]: null}));
};
const getBorderGradients = (index: number) => {
const hover = cardHovers[index];
if (!hover) return {
showTop: false,
showRight: false,
showBottom: false,
showLeft: false,
topGradient: '',
rightGradient: '',
bottomGradient: '',
leftGradient: ''
};
const { x, y } = hover;
// 判断鼠标靠近哪两个边
const nearTop = y < 50;
const nearLeft = x < 50;
// 计算渐变:以鼠标位置为中心向两边扩散
const spreadRange = 25; // 扩散范围百分比
// 上/下边框:以鼠标 x 位置为中心
const horizontalGradient = `linear-gradient(to right,
transparent 0%,
rgba(136,136,136,0.3) ${Math.max(0, x - spreadRange)}%,
rgba(136,136,136,1) ${x}%,
rgba(136,136,136,0.3) ${Math.min(100, x + spreadRange)}%,
transparent 100%)`;
// 左/右边框:以鼠标 y 位置为中心
const verticalGradient = `linear-gradient(to bottom,
transparent 0%,
rgba(136,136,136,0.3) ${Math.max(0, y - spreadRange)}%,
rgba(136,136,136,1) ${y}%,
rgba(136,136,136,0.3) ${Math.min(100, y + spreadRange)}%,
transparent 100%)`;
return {
showTop: nearTop,
showRight: !nearLeft,
showBottom: !nearTop,
showLeft: nearLeft,
topGradient: horizontalGradient,
rightGradient: verticalGradient,
bottomGradient: horizontalGradient,
leftGradient: verticalGradient
};
};
const features = [
{
icon: '/interface-search-magnifying-glass0.svg',
@@ -47,7 +110,7 @@ export default function SecuritySection() {
position: 'bottom-left'
},
{
icon: '/component-11.svg',
icon: '/component-10.svg',
titleKey: 'security.partners.title',
descKey: null,
position: 'bottom-right',
@@ -64,41 +127,30 @@ export default function SecuritySection() {
gap: '40px'
}}
>
{/* Main Container */}
<div className="flex flex-row items-start justify-start flex-shrink-0 w-[1440px] relative">
{/* Left Side - Title */}
<div
className={`flex flex-row items-center justify-center flex-shrink-0 w-[459px] h-[604px] relative transition-all duration-700 ease-out ${
animate
? 'translate-x-0 opacity-100'
: '-translate-x-12 opacity-0'
className={`flex flex-row items-center justify-center flex-shrink-0 w-[459px] h-[604px] relative transition-all duration-700 ease-out border-b border-[#222222] ${
animate ? 'translate-x-0 opacity-100' : '-translate-x-12 opacity-0'
}`}
style={{
borderStyle: 'solid',
borderColor: '#222222',
borderWidth: '0px 0px 1px 0px',
padding: '180px 24px 180px 120px'
}}
>
<div className="flex flex-col gap-6 items-start justify-start flex-1 relative">
<h2
className="text-[#fcfcfd] text-left relative self-stretch font-domine"
className="text-[#fcfcfd] text-left relative self-stretch font-domine text-5xl select-none"
style={{
fontSize: '48px',
lineHeight: '120%',
letterSpacing: '-0.01em',
fontWeight: 400
letterSpacing: '-0.01em'
}}
>
{t('security.title')}
</h2>
<p
className="text-[#9ca1af] text-left relative w-[290px] flex items-center justify-start font-domine"
className="text-[#9ca1af] text-left relative w-[290px] flex items-center justify-start font-domine text-base select-none"
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
lineHeight: '150%'
}}
>
{t('security.subtitle')}
@@ -106,7 +158,6 @@ export default function SecuritySection() {
</div>
</div>
{/* Right Side - Grid */}
<div
className="flex-shrink-0 grid gap-0 relative"
style={{
@@ -115,93 +166,138 @@ export default function SecuritySection() {
gridTemplateRows: 'repeat(2, fit-content(100%))'
}}
>
{features.map((feature, index) => (
{features.map((feature, index) => {
const borders = getBorderGradients(index);
return (
<div
key={feature.titleKey}
className={`flex flex-col items-start justify-center relative transition-all duration-700 ease-out ${
animate
? 'translate-y-0 opacity-100'
: 'translate-y-12 opacity-0'
}`}
className="relative group"
style={{
borderStyle: 'solid',
borderColor: '#222222',
borderWidth:
feature.position === 'top-left' ? '0px 1px 1px 1px' :
feature.position === 'top-right' ? '0px 0px 1px 0px' :
feature.position === 'bottom-left' ? '0px 1px 1px 1px' :
'0px 1px 1px 0px',
padding: '72px 48px 72px 48px',
gridColumn: feature.position.includes('left') ? '1 / span 1' : '2 / span 1',
gridRow: feature.position.includes('top') ? '1 / span 1' : '2 / span 1',
height: feature.position === 'bottom-right' ? '302px' : 'auto',
transitionDelay: `${index * 150}ms`
}}
onMouseMove={(e) => handleCardMouseMove(e, index)}
onMouseLeave={() => handleCardMouseLeave(index)}
>
{feature.special ? (
// Special card (bottom-right)
<div className="flex flex-col gap-6 items-start justify-center self-stretch flex-shrink-0 h-[166px] relative">
<div className="flex flex-col gap-4 items-start justify-start self-stretch flex-shrink-0 relative">
<h3
className="text-[#fcfcfd] text-left relative self-stretch font-domine"
style={{
fontSize: '24px',
lineHeight: '140%',
fontWeight: 400
}}
>
{t(feature.titleKey)}
</h3>
{/* 上边框渐变 */}
{borders.showTop && (
<div
className="absolute top-0 left-0 right-0 h-[1px] z-10"
style={{
background: borders.topGradient,
pointerEvents: 'none'
}}
/>
)}
{/* 右边框渐变 */}
{borders.showRight && (
<div
className="absolute top-0 right-0 bottom-0 w-[1px] z-10"
style={{
background: borders.rightGradient,
pointerEvents: 'none'
}}
/>
)}
{/* 下边框渐变 */}
{borders.showBottom && (
<div
className="absolute bottom-0 left-0 right-0 h-[1px] z-10"
style={{
background: borders.bottomGradient,
pointerEvents: 'none'
}}
/>
)}
{/* 左边框渐变 */}
{borders.showLeft && (
<div
className="absolute top-0 left-0 bottom-0 w-[1px] z-10"
style={{
background: borders.leftGradient,
pointerEvents: 'none'
}}
/>
)}
<Card
className={`rounded-none bg-black border-[#222222] transition-all duration-300 ${
animate ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
}`}
shadow="none"
style={{
borderStyle: 'solid',
borderWidth:
feature.position === 'top-left' ? '0px 1px 1px 1px' :
feature.position === 'top-right' ? '0px 0px 1px 0px' :
feature.position === 'bottom-left' ? '0px 1px 1px 1px' :
'0px 1px 1px 0px',
height: '302px',
transitionDelay: animate ? `${index * 150}ms` : '0ms'
}}
>
<CardBody className="p-[72px_48px] flex items-start justify-center overflow-hidden">
{feature.special ? (
<div className="flex flex-col gap-6 items-start justify-center self-stretch h-[166px]">
<div className="flex flex-col gap-4 items-start justify-start self-stretch">
<h3
className="text-[#fcfcfd] text-left relative self-stretch font-domine text-2xl"
style={{
lineHeight: '140%'
}}
>
{t(feature.titleKey)}
</h3>
<Image
src={feature.icon}
alt="Icon"
width={24}
height={24}
className="flex-shrink-0 brightness-0 invert arrow-icon"
/>
</div>
</div>
) : (
<div className="flex flex-col gap-6 items-start justify-start self-stretch">
<Image
src={feature.icon}
alt="Icon"
width={24}
height={24}
alt={t(feature.titleKey)}
width={32}
height={32}
className="flex-shrink-0"
/>
<div className="flex flex-col gap-2 items-start justify-start self-stretch">
<h3
className="text-[#fcfcfd] text-left relative self-stretch font-domine text-2xl font-bold"
style={{
lineHeight: '130%',
letterSpacing: '-0.005em'
}}
>
{t(feature.titleKey)}
</h3>
<p
className="text-[#9ca1af] text-left relative self-stretch font-domine text-sm"
style={{
lineHeight: '150%'
}}
>
{feature.descKey && t(feature.descKey)}
</p>
</div>
</div>
</div>
) : (
// Regular cards
<div className="flex flex-col gap-6 items-start justify-start self-stretch flex-shrink-0 relative">
<Image
src={feature.icon}
alt={t(feature.titleKey)}
width={32}
height={32}
className="flex-shrink-0"
/>
<div className="flex flex-col gap-2 items-start justify-start self-stretch flex-shrink-0 relative">
<h3
className="text-[#fcfcfd] text-left relative self-stretch font-inter"
style={{
fontSize: '24px',
lineHeight: '130%',
letterSpacing: '-0.005em',
fontWeight: 700
}}
>
{t(feature.titleKey)}
</h3>
<p
className="text-[#9ca1af] text-left relative self-stretch font-inter"
style={{
fontSize: '14px',
lineHeight: '150%',
fontWeight: 400
}}
>
{feature.descKey && t(feature.descKey)}
</p>
</div>
</div>
)}
)}
</CardBody>
</Card>
</div>
))}
);
})}
</div>
</div>
{/* Logo */}
<div className="flex-shrink-0 w-[1200px] h-[187px] relative">
<Image
src="/logo1.svg"

View File

@@ -1,8 +1,9 @@
'use client';
import { useState, useEffect, useRef } from 'react';
import Image from 'next/image';
import { Card, CardBody, Avatar, AvatarGroup } from '@heroui/react';
import { useLanguage } from '@/contexts/LanguageContext';
import { useTheme } from '@/contexts/ThemeContext';
// 数字增长动画Hook - 可重复触发
function useCountUp(end: number, duration: number = 1500, startRangePercent: number = 0.75) {
@@ -93,39 +94,31 @@ function formatNumber(num: number, prefix: string = '', suffix: string = '', for
export default function StatsSection() {
const { t } = useLanguage();
const tvl = useCountUp(485, 1500, 0.80); // 从80-95%开始
const apy = useCountUp(515, 1500, 0.85); // 5.15 * 100从85-100%开始
const yield_ = useCountUp(45, 1500, 0.75); // 从75-90%开始
const users = useCountUp(23928, 1800, 0.80); // 从80-95%开始
const { theme } = useTheme();
const tvl = useCountUp(485, 1500, 0.80);
const apy = useCountUp(515, 1500, 0.85);
const yield_ = useCountUp(45, 1500, 0.75);
const users = useCountUp(23928, 1800, 0.80);
const [mounted, setMounted] = useState(false);
const [imagesVisible, setImagesVisible] = useState(false);
useEffect(() => {
// 客户端挂载
setMounted(true);
// 延迟显示图片动画
const timer = setTimeout(() => {
setImagesVisible(true);
}, 500);
return () => clearTimeout(timer);
}, []);
const isDark = theme === 'dark';
return (
<section
className="bg-white flex flex-row items-center justify-center flex-shrink-0 w-full relative"
style={{
borderStyle: 'solid',
borderColor: '#e5e7eb',
borderWidth: '0px 0px 1px 0px',
padding: '0px 0px 1px 0px'
}}
className={`flex flex-row items-center justify-center flex-shrink-0 w-full relative border-b transition-colors ${
isDark ? 'bg-[#0a0a0a] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}
>
{/* .section2 */}
<div
className="flex flex-row items-center justify-center w-[1440px] h-[183px] relative"
>
{/* .container4 - Grid container */}
<div className="flex flex-row items-center justify-center w-[1440px] h-[183px] relative">
<div
className="flex-shrink-0 grid gap-0 relative w-full"
style={{
@@ -133,279 +126,140 @@ export default function StatsSection() {
gridTemplateRows: 'repeat(1, minmax(0, 1fr))'
}}
>
{/* Card 1 - Total Value Locked */}
<div
className="bg-white flex flex-row items-center justify-between h-[182px] relative"
<Card
className={`h-[182px] rounded-none border-r transition-colors ${
isDark ? 'bg-[#0a0a0a] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}
shadow="none"
style={{
borderStyle: 'solid',
borderColor: '#e5e7eb',
borderWidth: '0px 1px 0px 0px',
gridColumn: '1 / span 1',
gridRow: '1 / span 1'
}}
>
<div className="flex flex-col gap-2 items-start justify-center flex-1 relative">
<div
className="text-[#4b5563] text-left relative font-inter"
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
}}
>
<CardBody className="flex flex-col gap-2 items-start justify-center">
<p className={`text-base font-domine transition-colors ${isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'}`}>
{t('stats.tvl')}
</div>
</p>
<div
ref={tvl.elementRef}
className="text-[#111827] text-left relative font-jetbrains"
className={`text-5xl font-extrabold font-domine transition-colors ${isDark ? 'text-[#fafafa]' : 'text-[#111827]'}`}
style={{
fontSize: '48px',
lineHeight: '110%',
letterSpacing: '-0.01em',
fontWeight: 800
letterSpacing: '-0.01em'
}}
>
{formatNumber(tvl.count, '$', 'M+', 'M')}
</div>
</div>
</div>
</CardBody>
</Card>
{/* Card 2 - Avg. APY */}
<div
className="bg-white flex flex-row items-center justify-between h-[182px] relative"
<Card
className={`h-[182px] rounded-none border-r px-8 transition-colors ${
isDark ? 'bg-[#0a0a0a] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}
shadow="none"
style={{
borderStyle: 'solid',
borderColor: '#e5e7eb',
borderWidth: '0px 1px 0px 0px',
padding: '0px 32px',
gridColumn: '2 / span 1',
gridRow: '1 / span 1'
}}
>
<div className="flex flex-col gap-2 items-start justify-center flex-1 relative">
<div
className="text-[#4b5563] text-left relative font-inter"
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
}}
>
<CardBody className="flex flex-col gap-2 items-start justify-center">
<p className={`text-base font-domine transition-colors ${isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'}`}>
{t('stats.apy')}
</div>
</p>
<div
ref={apy.elementRef}
className="text-[#111827] text-left relative font-jetbrains"
className={`text-5xl font-extrabold font-domine transition-colors ${isDark ? 'text-[#fafafa]' : 'text-[#111827]'}`}
style={{
fontSize: '48px',
lineHeight: '110%',
letterSpacing: '-0.01em',
fontWeight: 800
letterSpacing: '-0.01em'
}}
>
{(apy.count / 100).toFixed(2)}%
</div>
</div>
</div>
</CardBody>
</Card>
{/* Card 3 - Yield Captured */}
<div
className="bg-white flex flex-row items-center justify-between h-[182px] relative"
<Card
className={`h-[182px] rounded-none border-r px-8 transition-colors ${
isDark ? 'bg-[#0a0a0a] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}
shadow="none"
style={{
borderStyle: 'solid',
borderColor: '#e5e7eb',
borderWidth: '0px 1px 0px 0px',
padding: '0px 32px',
gridColumn: '3 / span 1',
gridRow: '1 / span 1'
}}
>
<div className="flex flex-col gap-2 items-start justify-center flex-1 relative">
<div
className="text-[#4b5563] text-left relative font-inter"
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
}}
>
<CardBody className="flex flex-col gap-2 items-start justify-center">
<p className={`text-base font-domine transition-colors ${isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'}`}>
{t('stats.yield')}
</div>
</p>
<div
ref={yield_.elementRef}
className="text-[#111827] text-left relative self-stretch font-jetbrains"
className={`text-5xl font-extrabold font-domine transition-colors ${isDark ? 'text-[#fafafa]' : 'text-[#111827]'}`}
style={{
fontSize: '48px',
lineHeight: '110%',
letterSpacing: '-0.01em',
fontWeight: 800
letterSpacing: '-0.01em'
}}
>
{formatNumber(yield_.count, '$', 'M', 'M')}
</div>
</div>
</div>
</CardBody>
</Card>
{/* Card 4 - Connected Users */}
<div
className="bg-white flex flex-row items-center justify-between h-[182px] relative"
<Card
className={`h-[182px] rounded-none pl-8 transition-colors ${
isDark ? 'bg-[#0a0a0a]' : 'bg-white'
}`}
shadow="none"
style={{
borderStyle: 'solid',
borderColor: 'transparent',
borderWidth: '0px 1px 0px 0px',
padding: '0px 0px 0px 32px',
gridColumn: '4 / span 1',
gridRow: '1 / span 1'
}}
>
<div className="flex flex-col gap-2 items-start justify-center flex-1 relative">
<div
className="text-[#4b5563] text-left relative font-inter"
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
}}
>
<CardBody className="flex flex-col gap-2 items-start justify-center">
<p className={`text-base font-domine transition-colors ${isDark ? 'text-[#a1a1aa]' : 'text-[#4b5563]'}`}>
{t('stats.users')}
</div>
</p>
{/* .frame-38 - Number and avatars */}
<div className="flex flex-row items-center justify-between self-stretch flex-shrink-0 relative">
{/* Number */}
<div className="flex flex-row items-center justify-between self-stretch">
<div
ref={users.elementRef}
className="text-[#111827] text-left relative font-jetbrains"
className={`text-5xl font-extrabold font-domine transition-colors ${isDark ? 'text-[#fafafa]' : 'text-[#111827]'}`}
style={{
fontSize: '48px',
lineHeight: '110%',
letterSpacing: '-0.01em',
fontWeight: 800
letterSpacing: '-0.01em'
}}
>
{users.count.toLocaleString()}+
</div>
{/* .container9 - Avatar group */}
<div className="flex flex-row items-center justify-start flex-shrink-0 relative overflow-hidden">
{/* Avatar 1 - image-23 */}
<div
className={`flex-shrink-0 w-9 h-9 relative overflow-hidden border-white transition-all duration-700 ease-out ${
mounted && imagesVisible ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
}`}
style={{
borderRadius: '15239273px',
borderStyle: 'solid',
borderWidth: '1.82px',
padding: '1.82px',
aspectRatio: 1,
transitionDelay: '100ms'
}}
>
<Image
src="/image-230.png"
alt="User"
width={33}
height={33}
className="absolute object-cover"
style={{
left: '1.82px',
top: '1.82px',
aspectRatio: 1
}}
/>
</div>
{/* Avatar 2 - image-24 */}
<div
className={`flex-shrink-0 w-9 h-9 relative overflow-hidden border-white transition-all duration-700 ease-out ${
mounted && imagesVisible ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
}`}
style={{
margin: '0 0 0 -8px',
borderRadius: '15239273px',
borderStyle: 'solid',
borderWidth: '1.82px',
padding: '1.82px',
aspectRatio: 1,
transitionDelay: '200ms'
}}
>
<Image
src="/image-240.png"
alt="User"
width={36}
height={36}
className="absolute object-cover"
style={{
left: '0px',
top: '0px',
aspectRatio: 1
}}
/>
</div>
{/* Avatar 3 - image-25 */}
<div
className={`flex-shrink-0 w-9 h-9 relative overflow-hidden border-white transition-all duration-700 ease-out ${
mounted && imagesVisible ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
}`}
style={{
margin: '0 0 0 -8px',
borderRadius: '15239273px',
borderStyle: 'solid',
borderWidth: '1.82px',
padding: '1.82px',
aspectRatio: 1,
transitionDelay: '300ms'
}}
>
<Image
src="/image-250.png"
alt="User"
width={40}
height={40}
className="absolute object-cover"
style={{
left: '6px',
top: '0.5px',
aspectRatio: 1
}}
/>
</div>
{/* Avatar 4 - image-252 */}
<div
className={`flex-shrink-0 w-9 h-9 relative overflow-hidden border-white transition-all duration-700 ease-out ${
mounted && imagesVisible ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
}`}
style={{
margin: '0 0 0 -8px',
borderRadius: '15239273px',
borderStyle: 'solid',
borderWidth: '1.82px',
padding: '1.82px',
aspectRatio: 1,
transitionDelay: '400ms'
}}
>
<Image
src="/image-251.png"
alt="User"
width={36}
height={36}
className="absolute object-cover"
style={{
left: '0px',
top: '0px',
aspectRatio: 1
}}
/>
</div>
</div>
<AvatarGroup
max={4}
className={`transition-all duration-700 ease-out ${
mounted && imagesVisible ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
}`}
>
<Avatar
src="/image-230.png"
size="sm"
/>
<Avatar
src="/image-240.png"
size="sm"
/>
<Avatar
src="/image-250.png"
size="sm"
/>
<Avatar
src="/image-251.png"
size="sm"
/>
</AvatarGroup>
</div>
</div>
</div>
</CardBody>
</Card>
</div>
</div>
</section>

View File

@@ -2,7 +2,7 @@
import { useLanguage } from '@/contexts/LanguageContext';
import ShatterTransition from './ShatterTransition';
import { useState, useEffect } from 'react';
import { useState, useEffect, useCallback } from 'react';
export default function TransitionWrapper({ children }: { children: React.ReactNode }) {
const { transitionKey } = useLanguage();
@@ -22,14 +22,16 @@ export default function TransitionWrapper({ children }: { children: React.ReactN
}
}, [transitionKey]);
const handleComplete = useCallback(() => {
// 动画完成后的回调
}, []);
return (
<>
{children}
<ShatterTransition
isActive={isActive}
onComplete={() => {
// 动画完成后的回调
}}
onComplete={handleComplete}
/>
</>
);

View File

@@ -3,10 +3,12 @@
import { useState, useEffect, useRef } from 'react';
import Image from 'next/image';
import { useLanguage } from '@/contexts/LanguageContext';
import { useTheme } from '@/contexts/ThemeContext';
import ConsenSysLogo from './ConsenSysLogo';
export default function TrustedBySection() {
const { t } = useLanguage();
const { theme } = useTheme();
const [animate, setAnimate] = useState(false);
const sectionRef = useRef<HTMLElement>(null);
@@ -18,7 +20,7 @@ export default function TrustedBySection() {
(entries) => {
if (entries[0].isIntersecting) {
setAnimate(true);
observer.disconnect(); // 触发后立即断开
observer.disconnect();
}
},
{ threshold: 0.3 }
@@ -28,80 +30,70 @@ export default function TrustedBySection() {
return () => observer.disconnect();
}, []);
// 合作伙伴 logo 数据 - 统一高度为40px
const isDark = theme === 'dark';
const partners = [
{
name: 'BlackRock',
src: '/nav-ireland0.svg',
width: 200,
height: 40,
className: 'w-[200px] h-[40px]'
height: 40
},
{
name: 'Coinbase',
src: '/coinbase-10.svg',
width: 180,
height: 40,
className: 'w-[180px] h-[40px]'
height: 40
},
{
name: 'Wintermute',
src: '/wintermute0.svg',
width: 247,
height: 40,
className: 'w-[247px] h-[40px]'
height: 40
},
{
name: 'Circle',
src: '/group0.svg',
width: 156,
height: 40,
className: 'w-[156px] h-[40px]'
height: 40
},
{
name: 'ConsenSys',
src: '', // 使用组合的vector文件
src: '',
width: 220,
height: 50,
className: 'w-[220px] h-[50px]'
height: 50
}
];
return (
<section
ref={sectionRef}
className="bg-[#f9fafb] flex flex-col items-center justify-center flex-shrink-0 w-full relative"
className={`flex flex-col items-center justify-center flex-shrink-0 w-full relative border-b ${
isDark ? 'bg-[#0a0a0a] border-[#27272a]' : 'bg-[#f9fafb] border-[#e5e7eb]'
}`}
style={{
borderStyle: 'solid',
borderColor: '#e5e7eb',
borderWidth: '0px 0px 1px 0px',
padding: '80px 0px',
gap: '32px'
}}
>
{/* 标题 - .text6 */}
<div
className="text-[#111827] text-center relative flex items-center justify-center font-inter"
style={{
fontSize: '18px',
lineHeight: '150%',
fontWeight: 500
}}
className={`text-lg font-medium text-center font-domine ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
>
{t('trusted.title')}
</div>
{/* Logo容器 - .frame-26 */}
<div
className="flex flex-row items-center justify-between flex-shrink-0 w-[1440px] relative"
>
<div className="flex flex-row items-center justify-between flex-shrink-0 w-[1440px] relative">
{partners.map((partner, index) => (
<div
key={partner.name}
className={`flex-shrink-0 relative overflow-hidden cursor-pointer hover:brightness-0 ${
animate
? 'translate-y-0 opacity-100'
: 'translate-y-12 opacity-0'
className={`flex-shrink-0 relative overflow-hidden cursor-pointer transition-all ${
animate ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
} ${
isDark
? 'hover:brightness-200 hover:invert'
: 'hover:brightness-0'
}`}
style={{
transition: `transform 0.7s ease-out ${index * 100}ms, opacity 0.7s ease-out ${index * 100}ms, filter 0.3s ease-out`,
@@ -119,6 +111,9 @@ export default function TrustedBySection() {
width={partner.width}
height={partner.height}
className="w-full h-full object-contain"
style={{
filter: isDark ? 'brightness(0) invert(1)' : 'brightness(0)'
}}
/>
)}
</div>

View File

@@ -2,10 +2,13 @@
import { useState, useEffect, useRef } from 'react';
import Image from 'next/image';
import { Card, CardBody, Chip } from '@heroui/react';
import { useLanguage } from '@/contexts/LanguageContext';
import { useTheme } from '@/contexts/ThemeContext';
export default function WhyAssetXSection() {
const { t } = useLanguage();
const { theme } = useTheme();
const [animate, setAnimate] = useState(false);
const sectionRef = useRef<HTMLElement>(null);
@@ -17,21 +20,24 @@ export default function WhyAssetXSection() {
(entries) => {
if (entries[0].isIntersecting) {
setAnimate(true);
observer.disconnect(); // 触发后立即断开,不再监听
observer.disconnect();
}
},
{ threshold: 0.5 } // 当50%可见时才触发
{ threshold: 0.5 }
);
observer.observe(currentRef);
return () => observer.disconnect();
}, []);
const isDark = theme === 'dark';
return (
<section
ref={sectionRef}
className="flex flex-row items-center justify-center flex-wrap flex-shrink-0 w-full relative"
className={`flex flex-row items-center justify-center flex-wrap flex-shrink-0 w-full relative ${
isDark ? 'bg-[#0a0a0a]' : 'bg-white'
}`}
style={{
padding: '80px 0px',
gap: '40px',
@@ -39,147 +45,138 @@ export default function WhyAssetXSection() {
}}
>
<div className="flex flex-col items-center justify-center w-[1440px]">
{/* Header - .frame-27 */}
<div className="flex flex-col gap-2 items-start justify-start flex-shrink-0 w-[1440px] relative mb-10">
{/* Title - .why-assetx */}
<h2
className="text-[#111827] text-left relative font-inter"
className={`text-left relative font-domine text-5xl font-bold ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
fontSize: '48px',
lineHeight: '120%',
letterSpacing: '-0.01em',
fontWeight: 700
letterSpacing: '-0.01em'
}}
>
{t('why.title')}
</h2>
{/* Subtitle */}
<p
className="text-[#9ca1af] text-left relative font-inter"
className={`text-left relative font-domine text-xl ${
isDark ? 'text-[#a1a1aa]' : 'text-[#9ca1af]'
}`}
style={{
fontSize: '20px',
lineHeight: '140%',
fontWeight: 400
lineHeight: '140%'
}}
>
{t('why.subtitle')}
</p>
</div>
{/* Cards Container - .frame-30 */}
<div className="flex flex-row gap-6 items-center justify-start flex-shrink-0 w-[1440px] relative">
{/* Left Large Card - Sustainable Real Yield */}
<div
className={`bg-white rounded-[24px] border border-[#e5e7eb] p-10 flex flex-col items-start justify-between self-stretch flex-1 relative overflow-hidden
${
animate
? 'translate-y-0 opacity-100'
: 'translate-y-12 opacity-0'
}
hover:-translate-y-2 hover:shadow-xl`}
<Card
className={`flex-1 self-stretch transition-all hover:-translate-y-2 ${
animate ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
} ${
isDark ? 'bg-[#18181b] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}
shadow="sm"
style={{
transition: 'transform 0.3s ease-out, box-shadow 0.3s ease-out, opacity 0.7s ease-out, translate 0.7s ease-out'
}}
>
{/* .frame-33 */}
<div className="flex flex-col gap-6 items-start justify-start self-stretch flex-shrink-0 relative">
{/* Icon Container - .container12 */}
<div className="bg-[#f9fafb] rounded-[16px] flex flex-row items-center justify-center flex-shrink-0 w-12 h-12 relative">
<Image
src="/system-data0.svg"
alt="System Data"
width={24}
height={24}
/>
<CardBody className="flex flex-col items-start justify-between p-10 gap-6">
<div className="flex flex-col gap-6 items-start justify-start self-stretch">
<div className={`rounded-2xl flex items-center justify-center w-12 h-12 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f9fafb]'
}`}>
<Image
src="/system-data0.svg"
alt="System Data"
width={24}
height={24}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
<div className="flex flex-col gap-4 items-start justify-start self-stretch">
<h3 className={`text-2xl font-bold font-domine ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
lineHeight: '130%',
letterSpacing: '-0.005em'
}}
>
{t('why.sustainable.title')}
</h3>
<p className={`text-base font-domine ${
isDark ? 'text-[#a1a1aa]' : 'text-[#9ca1af]'
}`}
style={{
lineHeight: '150%'
}}
>
{t('why.sustainable.desc')}
</p>
</div>
</div>
{/* Text Content - .frame-31 */}
<div className="flex flex-col gap-4 items-start justify-start self-stretch flex-shrink-0 relative">
<h3
className="text-[#111827] text-left relative font-inter"
style={{
fontSize: '24px',
lineHeight: '130%',
letterSpacing: '-0.005em',
fontWeight: 700
}}
>
{t('why.sustainable.title')}
</h3>
<p
className="text-[#9ca1af] text-left relative self-stretch font-inter"
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
}}
>
{t('why.sustainable.desc')}
</p>
</div>
</div>
<Image
src="/frame-110.svg"
alt="Chart"
width={305}
height={162}
className="w-full h-auto"
/>
</CardBody>
</Card>
{/* Chart Image - .frame-11 */}
<Image
src="/frame-110.svg"
alt="Chart"
width={305}
height={162}
className="w-full h-auto flex-shrink-0 relative"
/>
</div>
{/* Right Column - .frame-29 */}
<div className="flex flex-col gap-6 items-start justify-start flex-shrink-0 w-[850px] relative">
{/* Proven Reliability Card */}
<div
className={`bg-white rounded-[24px] border border-[#e5e7eb] p-10 flex flex-col items-start justify-start self-stretch flex-shrink-0 relative overflow-hidden
${
animate
? 'translate-y-0 opacity-100'
: 'translate-y-12 opacity-0'
}
hover:-translate-y-2 hover:shadow-xl`}
<Card
className={`self-stretch transition-all hover:-translate-y-2 ${
animate ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
} ${
isDark ? 'bg-[#18181b] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}
shadow="sm"
style={{
transition: 'transform 0.3s ease-out, box-shadow 0.3s ease-out, opacity 0.7s ease-out 0.15s, translate 0.7s ease-out 0.15s'
}}
>
{/* .features2 */}
<div className="flex flex-row items-center justify-between self-stretch flex-shrink-0 relative">
{/* Left Content - .container13 */}
<div className="flex flex-col gap-6 items-start justify-start flex-shrink-0 w-[414px] relative">
{/* Icon */}
<div className="bg-[#f9fafb] rounded-[16px] flex flex-row items-center justify-center flex-shrink-0 w-12 h-12 relative">
<CardBody className="flex flex-row items-center justify-between p-10">
<div className="flex flex-col gap-6 items-start justify-start flex-shrink-0 w-[414px]">
<div className={`rounded-2xl flex items-center justify-center w-12 h-12 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f9fafb]'
}`}>
<Image
src="/warning-shield-check0.svg"
alt="Shield Check"
width={24}
height={24}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
{/* Text - .frame-28 */}
<div className="flex flex-col gap-4 items-start justify-start self-stretch flex-shrink-0 relative">
<h3
className="text-[#111827] text-left relative self-stretch font-inter"
<div className="flex flex-col gap-4 items-start justify-start self-stretch">
<h3 className={`text-2xl font-bold font-domine ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
fontSize: '24px',
lineHeight: '130%',
letterSpacing: '-0.005em',
fontWeight: 700
letterSpacing: '-0.005em'
}}
>
{t('why.reliability.title')}
</h3>
<p
className="text-[#9ca1af] text-left relative font-inter"
<p className={`text-base font-domine ${
isDark ? 'text-[#a1a1aa]' : 'text-[#9ca1af]'
}`}
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
lineHeight: '150%'
}}
>
{t('why.reliability.desc')}
@@ -187,38 +184,32 @@ export default function WhyAssetXSection() {
</div>
</div>
{/* Right Icon */}
<div
className="bg-[#f9fafb] rounded-[16px] border border-[#e5e7eb] flex items-center justify-center flex-shrink-0 relative"
className={`rounded-2xl border flex items-center justify-center ${
isDark ? 'bg-[#27272a] border-[#3f3f46]' : 'bg-[#f9fafb] border-[#e5e7eb]'
}`}
style={{
padding: '32px',
height: '180px',
width: '196px',
isolation: 'isolate',
willChange: 'auto',
contain: 'layout style paint'
width: '196px'
}}
>
<div
className="rounded-full border-2 border-[#e5e7eb] flex items-center justify-center flex-shrink-0 relative"
className={`rounded-full border-2 flex items-center justify-center ${
isDark ? 'border-[#3f3f46]' : 'border-[#e5e7eb]'
}`}
style={{
width: '132px',
height: '132px',
minWidth: '132px',
minHeight: '132px',
maxWidth: '132px',
maxHeight: '132px'
height: '132px'
}}
>
<div
className="bg-[#e5e7eb] rounded-full flex items-center justify-center flex-shrink-0 relative"
className={`rounded-full flex items-center justify-center ${
isDark ? 'bg-[#3f3f46]' : 'bg-[#e5e7eb]'
}`}
style={{
width: '88.59px',
height: '88.59px',
minWidth: '88.59px',
minHeight: '88.59px',
maxWidth: '88.59px',
maxHeight: '88.59px'
height: '88.59px'
}}
>
<img
@@ -233,54 +224,52 @@ export default function WhyAssetXSection() {
</div>
</div>
</div>
</div>
</div>
</CardBody>
</Card>
{/* Flexible Liquidity Card */}
<div
className={`bg-white rounded-[24px] border border-[#e5e7eb] p-10 flex flex-col items-start justify-start self-stretch flex-shrink-0 relative overflow-hidden
${
animate
? 'translate-y-0 opacity-100'
: 'translate-y-12 opacity-0'
}
hover:-translate-y-2 hover:shadow-xl`}
<Card
className={`self-stretch transition-all hover:-translate-y-2 ${
animate ? 'translate-y-0 opacity-100' : 'translate-y-12 opacity-0'
} ${
isDark ? 'bg-[#18181b] border-[#27272a]' : 'bg-white border-[#e5e7eb]'
}`}
shadow="sm"
style={{
transition: 'transform 0.3s ease-out, box-shadow 0.3s ease-out, opacity 0.7s ease-out 0.3s, translate 0.7s ease-out 0.3s'
}}
>
<div className="flex flex-row items-start justify-between self-stretch flex-shrink-0 relative">
{/* Left Content */}
<div className="flex flex-col gap-6 items-start justify-start flex-shrink-0 w-[550px] relative">
{/* Icon */}
<div className="bg-[#f9fafb] rounded-[16px] flex flex-row items-center justify-center flex-shrink-0 w-12 h-12 relative">
<CardBody className="flex flex-row items-start justify-between p-10">
<div className="flex flex-col gap-6 items-start justify-start flex-shrink-0 w-[550px]">
<div className={`rounded-2xl flex items-center justify-center w-12 h-12 ${
isDark ? 'bg-[#27272a]' : 'bg-[#f9fafb]'
}`}>
<Image
src="/arrow-arrow-left-right0.svg"
alt="Arrow"
width={24}
height={24}
style={{
filter: isDark ? 'invert(1) brightness(0.8)' : 'none'
}}
/>
</div>
{/* Text Content */}
<div className="flex flex-col gap-4 items-start justify-start flex-shrink-0 relative">
<h3
className="text-[#111827] text-left relative font-inter"
<div className="flex flex-col gap-4 items-start justify-start">
<h3 className={`text-2xl font-bold font-domine ${
isDark ? 'text-[#fafafa]' : 'text-[#111827]'
}`}
style={{
fontSize: '24px',
lineHeight: '130%',
letterSpacing: '-0.005em',
fontWeight: 700
letterSpacing: '-0.005em'
}}
>
{t('why.liquidity.title')}
</h3>
<p
className="text-[#9ca1af] text-left relative font-inter"
<p className={`text-base font-domine ${
isDark ? 'text-[#a1a1aa]' : 'text-[#9ca1af]'
}`}
style={{
fontSize: '16px',
lineHeight: '150%',
fontWeight: 400
lineHeight: '150%'
}}
>
{t('why.liquidity.desc')}
@@ -288,21 +277,22 @@ export default function WhyAssetXSection() {
</div>
</div>
{/* Right Badges */}
<div className="flex flex-row gap-3 items-center justify-end flex-shrink-0">
<div className="bg-[#e1f8ec] rounded-lg px-4 py-2 flex items-center justify-center">
<span className="text-[#10b981] font-inter font-bold" style={{ fontSize: '12px' }}>
{t('why.liquidity.badge1')}
</span>
</div>
<div className="bg-[#ebf2ff] rounded-lg px-4 py-2 flex items-center justify-center">
<span className="text-[#1447e6] font-inter font-bold" style={{ fontSize: '12px' }}>
{t('why.liquidity.badge2')}
</span>
</div>
<div className="flex flex-row gap-3 items-center justify-end">
<Chip
className="bg-[#e1f8ec] text-[#10b981] font-bold"
size="sm"
>
{t('why.liquidity.badge1')}
</Chip>
<Chip
className="bg-[#ebf2ff] text-[#1447e6] font-bold"
size="sm"
>
{t('why.liquidity.badge2')}
</Chip>
</div>
</div>
</div>
</CardBody>
</Card>
</div>
</div>