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 (