From 0a1bd07492b3fccfcf42f0f977b6ecf5939f7448 Mon Sep 17 00:00:00 2001 From: xufuhan Date: Wed, 28 Jan 2026 17:55:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=93=E7=A3=A8=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEV-GUIDE.md | 62 +++++ app/globals.css | 91 ++++++- app/layout.tsx | 23 +- components/ConsenSysLogo.tsx | 141 +++++++++++ components/Footer.tsx | 58 ++--- components/HeroButtons.tsx | 86 +++++++ components/HeroSection.tsx | 132 ++-------- components/HeroTitle.tsx | 71 ++++++ components/HowItWorksSection.tsx | 411 ++++++++++++++++++++++++++----- components/Navbar.tsx | 55 +++-- components/ProductMenu.tsx | 26 +- components/Providers.tsx | 15 ++ components/ResourceMenu.tsx | 28 ++- components/SecuritySection.tsx | 68 +++-- components/ShatterTransition.tsx | 103 ++++++++ components/StatsSection.tsx | 70 ++++-- components/TransitionWrapper.tsx | 36 +++ components/TrustedBySection.tsx | 88 ++++--- components/WhyAssetXSection.tsx | 234 +++++++++--------- contexts/LanguageContext.tsx | 232 +++++++++++++++++ package.json | 3 +- public/component-10.svg | 6 +- public/hero-background.mp4 | Bin 0 -> 6200350 bytes public/icon-book.svg | 4 + public/vector0.svg | 3 + public/vector1.svg | 3 + public/vector2.svg | 3 + public/vector3.svg | 3 + public/vector4.svg | 3 + public/vector5.svg | 3 + public/vector6.svg | 3 + public/vector7.svg | 3 + public/vector8.svg | 3 + public/vector9.svg | 3 + scripts/dev.sh | 36 +++ tailwind.config.ts | 6 +- 36 files changed, 1649 insertions(+), 466 deletions(-) create mode 100644 DEV-GUIDE.md create mode 100644 components/ConsenSysLogo.tsx create mode 100644 components/HeroButtons.tsx create mode 100644 components/HeroTitle.tsx create mode 100644 components/Providers.tsx create mode 100644 components/ShatterTransition.tsx create mode 100644 components/TransitionWrapper.tsx create mode 100644 contexts/LanguageContext.tsx create mode 100644 public/hero-background.mp4 create mode 100644 public/icon-book.svg create mode 100644 public/vector0.svg create mode 100644 public/vector1.svg create mode 100644 public/vector2.svg create mode 100644 public/vector3.svg create mode 100644 public/vector4.svg create mode 100644 public/vector5.svg create mode 100644 public/vector6.svg create mode 100644 public/vector7.svg create mode 100644 public/vector8.svg create mode 100644 public/vector9.svg create mode 100644 scripts/dev.sh diff --git a/DEV-GUIDE.md b/DEV-GUIDE.md new file mode 100644 index 0000000..bebf3e1 --- /dev/null +++ b/DEV-GUIDE.md @@ -0,0 +1,62 @@ +# 开发指南 + +## 启动开发服务器 + +### 自动端口选择 +```bash +npm run dev +``` + +脚本会自动尝试以下端口: +- 3002 (默认) +- 3003 +- 3004 +- 3005 +- 3006 + +如果以上端口都被占用,会随机选择一个3000-4000之间的端口。 + +### 结束所有开发进程 + +如果遇到端口占用问题,可以运行: +```bash +npm run dev:kill +``` + +这会清理所有正在运行的Next.js开发服务器。 + +然后再运行: +```bash +npm run dev +``` + +## 其他命令 + +### 构建生产版本 +```bash +npm run build +``` + +### 启动生产服务器 +```bash +npm run start +``` + +### 代码检查 +```bash +npm run lint +``` + +## 常见问题 + +**Q: 端口被占用怎么办?** +A: 直接运行 `npm run dev`,脚本会自动找到可用端口。如果还是不行,先运行 `npm run dev:kill` 清理进程。 + +**Q: 如何查看当前使用的端口?** +A: 启动时会显示 "🚀 Starting dev server on port XXXX" + +**Q: 如何强制使用特定端口?** +A: 直接运行: +```bash +npx next dev -H 0.0.0.0 -p 3002 +``` diff --git a/app/globals.css b/app/globals.css index 8ae91e5..bd34368 100644 --- a/app/globals.css +++ b/app/globals.css @@ -17,7 +17,7 @@ body { color: var(--foreground); background: var(--background); - font-family: var(--font-inter), Arial, Helvetica, sans-serif; + font-family: var(--font-noto-sans-sc), var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif; } @layer utilities { @@ -26,6 +26,19 @@ body { } } +/* Font family utilities with Chinese support */ +.font-inter { + font-family: var(--font-noto-sans-sc), var(--font-inter), -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif; +} + +.font-domine { + font-family: var(--font-noto-serif-sc), var(--font-domine), Georgia, "Noto Serif", serif; +} + +.font-jetbrains { + font-family: var(--font-jetbrains), "Courier New", monospace; +} + /* Calculator card wiggle animation */ @keyframes wiggle { 0% { transform: rotate(0deg); } @@ -37,6 +50,10 @@ body { 100% { transform: rotate(0deg); } } +.calculator-card-container { + cursor: pointer; +} + .calculator-card-container:hover { animation: wiggle 2.5s ease-in-out infinite; } @@ -69,3 +86,75 @@ body { .animate-slide-down { animation: slideDown 0.3s ease-out; } + +@keyframes slideUp { + from { + opacity: 1; + transform: translateX(-50%) translateY(0); + } + to { + opacity: 0; + transform: translateX(-50%) translateY(-10px); + } +} + +@keyframes fadeOutFast { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +.animate-slide-up { + animation: slideUp 0.3s ease-out forwards; +} + +.animate-fade-out-fast { + animation: fadeOutFast 0.3s ease-out forwards; +} + +/* Shatter transition animation - 3D effect */ +@keyframes shatter { + 0%, 20% { + transform: translate3d(0, 0, 0) rotateX(0deg) rotateY(0deg) scale(1); + opacity: 1; + } + 100% { + transform: translate3d(var(--tx), var(--ty), -200px) + rotateX(var(--rx)) + rotateY(var(--ry)) + scale(var(--s)); + opacity: 0; + } +} + +.shatter-fragment { + animation: shatter 0.9s cubic-bezier(0.68, -0.55, 0.265, 1.55) forwards; + animation-delay: var(--delay); + will-change: transform, opacity; + transform-style: preserve-3d; + backface-visibility: hidden; +} + +.glass-shard { + transform-style: preserve-3d; + transition: all 0.3s ease; + /* 确保在动画开始时完全不透明 */ + background-color: rgba(255, 255, 255, 1) !important; +} + +/* Fade out animation for background mask */ +@keyframes fadeOut { + 0%, 30% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +.animate-fade-out { + animation: fadeOut 1.5s ease-out forwards; +} diff --git a/app/layout.tsx b/app/layout.tsx index b658dc8..8ed37db 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; -import { Inter, JetBrains_Mono, Domine } from "next/font/google"; +import { Inter, JetBrains_Mono, Domine, Noto_Sans_SC, Noto_Serif_SC } from "next/font/google"; import "./globals.css"; +import Providers from "@/components/Providers"; const inter = Inter({ subsets: ["latin"], @@ -21,6 +22,20 @@ const domine = Domine({ display: "swap", }); +const notoSansSC = Noto_Sans_SC({ + subsets: ["latin"], + variable: "--font-noto-sans-sc", + weight: ["400", "500", "700"], + display: "swap", +}); + +const notoSerifSC = Noto_Serif_SC({ + subsets: ["latin"], + variable: "--font-noto-serif-sc", + weight: ["400", "700"], + display: "swap", +}); + export const metadata: Metadata = { title: "Asset Homepage", description: "Asset management platform homepage", @@ -32,9 +47,11 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + - {children} + + {children} + ); diff --git a/components/ConsenSysLogo.tsx b/components/ConsenSysLogo.tsx new file mode 100644 index 0000000..517f63b --- /dev/null +++ b/components/ConsenSysLogo.tsx @@ -0,0 +1,141 @@ +export default function ConsenSysLogo({ width = 176, height = 40 }: { width?: number; height?: number }) { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +} + diff --git a/components/Footer.tsx b/components/Footer.tsx index 2bcca23..81a5169 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -1,30 +1,10 @@ 'use client'; import Image from 'next/image'; +import { useLanguage } from '@/contexts/LanguageContext'; export default function Footer() { - const productLinks = [ - 'AX-Fund', - 'AX-Matrix', - 'Launchpad', - 'Liquid Market', - 'Token Factory' - ]; - - const resourceLinks = [ - 'Docs', - 'FAQ & Support', - 'Trust & Security', - 'Learning Center', - 'Community Forum' - ]; - - const companyLinks = [ - 'About Team', - 'Careers', - 'Contact Us', - 'Press & Media' - ]; + const { t } = useLanguage(); const socialIcons = [ { src: '/component-12.svg', alt: 'Twitter', width: 24, height: 24 }, @@ -36,7 +16,7 @@ export default function Footer() { return (