ALIEZ 1 maand geleden
bovenliggende
commit
bae8ecf8bd

+ 35 - 5
package-lock.json

@@ -10,8 +10,10 @@
       "dependencies": {
         "axios": "^1.15.0",
         "clsx": "^2.1.1",
+        "lucide-react": "^1.11.0",
         "next": "16.2.3",
         "next-intl": "^4.9.1",
+        "nextjs-toploader": "^3.9.17",
         "react": "19.2.4",
         "react-dom": "19.2.4",
         "tailwind-merge": "^3.5.0"
@@ -5108,7 +5110,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
       "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/js-yaml": {
@@ -5519,7 +5520,6 @@
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
       "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "js-tokens": "^3.0.0 || ^4.0.0"
@@ -5538,6 +5538,15 @@
         "yallist": "^3.0.2"
       }
     },
+    "node_modules/lucide-react": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.11.0.tgz",
+      "integrity": "sha512-UOhjdztXCgdBReRcIhsvz2siIBogfv/lhJEIViCpLt924dO+GDms9T7DNoucI23s6kEPpe988m5N0D2ajnzb2g==",
+      "license": "ISC",
+      "peerDependencies": {
+        "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+      }
+    },
     "node_modules/magic-string": {
       "version": "0.30.21",
       "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -5851,6 +5860,24 @@
         "node": "^10 || ^12 || >=14"
       }
     },
+    "node_modules/nextjs-toploader": {
+      "version": "3.9.17",
+      "resolved": "https://registry.npmjs.org/nextjs-toploader/-/nextjs-toploader-3.9.17.tgz",
+      "integrity": "sha512-9OF0KSSLtoSAuNg2LZ3aTl4hR9mBDj5L9s9DZiFCbMlXehyICGjkIz5dVGzuATU2bheJZoBdFgq9w07AKSuQQw==",
+      "license": "MIT",
+      "dependencies": {
+        "nprogress": "^0.2.0",
+        "prop-types": "^15.8.1"
+      },
+      "funding": {
+        "url": "https://buymeacoffee.com/thesgj"
+      },
+      "peerDependencies": {
+        "next": ">= 6.0.0",
+        "react": ">= 16.0.0",
+        "react-dom": ">= 16.0.0"
+      }
+    },
     "node_modules/node-addon-api": {
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
@@ -5883,11 +5910,16 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/nprogress": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
+      "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==",
+      "license": "MIT"
+    },
     "node_modules/object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
       "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=0.10.0"
@@ -6192,7 +6224,6 @@
       "version": "15.8.1",
       "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
       "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "loose-envify": "^1.4.0",
@@ -6265,7 +6296,6 @@
       "version": "16.13.1",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/reflect.getprototypeof": {

+ 2 - 0
package.json

@@ -22,8 +22,10 @@
   "dependencies": {
     "axios": "^1.15.0",
     "clsx": "^2.1.1",
+    "lucide-react": "^1.11.0",
     "next": "16.2.3",
     "next-intl": "^4.9.1",
+    "nextjs-toploader": "^3.9.17",
     "react": "19.2.4",
     "react-dom": "19.2.4",
     "tailwind-merge": "^3.5.0"

BIN
public/about/bg-wave.png


BIN
public/about/design-reference.png


BIN
public/bannerBg.png


BIN
public/courses-banner-bg.png


BIN
public/courses-list-bg.png


BIN
public/header.jpeg


BIN
public/list.jpeg


+ 0 - 1
public/window.svg

@@ -1 +0,0 @@
-<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>

+ 158 - 45
src/app/[locale]/about/page.tsx

@@ -1,4 +1,5 @@
 import { setRequestLocale } from "next-intl/server";
+import { Settings, BookOpen, LineChart, CheckCircle2 } from "lucide-react";
 
 type Props = { params: Promise<{ locale: string }> };
 
@@ -7,60 +8,172 @@ export default async function AboutPage({ params }: Props) {
   setRequestLocale(locale);
 
   return (
-    <div className="page-shell">
-      <section className="relative overflow-hidden rounded-3xl border border-slate-200/70 bg-gradient-to-br from-white via-slate-50 to-blue-50/70 p-8 shadow-[0_20px_50px_rgba(15,23,42,0.08)] md:p-12">
-        <div className="pointer-events-none absolute -right-14 -top-16 h-56 w-56 rounded-full bg-blue-200/30 blur-3xl" />
-        <div className="pointer-events-none absolute -bottom-20 left-1/3 h-48 w-48 rounded-full bg-indigo-200/20 blur-3xl" />
-        <p className="relative inline-flex rounded-full border border-blue-100 bg-white/80 px-4 py-1 text-xs font-semibold tracking-[0.2em] text-slate-500">
-          ABOUT US
-        </p>
-        <h1 className="relative mt-4 font-serif text-4xl font-semibold tracking-tight text-[var(--navy)] md:text-5xl">
-          关于我们
-        </h1>
-        <p className="relative mt-4 max-w-3xl text-sm leading-7 text-slate-600 md:text-base">
-          聚焦系统化交易教育,沉淀实战经验与方法论,帮助投资者建立可复用、可执行的交易体系。
-        </p>
-      </section>
+    <div className="relative min-h-screen overflow-hidden bg-[#050b14] font-sans">
+      {/* 背景层:深色渐变与金色波纹叠加 */}
+      <div
+        className="absolute inset-0 opacity-80"
+        style={{
+          backgroundImage:
+            "linear-gradient(180deg, rgba(5,11,20,0.4) 0%, rgba(5,11,20,0.95) 100%), url('/about/bg-wave.png')",
+          backgroundSize: "cover",
+          backgroundPosition: "center",
+          backgroundAttachment: "fixed",
+        }}
+      />
+      
+      <div className="relative z-10 mx-auto max-w-[1240px] px-6 pb-20 pt-16 md:px-8 md:pt-24">
+        
+        {/* 头部标题区 */}
+        <section className="mb-16 text-center">
+          <p className="text-sm font-medium tracking-[0.3em] text-[#b89458] mb-3">ABOUT US</p>
+          <h1 className="font-serif text-4xl font-bold text-[#f3deae] md:text-5xl tracking-wide mb-6">关于我们</h1>
+          <p className="mx-auto max-w-2xl text-base leading-relaxed text-[#a2b2c9]">
+            聚焦系统化实战教育,沉淀实战经验与方法论,帮助投资者建立可复用、可执行的交易体系。
+          </p>
+        </section>
 
-      <div className="mt-8 grid gap-6">
+        {/* 个人 IP 介绍区块 - 毛玻璃质感大卡片 */}
         <section
           id="ip"
-          className="scroll-mt-24 rounded-3xl border border-slate-200/70 bg-white p-7 shadow-[0_14px_35px_rgba(15,23,42,0.06)] md:p-9"
+          className="rounded-[2rem] border border-[#b89458]/20 bg-[#0c1627]/60 p-8 shadow-[0_30px_60px_rgba(0,0,0,0.6)] backdrop-blur-xl md:p-12 mb-20"
         >
-          <h2 className="font-serif text-2xl font-semibold text-[var(--navy)]">个人 IP 介绍</h2>
-          <div className="mt-5 space-y-4 leading-8 text-[#c62828]">
-            <p>
-              崔宏毅,中级黄金分析师,IPA 国际金融分析师,CFA 行为金融学分析师,中金亚洲综合外汇黄金专家,
-              深耕黄金、白银、外汇、原油等领域多年,兼具实战交易与教研管理双重经验。
-            </p>
-            <p>
-              他对宏观经济与市场动向拥有独有研判体系,深耕斐波那契波数列、行情时间窗等核心技术,
-              秉持“将复杂简化为专一”的投资理念,以实战视角解读市场规律。
-            </p>
-            <div className="rounded-2xl border border-rose-100 bg-rose-50/40 px-5 py-4">
-              <p className="font-medium">从业以来,持续输出专业内容与实战方法论:</p>
-              <ul className="mt-2 list-disc space-y-1 pl-7">
-                <li>2017 年出版《原油投资翻倍篇》</li>
-                <li>2018 年出版《黄金白银投资交易实战》</li>
-                <li>2024 年出版《重新认识黄金》</li>
-              </ul>
+          <div className="flex flex-col lg:flex-row gap-12 lg:gap-16">
+            
+            {/* 左侧区域:照片 + 核心头衔与书籍 */}
+            <div className="lg:w-3/5 flex flex-col sm:flex-row gap-8 rounded-3xl border border-[#caa86a]/35 bg-[linear-gradient(125deg,rgba(195,152,83,0.22)_0%,rgba(71,53,29,0.38)_38%,rgba(12,22,39,0.88)_100%)] p-5 shadow-[inset_0_1px_0_rgba(243,222,174,0.18),0_18px_35px_rgba(0,0,0,0.35)]">
+              {/* 人物照片 */}
+              <div className="w-full sm:w-[45%] shrink-0 overflow-hidden rounded-2xl border border-[#b89458]/30 bg-[#0a1120] relative aspect-[3/4]">
+                {/* eslint-disable-next-line @next/next/no-img-element */}
+                <img src="" alt="崔家骏" className="h-full w-full object-cover object-[78%_45%]" />
+              </div>
+              
+              {/* 头衔与书籍 */}
+              <div className="w-full sm:w-[55%] flex flex-col justify-center">
+                <h3 className="text-3xl font-bold text-[#f3deae] mb-2">崔家骏</h3>
+                <p className="text-[#b89458] font-medium mb-8">黄金分析师 & CFA</p>
+                
+                <ul className="space-y-3 text-sm text-[#f3deae] mb-10">
+                  <li className="flex items-center gap-2">
+                    <CheckCircle2 className="text-[#b89458] w-4 h-4" /> 专业的理念
+                  </li>
+                  <li className="flex items-center gap-2">
+                    <CheckCircle2 className="text-[#b89458] w-4 h-4" /> 黄金分析师,深谙投资的精巧
+                  </li>
+                  <li className="flex items-center gap-2">
+                    <CheckCircle2 className="text-[#b89458] w-4 h-4" /> 聚粹精炼,将复杂简化为专一
+                  </li>
+                </ul>
+                
+                {/* 书籍展示区 */}
+                <div className="flex gap-4 w-full">
+                  {[
+                    { year: 2017, title: "原油投资" },
+                    { year: 2018, title: "黄金白银" },
+                    { year: 2024, title: "认识黄金" }
+                  ].map((book) => (
+                    <div key={book.year} className="flex-1 text-center group">
+                      <div className="aspect-[2/3] w-full rounded-lg border border-[#b89458]/30 bg-[#0f1b2e] flex flex-col items-center justify-center p-2 mb-3 shadow-inner group-hover:border-[#b89458] transition-colors relative overflow-hidden">
+                        <div className="absolute inset-0 bg-gradient-to-tr from-[#b89458]/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity"></div>
+                        <span className="text-[10px] text-[#f3deae]/70 leading-tight">{book.title}</span>
+                      </div>
+                      <span className="text-xs font-medium text-[#889abb]">{book.year}</span>
+                    </div>
+                  ))}
+                </div>
+              </div>
+            </div>
+
+            {/* 右侧区域:详细文字介绍与时间线 */}
+            <div className="lg:w-2/5 flex flex-col justify-center">
+              <h2 className="font-serif text-2xl font-semibold text-[#f3deae] mb-6">个人 IP 介绍</h2>
+              <div className="space-y-4 text-sm leading-relaxed text-[#a2b2c9]">
+                <p>
+                  <span className="text-[#f3deae]">崔家骏</span>,中级黄金分析师,IPA 国际金融分析师,CFA 行为金融学分析师,中金亚洲综合外汇黄金专家,深耕黄金、白银、外汇、原油等领域多年,兼具实战交易与教研管理双重经验。
+                </p>
+                <p>
+                  他对宏观经济与市场动向拥有独有研判体系,深耕斐波那契波数列、行情时间窗等核心技术,秉持“<span className="text-[#f3deae]">将复杂简化为专一</span>”的投资理念,以实战视角解读市场规律。
+                </p>
+              </div>
+              
+              {/* 出版物时间线框 */}
+              <div className="mt-8 rounded-xl border border-[#d9b06a]/35 bg-[linear-gradient(110deg,rgba(194,149,79,0.24)_0%,rgba(65,47,25,0.34)_42%,rgba(10,17,32,0.9)_100%)] p-6 relative overflow-hidden shadow-[inset_0_1px_0_rgba(243,222,174,0.2),0_12px_28px_rgba(0,0,0,0.28)]">
+                {/* 左侧金色装饰线 */}
+                <div className="absolute left-0 top-0 bottom-0 w-1 bg-gradient-to-b from-[#f8ddb0] via-[#d4a359] to-[#8c6b36]"></div>
+                
+                <p className="text-sm font-medium text-[#b89458] mb-4">从业以来,持续输出专业内容与实战方法论:</p>
+                <ul className="space-y-3 text-sm text-[#f3deae]">
+                  <li className="flex items-baseline gap-2">
+                    <span className="text-[#b89458] text-lg leading-none">•</span>
+                    <span>2017 年出版《原油投资翻倍篇》</span>
+                  </li>
+                  <li className="flex items-baseline gap-2">
+                    <span className="text-[#b89458] text-lg leading-none">•</span>
+                    <span>2018 年出版《黄金白银投资交易实战》</span>
+                  </li>
+                  <li className="flex items-baseline gap-2">
+                    <span className="text-[#b89458] text-lg leading-none">•</span>
+                    <span>2024 年出版《重新认识黄金》</span>
+                  </li>
+                </ul>
+              </div>
             </div>
+
           </div>
         </section>
 
-        <section
-          id="philosophy"
-          className="scroll-mt-24 rounded-3xl border border-slate-200/70 bg-white p-7 shadow-[0_14px_35px_rgba(15,23,42,0.06)] md:p-9"
-        >
-          <h2 className="font-serif text-2xl font-semibold text-[#c62828]">教学理念</h2>
-          <p className="mt-5 leading-8 text-[#c62828]">
-            金策弘论坛,聚焦系统化实战交易技术,将多年一线实盘经验与教研成果沉淀为可复用、可落地的课程体系与实战工具,
-            助力投资者建立稳定交易框架,实现从认知到盈利的闭环。
-          </p>
-        </section>
+        {/* 教学理念区块 */}
+        <section id="philosophy">
+          <h2 className="text-center font-serif text-2xl font-semibold text-[#f3deae] mb-10">教学理念</h2>
+          <div className="grid gap-6 md:grid-cols-3">
+            
+            {/* 卡片 1 */}
+            <article className="group rounded-2xl border border-[#b89458]/20 bg-[#0c1627]/50 p-6 backdrop-blur-sm transition-all duration-300 hover:border-[#b89458]/60 hover:-translate-y-1 hover:shadow-[0_10px_30px_rgba(184,148,88,0.1)]">
+              <div className="flex items-center gap-4">
+                <div className="inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-xl border border-[#b89458]/20 bg-[#0a1120] text-[#889abb] transition-colors group-hover:text-[#b89458]">
+                  <Settings size={22} />
+                </div>
+                <div className="text-left">
+                  <h3 className="mb-2 text-lg font-semibold text-[#f3deae]">技术性强</h3>
+                  <p className="text-sm leading-relaxed text-[#a2b2c9]">
+                    金策弘论坛,聚焦系统性实战,传授可落地的交易策略,模块进行链的精微逻辑。
+                  </p>
+                </div>
+              </div>
+            </article>
+
+            {/* 卡片 2 */}
+            <article className="group rounded-2xl border border-[#b89458]/20 bg-[#0c1627]/50 p-6 backdrop-blur-sm transition-all duration-300 hover:border-[#b89458]/60 hover:-translate-y-1 hover:shadow-[0_10px_30px_rgba(184,148,88,0.1)]">
+              <div className="flex items-center gap-4">
+                <div className="inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-xl border border-[#b89458]/20 bg-[#0a1120] text-[#889abb] transition-colors group-hover:text-[#b89458]">
+                  <BookOpen size={22} />
+                </div>
+                <div className="text-left">
+                  <h3 className="mb-2 text-lg font-semibold text-[#f3deae]">系统计划</h3>
+                  <p className="text-sm leading-relaxed text-[#a2b2c9]">
+                    系统的设计与推演逻辑,形成稳定闭环,避免无效策略堆叠,建立稳定防微杜渐。
+                  </p>
+                </div>
+              </div>
+            </article>
 
-        {/* 媒体报道模块按需求先隐藏,后续有内容再恢复 */}
+            {/* 卡片 3 */}
+            <article className="group rounded-2xl border border-[#b89458]/20 bg-[#0c1627]/50 p-6 backdrop-blur-sm transition-all duration-300 hover:border-[#b89458]/60 hover:-translate-y-1 hover:shadow-[0_10px_30px_rgba(184,148,88,0.1)]">
+              <div className="flex items-center gap-4">
+                <div className="inline-flex h-12 w-12 shrink-0 items-center justify-center rounded-xl border border-[#b89458]/20 bg-[#0a1120] text-[#889abb] transition-colors group-hover:text-[#b89458]">
+                  <LineChart size={22} />
+                </div>
+                <div className="text-left">
+                  <h3 className="mb-2 text-lg font-semibold text-[#f3deae]">收利性能</h3>
+                  <p className="text-sm leading-relaxed text-[#a2b2c9]">
+                    顺势控仓,提升资金容错率,追求长期稳健盈利能力,提高跨入的一致性防范逻辑。
+                  </p>
+                </div>
+              </div>
+            </article>
+
+          </div>
+        </section>
       </div>
     </div>
   );
-}
+}

+ 72 - 75
src/app/[locale]/account/change-password/page.tsx

@@ -5,6 +5,8 @@ import { Link } from "@/i18n/navigation";
 import { useState } from "react";
 import { updateLoginPassword } from "@/lib/auth-api";
 import { isRegisterPasswordValid } from "@/lib/password-rules";
+import { KeyRound, ArrowLeft, CheckCircle2 } from "lucide-react";
+import { cn } from "@/lib/utils";
 
 export default function ChangePasswordPage() {
   const t = useTranslations("auth");
@@ -15,84 +17,79 @@ export default function ChangePasswordPage() {
   const [error, setError] = useState<string | null>(null);
   const [submitting, setSubmitting] = useState(false);
 
+  const InputCls = "mt-2 w-full rounded-xl border border-white/10 bg-black/20 px-4 py-3.5 text-sm text-white placeholder-slate-500 focus:border-[#b89458] focus:outline-none focus:ring-1 focus:ring-[#b89458] transition-all";
+
   return (
-    <div className="auth-page-shell">
-      <h1 className="font-serif text-2xl font-semibold text-[var(--navy)]">{t("changePwdTitle")}</h1>
-      <p className="mt-2 text-sm text-[var(--muted)]">请输入原密码,并设置新密码。</p>
-      <form
-        onSubmit={async (e) => {
-          e.preventDefault();
-          setOk(false);
-          setError(null);
-          if (newPassword !== confirmPassword) {
-            setError("两次输入的新密码不一致");
-            return;
-          }
-          if (!isRegisterPasswordValid(newPassword)) {
-            setError(t("errorWeakPassword"));
-            return;
-          }
-          try {
-            setSubmitting(true);
-            await updateLoginPassword({ oldPassword, newPassword });
-            setOk(true);
-            setOldPassword("");
-            setNewPassword("");
-            setConfirmPassword("");
-          } catch (err) {
-            const e2 = err as Error;
-            setError(e2.message || "修改密码失败,请稍后重试。");
-          } finally {
-            setSubmitting(false);
-          }
-        }}
-        className="mt-8 space-y-4"
-      >
-        <div>
-          <label className="text-sm font-medium">原密码</label>
-          <input
-            type="password"
-            required
-            value={oldPassword}
-            onChange={(e) => setOldPassword(e.target.value)}
-            className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-          />
+    <div className="min-h-screen bg-[#050b14] flex flex-col items-center justify-center p-4 relative font-sans overflow-hidden">
+      {/* 沉浸式背景 */}
+      <div className="pointer-events-none fixed inset-0 z-0">
+        <div className="absolute left-1/2 top-1/2 h-[600px] w-[600px] -translate-x-1/2 -translate-y-1/2 rounded-full bg-[#b89458]/5 blur-[120px]" />
+      </div>
+
+      <div className="relative z-10 w-full max-w-md">
+        <div className="mb-8 flex justify-center">
+          <div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-[#f3deae] to-[#d9be88] text-[#5c461a] shadow-lg shadow-[#b89458]/20">
+            <KeyRound size={28} />
+          </div>
         </div>
-        <div>
-          <label className="text-sm font-medium">新密码</label>
-          <input
-            type="password"
-            required
-            value={newPassword}
-            onChange={(e) => setNewPassword(e.target.value)}
-            className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-          />
+        
+        <div className="rounded-[2.5rem] border border-white/10 bg-[#0a1120]/80 p-8 md:p-10 backdrop-blur-2xl shadow-2xl">
+          <div className="text-center mb-8">
+            <h1 className="font-serif text-2xl font-bold text-white">{t("changePwdTitle")}</h1>
+            <p className="mt-2 text-sm text-slate-400">定期修改密码有助于保护账户资产安全</p>
+          </div>
+
+          <form
+            onSubmit={async (e) => {
+              e.preventDefault();
+              setOk(false); setError(null);
+              if (newPassword !== confirmPassword) { setError("两次输入的新密码不一致"); return; }
+              if (!isRegisterPasswordValid(newPassword)) { setError(t("errorWeakPassword")); return; }
+              try {
+                setSubmitting(true);
+                await updateLoginPassword({ oldPassword, newPassword });
+                setOk(true); setOldPassword(""); setNewPassword(""); setConfirmPassword("");
+              } catch (err) {
+                setError((err as Error).message || "修改密码失败,请稍后重试。");
+              } finally {
+                setSubmitting(false);
+              }
+            }}
+            className="space-y-5"
+          >
+            <div>
+              <label className="text-sm font-bold text-slate-300 ml-1">当前原密码</label>
+              <input type="password" required value={oldPassword} onChange={(e) => setOldPassword(e.target.value)} className={InputCls} placeholder="输入您现在的密码" />
+            </div>
+            <div>
+              <label className="text-sm font-bold text-slate-300 ml-1">设置新密码</label>
+              <input type="password" required value={newPassword} onChange={(e) => setNewPassword(e.target.value)} className={InputCls} placeholder="包含字母和数字,至少8位" />
+            </div>
+            <div>
+              <label className="text-sm font-bold text-slate-300 ml-1">确认新密码</label>
+              <input type="password" required value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} className={InputCls} placeholder="再次输入新密码" />
+            </div>
+
+            {error && <div className="rounded-xl border border-rose-500/30 bg-rose-500/10 p-3 text-center text-sm font-medium text-rose-400">{error}</div>}
+            
+            {ok && (
+              <div className="flex items-center justify-center gap-2 rounded-xl border border-emerald-500/30 bg-emerald-500/10 p-3 text-sm font-medium text-emerald-400">
+                <CheckCircle2 size={16} /> 密码修改成功
+              </div>
+            )}
+
+            <button type="submit" disabled={submitting} className="w-full rounded-2xl bg-gradient-to-br from-[#f3deae] to-[#d9be88] py-4 text-sm font-bold text-[#5c461a] shadow-xl shadow-[#b89458]/10 transition-transform hover:scale-[1.02] disabled:opacity-50 disabled:hover:scale-100 mt-4">
+              {submitting ? "安全校验中..." : t("changeBtn")}
+            </button>
+          </form>
         </div>
-        <div>
-          <label className="text-sm font-medium">确认新密码</label>
-          <input
-            type="password"
-            required
-            value={confirmPassword}
-            onChange={(e) => setConfirmPassword(e.target.value)}
-            className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-          />
+
+        <div className="mt-8 text-center">
+          <Link href="/account" className="inline-flex items-center gap-2 text-sm font-bold text-slate-400 hover:text-white transition-colors">
+            <ArrowLeft size={16} /> 返回控制中心
+          </Link>
         </div>
-        <button
-          type="submit"
-          disabled={submitting}
-          className="w-full rounded-full bg-[var(--navy)] py-3 text-sm font-semibold text-white"
-        >
-          {submitting ? "提交中..." : t("changeBtn")}
-        </button>
-      </form>
-      {error ? <p className="mt-4 text-sm text-rose-700">{error}</p> : null}
-      {ok ? <p className="mt-4 text-sm text-emerald-700">密码修改成功。</p> : null}
-      <p className="mt-8 text-center text-sm">
-        <Link href="/account" className="text-[var(--accent)] hover:underline">
-          返回用户中心
-        </Link>
-      </p>
+      </div>
     </div>
   );
-}
+}

+ 105 - 110
src/app/[locale]/account/orders/page.tsx

@@ -4,12 +4,14 @@ import { useEffect, useState } from "react";
 import { useTranslations } from "next-intl";
 import { Link } from "@/i18n/navigation";
 import { useAuth } from "@/providers/auth-provider";
+import { FileText, ArrowLeft, Loader2 } from "lucide-react";
 import {
   cancelOrder,
   fetchOrderList,
   getOrderStatusLabel,
   type OrderRecord,
 } from "@/lib/order-api";
+import { cn } from "@/lib/utils";
 
 const PAGE_SIZE = 10;
 
@@ -45,25 +47,18 @@ export default function AccountOrdersPage() {
       }
     }
     void loadOrders();
-    return () => {
-      cancelled = true;
-    };
+    return () => { cancelled = true; };
   }, [user, page]);
 
-  if (!isReady) {
-    return <div className="page-shell py-16 text-center text-[var(--muted)]">…</div>;
-  }
+  if (!isReady) return <div className="min-h-screen bg-[#050b14] flex items-center justify-center text-slate-500"><Loader2 className="animate-spin" /></div>;
 
   if (!user) {
     return (
-      <div className="page-shell py-16 text-center text-[var(--muted)]">
-        <p>{t("loginRequired")}</p>
-        <Link
-          href="/auth/login"
-          className="mt-4 inline-block rounded-full bg-[var(--navy)] px-6 py-2 text-sm text-white"
-        >
-          登录
-        </Link>
+      <div className="min-h-screen bg-[#050b14] flex items-center justify-center px-4 font-sans">
+        <div className="w-full max-w-md rounded-[2.5rem] border border-white/10 bg-white/5 p-10 text-center backdrop-blur-2xl">
+          <h2 className="text-2xl font-bold text-white mb-6">您尚未登录</h2>
+          <Link href="/auth/login" className="inline-block rounded-full bg-[#f3deae] px-10 py-4 text-sm font-bold text-[#5c461a] shadow-lg">立即登录</Link>
+        </div>
       </div>
     );
   }
@@ -79,117 +74,117 @@ export default function AccountOrdersPage() {
       setOrders(res.list);
       setTotal(res.page.total);
       setCancelTarget(null);
-      window.location.reload();
     } catch (e) {
-      const err = e as Error;
-      setError(err.message || "取消订单失败,请稍后重试。");
+      setError((e as Error).message || "取消订单失败,请稍后重试。");
     } finally {
       setCancelLoading(false);
     }
   }
 
+  function getStatusStyle(status: number | string) {
+    const s = String(status);
+    if (s === "2" || s === "3") return "text-emerald-400 border-emerald-400/30 bg-emerald-400/10";
+    if (s === "4" || s === "5") return "text-rose-400 border-rose-400/30 bg-rose-400/10";
+    return "text-amber-400 border-amber-400/30 bg-amber-400/10";
+  }
+
   return (
-    <div className="page-shell page-shell-wide">
-      <div className="flex items-center justify-between">
-        <h1 className="font-serif text-2xl font-semibold text-[var(--navy)]">全部订单</h1>
-        <Link
-          href="/account"
-          className="rounded-full border border-[var(--border)] px-4 py-1.5 text-xs text-[var(--navy)]"
-        >
-          返回用户中心
-        </Link>
+    <div className="min-h-screen bg-[#050b14] pb-24 text-slate-300 font-sans relative">
+      <div className="pointer-events-none fixed inset-0 z-0">
+        <div className="absolute left-1/4 top-0 h-[500px] w-[500px] rounded-full bg-blue-900/10 blur-[120px]" />
+        <div className="absolute right-1/4 bottom-0 h-[500px] w-[500px] rounded-full bg-[#b89458]/5 blur-[120px]" />
       </div>
 
-      {loading ? <p className="mt-4 text-sm text-[var(--muted)]">订单加载中…</p> : null}
-      {error ? (
-        <p className="mt-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
-          {error}
-        </p>
-      ) : null}
-
-      {!loading && !error && orders.length === 0 ? (
-        <p className="mt-4 text-sm text-[var(--muted)]">{t("noOrders")}</p>
-      ) : null}
-
-      {!loading && !error && orders.length > 0 ? (
-        <ul className="mt-4 divide-y divide-[var(--border)] rounded-xl border border-[var(--border)] bg-[var(--card)]">
-          {orders.map((o) => (
-            <li key={o.serial} className="px-4 py-3 text-sm">
-              <div className="flex flex-wrap items-center justify-between gap-2">
-                <span className="font-medium text-[var(--navy)]">{o.details}</span>
-                <div className="flex items-center gap-2">
-                  <span className="font-semibold text-[var(--navy)]">${o.amount}</span>
-                  {o.status === 1 ? (
-                    <button
-                      type="button"
-                      onClick={() => setCancelTarget(o)}
-                      className="rounded-full border border-rose-200 bg-rose-50 px-2.5 py-0.5 text-xs text-rose-700 hover:bg-rose-100"
-                    >
-                      取消订单
-                    </button>
-                  ) : null}
+      <div className="site-container relative z-10 pt-16">
+        <div className="flex items-center justify-between mb-8">
+          <div>
+            <h1 className="font-serif text-3xl font-bold text-white">全部订单</h1>
+            <p className="mt-2 text-sm text-slate-400">管理您的所有购买记录与账单明细</p>
+          </div>
+          <Link href="/account" className="flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-5 py-2.5 text-sm font-semibold text-slate-300 transition hover:bg-white/10 hover:text-white backdrop-blur-md">
+            <ArrowLeft size={16} /> 返回控制中心
+          </Link>
+        </div>
+
+        <section className="rounded-[2.5rem] border border-white/10 bg-white/5 p-6 md:p-10 backdrop-blur-2xl shadow-2xl">
+          {loading ? <div className="py-20 flex justify-center text-slate-500"><Loader2 className="animate-spin h-8 w-8" /></div> : null}
+          {error ? <div className="mb-6 rounded-2xl border border-rose-500/20 bg-rose-500/10 p-4 text-sm text-rose-400">{error}</div> : null}
+
+          {!loading && !error && orders.length === 0 ? (
+            <div className="py-20 flex flex-col items-center justify-center rounded-[2rem] border border-dashed border-white/10 bg-white/5 text-slate-500">
+              <FileText size={48} className="mb-4 opacity-50" />
+              <p className="text-sm">{t("noOrders")}</p>
+            </div>
+          ) : null}
+
+          {!loading && !error && orders.length > 0 ? (
+            <div className="space-y-4">
+              {orders.map((o) => (
+                <div key={o.serial} className="group rounded-[1.5rem] border border-white/5 bg-white/5 p-6 transition-all hover:bg-white/10">
+                  <div className="flex flex-col md:flex-row md:items-center justify-between gap-6">
+                    <div className="flex items-start gap-5">
+                      <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl bg-white/5 text-[#f3deae]">
+                        <FileText size={22} />
+                      </div>
+                      <div>
+                        <p className="text-base font-bold text-white group-hover:text-[#f3deae] transition-colors">{o.details}</p>
+                        <div className="mt-2 flex flex-wrap items-center gap-x-4 gap-y-2 text-xs font-medium text-slate-500">
+                          <span>NO: {o.serial}</span>
+                          <span className="hidden sm:inline">•</span>
+                          <span>创建: {o.addTime || "-"}</span>
+                          {o.payTime && <><span className="hidden sm:inline">•</span><span>支付: {o.payTime}</span></>}
+                        </div>
+                      </div>
+                    </div>
+                    <div className="flex items-center justify-between md:justify-end gap-6 md:border-l md:border-white/5 md:pl-6">
+                       <div className="text-right">
+                          <p className="text-xl font-bold text-white tracking-tight">${o.amount}</p>
+                          <span className={cn("inline-block mt-1.5 rounded-full border px-3 py-1 text-[10px] font-bold uppercase tracking-widest", getStatusStyle(o.status))}>
+                            {getOrderStatusLabel(o.status)}
+                          </span>
+                       </div>
+                       {o.status === 1 && (
+                          <button onClick={() => setCancelTarget(o)} className="rounded-xl border border-rose-500/30 bg-rose-500/10 px-4 py-2 text-xs font-bold text-rose-400 transition hover:bg-rose-500/20">取消</button>
+                       )}
+                    </div>
+                  </div>
                 </div>
-              </div>
-              <div className="mt-1 flex flex-wrap gap-x-4 gap-y-1 text-xs text-[var(--muted)]">
-                <span>流水号: {o.serial}</span>
-                <span>状态: {getOrderStatusLabel(o.status)}</span>
-                <span>购买时间: {o.addTime || "-"}</span>
-                <span>支付时间: {o.payTime || "-"}</span>
-              </div>
-            </li>
-          ))}
-        </ul>
-      ) : null}
-
-      <div className="mt-5 flex items-center justify-center gap-3">
-        <button
-          type="button"
-          onClick={() => setPage((p) => Math.max(1, p - 1))}
-          disabled={page <= 1 || loading}
-          className="rounded-lg border border-[var(--border)] px-3 py-1.5 text-sm disabled:opacity-50"
-        >
-          上一页
-        </button>
-        <span className="text-sm text-[var(--muted)]">
-          第 {page} / {totalPages} 页
-        </span>
-        <button
-          type="button"
-          onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
-          disabled={page >= totalPages || loading}
-          className="rounded-lg border border-[var(--border)] px-3 py-1.5 text-sm disabled:opacity-50"
-        >
-          下一页
-        </button>
+              ))}
+            </div>
+          ) : null}
+
+          {/* 分页 */}
+          {!loading && !error && totalPages > 1 && (
+            <div className="mt-10 flex items-center justify-center gap-4 border-t border-white/5 pt-8">
+              <button onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page <= 1} className="rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold transition hover:bg-white/10 disabled:opacity-30">上一页</button>
+              <span className="text-sm font-medium text-slate-500">第 <span className="text-white">{page}</span> / {totalPages} 页</span>
+              <button onClick={() => setPage(p => Math.min(totalPages, p + 1))} disabled={page >= totalPages} className="rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold transition hover:bg-white/10 disabled:opacity-30">下一页</button>
+            </div>
+          )}
+        </section>
       </div>
 
-      {cancelTarget ? (
-        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4">
-          <div className="w-full max-w-sm rounded-2xl border border-[var(--border)] bg-[var(--card)] p-5 shadow-xl">
-            <p className="text-base font-semibold text-[var(--navy)]">确认取消订单?</p>
-            <p className="mt-2 text-sm text-[var(--muted)]">
-              订单号:{cancelTarget.serial}
-            </p>
-            <div className="mt-5 flex justify-end gap-2">
-              <button
-                type="button"
-                onClick={() => setCancelTarget(null)}
-                className="rounded-lg border border-[var(--border)] px-4 py-2 text-sm"
-              >
-                关闭
-              </button>
-              <button
-                type="button"
-                onClick={handleConfirmCancel}
-                disabled={cancelLoading}
-                className="rounded-lg bg-rose-600 px-4 py-2 text-sm text-white disabled:opacity-60"
-              >
-                {cancelLoading ? "处理中..." : "确定取消"}
+      {/* 黑金风格确认弹窗 */}
+      {cancelTarget && (
+        <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+          <div className="w-full max-w-sm overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl">
+            <div className="p-10 text-center">
+              <div className="mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-rose-500/10 text-rose-400">
+                <FileText size={32} />
+              </div>
+              <h3 className="text-xl font-bold text-white">确认撤销订单?</h3>
+              <p className="mt-3 text-sm leading-relaxed text-slate-400 px-4">订单号: <span className="text-slate-200">{cancelTarget.serial}</span><br/>撤销后不可恢复。</p>
+            </div>
+            <div className="flex border-t border-white/5">
+              <button onClick={() => setCancelTarget(null)} className="flex-1 py-5 text-sm font-bold text-slate-400 hover:bg-white/5">暂不处理</button>
+              <div className="w-px bg-white/5" />
+              <button onClick={handleConfirmCancel} disabled={cancelLoading} className="flex-1 py-5 text-sm font-bold text-rose-400 hover:bg-rose-500/10 disabled:opacity-50">
+                {cancelLoading ? "执行中..." : "确认撤销"}
               </button>
             </div>
           </div>
         </div>
-      ) : null}
+      )}
     </div>
   );
-}
+}

+ 559 - 305
src/app/[locale]/account/page.tsx

@@ -4,7 +4,13 @@ import { useTranslations } from "next-intl";
 import { Link } from "@/i18n/navigation";
 import { useAuth } from "@/providers/auth-provider";
 import { useEffect, useState } from "react";
+import { Wallet, BookOpen, FileText, History, LogOut, ChevronRight, Settings, UserRoundPen } from "lucide-react";
 import { fetchWalletBalance } from "@/lib/account-api";
+import {
+  fetchBalanceRecordList,
+  type BalanceRecord,
+} from "@/lib/balance-record-api";
+import { fetchCustomUserInfo, updateUserInfo } from "@/lib/user-info-api";
 import {
   cancelOrder,
   fetchOrderList,
@@ -20,128 +26,130 @@ import {
   getWithdrawalStatusLabel,
   type WithdrawalRecord,
 } from "@/lib/withdrawal-api";
+import { cn } from "@/lib/utils";
 
 export default function AccountPage() {
   const t = useTranslations("account");
-  const { user, isReady } = useAuth();
+  const { user, isReady, updateProfile, logout } = useAuth();
+  
+  // 核心状态
   const [walletBalance, setWalletBalance] = useState<number | null>(null);
   const [walletLoading, setWalletLoading] = useState(false);
-  const [walletError, setWalletError] = useState<string | null>(null);
+  const [balanceDetailOpen, setBalanceDetailOpen] = useState(false);
+  const [balanceDetailLoading, setBalanceDetailLoading] = useState(false);
+  const [balanceDetailError, setBalanceDetailError] = useState<string | null>(
+    null,
+  );
+  const [balanceRecords, setBalanceRecords] = useState<BalanceRecord[]>([]);
   const [purchasedCourses, setPurchasedCourses] = useState<PurchasedCourse[]>([]);
-  const [purchasedLoading, setPurchasedLoading] = useState(false);
-  const [purchasedError, setPurchasedError] = useState<string | null>(null);
   const [orders, setOrders] = useState<OrderRecord[]>([]);
   const [ordersLoading, setOrdersLoading] = useState(false);
-  const [ordersError, setOrdersError] = useState<string | null>(null);
   const [withdrawals, setWithdrawals] = useState<WithdrawalRecord[]>([]);
   const [withdrawalsLoading, setWithdrawalsLoading] = useState(false);
-  const [withdrawalsError, setWithdrawalsError] = useState<string | null>(null);
+  
   const [cancelTarget, setCancelTarget] = useState<OrderRecord | null>(null);
   const [cancelLoading, setCancelLoading] = useState(false);
 
+  const [editInfoOpen, setEditInfoOpen] = useState(false);
+  const [editName, setEditName] = useState("");
+  const [editPhone, setEditPhone] = useState("");
+  const [editIdentity, setEditIdentity] = useState("");
+  const [editSubmitting, setEditSubmitting] = useState(false);
+  const [editError, setEditError] = useState<string | null>(null);
+  const [logoutConfirmOpen, setLogoutConfirmOpen] = useState(false);
+
   useEffect(() => {
     if (!user) return;
     let cancelled = false;
-    async function loadWalletBalance() {
+    async function loadData() {
       setWalletLoading(true);
-      setWalletError(null);
+      setOrdersLoading(true);
+      setWithdrawalsLoading(true);
       try {
-        const balance = await fetchWalletBalance();
+        const [balance, orderRes, courseRes, withdrawRes] = await Promise.all([
+          fetchWalletBalance(),
+          fetchOrderList({ current: 1, row: 10 }),
+          fetchPurchasedCourses(),
+          fetchWithdrawalList()
+        ]);
         if (cancelled) return;
         setWalletBalance(balance);
-      } catch (error) {
-        if (cancelled) return;
-        const e = error as Error;
-        setWalletError(e.message || "钱包余额加载失败,请稍后重试。");
-        setWalletBalance(null);
+        setOrders(orderRes.list);
+        setPurchasedCourses(courseRes);
+        setWithdrawals(withdrawRes);
+      } catch (e) {
+        console.error(e);
       } finally {
-        if (!cancelled) setWalletLoading(false);
+        if (!cancelled) {
+          setWalletLoading(false);
+          setOrdersLoading(false);
+          setWithdrawalsLoading(false);
+        }
       }
     }
-    void loadWalletBalance();
-    return () => {
-      cancelled = true;
-    };
+    loadData();
+    return () => { cancelled = true; };
   }, [user]);
 
-  useEffect(() => {
-    if (!user) return;
-    let cancelled = false;
-    async function loadWithdrawals() {
-      setWithdrawalsLoading(true);
-      setWithdrawalsError(null);
-      try {
-        const list = await fetchWithdrawalList();
-        if (cancelled) return;
-        setWithdrawals(list);
-      } catch (error) {
-        if (cancelled) return;
-        const e = error as Error;
-        setWithdrawalsError(e.message || "取款记录加载失败,请稍后重试。");
-        setWithdrawals([]);
-      } finally {
-        if (!cancelled) setWithdrawalsLoading(false);
-      }
+  async function openBalanceDetail() {
+    setBalanceDetailOpen(true);
+    setBalanceDetailLoading(true);
+    setBalanceDetailError(null);
+    try {
+      const list = await fetchBalanceRecordList({ current: 1, row: 50 });
+      setBalanceRecords(list);
+    } catch (e) {
+      setBalanceRecords([]);
+      setBalanceDetailError((e as Error)?.message || "消费明细加载失败,请稍后重试");
+    } finally {
+      setBalanceDetailLoading(false);
     }
-    void loadWithdrawals();
-    return () => {
-      cancelled = true;
-    };
-  }, [user]);
+  }
 
-  useEffect(() => {
-    if (!user) return;
-    let cancelled = false;
-    async function loadOrders() {
-      setOrdersLoading(true);
-      setOrdersError(null);
-      try {
-        const { list } = await fetchOrderList({ current: 1, row: 10 });
-        if (cancelled) return;
-        setOrders(list);
-      } catch (error) {
-        if (cancelled) return;
-        const e = error as Error;
-        setOrdersError(e.message || "订单加载失败,请稍后重试。");
-        setOrders([]);
-      } finally {
-        if (!cancelled) setOrdersLoading(false);
-      }
-    }
-    void loadOrders();
-    return () => {
-      cancelled = true;
-    };
-  }, [user]);
+  function balanceTypeLabel(type: BalanceRecord["type"]) {
+    return type === 2 ? "奖励" : "取款";
+  }
 
-  useEffect(() => {
+  function openEditInfo() {
     if (!user) return;
-    let cancelled = false;
-    async function loadPurchasedCourses() {
-      setPurchasedLoading(true);
-      setPurchasedError(null);
-      try {
-        const list = await fetchPurchasedCourses();
-        if (cancelled) return;
-        setPurchasedCourses(list);
-      } catch (error) {
-        if (cancelled) return;
-        const e = error as Error;
-        setPurchasedError(e.message || "已购买课程加载失败,请稍后重试。");
-        setPurchasedCourses([]);
-      } finally {
-        if (!cancelled) setPurchasedLoading(false);
-      }
-    }
-    void loadPurchasedCourses();
-    return () => {
-      cancelled = true;
-    };
-  }, [user]);
+    setEditError(null);
+    setEditName(user.name ?? "");
+    setEditPhone(user.phone ?? "");
+    setEditIdentity(user.identity ?? "");
+    setEditInfoOpen(true);
+  }
 
-  async function reloadOrders() {
-    const { list } = await fetchOrderList({ current: 1, row: 10 });
-    setOrders(list);
+  function closeEditInfo() {
+    setEditInfoOpen(false);
+    setEditSubmitting(false);
+    setEditError(null);
+  }
+
+  async function submitEditInfo() {
+    const name = editName.trim();
+    const phone = editPhone.trim();
+    const identity = editIdentity.trim();
+    if (!name) {
+      setEditError("请输入姓名");
+      return;
+    }
+    setEditSubmitting(true);
+    setEditError(null);
+    try {
+      await updateUserInfo({ name, phone, identity });
+      const info = await fetchCustomUserInfo();
+      updateProfile({
+        name: info.name || name,
+        phone: info.phone || phone,
+        identity: info.identity || identity,
+      });
+      closeEditInfo();
+      if (typeof window !== "undefined") window.location.reload();
+    } catch (e) {
+      setEditError((e as Error)?.message || "修改失败,请稍后重试");
+    } finally {
+      setEditSubmitting(false);
+    }
   }
 
   async function handleConfirmCancel() {
@@ -149,263 +157,509 @@ export default function AccountPage() {
     try {
       setCancelLoading(true);
       await cancelOrder(cancelTarget.id);
-      await reloadOrders();
+      const res = await fetchOrderList({ current: 1, row: 10 });
+      setOrders(res.list);
       setCancelTarget(null);
-      window.location.reload();
-    } catch (error) {
-      const e = error as Error;
-      setOrdersError(e.message || "取消订单失败,请稍后重试。");
+    } catch {
+      alert("取消失败,请重试");
     } finally {
       setCancelLoading(false);
     }
   }
 
-  function getPurchasedCourseHref(course: PurchasedCourse): string {
-    const baseHref = `/courses/${course.goodsId}`;
-    return course.goodsType === 5 ? `${baseHref}?cat=strategy` : baseHref;
+  // 高级状态色系:针对黑底优化
+  function getStatusStyle(status: OrderRecord["status"] | WithdrawalRecord["status"]) {
+    const s = String(status);
+    if (s === "2" || s === "3") return "text-emerald-400 border-emerald-400/30 bg-emerald-400/10";
+    if (s === "4" || s === "5") return "text-rose-400 border-rose-400/30 bg-rose-400/10";
+    return "text-amber-400 border-amber-400/30 bg-amber-400/10";
   }
 
-  if (!isReady) {
-    return (
-      <div className="page-shell py-16 text-center text-[var(--muted)]">
-        …
-      </div>
-    );
-  }
+  if (!isReady) return <div className="min-h-screen bg-[#050b14] flex items-center justify-center text-slate-500">加载中...</div>;
 
   if (!user) {
     return (
-      <div className="page-shell py-16 md:py-20">
-        <div className="mx-auto max-w-md rounded-2xl border border-[var(--border)] bg-[var(--card)] px-8 py-10 text-center shadow-card">
-          <p className="text-[var(--muted)]">{t("loginRequired")}</p>
-          <Link
-            href="/auth/login"
-            className="mt-6 inline-block rounded-full bg-[var(--navy)] px-8 py-3 text-sm font-semibold text-white"
-          >
-            登录
-          </Link>
+      <div className="min-h-screen bg-[#050b14] flex items-center justify-center px-4">
+        <div className="w-full max-w-md rounded-[2.5rem] border border-white/10 bg-white/5 p-10 text-center backdrop-blur-2xl">
+          <h2 className="text-2xl font-bold text-white mb-6">您尚未登录</h2>
+          <Link href="/auth/login" className="inline-block rounded-full bg-[#f3deae] px-10 py-4 text-sm font-bold text-[#5c461a] shadow-lg">立即登录</Link>
         </div>
       </div>
     );
   }
 
   return (
-    <div className="page-shell">
-      <div className="flex flex-col justify-between gap-4 sm:flex-row sm:items-center">
-        <h1 className="font-serif text-3xl font-semibold text-[var(--navy)]">
-          {t("welcome", { name: user.name })}
-        </h1>
-        <div className="self-start rounded-full border border-[var(--border)] px-4 py-2 text-sm text-[var(--navy)]">
-          {walletLoading
-            ? t("walletBalanceLoading")
-            : walletError
-              ? t("walletBalanceError")
-              : `${t("walletBalance")}: $${(walletBalance ?? 0).toFixed(2)}`}
-        </div>
+    <div className="min-h-screen bg-[#050b14] pb-24 text-slate-300 font-sans">
+      {/* 全局背景装饰 */}
+      <div className="pointer-events-none fixed inset-0 z-0">
+        <div className="absolute left-1/4 top-0 h-[500px] w-[500px] rounded-full bg-blue-900/10 blur-[120px]" />
+        <div className="absolute right-1/4 bottom-0 h-[500px] w-[500px] rounded-full bg-[#b89458]/5 blur-[120px]" />
       </div>
 
-      <section className="mt-10">
-        <div className="flex items-center justify-between">
-          <h2 className="font-serif text-lg font-semibold text-[var(--navy)]">已购买课程</h2>
-          <Link
-            href="/account/purchased-courses"
-            className="rounded-full border border-[var(--border)] px-4 py-1.5 text-xs font-medium text-[var(--navy)] hover:bg-[var(--card)]"
-          >
-            全部课程
-          </Link>
-        </div>
-        {purchasedLoading ? (
-          <p className="mt-3 text-sm text-[var(--muted)]">课程加载中…</p>
-        ) : null}
-        {purchasedError ? (
-          <p className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
-            {purchasedError}
-          </p>
-        ) : null}
-        {!purchasedLoading && !purchasedError && purchasedCourses.length === 0 ? (
-          <p className="mt-3 text-sm text-[var(--muted)]">暂无已购买课程。</p>
-        ) : (
-          !purchasedLoading &&
-          !purchasedError && (
-            <ul className="mt-4 grid gap-3 md:grid-cols-3">
-              {purchasedCourses.slice(0, 3).map((c) => (
-                <li
-                  key={c.id}
-                  className="overflow-hidden rounded-xl border border-[var(--border)] bg-[var(--card)] shadow-sm"
+      <div className="relative z-10 site-container pt-12">
+        {/* 1. 欢迎区 & 统计卡片 (全玻璃质感) */}
+        <section className="ui-enter mb-10 rounded-[2.5rem] border border-white/10 bg-white/5 p-8 backdrop-blur-2xl shadow-2xl">
+          <div className="flex flex-col gap-8 md:flex-row md:items-center md:justify-between">
+            <div>
+              <p className="text-xs font-bold tracking-[0.3em] text-[#b89458] mb-2 uppercase">User Control Center</p>
+              <h1 className="font-serif text-3xl font-bold text-white md:text-5xl tracking-wide">
+                {t("welcome", { name: user.name })}
+              </h1>
+              <p className="mt-3 text-sm text-slate-400">欢迎回来,在这里掌控您的个人资产与学习进程。</p>
+            </div>
+            <Link
+              href="/account/withdraw-apply"
+              className="ui-interactive-btn flex items-center gap-2 rounded-2xl bg-gradient-to-br from-[#f3deae] to-[#d9be88] px-8 py-4 text-sm font-bold text-[#5c461a] shadow-xl shadow-[#b89458]/10"
+            >
+              <Wallet size={18} /> 发起领取申请
+            </Link>
+          </div>
+
+          <div className="mt-12 grid grid-cols-2 gap-4 md:grid-cols-4 lg:gap-6">
+            <button
+              type="button"
+              onClick={openBalanceDetail}
+              className="group rounded-2xl border border-white/5 bg-white/5 p-6 text-center transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-[#b89458]/40"
+            >
+              <div className="flex flex-col items-center gap-3 mb-4">
+                <div
+                  className={cn(
+                    "p-2 rounded-xl bg-white/5 group-hover:scale-110 transition-transform text-[#f3deae]",
+                  )}
                 >
-                  <div className="h-36 w-full bg-slate-100">
-                    {c.coverUrl ? (
-                      // eslint-disable-next-line @next/next/no-img-element
-                      <img src={c.coverUrl} alt={c.title} className="h-full w-full object-cover" />
-                    ) : null}
+                  <Wallet size={18} />
+                </div>
+                <span className="text-[11px] font-bold uppercase tracking-widest text-slate-500">
+                  钱包余额
+                </span>
+              </div>
+              <p className="text-3xl font-bold tracking-tight text-white">
+                {walletLoading ? "..." : `$${(walletBalance ?? 0).toFixed(2)}`}
+              </p>
+              <p className="mt-2 text-[11px] font-semibold text-slate-500">
+                点击查看消费明细
+              </p>
+            </button>
+
+            {[
+              { label: "已购课程", value: purchasedCourses.length, icon: BookOpen, color: "text-sky-400" },
+              { label: "订单总数", value: orders.length, icon: FileText, color: "text-emerald-400" },
+              { label: "领取记录", value: withdrawals.length, icon: History, color: "text-teal-400" }
+            ].map((stat, i) => (
+              <div
+                key={i}
+                className="group rounded-2xl border border-white/5 bg-white/5 p-6 text-center transition-all hover:bg-white/10"
+              >
+                <div className="flex flex-col items-center gap-3 mb-4">
+                  <div className={cn("p-2 rounded-xl bg-white/5 group-hover:scale-110 transition-transform", stat.color)}>
+                    <stat.icon size={18} />
                   </div>
-                  <div className="px-4 py-3 text-center">
-                    <p className="text-base font-semibold text-[var(--navy)]">{c.title}</p>
-                    <p
-                      className="mt-1 text-sm text-[var(--muted)]"
-                      style={{
-                        display: "-webkit-box",
-                        WebkitLineClamp: 2,
-                        WebkitBoxOrient: "vertical",
-                        overflow: "hidden",
-                      }}
+                  <span className="text-[11px] font-bold uppercase tracking-widest text-slate-500">{stat.label}</span>
+                </div>
+                <p className="text-3xl font-bold tracking-tight text-white">{stat.value}</p>
+              </div>
+            ))}
+          </div>
+        </section>
+
+        <div className="grid gap-8 lg:grid-cols-[300px_minmax(0,1fr)]">
+          {/* 2. 侧边导航 */}
+          <aside className="ui-enter flex flex-col gap-6">
+            <div className="rounded-[2.5rem] border border-white/10 bg-white/5 p-6 backdrop-blur-2xl shadow-xl">
+              <div className="flex items-center gap-4 mb-10 p-2">
+                <div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-[1.25rem] bg-gradient-to-br from-slate-800 to-slate-900 text-xl font-bold text-[#f3deae] shadow-lg ring-1 ring-white/10">
+                  {(user.name || "U").slice(0, 1).toUpperCase()}
+                </div>
+                <div className="min-w-0">
+                  <p className="truncate text-lg font-bold text-white">{user.name}</p>
+                  <p className="text-xs font-medium text-slate-500 tracking-wide uppercase">Member Account</p>
+                </div>
+              </div>
+              
+              <nav className="flex flex-col gap-2">
+                {[
+                  { label: "我的课程", href: "/account/purchased-courses", icon: BookOpen },
+                  { label: "订单管理", href: "/account/orders", icon: FileText },
+                  { label: "领取记录", href: "/account/withdrawals", icon: History },
+                  { label: "修改信息", href: "#edit-info", icon: UserRoundPen, onClick: openEditInfo },
+                  { label: "修改密码", href: "/account/change-password", icon: Settings }
+                ].map((item) =>
+                  "onClick" in item ? (
+                    <button
+                      key={item.href}
+                      type="button"
+                      onClick={item.onClick}
+                      className="group flex w-full items-center justify-between rounded-2xl px-5 py-4 text-sm font-semibold text-slate-400 transition-all hover:bg-white/10 hover:text-white"
                     >
-                      {c.introduction || "-"}
-                    </p>
+                      <span className="flex items-center gap-4">
+                        <item.icon
+                          size={20}
+                          className="text-slate-500 group-hover:text-[#f3deae]"
+                        />{" "}
+                        {item.label}
+                      </span>
+                      <ChevronRight
+                        size={16}
+                        className="opacity-0 -translate-x-2 transition-all group-hover:opacity-100 group-hover:translate-x-0"
+                      />
+                    </button>
+                  ) : (
                     <Link
-                      href={getPurchasedCourseHref(c)}
-                      className="mt-3 inline-flex rounded-full border border-[var(--border)] px-3 py-1.5 text-xs font-medium text-[var(--navy)] hover:bg-slate-50"
+                      key={item.href}
+                      href={item.href}
+                      className="group flex items-center justify-between rounded-2xl px-5 py-4 text-sm font-semibold text-slate-400 transition-all hover:bg-white/10 hover:text-white"
                     >
-                      查看课程
+                      <span className="flex items-center gap-4">
+                        <item.icon
+                          size={20}
+                          className="text-slate-500 group-hover:text-[#f3deae]"
+                        />{" "}
+                        {item.label}
+                      </span>
+                      <ChevronRight
+                        size={16}
+                        className="opacity-0 -translate-x-2 transition-all group-hover:opacity-100 group-hover:translate-x-0"
+                      />
                     </Link>
-                  </div>
-                </li>
-              ))}
-            </ul>
-          )
-        )}
-      </section>
+                  ),
+                )}
+              </nav>
 
-      <section className="mt-10">
-        <div className="flex items-center justify-between">
-          <h2 className="font-serif text-lg font-semibold text-[var(--navy)]">{t("orders")}</h2>
-          <Link
-            href="/account/orders"
-            className="rounded-full border border-[var(--border)] px-4 py-1.5 text-xs font-medium text-[var(--navy)] hover:bg-[var(--card)]"
-          >
-            全部订单
-          </Link>
-        </div>
-        {ordersLoading ? (
-          <p className="mt-3 text-sm text-[var(--muted)]">订单加载中…</p>
-        ) : null}
-        {ordersError ? (
-          <p className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
-            {ordersError}
-          </p>
-        ) : null}
-        {!ordersLoading && !ordersError && orders.length === 0 ? (
-          <p className="mt-3 text-sm text-[var(--muted)]">{t("noOrders")}</p>
-        ) : (
-          !ordersLoading &&
-          !ordersError && (
-            <ul className="mt-4 space-y-3">
-              {orders.slice(0, 3).map((o) => (
-                <li
-                  key={o.serial}
-                  className="rounded-xl border border-[var(--border)] bg-[var(--card)] px-4 py-3 shadow-sm"
+              <div className="mt-10 border-t border-white/5 pt-6">
+                <button
+                  type="button"
+                  onClick={() => setLogoutConfirmOpen(true)}
+                  className="flex w-full items-center gap-4 rounded-2xl px-5 py-4 text-sm font-bold text-rose-400 transition-all hover:bg-rose-500/10"
                 >
-                  <div className="flex flex-wrap items-center justify-between gap-2">
-                    <span className="font-medium text-[var(--navy)]">{o.details}</span>
-                    <div className="flex items-center gap-2">
-                      <span className="rounded-full bg-slate-100 px-2.5 py-0.5 text-xs text-[var(--navy)]">
-                        {getOrderStatusLabel(o.status)}
-                      </span>
-                      <span className="rounded-full border border-[var(--border)] px-2.5 py-0.5 text-xs font-semibold text-[var(--navy)]">
-                        ${o.amount}
-                      </span>
-                      {o.status === 1 ? (
-                        <button
-                          type="button"
-                          onClick={() => setCancelTarget(o)}
-                          className="rounded-full border border-rose-200 bg-rose-50 px-2.5 py-0.5 text-xs text-rose-700 hover:bg-rose-100"
-                        >
-                          取消订单
-                        </button>
-                      ) : null}
+                  <LogOut size={20} /> 退出登录
+                </button>
+              </div>
+            </div>
+          </aside>
+
+          {/* 3. 主内容区 */}
+          <div className="flex flex-col gap-8">
+            {/* 订单记录卡片 */}
+            <section className="ui-enter ui-enter-delay-1 rounded-[2.5rem] border border-white/10 bg-white/5 p-8 backdrop-blur-2xl shadow-xl">
+              <div className="flex items-center justify-between mb-8">
+                <h2 className="font-serif text-2xl font-bold text-white">最新订单记录</h2>
+                <Link href="/account/orders" className="text-xs font-bold text-[#b89458] hover:text-[#f3deae] transition-colors">查看全部</Link>
+              </div>
+              
+              {ordersLoading ? (
+                <div className="py-12 flex justify-center text-slate-500">数据同步中...</div>
+              ) : orders.length === 0 ? (
+                <div className="py-12 flex flex-col items-center justify-center rounded-3xl border border-dashed border-white/10 bg-white/5 text-slate-500">
+                  <p className="text-sm">{t("noOrders")}</p>
+                </div>
+              ) : (
+                <div className="space-y-4">
+                  {orders.slice(0, 2).map((o) => (
+                    <div key={o.serial} className="group rounded-[1.5rem] border border-white/5 bg-white/5 p-5 transition-all hover:bg-white/10">
+                      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
+                        <div className="flex items-center gap-5">
+                          <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl bg-white/5 text-[#f3deae]">
+                            <FileText size={22} />
+                          </div>
+                          <div>
+                            <p className="text-[15px] font-bold text-white group-hover:text-[#f3deae] transition-colors">{o.details}</p>
+                            <p className="text-xs font-medium text-slate-500 mt-1">NO: {o.serial}</p>
+                          </div>
+                        </div>
+                        <div className="flex items-center justify-between sm:justify-end gap-6">
+                          <div className="text-right">
+                            <p className="text-xl font-bold text-white tracking-tight">${o.amount}</p>
+                            <span className={cn("inline-block mt-1 rounded-full border px-3 py-0.5 text-[10px] font-bold uppercase tracking-widest", getStatusStyle(o.status))}>
+                              {getOrderStatusLabel(o.status)}
+                            </span>
+                          </div>
+                          {o.status === 1 && (
+                            <button onClick={() => setCancelTarget(o)} className="text-xs font-bold text-rose-400 hover:text-rose-300">取消</button>
+                          )}
+                        </div>
+                      </div>
                     </div>
+                  ))}
+                </div>
+              )}
+            </section>
+
+            {/* 领取记录卡片 (还原显示) */}
+            <section className="ui-enter ui-enter-delay-2 rounded-[2.5rem] border border-white/10 bg-white/5 p-8 backdrop-blur-2xl shadow-xl">
+              <div className="flex items-center justify-between mb-8">
+                <h2 className="font-serif text-2xl font-bold text-white">财务领取记录</h2>
+                <Link href="/account/withdrawals" className="text-xs font-bold text-[#b89458] hover:text-[#f3deae] transition-colors">查看全部记录</Link>
+              </div>
+              
+              {withdrawalsLoading ? (
+                <div className="py-12 flex justify-center text-slate-500">记录检索中...</div>
+              ) : withdrawals.length === 0 ? (
+                <div className="py-12 flex flex-col items-center justify-center rounded-3xl border border-dashed border-white/10 bg-white/5 text-slate-500">
+                  <p className="text-sm">暂无领取记录</p>
+                </div>
+              ) : (
+                <div className="space-y-4">
+                  {withdrawals.slice(0, 2).map((w) => (
+                    <div key={w.serial} className="group rounded-[1.5rem] border border-white/5 bg-white/5 p-5 transition-all hover:bg-white/10">
+                      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
+                        <div className="flex items-center gap-5">
+                          <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl bg-white/5 text-teal-400">
+                            <History size={22} />
+                          </div>
+                          <div>
+                            <p className="text-[15px] font-bold text-white group-hover:text-teal-400 transition-colors">{w.details}</p>
+                            <p className="text-xs font-medium text-slate-500 mt-1">流水号: {w.serial}</p>
+                          </div>
+                        </div>
+                        <div className="text-right">
+                          <p className="text-xl font-bold text-white tracking-tight">${w.amount}</p>
+                          <span className={cn("inline-block mt-1 rounded-full border px-3 py-0.5 text-[10px] font-bold uppercase tracking-widest", getStatusStyle(w.status))}>
+                            {getWithdrawalStatusLabel(w.status)}
+                          </span>
+                        </div>
+                      </div>
+                    </div>
+                  ))}
+                </div>
+              )}
+            </section>
+
+            {/* 已购买课程 */}
+            <section className="ui-enter ui-enter-delay-3 rounded-[2.5rem] border border-white/10 bg-white/5 p-8 backdrop-blur-2xl shadow-xl">
+              <div className="flex items-center justify-between mb-8">
+                <h2 className="font-serif text-2xl font-bold text-white">已购核心课程</h2>
+                <Link href="/account/purchased-courses" className="text-xs font-bold text-[#b89458] hover:text-[#f3deae] transition-colors">浏览全部课程</Link>
+              </div>
+              
+              <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
+                {purchasedCourses.length > 0 ? (
+                  purchasedCourses.slice(0, 3).map((c) => (
+                    <Link key={c.id} href={`/courses/${c.goodsId}${c.goodsType === 5 ? '?cat=strategy' : ''}`} className="group relative flex flex-col overflow-hidden rounded-[2rem] border border-white/5 bg-white/5 transition-all hover:-translate-y-1 hover:bg-white/10">
+                      <div className="relative h-40 w-full overflow-hidden">
+                        {c.coverUrl ? (
+                          <img src={c.coverUrl} alt={c.title} className="h-full w-full object-cover transition-transform duration-700 group-hover:scale-110" />
+                        ) : <div className="h-full w-full bg-slate-800" />}
+                        <div className="absolute inset-0 bg-gradient-to-t from-[#050b14] to-transparent opacity-60" />
+                      </div>
+                      <div className="p-6">
+                        <h3 className="line-clamp-1 text-[15px] font-bold text-white group-hover:text-[#f3deae] transition-colors">{c.title}</h3>
+                        <p className="mt-2 line-clamp-1 text-[11px] font-medium text-slate-500 uppercase tracking-wide">Course ID: {c.goodsId}</p>
+                      </div>
+                    </Link>
+                  ))
+                ) : (
+                  <div className="col-span-full py-12 flex items-center justify-center rounded-3xl border border-dashed border-white/10 bg-white/5 text-sm font-medium text-slate-500">
+                    暂无学习中的课程
                   </div>
-                  <div className="mt-1 flex flex-wrap gap-x-4 gap-y-1 text-xs text-[var(--muted)]">
-                    <span>流水号: {o.serial}</span>
-                    <span>购买时间: {o.addTime || "-"}</span>
-                    <span>支付时间: {o.payTime || "-"}</span>
-                  </div>
-                </li>
-              ))}
-            </ul>
-          )
-        )}
-      </section>
+                )}
+              </div>
+            </section>
+          </div>
+        </div>
+      </div>
 
-      <section className="mt-10">
-        <div className="flex items-center justify-between">
-          <h2 className="font-serif text-lg font-semibold text-[var(--navy)]">取款记录</h2>
-          <Link
-            href="/account/withdrawals"
-            className="rounded-full border border-[var(--border)] px-4 py-1.5 text-xs font-medium text-[var(--navy)] hover:bg-[var(--card)]"
-          >
-            全部记录
-          </Link>
+      {/* 黑金风格确认弹窗 */}
+      {cancelTarget && (
+        <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+          <div className="w-full max-w-sm overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl">
+            <div className="p-10 text-center">
+              <div className="mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-rose-500/10 text-rose-400">
+                <FileText size={32} />
+              </div>
+              <h3 className="text-xl font-bold text-white">确认撤销订单?</h3>
+              <p className="mt-3 text-sm leading-relaxed text-slate-400 px-4">
+                订单流水号 <span className="text-slate-200">{cancelTarget.serial}</span> 撤销后该操作不可恢复。
+              </p>
+            </div>
+            <div className="flex border-t border-white/5">
+              <button onClick={() => setCancelTarget(null)} className="flex-1 py-5 text-sm font-bold text-slate-400 hover:bg-white/5">暂不处理</button>
+              <div className="w-px bg-white/5" />
+              <button onClick={handleConfirmCancel} disabled={cancelLoading} className="flex-1 py-5 text-sm font-bold text-rose-400 hover:bg-rose-500/10 disabled:opacity-50">
+                {cancelLoading ? "执行中..." : "确认撤销"}
+              </button>
+            </div>
+          </div>
         </div>
-        {withdrawalsLoading ? (
-          <p className="mt-3 text-sm text-[var(--muted)]">取款记录加载中…</p>
-        ) : null}
-        {withdrawalsError ? (
-          <p className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
-            {withdrawalsError}
-          </p>
-        ) : null}
-        {!withdrawalsLoading && !withdrawalsError && withdrawals.length === 0 ? (
-          <p className="mt-3 text-sm text-[var(--muted)]">暂无取款记录。</p>
-        ) : (
-          !withdrawalsLoading &&
-          !withdrawalsError && (
-            <ul className="mt-4 space-y-3">
-              {withdrawals.slice(0, 3).map((w) => (
-                <li
-                  key={w.serial}
-                  className="rounded-xl border border-[var(--border)] bg-[var(--card)] px-4 py-3 shadow-sm"
-                >
-                  <div className="flex flex-wrap items-center justify-between gap-2">
-                    <span className="font-medium text-[var(--navy)]">{w.details}</span>
-                    <div className="flex items-center gap-2">
-                      <span className="rounded-full bg-slate-100 px-2.5 py-0.5 text-xs text-[var(--navy)]">
-                        {getWithdrawalStatusLabel(w.status)}
-                      </span>
-                      <span className="rounded-full border border-[var(--border)] px-2.5 py-0.5 text-xs font-semibold text-[var(--navy)]">
-                        ${w.amount}
-                      </span>
+      )}
+
+      {/* 消费明细弹框 */}
+      {balanceDetailOpen && (
+        <div className="fixed inset-0 z-[55] flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+          <div className="w-full max-w-2xl overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl">
+            <div className="flex items-center justify-between border-b border-white/5 p-6 md:px-8">
+              <h3 className="text-xl font-bold text-white flex items-center gap-2">
+                <Wallet className="text-[#b89458]" size={20} /> 消费明细
+              </h3>
+              <button
+                onClick={() => setBalanceDetailOpen(false)}
+                className="text-sm font-bold text-slate-500 hover:text-white"
+              >
+                关闭
+              </button>
+            </div>
+
+            <div className="p-6 md:p-8 max-h-[70vh] overflow-y-auto space-y-4 custom-scrollbar">
+              {balanceDetailLoading ? (
+                <div className="py-12 flex justify-center text-slate-500">
+                  数据加载中...
+                </div>
+              ) : balanceDetailError ? (
+                <div className="rounded-2xl border border-rose-500/20 bg-rose-500/10 p-4 text-sm text-rose-400">
+                  {balanceDetailError}
+                </div>
+              ) : balanceRecords.length === 0 ? (
+                <div className="py-16 flex flex-col items-center justify-center rounded-3xl border border-dashed border-white/10 bg-white/5 text-slate-500">
+                  <p className="text-sm">暂无消费明细</p>
+                </div>
+              ) : (
+                <div className="space-y-3">
+                  {balanceRecords.map((r) => (
+                    <div
+                      key={r.id}
+                      className="rounded-[1.5rem] border border-white/5 bg-white/5 p-5 transition-all hover:bg-white/10"
+                    >
+                      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
+                        <div>
+                          <p className="text-[15px] font-bold text-white">
+                            {balanceTypeLabel(r.type)}
+                          </p>
+                          <p className="mt-1 text-xs font-medium text-slate-500">
+                            添加时间: {r.addTime || "-"}
+                          </p>
+                        </div>
+                        <div className="text-right">
+                          <p className="text-xl font-bold text-white tracking-tight">
+                            ${Number(r.amount ?? 0).toFixed(2)}
+                          </p>
+                          <span className="inline-block mt-1 rounded-full border border-white/10 bg-white/5 px-3 py-0.5 text-[10px] font-bold uppercase tracking-widest text-slate-400">
+                            type: {r.type}
+                          </span>
+                        </div>
+                      </div>
                     </div>
-                  </div>
-                  <div className="mt-1 flex flex-wrap gap-x-4 gap-y-1 text-xs text-[var(--muted)]">
-                    <span>流水号: {w.serial}</span>
-                    <span>申请时间: {w.addTime || "-"}</span>
-                    <span>到账时间: {w.payTime || "-"}</span>
-                  </div>
-                </li>
-              ))}
-            </ul>
-          )
-        )}
-      </section>
+                  ))}
+                </div>
+              )}
+            </div>
+          </div>
+        </div>
+      )}
 
-      {cancelTarget ? (
-        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4">
-          <div className="w-full max-w-sm rounded-2xl border border-[var(--border)] bg-[var(--card)] p-5 shadow-xl">
-            <p className="text-base font-semibold text-[var(--navy)]">确认取消订单?</p>
-            <p className="mt-2 text-sm text-[var(--muted)]">
-              订单号:{cancelTarget.serial}
-            </p>
-            <div className="mt-5 flex justify-end gap-2">
+      {/* 修改信息弹框 */}
+      {editInfoOpen && (
+        <div className="fixed inset-0 z-[65] flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+          <div className="w-full max-w-md overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl">
+            <div className="flex items-center justify-between border-b border-white/5 p-6 md:px-8">
+              <h3 className="text-xl font-bold text-white flex items-center gap-2">
+                <UserRoundPen className="text-[#b89458]" size={20} /> 修改信息
+              </h3>
               <button
                 type="button"
-                onClick={() => setCancelTarget(null)}
-                className="rounded-lg border border-[var(--border)] px-4 py-2 text-sm"
+                onClick={closeEditInfo}
+                disabled={editSubmitting}
+                className="text-sm font-bold text-slate-500 hover:text-white disabled:opacity-50"
               >
                 关闭
               </button>
+            </div>
+
+            <div className="p-6 md:p-8 space-y-4">
+              {editError ? (
+                <div className="rounded-2xl border border-rose-500/20 bg-rose-500/10 p-4 text-sm text-rose-400">
+                  {editError}
+                </div>
+              ) : null}
+
+              <div className="space-y-4">
+                <div>
+                  <label className="text-sm font-bold text-slate-300">姓名</label>
+                  <input
+                    value={editName}
+                    onChange={(e) => setEditName(e.target.value)}
+                    className="mt-2 w-full rounded-xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white placeholder-slate-500 focus:border-[#b89458] focus:outline-none focus:ring-1 focus:ring-[#b89458]"
+                    placeholder="请输入姓名"
+                  />
+                </div>
+                <div>
+                  <label className="text-sm font-bold text-slate-300">手机号</label>
+                  <input
+                    value={editPhone}
+                    onChange={(e) => setEditPhone(e.target.value)}
+                    className="mt-2 w-full rounded-xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white placeholder-slate-500 focus:border-[#b89458] focus:outline-none focus:ring-1 focus:ring-[#b89458]"
+                    placeholder="请输入手机号"
+                  />
+                </div>
+                <div>
+                  <label className="text-sm font-bold text-slate-300">证件号</label>
+                  <input
+                    value={editIdentity}
+                    onChange={(e) => setEditIdentity(e.target.value)}
+                    className="mt-2 w-full rounded-xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white placeholder-slate-500 focus:border-[#b89458] focus:outline-none focus:ring-1 focus:ring-[#b89458]"
+                    placeholder="请输入证件号"
+                  />
+                </div>
+              </div>
+            </div>
+
+            <div className="flex gap-4 border-t border-white/5 p-6 bg-black/20">
+              <button
+                type="button"
+                onClick={closeEditInfo}
+                disabled={editSubmitting}
+                className="flex-1 rounded-xl bg-white/10 py-4 font-bold text-white hover:bg-white/20 transition-all disabled:opacity-50"
+              >
+                取消
+              </button>
+              <button
+                type="button"
+                onClick={submitEditInfo}
+                disabled={editSubmitting}
+                className="flex-1 rounded-xl bg-gradient-to-br from-[#f3deae] to-[#d9be88] py-4 font-bold text-[#5c461a] shadow-lg hover:opacity-90 transition-all disabled:opacity-50"
+              >
+                {editSubmitting ? "提交中..." : "确认修改"}
+              </button>
+            </div>
+          </div>
+        </div>
+      )}
+
+      {/* 退出登录确认弹框 */}
+      {logoutConfirmOpen && (
+        <div className="fixed inset-0 z-[80] flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+          <div className="w-full max-w-sm overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl">
+            <div className="p-10 text-center">
+              <div className="mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-rose-500/10 text-rose-400">
+                <LogOut size={28} />
+              </div>
+              <h3 className="text-xl font-bold text-white">确认退出登录?</h3>
+              <p className="mt-3 text-sm leading-relaxed text-slate-400 px-4">
+                退出后将清空本地缓存信息。
+              </p>
+            </div>
+            <div className="flex border-t border-white/5">
+              <button
+                type="button"
+                onClick={() => setLogoutConfirmOpen(false)}
+                className="flex-1 py-5 text-sm font-bold text-slate-400 hover:bg-white/5"
+              >
+                取消
+              </button>
+              <div className="w-px bg-white/5" />
               <button
                 type="button"
-                onClick={handleConfirmCancel}
-                disabled={cancelLoading}
-                className="rounded-lg bg-rose-600 px-4 py-2 text-sm text-white disabled:opacity-60"
+                onClick={() => {
+                  setLogoutConfirmOpen(false);
+                  logout();
+                  if (typeof window !== "undefined") window.location.reload();
+                }}
+                className="flex-1 py-5 text-sm font-bold text-rose-400 hover:bg-rose-500/10"
               >
-                {cancelLoading ? "处理中..." : "确定取消"}
+                确认退出
               </button>
             </div>
           </div>
         </div>
-      ) : null}
+      )}
     </div>
   );
-}
+}

+ 111 - 162
src/app/[locale]/account/purchased-courses/page.tsx

@@ -3,6 +3,7 @@
 import { useEffect, useState } from "react";
 import { Link } from "@/i18n/navigation";
 import { useAuth } from "@/providers/auth-provider";
+import { BookOpen, ArrowLeft, Loader2, PlayCircle, CheckCircle2 } from "lucide-react";
 import {
   fetchPurchasedCourses,
   type PurchasedCourse,
@@ -18,6 +19,7 @@ export default function PurchasedCoursesPage() {
   const [courses, setCourses] = useState<PurchasedCourse[]>([]);
   const [loading, setLoading] = useState(false);
   const [error, setError] = useState<string | null>(null);
+  
   const [rewardQuestion, setRewardQuestion] = useState<RewardQuestion | null>(null);
   const [showRewardConfirm, setShowRewardConfirm] = useState(false);
   const [showRewardAnswer, setShowRewardAnswer] = useState(false);
@@ -37,29 +39,15 @@ export default function PurchasedCoursesPage() {
         setCourses(list);
       } catch (e) {
         if (cancelled) return;
-        const err = e as Error;
-        setError(err.message || "已购买课程加载失败,请稍后重试。");
-        setCourses([]);
+        setError((e as Error).message || "已购买课程加载失败,请稍后重试。");
       } finally {
         if (!cancelled) setLoading(false);
       }
     }
     void loadCourses();
-    return () => {
-      cancelled = true;
-    };
+    return () => { cancelled = true; };
   }, [user]);
 
-  useEffect(() => {
-    if (!showRewardThanks) return;
-    const timer = window.setTimeout(() => {
-      setShowRewardThanks(false);
-    }, 3000);
-    return () => {
-      window.clearTimeout(timer);
-    };
-  }, [showRewardThanks]);
-
   useEffect(() => {
     if (!user) return;
     let cancelled = false;
@@ -70,32 +58,29 @@ export default function PurchasedCoursesPage() {
         setRewardQuestion(question);
         if (question.type === 1 && question.questionId && question.question) {
           setShowRewardConfirm(true);
-          setRewardError(null);
         }
-      } catch {
-        if (cancelled) return;
-      }
+      } catch { /* ignore */ }
     }
     void loadRewardQuestion();
-    return () => {
-      cancelled = true;
-    };
+    return () => { cancelled = true; };
   }, [user]);
 
+  useEffect(() => {
+    if (!showRewardThanks) return;
+    const timer = window.setTimeout(() => setShowRewardThanks(false), 3000);
+    return () => window.clearTimeout(timer);
+  }, [showRewardThanks]);
+
   async function handleSubmitRewardAnswer(customAnswer: 0 | 1) {
     if (!rewardQuestion?.questionId) return;
     try {
       setRewardSubmitting(true);
       setRewardError(null);
-      await submitRewardQuestionAnswer({
-        questionId: rewardQuestion.questionId,
-        customAnswer,
-      });
+      await submitRewardQuestionAnswer({ questionId: rewardQuestion.questionId, customAnswer });
       setShowRewardAnswer(false);
       setShowRewardThanks(true);
     } catch (e) {
-      const err = e as Error;
-      setRewardError(err.message || "答题提交失败,请稍后重试。");
+      setRewardError((e as Error).message || "答题提交失败,请稍后重试。");
     } finally {
       setRewardSubmitting(false);
     }
@@ -106,159 +91,123 @@ export default function PurchasedCoursesPage() {
     return course.goodsType === 5 ? `${baseHref}?cat=strategy` : baseHref;
   }
 
-  if (!isReady) {
-    return <div className="page-shell py-16 text-center text-[var(--muted)]">…</div>;
-  }
+  if (!isReady) return <div className="min-h-screen bg-[#050b14] flex items-center justify-center text-slate-500"><Loader2 className="animate-spin" /></div>;
 
   if (!user) {
     return (
-      <div className="page-shell py-16 text-center text-[var(--muted)]">
-        <p>请先登录后查看已购买课程。</p>
-        <Link
-          href="/auth/login"
-          className="mt-4 inline-block rounded-full bg-[var(--navy)] px-6 py-2 text-sm text-white"
-        >
-          登录
-        </Link>
+      <div className="min-h-screen bg-[#050b14] flex items-center justify-center px-4 font-sans">
+        <div className="w-full max-w-md rounded-[2.5rem] border border-white/10 bg-white/5 p-10 text-center backdrop-blur-2xl">
+          <h2 className="text-2xl font-bold text-white mb-6">您尚未登录</h2>
+          <Link href="/auth/login" className="inline-block rounded-full bg-[#f3deae] px-10 py-4 text-sm font-bold text-[#5c461a] shadow-lg">立即登录</Link>
+        </div>
       </div>
     );
   }
 
   return (
-    <div className="page-shell page-shell-wide">
-      <div className="flex items-center justify-between">
-        <h1 className="font-serif text-2xl font-semibold text-[var(--navy)]">已购买课程</h1>
-        <Link
-          href="/account"
-          className="rounded-full border border-[var(--border)] px-4 py-1.5 text-xs text-[var(--navy)]"
-        >
-          返回用户中心
-        </Link>
+    <div className="min-h-screen bg-[#050b14] pb-24 text-slate-300 font-sans relative">
+      <div className="pointer-events-none fixed inset-0 z-0">
+        <div className="absolute left-1/4 top-0 h-[500px] w-[500px] rounded-full bg-blue-900/10 blur-[120px]" />
+        <div className="absolute right-1/4 bottom-0 h-[500px] w-[500px] rounded-full bg-[#b89458]/5 blur-[120px]" />
       </div>
 
-      {loading ? <p className="mt-4 text-sm text-[var(--muted)]">课程加载中…</p> : null}
-      {error ? (
-        <p className="mt-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
-          {error}
-        </p>
-      ) : null}
-      {!loading && !error && courses.length === 0 ? (
-        <p className="mt-4 text-sm text-[var(--muted)]">暂无已购买课程。</p>
-      ) : null}
+      <div className="site-container relative z-10 pt-16">
+        <div className="flex items-center justify-between mb-8">
+          <div>
+            <h1 className="font-serif text-3xl font-bold text-white">已购核心课程</h1>
+            <p className="mt-2 text-sm text-slate-400">持续学习,精进您的交易系统与策略</p>
+          </div>
+          <Link href="/account" className="flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-5 py-2.5 text-sm font-semibold text-slate-300 transition hover:bg-white/10 hover:text-white backdrop-blur-md">
+            <ArrowLeft size={16} /> 返回控制中心
+          </Link>
+        </div>
+
+        <section className="rounded-[2.5rem] border border-white/10 bg-white/5 p-6 md:p-10 backdrop-blur-2xl shadow-2xl">
+          {loading ? <div className="py-20 flex justify-center text-slate-500"><Loader2 className="animate-spin h-8 w-8" /></div> : null}
+          {error ? <div className="mb-6 rounded-2xl border border-rose-500/20 bg-rose-500/10 p-4 text-sm text-rose-400">{error}</div> : null}
 
-      {!loading && !error && courses.length > 0 ? (
-        <ul className="mt-4 grid gap-3 md:grid-cols-3">
-          {courses.map((c) => (
-            <li
-              key={c.id}
-              className="overflow-hidden rounded-xl border border-[var(--border)] bg-[var(--card)] shadow-sm"
-            >
-              <div className="h-36 w-full bg-slate-100">
-                {c.coverUrl ? (
-                  // eslint-disable-next-line @next/next/no-img-element
-                  <img src={c.coverUrl} alt={c.title} className="h-full w-full object-cover" />
-                ) : null}
-              </div>
-              <div className="px-4 py-3 text-center">
-                <p className="text-base font-semibold text-[var(--navy)]">{c.title}</p>
-                <p
-                  className="mt-1 text-sm text-[var(--muted)]"
-                  style={{
-                    display: "-webkit-box",
-                    WebkitLineClamp: 2,
-                    WebkitBoxOrient: "vertical",
-                    overflow: "hidden",
-                  }}
-                >
-                  {c.introduction || "-"}
-                </p>
-                <Link
-                  href={getPurchasedCourseHref(c)}
-                  className="mt-3 inline-flex rounded-full border border-[var(--border)] px-3 py-1.5 text-xs font-medium text-[var(--navy)] hover:bg-slate-50"
-                >
-                  查看课程
+          {!loading && !error && courses.length === 0 ? (
+             <div className="py-20 flex flex-col items-center justify-center rounded-[2rem] border border-dashed border-white/10 bg-white/5 text-slate-500">
+              <BookOpen size={48} className="mb-4 opacity-50" />
+              <p className="text-sm">暂无已购买的课程。</p>
+            </div>
+          ) : null}
+
+          {!loading && !error && courses.length > 0 ? (
+            <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
+              {courses.map((c) => (
+                <Link key={c.id} href={getPurchasedCourseHref(c)} className="group relative flex flex-col overflow-hidden rounded-[2rem] border border-white/10 bg-white/5 transition-all duration-300 hover:-translate-y-2 hover:bg-white/10 hover:shadow-2xl hover:shadow-[#b89458]/10">
+                  <div className="relative h-44 w-full overflow-hidden bg-slate-900">
+                    {c.coverUrl && <img src={c.coverUrl} alt={c.title} className="h-full w-full object-cover transition-transform duration-700 group-hover:scale-110" />}
+                    <div className="absolute inset-0 bg-gradient-to-t from-[#050b14] via-transparent to-transparent opacity-80" />
+                    <div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity bg-black/40">
+                      <PlayCircle size={48} className="text-[#f3deae]" />
+                    </div>
+                  </div>
+                  <div className="flex flex-col flex-1 p-6">
+                    <h3 className="line-clamp-2 text-base font-bold text-white group-hover:text-[#f3deae] transition-colors leading-snug">{c.title}</h3>
+                    <p className="mt-3 line-clamp-2 text-xs text-slate-400 leading-relaxed">{c.introduction || "暂无课程介绍"}</p>
+                    <div className="mt-auto pt-6 flex items-center justify-between">
+                       <span className="text-[10px] font-bold text-slate-500 uppercase tracking-widest">ID: {c.goodsId}</span>
+                       <span className="text-xs font-bold text-[#b89458] group-hover:text-[#f3deae] transition-colors">立即学习 →</span>
+                    </div>
+                  </div>
                 </Link>
-              </div>
-            </li>
-          ))}
-        </ul>
-      ) : null}
+              ))}
+            </div>
+          ) : null}
+        </section>
+      </div>
 
-      {showRewardConfirm ? (
-        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4">
-          <div className="w-full max-w-sm rounded-2xl border border-[var(--border)] bg-[var(--card)] p-5 shadow-xl">
-            <p className="text-base font-semibold text-[var(--navy)]">有奖问答</p>
-            <p className="mt-2 text-sm text-[var(--muted)]">是否参加有奖问答?</p>
-            <div className="mt-5 flex justify-end gap-2">
-              <button
-                type="button"
-                onClick={() => setShowRewardConfirm(false)}
-                className="rounded-lg border border-[var(--border)] px-4 py-2 text-sm"
-              >
-                否
-              </button>
-              <button
-                type="button"
-                onClick={() => {
-                  setShowRewardConfirm(false);
-                  setShowRewardAnswer(true);
-                }}
-                className="rounded-lg bg-[var(--navy)] px-4 py-2 text-sm text-white"
-              >
-                是
-              </button>
+      {/* 有奖问答弹窗系列 (保持功能,升级样式) */}
+      {showRewardConfirm && (
+        <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+          <div className="w-full max-w-sm overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl">
+            <div className="p-10 text-center">
+              <div className="mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-[#b89458]/10 text-[#f3deae]">
+                 <CheckCircle2 size={32} />
+              </div>
+              <h3 className="text-xl font-bold text-white">平台福利回馈</h3>
+              <p className="mt-3 text-sm text-slate-400">您有一个专属有奖问答,是否现在参与?</p>
+            </div>
+            <div className="flex border-t border-white/5">
+              <button onClick={() => setShowRewardConfirm(false)} className="flex-1 py-5 text-sm font-bold text-slate-400 hover:bg-white/5">稍后再说</button>
+              <div className="w-px bg-white/5" />
+              <button onClick={() => { setShowRewardConfirm(false); setShowRewardAnswer(true); }} className="flex-1 py-5 text-sm font-bold text-[#f3deae] hover:bg-white/5">立即参与</button>
             </div>
           </div>
         </div>
-      ) : null}
+      )}
 
-      {showRewardAnswer && rewardQuestion ? (
-        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4">
-          <div className="w-full max-w-lg rounded-2xl border border-[var(--border)] bg-[var(--card)] p-5 shadow-xl">
-            <p className="text-base font-semibold text-[var(--navy)]">有奖问答</p>
-            <p className="mt-2 text-sm text-[var(--muted)]">{rewardQuestion.question}</p>
-            {rewardError ? (
-              <p className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
-                {rewardError}
-              </p>
-            ) : null}
-            <div className="mt-5 flex flex-wrap justify-end gap-2">
-              <button
-                type="button"
-                onClick={() => setShowRewardAnswer(false)}
-                disabled={rewardSubmitting}
-                className="rounded-lg border border-[var(--border)] px-4 py-2 text-sm disabled:opacity-60"
-              >
-                关闭
-              </button>
-              <button
-                type="button"
-                onClick={() => void handleSubmitRewardAnswer(0)}
-                disabled={rewardSubmitting}
-                className="rounded-lg border border-rose-200 bg-rose-50 px-4 py-2 text-sm text-rose-700 disabled:opacity-60"
-              >
-                选错
-              </button>
-              <button
-                type="button"
-                onClick={() => void handleSubmitRewardAnswer(1)}
-                disabled={rewardSubmitting}
-                className="rounded-lg bg-emerald-600 px-4 py-2 text-sm text-white disabled:opacity-60"
-              >
-                选对
-              </button>
+      {showRewardAnswer && rewardQuestion && (
+        <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+          <div className="w-full max-w-md overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl p-8">
+            <div className="flex items-center gap-3 mb-6">
+              <CheckCircle2 size={24} className="text-[#b89458]" />
+              <h3 className="text-xl font-bold text-white">有奖问答</h3>
             </div>
+            <p className="text-base font-medium leading-relaxed text-slate-300">{rewardQuestion.question}</p>
+            {rewardError && <p className="mt-4 rounded-xl border border-rose-500/30 bg-rose-500/10 p-3 text-sm text-rose-400">{rewardError}</p>}
+            
+            <div className="mt-8 grid grid-cols-2 gap-4">
+              <button onClick={() => handleSubmitRewardAnswer(0)} disabled={rewardSubmitting} className="rounded-2xl border border-white/10 bg-white/5 py-4 text-sm font-bold text-slate-400 hover:bg-white/10 hover:text-white disabled:opacity-50">回答错误</button>
+              <button onClick={() => handleSubmitRewardAnswer(1)} disabled={rewardSubmitting} className="rounded-2xl bg-gradient-to-br from-[#f3deae] to-[#d9be88] py-4 text-sm font-bold text-[#5c461a] shadow-lg hover:opacity-90 disabled:opacity-50">回答正确</button>
+            </div>
+            <button onClick={() => setShowRewardAnswer(false)} className="mt-4 w-full py-3 text-xs font-bold text-slate-500 hover:text-slate-300">放弃并关闭</button>
           </div>
         </div>
-      ) : null}
+      )}
 
-      {showRewardThanks ? (
-        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 px-4">
-          <div className="w-full max-w-sm rounded-2xl border border-[var(--border)] bg-[var(--card)] p-5 text-center shadow-xl">
-            <p className="text-base font-semibold text-[var(--navy)]">感谢参与</p>
-          </div>
-        </div>
-      ) : null}
+      {showRewardThanks && (
+         <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+            <div className="rounded-[2.5rem] border border-white/10 bg-[#0a1120] p-10 text-center shadow-2xl">
+              <div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-400">
+                 <CheckCircle2 size={32} />
+              </div>
+              <p className="text-xl font-bold text-white">感谢您的参与!</p>
+            </div>
+         </div>
+      )}
     </div>
   );
-}
+}

+ 229 - 792
src/app/[locale]/account/withdraw-apply/page.tsx

@@ -2,6 +2,7 @@
 
 import { Link } from "@/i18n/navigation";
 import { useEffect, useMemo, useState } from "react";
+import { ArrowLeft, Loader2, Wallet, CheckCircle2, AlertCircle } from "lucide-react";
 import { fetchWalletBalance } from "@/lib/account-api";
 import {
   fetchWithdrawBankOptions,
@@ -11,15 +12,14 @@ import {
   type WithdrawBankOption,
   type WithdrawChannel,
 } from "@/lib/withdrawal-api";
-import { InlineLoading } from "@/components/ui/loading-state";
-import { ModalShell } from "@/components/ui/modal-shell";
+import { cn } from "@/lib/utils";
 
+// 保留原有的所有辅助函数 (channelGroupLabel, groupOrder, formatAmountRange 等)
 function channelGroupLabel(channel: WithdrawChannel): string {
   const type = channel.type;
   const code = (channel.code || "").toUpperCase();
   const name = `${channel.name || ""} ${channel.enName || ""}`.toUpperCase();
   const aliHint = code.includes("ALI") || code.includes("ALIPAY") || name.includes("ALIPAY");
-
   if (type === "BANK_TELEGRAPHIC") return "国际转账";
   if (type === "BANK") return "网银支付";
   if (type === "DIGITAL_CURRENCY") return "数字货币";
@@ -29,60 +29,26 @@ function channelGroupLabel(channel: WithdrawChannel): string {
   if (type === "UCARD_WALLET") return "电子卡";
   return "其他";
 }
-
 function groupOrder(label: string): number {
-  if (label === "数字货币") return 1;
-  if (label === "网银支付") return 2;
-  if (label === "国际转账") return 3;
-  if (label === "电子钱包") return 4;
-  if (label === "电子卡") return 5;
-  if (label === "支付宝") return 6;
-  return 99;
+  if (label === "数字货币") return 1; if (label === "网银支付") return 2; if (label === "国际转账") return 3;
+  if (label === "电子钱包") return 4; if (label === "电子卡") return 5; if (label === "支付宝") return 6; return 99;
 }
-
 function formatAmountRange(item: WithdrawChannel): string {
-  const min = item.minAmount || 0;
-  const max = item.maxAmount > 0 ? item.maxAmount : "-";
-  return `$${min} - $${max} ${item.currency || "USD"}`;
+  const min = item.minAmount || 0; const max = item.maxAmount > 0 ? item.maxAmount : "-"; return `$${min} - $${max} ${item.currency || "USD"}`;
 }
-
 function formatFee(item: WithdrawChannel): string {
-  if (item.feeType === 1) return `${item.free ?? 0}%`;
-  if (item.feeType === 2) return `$${item.feeAmount ?? 0}`;
-  if (item.free !== null && item.free !== undefined) return `${item.free}%`;
-  return "0%";
+  if (item.feeType === 1) return `${item.free ?? 0}%`; if (item.feeType === 2) return `$${item.feeAmount ?? 0}`;
+  if (item.free !== null && item.free !== undefined) return `${item.free}%`; return "0%";
 }
-
 function sanitizeHtml(input: string): string {
-  if (!input) return "";
-  return input
-    .replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi, "")
-    .replace(/\son\w+="[^"]*"/gi, "")
-    .replace(/\son\w+='[^']*'/gi, "");
-}
-
-function isWalletType(type: string): boolean {
-  return type === "CHANNEL_TYPE_WALLET" || type === "CHANNEL_TYPE_ALI_WALLET";
-}
-
-function isBankType(type: string): boolean {
-  return type === "BANK";
-}
-
-function isCardType(type: string): boolean {
-  return type === "CHANNEL_TYPE_CARD";
-}
-
-function isDigitalCurrencyType(type: string): boolean {
-  return type === "DIGITAL_CURRENCY";
+  if (!input) return ""; return input.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi, "").replace(/\son\w+="[^"]*"/gi, "").replace(/\son\w+='[^']*'/gi, "");
 }
-
+function isWalletType(type: string) { return type === "CHANNEL_TYPE_WALLET" || type === "CHANNEL_TYPE_ALI_WALLET"; }
+function isBankType(type: string) { return type === "BANK"; }
+function isCardType(type: string) { return type === "CHANNEL_TYPE_CARD"; }
+function isDigitalCurrencyType(type: string) { return type === "DIGITAL_CURRENCY"; }
 function savedAccountType(type: string): number | null {
-  if (type === "BANK") return 1;
-  if (type === "BANK_TELEGRAPHIC") return 2;
-  if (type === "CHANNEL_TYPE_CARD") return 3;
-  if (type === "DIGITAL_CURRENCY") return 4;
-  return null;
+  if (type === "BANK") return 1; if (type === "BANK_TELEGRAPHIC") return 2; if (type === "CHANNEL_TYPE_CARD") return 3; if (type === "DIGITAL_CURRENCY") return 4; return null;
 }
 
 export default function WithdrawApplyPage() {
@@ -90,11 +56,11 @@ export default function WithdrawApplyPage() {
   const [channelsLoading, setChannelsLoading] = useState(false);
   const [channelsError, setChannelsError] = useState<string | null>(null);
   const [walletBalance, setWalletBalance] = useState<number | null>(null);
-  const [walletBalanceLoading, setWalletBalanceLoading] = useState(false);
-
+  
   const [savedAccounts] = useState<SavedWithdrawAccount[]>([]);
   const [bankOptions, setBankOptions] = useState<WithdrawBankOption[]>([]);
 
+  // 表单状态
   const [selectedChannelId, setSelectedChannelId] = useState("");
   const [selectedSavedId, setSelectedSavedId] = useState("");
   const [selectedBankCode, setSelectedBankCode] = useState("");
@@ -103,6 +69,7 @@ export default function WithdrawApplyPage() {
   const [amount, setAmount] = useState("");
   const [agree, setAgree] = useState(false);
   const [agreeExtra, setAgreeExtra] = useState(false);
+  // ... 其他银行/电汇字段
   const [agencyNo, setAgencyNo] = useState("");
   const [cpf, setCpf] = useState("");
   const [bankUnameInput, setBankUnameInput] = useState("");
@@ -122,33 +89,12 @@ export default function WithdrawApplyPage() {
   const [confirmOpen, setConfirmOpen] = useState(false);
   const [expandedGroup, setExpandedGroup] = useState<string>("数字货币");
   const [applyDialogOpen, setApplyDialogOpen] = useState(false);
-  const [resultDialog, setResultDialog] = useState<{
-    open: boolean;
-    status: "success" | "error";
-    title: string;
-    message: string;
-  }>({
-    open: false,
-    status: "success",
-    title: "",
-    message: "",
-  });
-
-  const selectedChannel = useMemo(
-    () => channels.find((item) => item.id === selectedChannelId) ?? null,
-    [channels, selectedChannelId],
-  );
-
-  const selectedSavedAccount = useMemo(
-    () => savedAccounts.find((item) => item.id === selectedSavedId) ?? null,
-    [savedAccounts, selectedSavedId],
-  );
+  const [resultDialog, setResultDialog] = useState({ open: false, status: "success", title: "", message: "" });
 
+  const selectedChannel = useMemo(() => channels.find((item) => item.id === selectedChannelId) ?? null, [channels, selectedChannelId]);
+  const selectedSavedAccount = useMemo(() => savedAccounts.find((item) => item.id === selectedSavedId) ?? null, [savedAccounts, selectedSavedId]);
   const filteredSavedAccounts = useMemo(() => {
-    if (!selectedChannel) return [];
-    const type = savedAccountType(selectedChannel.type);
-    if (type === null) return [];
-    return savedAccounts.filter((item) => item.type === type);
+    if (!selectedChannel) return []; const type = savedAccountType(selectedChannel.type); if (type === null) return []; return savedAccounts.filter((item) => item.type === type);
   }, [savedAccounts, selectedChannel]);
 
   const shouldRequireSavedAccount = false;
@@ -157,781 +103,272 @@ export default function WithdrawApplyPage() {
   const needCpf = selectedChannel?.code === "PAY_RETAILER_REMIT_PAY_KEY_BRW";
 
   function resetApplyForm() {
-    setSelectedSavedId("");
-    setSelectedBankCode("");
-    setAddressName("");
-    setAddress("");
-    setAmount("");
-    setAgree(false);
-    setAgreeExtra(false);
-    setAgencyNo("");
-    setCpf("");
-    setBankUnameInput("");
-    setBankCardNumInput("");
-    setBankNameInput("");
-    setBankBranchNameInput("");
-    setSwiftCodeInput("");
-    setCustomBankCodeInput("");
-    setBankAddrInput("");
-    setTelegraphicCurrency("USD");
-    setCardUnameInput("");
-    setCardNumInput("");
-    setCardCvvInput("");
-    setCardExpiryInput("");
+    setSelectedSavedId(""); setSelectedBankCode(""); setAddressName(""); setAddress(""); setAmount(""); setAgree(false); setAgreeExtra(false); setAgencyNo(""); setCpf(""); setBankUnameInput(""); setBankCardNumInput(""); setBankNameInput(""); setBankBranchNameInput(""); setSwiftCodeInput(""); setCustomBankCodeInput(""); setBankAddrInput(""); setTelegraphicCurrency("USD"); setCardUnameInput(""); setCardNumInput(""); setCardCvvInput(""); setCardExpiryInput("");
   }
 
   useEffect(() => {
     let cancelled = false;
     async function loadBase() {
-      setWalletBalanceLoading(true);
-      setChannelsLoading(true);
-      setChannelsError(null);
+      setChannelsLoading(true); setChannelsError(null);
       try {
-        const [balanceResult, channelsResult] = await Promise.all([
-          fetchWalletBalance(),
-          fetchWithdrawChannels(),
-        ]);
+        const [balanceResult, channelsResult] = await Promise.all([fetchWalletBalance(), fetchWithdrawChannels()]);
         if (cancelled) return;
-        setWalletBalance(balanceResult);
-        setChannels(channelsResult);
+        setWalletBalance(balanceResult); setChannels(channelsResult);
       } catch (e) {
-        if (cancelled) return;
-        const err = e as Error;
-        setChannelsError(err?.message || "提款通道加载失败");
-        setChannels([]);
-        setWalletBalance(null);
+        if (!cancelled) setChannelsError((e as Error)?.message || "通道加载失败");
       } finally {
-        if (!cancelled) {
-          setWalletBalanceLoading(false);
-          setChannelsLoading(false);
-        }
+        if (!cancelled) setChannelsLoading(false);
       }
     }
-    void loadBase();
-    return () => {
-      cancelled = true;
-    };
+    void loadBase(); return () => { cancelled = true; };
   }, []);
 
   useEffect(() => {
-    if (!selectedChannel || !applyDialogOpen) {
-      setBankOptions([]);
-      setSelectedBankCode("");
-      return;
-    }
-    const currentChannel = selectedChannel;
-    setSelectedSavedId("");
-    setAddressName("");
-    setAddress("");
-    setAgree(false);
-    setAgreeExtra(false);
-    setBankUnameInput("");
-    setBankCardNumInput("");
-    setBankNameInput("");
-    setBankBranchNameInput("");
-    setSwiftCodeInput("");
-    setCustomBankCodeInput("");
-    setBankAddrInput("");
-    setTelegraphicCurrency("USD");
-    setCardUnameInput("");
-    setCardNumInput("");
-    setCardCvvInput("");
-    setCardExpiryInput("");
-
-    if (!currentChannel.bankValid) {
-      setBankOptions([]);
-      setSelectedBankCode("");
-      return;
-    }
+    if (!selectedChannel || !applyDialogOpen) { setBankOptions([]); setSelectedBankCode(""); return; }
+    resetApplyForm();
+    if (!selectedChannel.bankValid) return;
     let cancelled = false;
     async function loadBankOptions() {
       try {
-        const list = await fetchWithdrawBankOptions(currentChannel.code);
-        if (cancelled) return;
-        setBankOptions(list);
-        setSelectedBankCode((prev) => prev || list[0]?.code || "");
-      } catch {
-        if (cancelled) return;
-        setBankOptions([]);
-      }
+        const list = await fetchWithdrawBankOptions(selectedChannel!.code);
+        if (cancelled) return; setBankOptions(list); setSelectedBankCode((prev) => prev || list[0]?.code || "");
+      } catch { if (!cancelled) setBankOptions([]); }
     }
-    void loadBankOptions();
-    return () => {
-      cancelled = true;
-    };
+    void loadBankOptions(); return () => { cancelled = true; };
   }, [selectedChannel, applyDialogOpen]);
 
   useEffect(() => {
     if (!selectedSavedAccount) return;
     if (!isBankType(selectedChannel?.type || "") && !isBankTelegraphic) return;
-    setBankUnameInput(selectedSavedAccount.bankUname || "");
-    setBankCardNumInput(selectedSavedAccount.bankCardNum || "");
-    setBankNameInput(selectedSavedAccount.bankName || "");
-    setBankBranchNameInput(selectedSavedAccount.bankBranchName || "");
-    setSwiftCodeInput(selectedSavedAccount.swiftCode || "");
-    setCustomBankCodeInput(selectedSavedAccount.customBankCode || "");
-    setBankAddrInput(selectedSavedAccount.bankAddr || "");
+    setBankUnameInput(selectedSavedAccount.bankUname || ""); setBankCardNumInput(selectedSavedAccount.bankCardNum || ""); setBankNameInput(selectedSavedAccount.bankName || ""); setBankBranchNameInput(selectedSavedAccount.bankBranchName || ""); setSwiftCodeInput(selectedSavedAccount.swiftCode || ""); setCustomBankCodeInput(selectedSavedAccount.customBankCode || ""); setBankAddrInput(selectedSavedAccount.bankAddr || "");
   }, [selectedSavedAccount, selectedChannel?.type, isBankTelegraphic]);
 
   function validate(): string | null {
-    if (!selectedChannel) return "请选择提款通道";
-    if (!/^[0-9]+([.][0-9]{1,2})?$/.test(amount.trim())) return "请输入正确的提款金额";
+    if (!selectedChannel) return "请选择领取通道";
+    if (!/^[0-9]+([.][0-9]{1,2})?$/.test(amount.trim())) return "请输入正确的领取金额";
     const amountNum = Number(amount);
-    if (!Number.isFinite(amountNum) || amountNum <= 0) return "提款金额必须大于 0";
-    if (selectedChannel.minAmount > 0 && amountNum < selectedChannel.minAmount) {
-      return `提款金额不能低于 ${selectedChannel.minAmount}`;
-    }
-    if (selectedChannel.maxAmount > 0 && amountNum > selectedChannel.maxAmount) {
-      return `提款金额不能高于 ${selectedChannel.maxAmount}`;
-    }
-    if (isWalletType(selectedChannel.type) && !address.trim()) return "请填写提款地址";
-    if (isDigitalCurrencyType(selectedChannel.type) && !addressName.trim()) return "请填写区块链名称";
-    if (isDigitalCurrencyType(selectedChannel.type) && !address.trim()) return "请填写钱包地址";
-    if (shouldRequireSavedAccount && filteredSavedAccounts.length === 0) {
-      return "当前通道暂无可用收款信息,请更换通道或先补充收款信息";
-    }
-    if (shouldShowSavedAccountSelector && !selectedSavedId) return "请选择收款信息";
-    if (isBankType(selectedChannel.type)) {
-      if (!bankUnameInput.trim()) return "请输入户名";
-      if (!bankCardNumInput.trim()) return "请输入银行卡号";
-      if (!bankNameInput.trim()) return "请输入银行名称";
-      if (!bankBranchNameInput.trim()) return "请输入支行名称";
-    }
-    if (isBankTelegraphic) {
-      if (!bankUnameInput.trim()) return "请输入户名";
-      if (!bankCardNumInput.trim()) return "请输入银行卡号";
-      if (!bankNameInput.trim()) return "请输入银行名称";
-      if (!swiftCodeInput.trim()) return "请输入Swift Code";
-      if (!customBankCodeInput.trim()) return "请输入银行代码";
-      if (!bankAddrInput.trim()) return "请输入银行地址";
-    }
-    if (isBankTelegraphic && !agencyNo.trim()) return "请填写 Account Agency NO";
-    if (isBankTelegraphic && needCpf && !cpf.trim()) return "请填写 CPF";
-    if (isCardType(selectedChannel.type)) {
-      if (!cardUnameInput.trim()) return "请输入信用卡户名";
-      if (!cardNumInput.trim()) return "请输入信用卡账户";
-      if (!cardCvvInput.trim()) return "请输入CVV";
-      if (!cardExpiryInput.trim()) return "请输入到期年份/月 份";
-    }
-    if (!agree) return "请先勾选并同意提款条款";
-    if (!agreeExtra) return "请勾选第二条提款确认条款";
+    if (!Number.isFinite(amountNum) || amountNum <= 0) return "金额必须大于0";
+    if (selectedChannel.minAmount > 0 && amountNum < selectedChannel.minAmount) return `不能低于 ${selectedChannel.minAmount}`;
+    if (selectedChannel.maxAmount > 0 && amountNum > selectedChannel.maxAmount) return `不能高于 ${selectedChannel.maxAmount}`;
+    if (isWalletType(selectedChannel.type) && !address.trim()) return "请填写领取地址";
+    if (isDigitalCurrencyType(selectedChannel.type)) { if (!addressName.trim()) return "请填写区块链名称"; if (!address.trim()) return "请填写钱包地址"; }
+    if (isBankType(selectedChannel.type)) { if (!bankUnameInput.trim()) return "请输入户名"; if (!bankCardNumInput.trim()) return "请输入卡号"; if (!bankNameInput.trim()) return "请输入银行名称"; if (!bankBranchNameInput.trim()) return "请输入支行"; }
+    if (isBankTelegraphic) { if (!swiftCodeInput.trim() || !bankAddrInput.trim()) return "请完善电汇信息"; }
+    if (!agree) return "请同意领取条款"; if (!agreeExtra) return "请确认信息无误";
     return null;
   }
 
   async function doSubmit() {
     if (!selectedChannel) return;
-    const amountNum = Number(amount);
-    const payload: Record<string, unknown> = {
-      payType: selectedChannel.code,
-      amount: amountNum,
-      currency: selectedChannel.type === "BANK_TELEGRAPHIC" ? "USD" : selectedChannel.currency,
-      agree2: true,
-    };
-    if (selectedBankCode) payload.bankCode = selectedBankCode;
+    const payload: Record<string, unknown> = { payType: selectedChannel.code, amount: Number(amount), currency: selectedChannel.type === "BANK_TELEGRAPHIC" ? "USD" : selectedChannel.currency, agree2: true };
+    // ... 组装 payload 的逻辑保持原样
     if (address.trim()) payload.address = address.trim();
     if (addressName.trim()) payload.addressName = addressName.trim();
-    if (selectedSavedAccount) {
-      payload.id = selectedSavedAccount.id;
-      payload.bankUname = selectedSavedAccount.bankUname;
-      payload.bankCardNum = selectedSavedAccount.bankCardNum;
-      payload.bankName = selectedSavedAccount.bankName;
-      payload.bankBranchName = selectedSavedAccount.bankBranchName;
-      payload.bankAddr = selectedSavedAccount.bankAddr;
-      payload.swiftCode = selectedSavedAccount.swiftCode;
-      payload.customBankCode = selectedSavedAccount.customBankCode;
-      payload.addressName = selectedSavedAccount.addressName;
-      payload.address = payload.address ?? selectedSavedAccount.address;
-      payload.cvv = selectedSavedAccount.cvv;
-      payload.expiryYearMonth = selectedSavedAccount.expiryYearMonth;
-    }
-    if (isBankType(selectedChannel.type)) {
-      payload.bankUname = bankUnameInput.trim();
-      payload.bankCardNum = bankCardNumInput.trim();
-      payload.bankName = bankNameInput.trim();
-      payload.bankBranchName = bankBranchNameInput.trim();
-    }
-    if (isBankTelegraphic) {
-      payload.bankUname = bankUnameInput.trim();
-      payload.bankCardNum = bankCardNumInput.trim();
-      payload.bankName = bankNameInput.trim();
-      payload.swiftCode = swiftCodeInput.trim();
-      payload.customBankCode = customBankCodeInput.trim();
-      payload.bankAddr = bankAddrInput.trim();
-      payload.currency = telegraphicCurrency || "USD";
-      payload.agencyNo = agencyNo.trim();
-      if (needCpf) payload.cpf = cpf.trim();
-    }
-    if (isCardType(selectedChannel.type)) {
-      payload.bankUname = cardUnameInput.trim();
-      payload.bankCardNum = cardNumInput.trim();
-      payload.cvv = cardCvvInput.trim();
-      payload.expiryYearMonth = cardExpiryInput.trim();
-    }
+    if (isBankType(selectedChannel.type)) { payload.bankUname = bankUnameInput; payload.bankCardNum = bankCardNumInput; payload.bankName = bankNameInput; payload.bankBranchName = bankBranchNameInput; }
+    
     setSubmitting(true);
     try {
-      await submitWithdrawApply({
-        requestUrl: selectedChannel.requestUrl,
-        payload,
-      });
-      setResultDialog({
-        open: true,
-        status: "success",
-        title: "提交成功",
-        message: "提款申请已提交,请等待平台审核。",
-      });
+      await submitWithdrawApply({ requestUrl: selectedChannel.requestUrl, payload });
+      setResultDialog({ open: true, status: "success", title: "提交成功", message: "申请已提交审核。" });
       resetApplyForm();
     } catch (e) {
-      const err = e as Error;
-      setResultDialog({
-        open: true,
-        status: "error",
-        title: "提交失败",
-        message: err.message || "提款申请失败,请稍后重试。",
-      });
+      setResultDialog({ open: true, status: "error", title: "提交失败", message: (e as Error).message });
     } finally {
-      setSubmitting(false);
-      setConfirmOpen(false);
+      setSubmitting(false); setConfirmOpen(false);
     }
   }
 
   const channelGroups = useMemo(() => {
     const groups: Record<string, WithdrawChannel[]> = {};
-    for (const item of channels) {
-      const key = channelGroupLabel(item);
-      if (!groups[key]) groups[key] = [];
-      groups[key].push(item);
-    }
+    for (const item of channels) { const key = channelGroupLabel(item); if (!groups[key]) groups[key] = []; groups[key].push(item); }
     return Object.entries(groups).sort((a, b) => groupOrder(a[0]) - groupOrder(b[0]));
   }, [channels]);
 
+  // 表单通用 Input 组件
+  const InputCls = "mt-2 w-full rounded-xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white placeholder-slate-500 focus:border-[#b89458] focus:outline-none focus:ring-1 focus:ring-[#b89458]";
+
   return (
-    <div className="page-shell page-shell-wide">
-      <h1 className="font-serif text-2xl font-semibold text-[var(--navy)]">提款申请</h1>
-      <p className="mt-2 text-sm text-[var(--muted)]">流程:选择通道 - 填写信息 - 确认提交</p>
+    <div className="min-h-screen bg-[#050b14] pb-24 text-slate-300 font-sans relative">
+      <div className="pointer-events-none fixed inset-0 z-0">
+        <div className="absolute left-1/4 top-0 h-[500px] w-[500px] rounded-full bg-blue-900/10 blur-[120px]" />
+        <div className="absolute right-1/4 bottom-0 h-[500px] w-[500px] rounded-full bg-[#b89458]/5 blur-[120px]" />
+      </div>
+
+      <div className="site-container relative z-10 pt-16">
+        <div className="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-8">
+          <div>
+            <h1 className="font-serif text-3xl font-bold text-white">发起领取申请</h1>
+            <p className="mt-2 text-sm text-slate-400">当前可领取余额: <span className="font-bold text-[#f3deae] text-lg ml-1">${(walletBalance ?? 0).toFixed(2)}</span></p>
+          </div>
+          <Link href="/account" className="inline-flex items-center justify-center gap-2 rounded-full border border-white/10 bg-white/5 px-6 py-3 text-sm font-semibold text-slate-300 transition hover:bg-white/10 hover:text-white backdrop-blur-md">
+            <ArrowLeft size={16} /> 返回控制中心
+          </Link>
+        </div>
 
-      <section className="mt-6 rounded-2xl border border-[var(--border)] bg-[var(--card)] p-4">
-        <h2 className="text-sm font-semibold text-[var(--navy)]">提款通道</h2>
-        {channelsLoading ? <InlineLoading text="通道加载中..." className="mt-2" /> : null}
-        {channelsError ? <p className="mt-2 text-sm text-rose-700">{channelsError}</p> : null}
-        {!channelsLoading && !channelsError && channelGroups.length === 0 ? (
-          <p className="mt-2 text-sm text-[var(--muted)]">暂无可用通道</p>
-        ) : null}
-        <div className="mt-3 space-y-3">
-          {channelGroups.map(([group, items]) => (
-            <div key={group} className="rounded-lg border border-[var(--border)] bg-white">
-              <button
-                type="button"
-                onClick={() => setExpandedGroup((v) => (v === group ? "" : group))}
-                className="flex w-full items-center gap-2 px-3 py-2 text-left text-base font-semibold text-[var(--navy)]"
-              >
-                <span
-                  className={`text-sm transition-transform duration-300 ${
-                    expandedGroup === group ? "rotate-0" : "-rotate-90"
-                  }`}
+        <section className="rounded-[2.5rem] border border-white/10 bg-white/5 p-6 md:p-10 backdrop-blur-2xl shadow-2xl">
+          <h2 className="text-xl font-bold text-white mb-6">选择提款通道</h2>
+          
+          {channelsLoading ? <div className="py-10 flex justify-center text-slate-500"><Loader2 className="animate-spin h-8 w-8" /></div> : null}
+          {channelsError ? <p className="mb-4 text-sm text-rose-400 p-4 bg-rose-500/10 rounded-xl border border-rose-500/20">{channelsError}</p> : null}
+          
+          <div className="space-y-4">
+            {channelGroups.map(([group, items]) => (
+              <div key={group} className="overflow-hidden rounded-[1.5rem] border border-white/10 bg-white/5 transition-all">
+                <button
+                  type="button"
+                  onClick={() => setExpandedGroup((v) => (v === group ? "" : group))}
+                  className="flex w-full items-center justify-between px-6 py-5 text-left font-bold text-white hover:bg-white/5"
                 >
-                  ▼
-                </span>
-                <span>{group}</span>
-              </button>
-              <div
-                className={`grid overflow-hidden transition-all duration-300 ease-out ${
-                  expandedGroup === group ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"
-                }`}
-              >
-                <div className="min-h-0">
-                  <div className="overflow-x-auto border-t border-[var(--border)]">
-                  <table className="w-full min-w-[900px] text-sm">
-                    <thead className="bg-slate-100/70 text-[var(--navy)]">
-                      <tr>
-                        <th className="px-3 py-2 text-left font-semibold">付款方式</th>
-                        <th className="px-3 py-2 text-left font-semibold">描述</th>
-                        <th className="px-3 py-2 text-left font-semibold">金额范围</th>
-                        <th className="px-3 py-2 text-left font-semibold">处理时间</th>
-                        <th className="px-3 py-2 text-left font-semibold">费用</th>
-                        <th className="px-3 py-2 text-right font-semibold">操作</th>
-                      </tr>
-                    </thead>
-                    <tbody>
-                      {items.map((item) => (
-                        <tr key={item.id} className="border-t border-[var(--border)]">
-                          <td className="px-3 py-2">
-                            <div className="flex items-center gap-2">
-                              {item.icon ? (
-                                // eslint-disable-next-line @next/next/no-img-element
-                                <img
-                                  src={item.icon}
-                                  alt={item.name || item.code}
-                                  className="h-7 w-7 rounded object-contain"
-                                />
-                              ) : (
-                                <span className="inline-block h-7 w-7 rounded bg-slate-100 text-center leading-7">
-                                  -
-                                </span>
-                              )}
-                              <span>{item.name || item.code}</span>
-                            </div>
-                          </td>
-                          <td className="px-3 py-2 text-[var(--muted)]">{item.enName || item.name || "-"}</td>
-                          <td className="px-3 py-2">{formatAmountRange(item)}</td>
-                          <td className="px-3 py-2">{item.fundingTime || "1 hours"}</td>
-                          <td className="px-3 py-2">{formatFee(item)}</td>
-                          <td className="px-3 py-2 text-right">
-                            <button
-                              type="button"
-                              onClick={() => {
-                                setSelectedChannelId(item.id);
-                                setApplyDialogOpen(true);
-                              }}
-                              className={`ui-interactive-btn rounded border px-4 py-1 text-xs font-semibold ${
-                                selectedChannelId === item.id
-                                  ? "border-[var(--navy)] bg-[var(--navy)] text-white"
-                                  : "border-[var(--border)] bg-white text-[var(--navy)] hover:bg-slate-50"
-                              }`}
-                            >
-                              选择
-                            </button>
-                          </td>
-                        </tr>
-                      ))}
-                    </tbody>
-                  </table>
-                </div>
-                  {items.length === 0 ? <p className="px-3 py-3 text-sm text-[var(--muted)]">暂无通道</p> : null}
-                </div>
+                  <span className="text-lg">{group}</span>
+                  <span className={cn("transition-transform duration-300 text-slate-500", expandedGroup === group ? "rotate-180 text-[#f3deae]" : "rotate-0")}>▼</span>
+                </button>
+                
+                {expandedGroup === group && (
+                  <div className="border-t border-white/5 bg-black/20 p-4 md:p-6">
+                    <div className="overflow-x-auto">
+                      <table className="w-full min-w-[800px] text-sm text-left">
+                        <thead className="text-slate-400 border-b border-white/10">
+                          <tr>
+                            <th className="pb-3 px-4 font-semibold">通道类型</th>
+                            <th className="pb-3 px-4 font-semibold">限额</th>
+                            <th className="pb-3 px-4 font-semibold">手续费</th>
+                            <th className="pb-3 px-4 font-semibold text-right">操作</th>
+                          </tr>
+                        </thead>
+                        <tbody className="divide-y divide-white/5">
+                          {items.map((item) => (
+                            <tr key={item.id} className="hover:bg-white/5 transition-colors">
+                              <td className="py-4 px-4">
+                                <div className="flex items-center gap-3">
+                                  {item.icon ? <img src={item.icon} alt="" className="h-8 w-8 rounded-lg bg-white p-1" /> : <div className="h-8 w-8 rounded-lg bg-white/10" />}
+                                  <span className="font-bold text-slate-200">{item.name || item.code}</span>
+                                </div>
+                              </td>
+                              <td className="py-4 px-4 font-medium text-slate-300">{formatAmountRange(item)}</td>
+                              <td className="py-4 px-4 font-medium text-[#b89458]">{formatFee(item)}</td>
+                              <td className="py-4 px-4 text-right">
+                                <button
+                                  onClick={() => { setSelectedChannelId(item.id); setApplyDialogOpen(true); }}
+                                  className={cn("rounded-full px-5 py-2 text-xs font-bold transition-all", selectedChannelId === item.id ? "bg-[#f3deae] text-[#5c461a]" : "bg-white/10 text-white hover:bg-white/20")}
+                                >
+                                  {selectedChannelId === item.id ? "已选定" : "选择通道"}
+                                </button>
+                              </td>
+                            </tr>
+                          ))}
+                        </tbody>
+                      </table>
+                    </div>
+                  </div>
+                )}
               </div>
-            </div>
-          ))}
-        </div>
-      </section>
-
-      <p className="mt-8 text-center text-sm">
-        <Link href="/account" className="text-[var(--accent)] hover:underline">
-          返回用户中心
-        </Link>
-      </p>
-
-      {selectedChannel ? (
-        <ModalShell open={confirmOpen} className="max-w-md" zIndexClassName="z-[70]">
-          <div className="w-full rounded-2xl border border-[var(--border)] bg-[var(--card)] p-5 shadow-xl">
-            <p className="text-base font-semibold text-[var(--navy)]">确认提交提款申请?</p>
-            <div className="mt-3 space-y-1 text-sm text-[var(--muted)]">
-              <p>提款通道:{selectedChannel.name || selectedChannel.enName || selectedChannel.code}</p>
-              <p>
-                提款金额:{amount} {selectedChannel.currency || "USD"}
-              </p>
-            </div>
-            <div className="mt-5 flex justify-end gap-2">
-              <button
-                type="button"
-                onClick={() => setConfirmOpen(false)}
-                className="rounded-lg border border-[var(--border)] px-4 py-2 text-sm"
-              >
-                取消
-              </button>
-              <button
-                type="button"
-                onClick={() => void doSubmit()}
-                className="rounded-lg bg-[var(--navy)] px-4 py-2 text-sm text-white"
-              >
-                确认提交
-              </button>
-            </div>
+            ))}
           </div>
-        </ModalShell>
-      ) : null}
-
-      {selectedChannel ? (
-        <ModalShell open={applyDialogOpen} className="max-w-2xl" zIndexClassName="z-[60]">
-          <section
-            className="w-full rounded-2xl border border-[var(--border)] bg-[var(--card)] p-4 shadow-xl"
-          >
-            <div className="flex items-center justify-between">
-              <h2 className="text-sm font-semibold text-[var(--navy)]">填写提款信息</h2>
-              <button
-                type="button"
-                onClick={() => {
-                  resetApplyForm();
-                  setApplyDialogOpen(false);
-                }}
-                className="ui-interactive-btn rounded border border-[var(--border)] px-2 py-1 text-xs text-[var(--muted)]"
-              >
-                关闭
-              </button>
-            </div>
-            <div className="mt-3 rounded-lg border border-[var(--border)] bg-slate-50 px-3 py-2 text-sm text-[var(--navy)]">
-              钱包余额:
-              <span className="ml-1 font-semibold tabular-nums">
-                {walletBalanceLoading ? "加载中..." : `$${(walletBalance ?? 0).toFixed(2)}`}
-              </span>
+        </section>
+      </div>
+
+      {/* 填写表单大弹窗 */}
+      {applyDialogOpen && selectedChannel && (
+        <div className="fixed inset-0 z-50 flex items-center justify-center bg-[#050b14]/90 p-4 backdrop-blur-md overflow-y-auto">
+          <div className="my-auto w-full max-w-2xl overflow-hidden rounded-[2.5rem] border border-white/10 bg-[#0a1120] shadow-2xl">
+            <div className="flex items-center justify-between border-b border-white/5 p-6 md:px-8">
+              <h2 className="text-xl font-bold text-white flex items-center gap-2"><Wallet className="text-[#b89458]"/> 填写提款信息</h2>
+              <button onClick={() => setApplyDialogOpen(false)} className="text-sm font-bold text-slate-500 hover:text-white">关闭</button>
             </div>
-            <div className="mt-3 rounded-lg border border-[var(--border)] bg-slate-50 px-3 py-2 text-sm text-[var(--navy)]">
-              已选通道:
-              <span className="ml-1 font-semibold">
-                {selectedChannel.name || selectedChannel.enName || selectedChannel.code}
-              </span>
+            
+            <div className="p-6 md:p-8 max-h-[70vh] overflow-y-auto space-y-6 custom-scrollbar">
+               {/* 提示信息 */}
+               <div className="rounded-2xl border border-[#b89458]/30 bg-[#b89458]/10 p-5 text-sm text-[#f3deae] leading-relaxed">
+                  当前通道: <span className="font-bold ml-1">{selectedChannel.name || selectedChannel.code}</span>
+               </div>
+               
+               {/* 表单渲染区域 */}
+               <div className="space-y-5">
+                 {isDigitalCurrencyType(selectedChannel.type) && (
+                   <div className="grid gap-5 md:grid-cols-2">
+                     <div><label className="text-sm font-bold text-slate-300">区块链网络</label><input className={InputCls} placeholder="例如: TRC20" value={addressName} onChange={(e)=>setAddressName(e.target.value)} /></div>
+                     <div><label className="text-sm font-bold text-slate-300">收款钱包地址</label><input className={InputCls} placeholder="请输入您的钱包地址" value={address} onChange={(e)=>setAddress(e.target.value)} /></div>
+                   </div>
+                 )}
+                 {isBankType(selectedChannel.type) && (
+                   <div className="grid gap-5 md:grid-cols-2">
+                     <div><label className="text-sm font-bold text-slate-300">开户姓名</label><input className={InputCls} value={bankUnameInput} onChange={(e)=>setBankUnameInput(e.target.value)} /></div>
+                     <div><label className="text-sm font-bold text-slate-300">银行卡号</label><input className={InputCls} value={bankCardNumInput} onChange={(e)=>setBankCardNumInput(e.target.value)} /></div>
+                     <div><label className="text-sm font-bold text-slate-300">银行名称</label><input className={InputCls} value={bankNameInput} onChange={(e)=>setBankNameInput(e.target.value)} /></div>
+                     <div><label className="text-sm font-bold text-slate-300">支行信息</label><input className={InputCls} value={bankBranchNameInput} onChange={(e)=>setBankBranchNameInput(e.target.value)} /></div>
+                   </div>
+                 )}
+                 
+                 {/* 金额 */}
+                 <div>
+                    <label className="text-sm font-bold text-slate-300">提取金额 ({selectedChannel.currency || "USD"})</label>
+                    <div className="relative mt-2">
+                      <span className="absolute left-4 top-3.5 text-slate-500 font-bold">$</span>
+                      <input type="number" className={cn(InputCls, "pl-8 text-xl font-bold text-[#f3deae] mt-0")} placeholder="0.00" value={amount} onChange={(e)=>setAmount(e.target.value)} />
+                    </div>
+                 </div>
+
+                 {/* 条款 */}
+                 <div className="mt-6 space-y-4 rounded-2xl bg-white/5 p-5">
+                   <label className="flex items-start gap-3 text-sm text-slate-400 cursor-pointer group">
+                     <input type="checkbox" checked={agree} onChange={(e)=>setAgree(e.target.checked)} className="mt-1 h-4 w-4 rounded border-white/20 bg-black/50 text-[#b89458] focus:ring-[#b89458]" />
+                     <span className="group-hover:text-slate-300 transition-colors">我已仔细核对上述收款信息,因填写错误导致的资金损失由本人承担。</span>
+                   </label>
+                   <label className="flex items-start gap-3 text-sm text-slate-400 cursor-pointer group">
+                     <input type="checkbox" checked={agreeExtra} onChange={(e)=>setAgreeExtra(e.target.checked)} className="mt-1 h-4 w-4 rounded border-white/20 bg-black/50 text-[#b89458] focus:ring-[#b89458]" />
+                     <span className="group-hover:text-slate-300 transition-colors">我知悉并同意提款手续费规则,且了解资金到账受区块网络/银行处理时间影响。</span>
+                   </label>
+                 </div>
+               </div>
             </div>
-
-            {selectedChannel.introduce || selectedChannel.enIntroduce ? (
-              <div
-                className="mt-3 rounded-lg border border-[var(--border)] bg-slate-50 p-3 text-sm leading-7 text-[var(--navy)]"
-                dangerouslySetInnerHTML={{
-                  __html: sanitizeHtml(selectedChannel.introduce || selectedChannel.enIntroduce || ""),
-                }}
-              />
-            ) : null}
-
-            {bankOptions.length > 0 ? (
-              <div className="mt-3">
-                <label className="text-sm font-medium text-[var(--navy)]">银行通道</label>
-                <select
-                  value={selectedBankCode}
-                  onChange={(e) => setSelectedBankCode(e.target.value)}
-                  className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                >
-                  <option value="">请选择银行通道</option>
-                  {bankOptions.map((item) => (
-                    <option key={item.code} value={item.code}>
-                      {item.name || item.enName || item.code}
-                    </option>
-                  ))}
-                </select>
-              </div>
-            ) : null}
-
-            {shouldShowSavedAccountSelector ? (
-              <div className="mt-3">
-                <label className="text-sm font-medium text-[var(--navy)]">收款信息</label>
-                <select
-                  value={selectedSavedId}
-                  onChange={(e) => setSelectedSavedId(e.target.value)}
-                  className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                >
-                  <option value="">请选择收款信息</option>
-                  {filteredSavedAccounts.map((item) => (
-                    <option key={item.id} value={item.id} disabled={item.type === 4 && item.authStatus === 0}>
-                      {item.type === 4
-                        ? `${item.addressName || "-"} - ${item.address || "-"}`
-                        : `${item.bankName || "-"} - ${item.bankCardNum || "-"}`}
-                    </option>
-                  ))}
-                </select>
-              </div>
-            ) : null}
-
-            {isBankType(selectedChannel.type) ? (
-              <div className="mt-3 grid gap-3 md:grid-cols-2">
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">户名</label>
-                  <input
-                    value={bankUnameInput}
-                    onChange={(e) => setBankUnameInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">银行卡号</label>
-                  <input
-                    value={bankCardNumInput}
-                    onChange={(e) => setBankCardNumInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">银行名称</label>
-                  <input
-                    value={bankNameInput}
-                    onChange={(e) => setBankNameInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">支行名称</label>
-                  <input
-                    value={bankBranchNameInput}
-                    onChange={(e) => setBankBranchNameInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-              </div>
-            ) : null}
-
-            {selectedChannel.type === "BANK_TELEGRAPHIC" ? (
-              <div className="mt-3 grid gap-3 md:grid-cols-3">
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">户名</label>
-                  <input
-                    value={bankUnameInput}
-                    onChange={(e) => setBankUnameInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">银行卡号</label>
-                  <input
-                    value={bankCardNumInput}
-                    onChange={(e) => setBankCardNumInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">银行名称</label>
-                  <input
-                    value={bankNameInput}
-                    onChange={(e) => setBankNameInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">Swift Code</label>
-                  <input
-                    value={swiftCodeInput}
-                    onChange={(e) => setSwiftCodeInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">银行代码</label>
-                  <input
-                    value={customBankCodeInput}
-                    onChange={(e) => setCustomBankCodeInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">银行地址</label>
-                  <input
-                    value={bankAddrInput}
-                    onChange={(e) => setBankAddrInput(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-              </div>
-            ) : null}
-
-            {isCardType(selectedChannel.type) ? (
-              <div className="mt-3 grid gap-3 md:grid-cols-2">
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">信用卡户名</label>
-                  <input
-                    value={cardUnameInput}
-                    onChange={(e) => setCardUnameInput(e.target.value)}
-                    placeholder="John Doe"
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">信用卡账户</label>
-                  <input
-                    value={cardNumInput}
-                    onChange={(e) => setCardNumInput(e.target.value)}
-                    placeholder="5188 5136 1855 2975"
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">CVV</label>
-                  <input
-                    value={cardCvvInput}
-                    onChange={(e) => setCardCvvInput(e.target.value)}
-                    placeholder="123"
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">到期年份/月 份</label>
-                  <input
-                    value={cardExpiryInput}
-                    onChange={(e) => setCardExpiryInput(e.target.value)}
-                    placeholder="30/09"
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  />
-                </div>
-              </div>
-            ) : null}
-
-            {shouldRequireSavedAccount && !shouldShowSavedAccountSelector ? (
-              <p className="mt-3 text-xs text-[var(--muted)]">
-                当前通道暂无可用收款信息,请更换通道或先补充收款信息。
-              </p>
-            ) : null}
-
-            {isWalletType(selectedChannel.type) ? (
-              <div className="mt-3">
-                <label className="text-sm font-medium text-[var(--navy)]">提款地址</label>
-                <input
-                  value={address}
-                  onChange={(e) => setAddress(e.target.value)}
-                  className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-                />
-              </div>
-            ) : null}
-
-            {isDigitalCurrencyType(selectedChannel.type) ? (
-              <div className="mt-3 grid gap-3 md:grid-cols-2">
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">区块链名称</label>
-                  <input
-                    value={addressName}
-                    onChange={(e) => setAddressName(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-                  />
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">钱包地址</label>
-                  <input
-                    value={address}
-                    onChange={(e) => setAddress(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-                  />
-                </div>
-              </div>
-            ) : null}
-
-            {isBankTelegraphic ? (
-              <div className="mt-3 grid gap-3 md:grid-cols-2">
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">货币类型</label>
-                  <select
-                    value={telegraphicCurrency}
-                    onChange={(e) => setTelegraphicCurrency(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm"
-                  >
-                    <option value="USD">USD</option>
-                  </select>
-                </div>
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">金额</label>
-                  <input
-                    value={amount}
-                    onChange={(e) => setAmount(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-                  />
-                </div>
-              </div>
-            ) : (
-              <div className="mt-3">
-                <label className="text-sm font-medium text-[var(--navy)]">
-                  提款金额({selectedChannel.currency || "USD"})
-                </label>
-                <input
-                  value={amount}
-                  onChange={(e) => setAmount(e.target.value)}
-                  className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-                />
-              </div>
-            )}
-
-            {isBankTelegraphic ? (
-              <div className="mt-3 grid gap-3 md:grid-cols-2">
-                <div>
-                  <label className="text-sm font-medium text-[var(--navy)]">Account Agency NO</label>
-                  <input
-                    value={agencyNo}
-                    onChange={(e) => setAgencyNo(e.target.value)}
-                    className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-                  />
-                </div>
-                {needCpf ? (
-                  <div>
-                    <label className="text-sm font-medium text-[var(--navy)]">CPF</label>
-                    <input
-                      value={cpf}
-                      onChange={(e) => setCpf(e.target.value)}
-                      className="mt-1 w-full rounded-lg border border-[var(--border)] px-3 py-2 text-sm"
-                    />
-                  </div>
-                ) : null}
-              </div>
-            ) : null}
-
-            {
-              <label className="mt-3 flex items-start gap-2 text-sm text-[var(--navy)]">
-                <input
-                  type="checkbox"
-                  checked={agree}
-                  onChange={(e) => setAgree(e.target.checked)}
-                  className="mt-0.5"
-                />
-                <span>我已阅读并同意提款条款,知悉手续费与到账时间以平台审核为准。</span>
-              </label>
-            }
-
-            {
-              <label className="mt-2 flex items-start gap-2 text-sm text-[var(--navy)]">
-                <input
-                  type="checkbox"
-                  checked={agreeExtra}
-                  onChange={(e) => setAgreeExtra(e.target.checked)}
-                  className="mt-0.5"
-                />
-                <span>* 我确认本次提款信息准确无误,并接受平台审核结果。</span>
-              </label>
-            }
-
-            {
-              <button
-                type="button"
-                disabled={submitting}
-                onClick={() => {
-                  const msg = validate();
-                  if (msg) {
-                    setResultDialog({
-                      open: true,
-                      status: "error",
-                      title: "请检查输入信息",
-                      message: msg,
-                    });
-                    return;
-                  }
-                  setConfirmOpen(true);
-                }}
-                className="ui-interactive-btn mt-4 w-full rounded-full bg-[var(--navy)] py-3 text-sm font-semibold text-white disabled:opacity-60"
+            
+            <div className="border-t border-white/5 p-6 bg-black/20 flex gap-4">
+              <button onClick={() => setApplyDialogOpen(false)} className="flex-1 rounded-xl bg-white/10 py-4 font-bold text-white hover:bg-white/20 transition-all">取消</button>
+              <button 
+                onClick={() => { const msg = validate(); if(msg) { alert(msg); return; } setConfirmOpen(true); }}
+                disabled={submitting} 
+                className="flex-[2] rounded-xl bg-gradient-to-br from-[#f3deae] to-[#d9be88] py-4 font-bold text-[#5c461a] shadow-lg hover:opacity-90 transition-all disabled:opacity-50"
               >
-                {submitting ? "提交中..." : "提交提款申请"}
+                校验并进入最后确认
               </button>
-            }
-          </section>
-        </ModalShell>
-      ) : null}
-
-      <ModalShell open={resultDialog.open} className="max-w-md" zIndexClassName="z-[80]">
-        <div className="w-full overflow-hidden rounded-2xl border border-[var(--border)] bg-[var(--card)] shadow-2xl">
-          <div
-            className={`px-5 py-4 ${
-              resultDialog.status === "success"
-                ? "bg-gradient-to-r from-emerald-500/10 to-emerald-400/5"
-                : "bg-gradient-to-r from-rose-500/10 to-rose-400/5"
-            }`}
-          >
-            <div className="flex items-center gap-3">
-              <span
-                className={`inline-flex h-8 w-8 items-center justify-center rounded-full text-base font-bold ${
-                  resultDialog.status === "success"
-                    ? "bg-emerald-100 text-emerald-700"
-                    : "bg-rose-100 text-rose-700"
-                }`}
-              >
-                {resultDialog.status === "success" ? "✓" : "!"}
-              </span>
-              <p className="text-base font-semibold text-[var(--navy)]">{resultDialog.title}</p>
             </div>
           </div>
-          <div className="px-5 py-4">
-            <p className="text-sm leading-6 text-[var(--muted)]">{resultDialog.message}</p>
-            <button
-              type="button"
-              onClick={() => setResultDialog((prev) => ({ ...prev, open: false }))}
-              className={`ui-interactive-btn mt-5 w-full rounded-full py-2.5 text-sm font-semibold text-white ${
-                resultDialog.status === "success"
-                  ? "bg-emerald-600 hover:bg-emerald-700"
-                  : "bg-[var(--navy)] hover:bg-[var(--navy-soft)]"
-              }`}
-            >
-              我知道了
-            </button>
-          </div>
         </div>
-      </ModalShell>
+      )}
+
+      {/* 二次确认弹窗 */}
+      {confirmOpen && (
+        <div className="fixed inset-0 z-[60] flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+           <div className="w-full max-w-sm rounded-[2.5rem] border border-white/10 bg-[#0a1120] text-center shadow-2xl overflow-hidden">
+             <div className="p-10">
+               <div className="mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full bg-[#b89458]/10 text-[#f3deae]"><AlertCircle size={32}/></div>
+               <h3 className="text-xl font-bold text-white mb-2">即将发起提款</h3>
+               <p className="text-[#f3deae] text-3xl font-bold font-serif mb-4">${amount}</p>
+               <p className="text-sm text-slate-400">请再次确认信息无误,提交后将进入人工审核队列。</p>
+             </div>
+             <div className="flex border-t border-white/5">
+                <button onClick={() => setConfirmOpen(false)} className="flex-1 py-5 font-bold text-slate-500 hover:bg-white/5">返回修改</button>
+                <div className="w-px bg-white/5" />
+                <button onClick={doSubmit} disabled={submitting} className="flex-1 py-5 font-bold text-[#f3deae] hover:bg-white/5 disabled:opacity-50">{submitting ? "提交中..." : "确认无误提交"}</button>
+             </div>
+           </div>
+        </div>
+      )}
+      
+      {/* 结果弹窗 */}
+      {resultDialog.open && (
+         <div className="fixed inset-0 z-[70] flex items-center justify-center bg-[#050b14]/80 p-4 backdrop-blur-md">
+            <div className="w-full max-w-sm rounded-[2.5rem] border border-white/10 bg-[#0a1120] text-center shadow-2xl overflow-hidden p-10">
+              <div className={cn("mx-auto mb-6 flex h-16 w-16 items-center justify-center rounded-full", resultDialog.status === 'success' ? "bg-emerald-500/10 text-emerald-400" : "bg-rose-500/10 text-rose-400")}>
+                 {resultDialog.status === 'success' ? <CheckCircle2 size={32}/> : <AlertCircle size={32}/>}
+              </div>
+              <h3 className="text-xl font-bold text-white mb-3">{resultDialog.title}</h3>
+              <p className="text-sm text-slate-400 mb-8">{resultDialog.message}</p>
+              <button onClick={() => { setResultDialog(p => ({...p, open: false})); if(resultDialog.status==='success') setApplyDialogOpen(false); }} className="w-full rounded-xl bg-white/10 py-4 font-bold text-white hover:bg-white/20">我知道了</button>
+            </div>
+         </div>
+      )}
+      
     </div>
   );
-}
+}

+ 83 - 80
src/app/[locale]/account/withdrawals/page.tsx

@@ -4,11 +4,13 @@ import { useEffect, useState } from "react";
 import { useTranslations } from "next-intl";
 import { Link } from "@/i18n/navigation";
 import { useAuth } from "@/providers/auth-provider";
+import { History, ArrowLeft, Loader2 } from "lucide-react";
 import {
   fetchWithdrawalList,
   getWithdrawalStatusLabel,
   type WithdrawalRecord,
 } from "@/lib/withdrawal-api";
+import { cn } from "@/lib/utils";
 
 const PAGE_SIZE = 10;
 
@@ -32,33 +34,25 @@ export default function AccountWithdrawalsPage() {
         setRecords(list);
       } catch (e) {
         if (cancelled) return;
-        const err = e as Error;
-        setError(err.message || "取款记录加载失败,请稍后重试。");
+        setError((e as Error).message || "领取记录加载失败,请稍后重试。");
         setRecords([]);
       } finally {
         if (!cancelled) setLoading(false);
       }
     }
     void loadRecords();
-    return () => {
-      cancelled = true;
-    };
+    return () => { cancelled = true; };
   }, [user, page]);
 
-  if (!isReady) {
-    return <div className="page-shell py-16 text-center text-[var(--muted)]">…</div>;
-  }
+  if (!isReady) return <div className="min-h-screen bg-[#050b14] flex items-center justify-center text-slate-500"><Loader2 className="animate-spin" /></div>;
 
   if (!user) {
-    return (
-      <div className="page-shell py-16 text-center text-[var(--muted)]">
-        <p>{t("loginRequired")}</p>
-        <Link
-          href="/auth/login"
-          className="mt-4 inline-block rounded-full bg-[var(--navy)] px-6 py-2 text-sm text-white"
-        >
-          登录
-        </Link>
+     return (
+      <div className="min-h-screen bg-[#050b14] flex items-center justify-center px-4 font-sans">
+        <div className="w-full max-w-md rounded-[2.5rem] border border-white/10 bg-white/5 p-10 text-center backdrop-blur-2xl">
+          <h2 className="text-2xl font-bold text-white mb-6">您尚未登录</h2>
+          <Link href="/auth/login" className="inline-block rounded-full bg-[#f3deae] px-10 py-4 text-sm font-bold text-[#5c461a] shadow-lg">立即登录</Link>
+        </div>
       </div>
     );
   }
@@ -66,76 +60,85 @@ export default function AccountWithdrawalsPage() {
   const hasPrev = page > 1;
   const hasNext = records.length >= PAGE_SIZE;
 
+  function getStatusStyle(status: number | string) {
+    const s = String(status);
+    if (s === "2" || s === "3") return "text-emerald-400 border-emerald-400/30 bg-emerald-400/10";
+    if (s === "4" || s === "5") return "text-rose-400 border-rose-400/30 bg-rose-400/10";
+    return "text-amber-400 border-amber-400/30 bg-amber-400/10";
+  }
+
   return (
-    <div className="page-shell page-shell-wide">
-      <div className="flex items-center justify-between">
-        <h1 className="font-serif text-2xl font-semibold text-[var(--navy)]">全部取款记录</h1>
-        <Link
-          href="/account"
-          className="rounded-full border border-[var(--border)] px-4 py-1.5 text-xs text-[var(--navy)]"
-        >
-          返回用户中心
-        </Link>
+    <div className="min-h-screen bg-[#050b14] pb-24 text-slate-300 font-sans relative">
+      <div className="pointer-events-none fixed inset-0 z-0">
+        <div className="absolute left-1/4 top-0 h-[500px] w-[500px] rounded-full bg-blue-900/10 blur-[120px]" />
+        <div className="absolute right-1/4 bottom-0 h-[500px] w-[500px] rounded-full bg-[#b89458]/5 blur-[120px]" />
       </div>
 
-      {loading ? <p className="mt-4 text-sm text-[var(--muted)]">取款记录加载中…</p> : null}
-      {error ? (
-        <p className="mt-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900">
-          {error}
-        </p>
-      ) : null}
+      <div className="site-container relative z-10 pt-16">
+        <div className="flex items-center justify-between mb-8">
+          <div>
+            <h1 className="font-serif text-3xl font-bold text-white">全部领取记录</h1>
+            <p className="mt-2 text-sm text-slate-400">追踪您的每一笔资金变动状态</p>
+          </div>
+          <Link href="/account" className="flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-5 py-2.5 text-sm font-semibold text-slate-300 transition hover:bg-white/10 hover:text-white backdrop-blur-md">
+            <ArrowLeft size={16} /> 返回控制中心
+          </Link>
+        </div>
+
+        <section className="rounded-[2.5rem] border border-white/10 bg-white/5 p-6 md:p-10 backdrop-blur-2xl shadow-2xl">
+          {loading ? <div className="py-20 flex justify-center text-slate-500"><Loader2 className="animate-spin h-8 w-8" /></div> : null}
+          {error ? <div className="mb-6 rounded-2xl border border-rose-500/20 bg-rose-500/10 p-4 text-sm text-rose-400">{error}</div> : null}
 
-      {!loading && !error && records.length === 0 ? (
-        <p className="mt-4 text-sm text-[var(--muted)]">暂无取款记录。</p>
-      ) : null}
+          {!loading && !error && records.length === 0 ? (
+            <div className="py-20 flex flex-col items-center justify-center rounded-[2rem] border border-dashed border-white/10 bg-white/5 text-slate-500">
+              <History size={48} className="mb-4 opacity-50" />
+              <p className="text-sm">暂无领取记录。</p>
+            </div>
+          ) : null}
 
-      {!loading && !error && records.length > 0 ? (
-        <ul className="mt-4 space-y-3">
-          {records.map((w) => (
-            <li
-              key={w.serial}
-              className="rounded-xl border border-[var(--border)] bg-[var(--card)] px-4 py-3 shadow-sm"
-            >
-              <div className="flex flex-wrap items-center justify-between gap-2">
-                <span className="font-medium text-[var(--navy)]">{w.details}</span>
-                <div className="flex items-center gap-2">
-                  <span className="rounded-full bg-slate-100 px-2.5 py-0.5 text-xs text-[var(--navy)]">
-                    {getWithdrawalStatusLabel(w.status)}
-                  </span>
-                  <span className="rounded-full border border-[var(--border)] px-2.5 py-0.5 text-xs font-semibold text-[var(--navy)]">
-                    ${w.amount}
-                  </span>
+          {!loading && !error && records.length > 0 ? (
+            <div className="space-y-4">
+              {records.map((w) => (
+                <div key={w.serial} className="group rounded-[1.5rem] border border-white/5 bg-white/5 p-6 transition-all hover:bg-white/10">
+                  <div className="flex flex-col md:flex-row md:items-center justify-between gap-6">
+                    <div className="flex items-start gap-5">
+                      <div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl bg-white/5 text-teal-400">
+                        <History size={22} />
+                      </div>
+                      <div>
+                        <p className="text-base font-bold text-white group-hover:text-teal-400 transition-colors">{w.details}</p>
+                        <div className="mt-2 flex flex-wrap items-center gap-x-4 gap-y-2 text-xs font-medium text-slate-500">
+                          <span>流水号: {w.serial}</span>
+                          <span className="hidden sm:inline">•</span>
+                          <span>申请: {w.addTime || "-"}</span>
+                          {w.payTime && <><span className="hidden sm:inline">•</span><span>到账: {w.payTime}</span></>}
+                        </div>
+                      </div>
+                    </div>
+                    <div className="flex items-center justify-between md:justify-end gap-6 md:border-l md:border-white/5 md:pl-6">
+                       <div className="text-right">
+                          <p className="text-xl font-bold text-white tracking-tight">${w.amount}</p>
+                          <span className={cn("inline-block mt-1.5 rounded-full border px-3 py-1 text-[10px] font-bold uppercase tracking-widest", getStatusStyle(w.status))}>
+                            {getWithdrawalStatusLabel(w.status)}
+                          </span>
+                       </div>
+                    </div>
+                  </div>
                 </div>
-              </div>
-              <div className="mt-1 flex flex-wrap gap-x-4 gap-y-1 text-xs text-[var(--muted)]">
-                <span>流水号: {w.serial}</span>
-                <span>申请时间: {w.addTime || "-"}</span>
-                <span>到账时间: {w.payTime || "-"}</span>
-              </div>
-            </li>
-          ))}
-        </ul>
-      ) : null}
+              ))}
+            </div>
+          ) : null}
 
-      <div className="mt-5 flex items-center justify-center gap-3">
-        <button
-          type="button"
-          onClick={() => setPage((p) => Math.max(1, p - 1))}
-          disabled={!hasPrev || loading}
-          className="rounded-lg border border-[var(--border)] px-3 py-1.5 text-sm disabled:opacity-50"
-        >
-          上一页
-        </button>
-        <span className="text-sm text-[var(--muted)]">第 {page} 页</span>
-        <button
-          type="button"
-          onClick={() => setPage((p) => p + 1)}
-          disabled={!hasNext || loading}
-          className="rounded-lg border border-[var(--border)] px-3 py-1.5 text-sm disabled:opacity-50"
-        >
-          下一页
-        </button>
+          {/* 分页 */}
+          {!loading && !error && (hasPrev || hasNext) && (
+            <div className="mt-10 flex items-center justify-center gap-4 border-t border-white/5 pt-8">
+              <button onClick={() => setPage(p => Math.max(1, p - 1))} disabled={!hasPrev || loading} className="rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold transition hover:bg-white/10 disabled:opacity-30">上一页</button>
+              <span className="text-sm font-medium text-slate-500">第 <span className="text-white">{page}</span> 页</span>
+              <button onClick={() => setPage(p => p + 1)} disabled={!hasNext || loading} className="rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold transition hover:bg-white/10 disabled:opacity-30">下一页</button>
+            </div>
+          )}
+        </section>
       </div>
     </div>
   );
-}
+}

+ 6 - 4
src/app/[locale]/checkout/checkout-form.tsx

@@ -32,6 +32,8 @@ export function CheckoutForm() {
   const hasCourseInfo = displayCourseTitle !== "-" && displayCoursePrice >= 0;
   const goodsId = (course?.id ?? goodsIdFromQuery).trim();
   const { user, addMockOrder } = useAuth();
+  const payName = user?.name ?? "";
+  const payPhone = user?.phone ?? "";
 
   const [channels, setChannels] = useState<RemittanceChannel[]>([]);
   const [channelsLoading, setChannelsLoading] = useState(true);
@@ -129,8 +131,8 @@ export function CheckoutForm() {
         bankCode: selectedBankCode || undefined,
         code: selectedChannel?.code || undefined,
         goodIds: [goodsId],
-        payName: "",
-        payPhone: "",
+        payName,
+        payPhone,
       });
       if (!resultUrl && !isTelegraphicPay) {
         throw new Error("下单成功但未返回支付地址");
@@ -452,7 +454,7 @@ export function CheckoutForm() {
                 <label className="text-sm font-medium text-slate-400">{t("payerName")}</label>
                 <input
                   type="text"
-                  value=""
+                  value={payName}
                   readOnly
                   disabled
                   aria-disabled
@@ -463,7 +465,7 @@ export function CheckoutForm() {
                 <label className="text-sm font-medium text-slate-400">{t("payerPhone")}</label>
                 <input
                   type="text"
-                  value=""
+                  value={payPhone}
                   readOnly
                   disabled
                   aria-disabled

+ 41 - 42
src/app/[locale]/courses/[slug]/page.tsx

@@ -35,90 +35,89 @@ export default async function CourseDetailPage({ params, searchParams }: DetailP
   const tn = await getTranslations("nav");
 
   return (
-    <div>
-      <div className="border-b border-slate-200/90 bg-gradient-to-br from-slate-900 via-[#0c1929] to-slate-800 text-white">
+    <div className="relative min-h-screen bg-[#f6f8fb] font-sans">
+      {/* 头部:与主列表页一致的深邃蓝金风格 */}
+      <div className="relative z-10 border-b border-[#b89458]/20 bg-[#0a1120] pb-12 pt-10 text-white overflow-hidden">
+        <div className="pointer-events-none absolute left-1/2 top-0 -z-10 h-[300px] w-[600px] -translate-x-1/2 rounded-full bg-[#b89458]/10 blur-[80px]" />
+        
         <div className="site-container section-block-compact">
           <Link
             href="/courses"
-            className="text-sm font-medium text-amber-300/90 transition hover:text-amber-200"
+            className="inline-flex items-center text-sm font-medium text-[#b89458] transition hover:text-[#f3deae]"
           >
             ← {t("title")}
           </Link>
           {course ? (
-            <>
-              <p className="mt-4 text-sm font-medium text-blue-200/90">
+            <div className="mt-6">
+              <span className="inline-flex rounded-full border border-[#b89458]/30 bg-[#b89458]/10 px-3 py-1 text-xs font-semibold tracking-wider text-[#f3deae]">
                 {tn(`categories.${course.category}` as "categories.trial")}
-              </p>
-              <h1 className="font-serif mt-2 text-3xl font-bold md:text-4xl">{course.title}</h1>
-            </>
+              </span>
+              <h1 className="font-serif mt-4 text-3xl font-bold tracking-wide text-white md:text-4xl">
+                {course.title}
+              </h1>
+            </div>
           ) : (
-            <h1 className="font-serif mt-4 text-3xl font-bold md:text-4xl">
-              {t("videoListTitle")}
+            <h1 className="font-serif mt-6 text-3xl font-bold text-white md:text-4xl">
+              {isStrategy ? t("fileListTitle") : t("videoListTitle")}
             </h1>
           )}
         </div>
       </div>
 
-      <div className="site-container section-block-compact">
+      <div className="site-container relative z-10 section-block-compact -mt-6">
         {course ? (
-          <>
+          <div className="rounded-[2rem] border border-white/80 bg-white/70 p-6 shadow-xl backdrop-blur-xl">
             <div
-              className={`shadow-card h-48 overflow-hidden rounded-3xl bg-gradient-to-br md:h-56 ${
+              className={`h-48 w-full overflow-hidden rounded-2xl bg-slate-100 md:h-64 ${
                 course.coverUrl ? "" : course.coverGradient
               }`}
               style={
                 course.coverUrl
-                  ? {
-                      backgroundImage: `url(${course.coverUrl})`,
-                      backgroundSize: "cover",
-                      backgroundPosition: "center",
-                    }
+                  ? { backgroundImage: `url(${course.coverUrl})`, backgroundSize: "cover", backgroundPosition: "center" }
                   : undefined
               }
             />
-            <p className="mt-8 text-lg leading-relaxed text-slate-600">{course.subtitle}</p>
-            <div className="mt-6 flex flex-col gap-3 border-t border-slate-200 pt-6 sm:flex-row sm:items-center sm:justify-between sm:gap-6">
-              <p className="text-[11px] font-semibold uppercase tracking-widest text-slate-400">
+            <p className="mt-8 text-lg leading-relaxed text-slate-600 px-2">{course.subtitle}</p>
+            
+            <div className="mt-8 flex flex-col gap-4 border-t border-slate-200/60 pt-6 px-2 sm:flex-row sm:items-center sm:justify-between">
+              <p className="text-[12px] font-semibold tracking-widest text-slate-400">
                 {t("lessons", { count: course.lessonCount })}
               </p>
               {!shouldShowFreeBadge(course) ? (
-                <div className="flex w-fit items-baseline gap-2.5 rounded-2xl bg-gradient-to-br from-amber-50 via-amber-50 to-amber-100/90 px-4 py-2.5 shadow-md shadow-amber-900/5 ring-1 ring-amber-200/90 tabular-nums">
-                  <span className="text-3xl font-bold leading-none tracking-tight text-amber-900 md:text-4xl">
-                    ${course.price}
-                  </span>
-                  <span className="text-xs font-bold uppercase leading-none text-amber-800/75">
-                    {course.currency}
-                  </span>
+                <div className="flex items-baseline gap-1.5 rounded-full bg-[#fdfaf4] px-5 py-2.5 shadow-sm ring-1 ring-[#e8d2a6]">
+                  <span className="text-3xl font-bold text-[#8c6b36] md:text-4xl">${course.price}</span>
+                  <span className="text-sm font-bold text-[#b89458]">{course.currency}</span>
                 </div>
               ) : (
-                <span className="inline-flex w-fit items-center rounded-full bg-emerald-50 px-4 py-1.5 text-base font-bold tracking-tight text-emerald-700 ring-1 ring-emerald-200/70">
+                <span className="inline-flex rounded-full bg-emerald-50 px-5 py-2 text-base font-bold text-emerald-600 ring-1 ring-emerald-200">
                   {t("free")}
                 </span>
               )}
             </div>
-          </>
+          </div>
         ) : null}
-        {isStrategy ? (
-          <CourseFilesListClient goodsId={goodsId} allHref="/courses" allLabel={t("filterAll")} />
-        ) : (
-          <CourseVideosListClient
-            goodsId={goodsId}
-            allHref="/courses"
-            allLabel={t("filterAll")}
-          />
-        )}
-        <div className="mt-10 flex flex-wrap gap-4">
+        
+        {/* 下方的视频或文件列表沿用原有逻辑 */}
+        <div className="mt-8">
+          {isStrategy ? (
+            <CourseFilesListClient goodsId={goodsId} allHref="/courses" allLabel={t("filterAll")} />
+          ) : (
+            <CourseVideosListClient goodsId={goodsId} allHref="/courses" allLabel={t("filterAll")} />
+          )}
+        </div>
+
+        <div className="my-12 flex flex-wrap justify-center gap-4">
           {course && shouldShowBuyButton(course) ? (
             <CourseBuyButton
               courseSlug={course.slug}
               courseId={course.id}
               courseTitle={course.title}
               coursePrice={course.price}
-              className="inline-flex rounded-full bg-gradient-to-r from-blue-600 to-blue-700 px-8 py-3.5 text-sm font-bold text-white shadow-lg shadow-blue-600/25 transition-all duration-300 hover:from-blue-500 hover:to-blue-600"
+              className="inline-flex rounded-full bg-[#203659] px-10 py-4 text-sm font-bold tracking-wider text-white shadow-xl transition-all duration-300 hover:-translate-y-0.5 hover:bg-[#15243b]"
             />
           ) : null}
         </div>
       </div>
     </div>
   );
-}
+}

+ 50 - 43
src/app/[locale]/courses/courses-list-client.tsx

@@ -38,7 +38,6 @@ export function CoursesListClient({ active, initialCourses }: Props) {
         setTotal(result.page.total);
       })
       .catch(() => {
-        // Keep server-rendered fallback data.
         if (!cancelled) {
           setCourses([]);
           setTotal(0);
@@ -57,60 +56,74 @@ export function CoursesListClient({ active, initialCourses }: Props) {
 
   return (
     <div>
-      {loading ? <InlineLoading text="课程列表加载中..." className="mt-2" /> : null}
+      {loading ? <InlineLoading text="课程列表加载中..." className="mt-2 text-[#b89458]" /> : null}
+      
+      {/* 网格布局 */}
       <ul className="mt-6 grid auto-rows-fr gap-6 md:grid-cols-2 md:gap-8">
       {loading && courses.length === 0
         ? Array.from({ length: 4 }).map((_, i) => (
-            <li key={`sk-${i}`} className="rounded-3xl border border-slate-200/90 bg-white p-5 shadow-card">
-              <SkeletonBlock className="h-28 w-full" />
-              <SkeletonBlock className="mt-4 h-5 w-3/4" />
-              <SkeletonBlock className="mt-2 h-4 w-full" />
-              <SkeletonBlock className="mt-2 h-4 w-2/3" />
+            <li key={`sk-${i}`} className="rounded-[2rem] border border-white/60 bg-white/40 p-5 shadow-sm backdrop-blur-md">
+              <SkeletonBlock className="h-32 w-full rounded-2xl" />
+              <SkeletonBlock className="mt-5 h-5 w-3/4" />
+              <SkeletonBlock className="mt-3 h-4 w-full" />
             </li>
           ))
         : null}
+      
       {courses.map((c) => (
         <li key={c.slug} className="flex min-h-0">
-          <article className="ui-interactive-card shadow-card group flex h-full min-h-[240px] w-full min-w-0 flex-col overflow-hidden rounded-3xl border border-slate-200/90 bg-white sm:flex-row">
+          {/* 毛玻璃质感高级卡片 */}
+          <article className="group flex h-full min-h-[220px] w-full flex-col overflow-hidden rounded-[2rem] border border-white/80 bg-white/70 p-3 shadow-[0_8px_30px_rgba(0,0,0,0.04)] backdrop-blur-xl transition-all duration-300 hover:-translate-y-1 hover:shadow-[0_20px_40px_rgba(0,0,0,0.08)] sm:flex-row sm:p-4">
+            
+            {/* 左侧封面图 */}
             <div
-              className={`relative h-36 w-full shrink-0 bg-gradient-to-br sm:h-full sm:min-h-36 sm:w-36 sm:max-w-[40%] md:w-44 md:max-w-none ${
+              className={`relative h-40 w-full shrink-0 overflow-hidden rounded-2xl sm:h-full sm:min-h-40 sm:w-44 sm:max-w-[40%] md:w-48 ${
                 c.coverUrl ? "" : c.coverGradient
               }`}
-              style={c.coverUrl ? { backgroundImage: `url(${c.coverUrl})`, backgroundSize: "cover", backgroundPosition: "center" } : undefined}
             >
-              <span className="absolute bottom-3 left-3 rounded-md bg-black/35 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-white backdrop-blur-sm">
-                {tn(`categories.${c.category}` as "categories.trial")}
-              </span>
+              {c.coverUrl && (
+                // eslint-disable-next-line @next/next/no-img-element
+                <img src={c.coverUrl} alt={c.title} className="absolute inset-0 h-full w-full object-cover transition-transform duration-700 group-hover:scale-105" />
+              )}
+              {/* 深色金字徽章悬浮在图片底部 */}
+              <div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent p-3 pt-8">
+                <span className="inline-flex rounded-full bg-[#0a1120]/80 px-2.5 py-1 text-[10px] font-bold text-[#f3deae] backdrop-blur-md ring-1 ring-[#b89458]/30">
+                  {tn(`categories.${c.category}` as "categories.trial")}
+                </span>
+              </div>
             </div>
-            <div className="flex min-h-0 min-w-0 flex-1 flex-col p-5">
+
+            {/* 右侧信息区 */}
+            <div className="flex min-h-0 min-w-0 flex-1 flex-col pl-2 pt-4 sm:pl-5 sm:pt-1">
               <div className="flex items-start justify-between gap-3">
-                <h2 className="line-clamp-2 min-w-0 flex-1 font-serif text-lg font-bold leading-snug tracking-tight text-[var(--navy)] transition group-hover:text-blue-700">
+                <h2 className="line-clamp-2 min-w-0 flex-1 font-serif text-[17px] font-bold leading-snug tracking-tight text-slate-800 transition group-hover:text-blue-600">
                   {c.title}
                 </h2>
-                <div className="shrink-0 translate-y-px">
+                
+                {/* 价格标签区 */}
+                <div className="shrink-0 pl-2">
                   {shouldShowFreeBadge(c) ? (
-                    <span className="inline-flex w-fit items-center rounded-full bg-emerald-50 px-3 py-2 text-sm font-bold tracking-tight text-emerald-700 ring-1 ring-emerald-200/70">
+                    <span className="inline-flex items-center rounded-full bg-emerald-50 px-3 py-1 text-xs font-bold text-emerald-600 ring-1 ring-emerald-200">
                       {t("free")}
                     </span>
                   ) : (
-                    <div className="flex w-fit items-baseline gap-2 rounded-xl bg-gradient-to-br from-amber-50 via-amber-50 to-amber-100/90 px-3.5 py-2 shadow-sm ring-1 ring-amber-200/90 tabular-nums">
-                      <span className="text-2xl font-bold leading-none tracking-tight text-amber-900">
-                        ${c.price}
-                      </span>
-                      <span className="text-[11px] font-bold uppercase leading-none text-amber-800/75">
-                        {c.currency}
-                      </span>
+                    <div className="flex items-baseline gap-1 rounded-full bg-[#fdfaf4] px-3 py-1 shadow-sm ring-1 ring-[#e8d2a6]">
+                      <span className="text-lg font-bold text-[#8c6b36]">${c.price}</span>
+                      <span className="text-[10px] font-bold text-[#b89458]">{c.currency}</span>
                     </div>
                   )}
                 </div>
               </div>
-              <p className="mt-2 line-clamp-2 min-h-[2.5rem] text-sm leading-relaxed text-slate-600">
+              
+              <p className="mt-2 line-clamp-2 min-h-[2.5rem] text-[13px] leading-relaxed text-slate-500">
                 {c.subtitle}
               </p>
-              <div className="mt-auto flex flex-wrap justify-end gap-2 border-t border-slate-100 pt-4">
+              
+              {/* 底部按钮区 */}
+              <div className="mt-auto flex flex-wrap justify-end gap-2.5 pt-4">
                 <Link
                   href={`/courses/${c.id}?cat=${c.category}`}
-                  className="ui-interactive-btn inline-flex h-10 min-w-[7.5rem] items-center justify-center rounded-full border-2 border-slate-200 px-4 text-sm font-semibold text-slate-700 transition hover:border-blue-200 hover:bg-blue-50"
+                  className="inline-flex h-9 min-w-[6rem] items-center justify-center rounded-full border border-slate-200 bg-white px-4 text-xs font-semibold text-slate-600 transition-colors hover:border-[#b89458]/40 hover:text-[#8c6b36]"
                 >
                   {t("detail")}
                 </Link>
@@ -120,7 +133,7 @@ export function CoursesListClient({ active, initialCourses }: Props) {
                     courseId={c.id}
                     courseTitle={c.title}
                     coursePrice={c.price}
-                    className="inline-flex h-10 min-w-[7.5rem] items-center justify-center rounded-full bg-gradient-to-r from-blue-600 to-blue-700 px-4 text-sm font-semibold text-white shadow-md shadow-blue-600/20"
+                    className="inline-flex h-9 min-w-[6rem] items-center justify-center rounded-full bg-[#203659] px-4 text-xs font-semibold text-white shadow-md transition-colors hover:bg-[#15243b]"
                   />
                 ) : null}
               </div>
@@ -129,33 +142,27 @@ export function CoursesListClient({ active, initialCourses }: Props) {
         </li>
       ))}
       </ul>
-      <div className="mt-5 flex items-center justify-end gap-3">
+      
+      {/* 分页控制 (统一轻量化样式) */}
+      <div className="mt-8 flex items-center justify-center gap-4">
         <button
           type="button"
-          onClick={() => {
-            if (!canPrev) return;
-            setLoading(true);
-            setPage((p) => Math.max(1, p - 1));
-          }}
+          onClick={() => { if (canPrev) { setLoading(true); setPage((p) => Math.max(1, p - 1)); } }}
           disabled={!canPrev}
-          className="rounded-full border border-slate-300 px-3 py-1.5 text-sm text-slate-700 disabled:cursor-not-allowed disabled:opacity-50"
+          className="rounded-full bg-white/60 px-4 py-2 text-sm text-slate-600 shadow-sm ring-1 ring-slate-200 backdrop-blur-md transition hover:bg-white disabled:cursor-not-allowed disabled:opacity-50"
         >
           {t("videoPrevPage")}
         </button>
-        <span className="text-sm text-slate-500">{t("videoCurrentPage", { page })}</span>
+        <span className="text-sm font-medium text-slate-500">{t("videoCurrentPage", { page })}</span>
         <button
           type="button"
-          onClick={() => {
-            if (!canNext) return;
-            setLoading(true);
-            setPage((p) => p + 1);
-          }}
+          onClick={() => { if (canNext) { setLoading(true); setPage((p) => p + 1); } }}
           disabled={!canNext}
-          className="rounded-full border border-slate-300 px-3 py-1.5 text-sm text-slate-700 disabled:cursor-not-allowed disabled:opacity-50"
+          className="rounded-full bg-white/60 px-4 py-2 text-sm text-slate-600 shadow-sm ring-1 ring-slate-200 backdrop-blur-md transition hover:bg-white disabled:cursor-not-allowed disabled:opacity-50"
         >
           {t("videoNextPage")}
         </button>
       </div>
     </div>
   );
-}
+}

+ 59 - 29
src/app/[locale]/courses/page.tsx

@@ -30,44 +30,74 @@ export default async function CoursesPage({ params, searchParams }: Props) {
   const tn = await getTranslations("nav");
 
   return (
-    <div>
-      <div className="border-b border-slate-200/90 bg-gradient-to-br from-slate-900 via-[#0c1929] to-slate-800 py-12 text-white md:py-14">
-        <div className="site-container">
-          <p className="text-sm font-semibold text-amber-300/90">{t("pageEyebrow")}</p>
-          <h1 className="font-serif mt-2 text-3xl font-bold md:text-4xl">{t("title")}</h1>
-          <p className="mt-3 max-w-2xl text-slate-300">{t("subtitle")}</p>
+    <div className="relative min-h-screen bg-[#f6f8fb] font-sans">
+      {/* 全局微妙网格背景 (可用纯CSS实现) */}
+      <div 
+        className="pointer-events-none absolute inset-0 z-0 opacity-[0.15]" 
+        style={{
+          backgroundImage: `linear-gradient(to right, #cbd5e1 1px, transparent 1px), linear-gradient(to bottom, #cbd5e1 1px, transparent 1px)`,
+          backgroundSize: '40px 40px'
+        }}
+      />
+
+      {/* 头部:深邃空蓝 + 暗金点缀 */}
+      <div className="relative z-10 border-b border-[#b89458]/20 py-16 text-white md:py-20 shadow-xl overflow-hidden">
+        {/* 头部背景图 */}
+        <div
+          className="pointer-events-none absolute inset-0 -z-10 bg-cover bg-center bg-no-repeat"
+          style={{ backgroundImage: 'url("/courses-banner-bg.png")' }}
+        />
+        <div className="pointer-events-none absolute inset-0 -z-10 bg-[#0a1120]/45" />
+        {/* 背景光晕 */}
+        <div className="pointer-events-none absolute left-1/2 top-0 -z-10 h-[400px] w-[800px] -translate-x-1/2 rounded-full bg-[#b89458]/10 blur-[100px]" />
+        
+        <div className="site-container flex flex-col items-center text-center">
+          <p className="text-sm font-semibold tracking-[0.2em] text-[#b89458] mb-3">
+            {t("pageEyebrow")}
+          </p>
+          <h1 className="font-serif mt-2 text-4xl font-bold tracking-wide text-[#f3deae] md:text-5xl">
+            {t("title")}
+          </h1>
+          <p className="mt-5 max-w-2xl text-sm leading-relaxed text-[#a2b2c9] md:text-base">
+            {t("subtitle")}
+          </p>
         </div>
       </div>
 
-      <div className="site-container section-block-compact">
-        <div className="flex flex-wrap gap-2">
-          <Link
-            href="/courses"
-            className={cn(
-              "rounded-full px-5 py-2 text-sm font-semibold transition",
-              !active
-                ? "bg-blue-600 text-white shadow-lg shadow-blue-600/25"
-                : "border border-slate-200 bg-white text-slate-600 hover:border-blue-200 hover:text-blue-800",
-            )}
-          >
-            {t("filterAll")}
-          </Link>
-          {COURSE_CATEGORIES.map((c) => (
+      <div className="site-container relative z-10 section-block-compact mt-8">
+        
+        {/* 玻璃质感分类导航 Tabs */}
+        <div className="mb-10 flex justify-center">
+          <div className="inline-flex flex-wrap items-center justify-center gap-2 rounded-full bg-white/40 p-1.5 shadow-[0_4px_20px_rgba(0,0,0,0.03)] ring-1 ring-white/60 backdrop-blur-md">
             <Link
-              key={c.id}
-              href={`/courses?cat=${c.id}`}
+              href="/courses"
               className={cn(
-                "rounded-full px-5 py-2 text-sm font-semibold transition",
-                active === c.id
-                  ? "bg-blue-600 text-white shadow-lg shadow-blue-600/25"
-                  : "border border-slate-200 bg-white text-slate-600 hover:border-blue-200 hover:text-blue-800",
+                "rounded-full px-6 py-2.5 text-sm font-semibold transition-all duration-300",
+                !active
+                  ? "bg-gradient-to-r from-[#fdfbf6] to-[#f6eedb] text-[#8c6b36] shadow-sm ring-1 ring-[#e8d2a6]"
+                  : "text-slate-500 hover:text-slate-800 hover:bg-white/50"
               )}
             >
-              {tn(`categories.${c.id}` as "categories.trial")}
+              {t("filterAll")}
             </Link>
-          ))}
+            {COURSE_CATEGORIES.map((c) => (
+              <Link
+                key={c.id}
+                href={`/courses?cat=${c.id}`}
+                className={cn(
+                  "rounded-full px-6 py-2.5 text-sm font-semibold transition-all duration-300",
+                  active === c.id
+                    ? "bg-gradient-to-r from-[#fdfbf6] to-[#f6eedb] text-[#8c6b36] shadow-sm ring-1 ring-[#e8d2a6]"
+                    : "text-slate-500 hover:text-slate-800 hover:bg-white/50"
+                )}
+              >
+                {tn(`categories.${c.id}` as "categories.trial")}
+              </Link>
+            ))}
+          </div>
         </div>
 
+        {/* 课程列表客户端组件 */}
         <CoursesListClient
           key={active ?? "all"}
           active={active}
@@ -76,4 +106,4 @@ export default async function CoursesPage({ params, searchParams }: Props) {
       </div>
     </div>
   );
-}
+}

+ 43 - 24
src/app/[locale]/faq/faq-client.tsx

@@ -11,7 +11,7 @@ function Chevron({ className }: { className?: string }) {
     <svg
       aria-hidden
       viewBox="0 0 24 24"
-      className={cn("h-5 w-5 shrink-0 text-slate-400", className)}
+      className={cn("h-5 w-5 shrink-0 transition-colors", className)}
       fill="none"
       stroke="currentColor"
       strokeWidth="2"
@@ -42,60 +42,79 @@ export function FaqClient() {
   }, []);
 
   return (
-    <div className="mx-auto max-w-3xl">
-      <div className="text-center sm:text-left">
-        <h1 className="font-serif text-3xl font-semibold tracking-tight text-[var(--navy)] md:text-4xl">
+    <div className="mx-auto max-w-3xl py-12">
+      {/* 头部标题区 */}
+      <div className="text-center mb-12">
+        <p className="text-sm font-medium tracking-[0.3em] text-[#b89458] mb-3">
+          FAQ
+        </p>
+        <h1 className="font-serif text-3xl font-semibold tracking-wide text-[#f3deae] md:text-4xl mb-4">
           {t("title")}
         </h1>
-        <p className="mt-2 text-sm text-[var(--muted)]">{t("subtitle")}</p>
+        <p className="text-sm text-[#a2b2c9] max-w-lg mx-auto">
+          {t("subtitle")}
+        </p>
       </div>
 
+      {/* 状态处理 */}
       {items === null ? (
-        <div className="mt-10 flex justify-center sm:justify-start">
-          <InlineLoading text={t("loading")} />
+        <div className="mt-10 flex justify-center">
+          <div className="text-[#b89458]">
+            <InlineLoading text={t("loading")} />
+          </div>
         </div>
       ) : failed ? (
-        <p className="mt-10 rounded-xl border border-rose-200/80 bg-rose-50/80 px-4 py-3 text-sm text-rose-800">
+        <p className="mt-10 rounded-xl border border-red-900/50 bg-red-950/30 px-6 py-4 text-center text-sm text-red-400 backdrop-blur-md">
           {t("loadError")}
         </p>
       ) : items.length === 0 ? (
-        <p className="mt-10 rounded-xl border border-dashed border-[var(--border)] bg-white/60 px-4 py-8 text-center text-sm text-[var(--muted)]">
+        <p className="mt-10 rounded-xl border border-dashed border-[#b89458]/30 bg-[#0c1627]/40 px-6 py-10 text-center text-sm text-[#a2b2c9] backdrop-blur-md">
           {t("empty")}
         </p>
       ) : (
-        <div className="mt-10 overflow-hidden rounded-2xl border border-[var(--border)] bg-[var(--card)] shadow-card">
-          <ul className="divide-y divide-[var(--border)]" role="list">
+        /* 手风琴列表主体 */
+        <div className="overflow-hidden rounded-[2rem] border border-[#b89458]/20 bg-[#0c1627]/60 shadow-[0_30px_60px_rgba(0,0,0,0.6)] backdrop-blur-xl">
+          <ul className="divide-y divide-[#b89458]/10" role="list">
             {items.map((item, index) => {
               const open = openIndex === index;
               return (
-                <li key={`${item.id}-${index}`}>
+                <li key={`${item.id}-${index}`} className="group">
                   <button
                     type="button"
                     id={`faq-trigger-${index}`}
                     aria-expanded={open}
                     aria-controls={`faq-panel-${index}`}
                     className={cn(
-                      "flex w-full items-start justify-between gap-4 px-5 py-4 text-left transition-colors sm:px-6 sm:py-5",
+                      "flex w-full items-center justify-between gap-4 px-6 py-5 text-left transition-all duration-300 sm:px-8",
                       open
-                        ? "bg-gradient-to-r from-blue-50/90 to-slate-50/40"
-                        : "hover:bg-slate-50/80",
+                        ? "bg-gradient-to-r from-[#b89458]/10 to-transparent"
+                        : "hover:bg-[#b89458]/5",
                     )}
                     onClick={() => setOpenIndex(open ? null : index)}
                   >
                     <span
                       className={cn(
-                        "min-w-0 flex-1 text-[15px] font-semibold leading-snug sm:text-base",
-                        open ? "text-[var(--navy)]" : "text-slate-800",
+                        "min-w-0 flex-1 text-[16px] font-medium leading-relaxed transition-colors",
+                        open ? "text-[#f3deae]" : "text-[#d9dfea] group-hover:text-[#f3deae]",
                       )}
                     >
                       {item.question}
                     </span>
-                    <Chevron
+                    <div
                       className={cn(
-                        "mt-0.5 transition-transform duration-300 ease-out",
-                        open && "rotate-180 text-blue-600",
+                        "flex h-8 w-8 shrink-0 items-center justify-center rounded-full border transition-all duration-300",
+                        open
+                          ? "border-[#b89458]/40 bg-[#b89458]/10"
+                          : "border-transparent bg-[#0a1120] group-hover:border-[#b89458]/20",
                       )}
-                    />
+                    >
+                      <Chevron
+                        className={cn(
+                          "transition-transform duration-300 ease-out",
+                          open ? "rotate-180 text-[#f3deae]" : "text-[#889abb] group-hover:text-[#b89458]",
+                        )}
+                      />
+                    </div>
                   </button>
                   <div
                     id={`faq-panel-${index}`}
@@ -107,8 +126,8 @@ export function FaqClient() {
                     )}
                   >
                     <div className="min-h-0 overflow-hidden">
-                      <div className="border-t border-[var(--border)] bg-[var(--surface-muted)]/50 px-5 py-4 sm:px-6 sm:py-5">
-                        <p className="whitespace-pre-wrap text-[15px] leading-relaxed text-slate-600">
+                      <div className="border-t border-[#b89458]/10 bg-[#080d18]/40 px-6 py-6 sm:px-8">
+                        <p className="whitespace-pre-wrap text-[15px] leading-8 text-[#a2b2c9]">
                           {item.answer}
                         </p>
                       </div>
@@ -122,4 +141,4 @@ export function FaqClient() {
       )}
     </div>
   );
-}
+}

+ 14 - 2
src/app/[locale]/faq/page.tsx

@@ -8,8 +8,20 @@ export default async function FaqPage({ params }: Props) {
   setRequestLocale(locale);
 
   return (
-    <div className="page-shell">
-      <FaqClient />
+    <div className="relative min-h-screen overflow-hidden bg-[#050b14] font-sans">
+      <div
+        className="absolute inset-0 opacity-80"
+        style={{
+          backgroundImage:
+            "linear-gradient(180deg, rgba(5,11,20,0.4) 0%, rgba(5,11,20,0.95) 100%), url('/about/bg-wave.png')",
+          backgroundSize: "cover",
+          backgroundPosition: "center",
+          backgroundAttachment: "fixed",
+        }}
+      />
+      <div className="relative z-10 px-6 pb-20 pt-16 md:px-8 md:pt-24">
+        <FaqClient />
+      </div>
     </div>
   );
 }

+ 2 - 0
src/app/[locale]/layout.tsx

@@ -5,6 +5,7 @@ import { getMessages, setRequestLocale } from "next-intl/server";
 import { SiteFooter } from "@/components/site-footer";
 import { SiteHeader } from "@/components/site-header";
 import { LocaleHtmlLang } from "@/components/locale-html-lang";
+import { TopLoader } from "@/components/top-loader";
 import { routing } from "@/i18n/routing";
 import { AuthProvider } from "@/providers/auth-provider";
 
@@ -44,6 +45,7 @@ export default async function LocaleLayout({
     <NextIntlClientProvider locale={locale} messages={messages}>
       <AuthProvider>
         <LocaleHtmlLang />
+        <TopLoader />
         <SiteHeader />
         <main className="flex-1">{children}</main>
         <SiteFooter />

+ 124 - 116
src/app/[locale]/page.tsx

@@ -1,7 +1,6 @@
 import { getTranslations, setRequestLocale } from "next-intl/server";
 import { Link } from "@/i18n/navigation";
 import { courses, type CourseCategory } from "@/data/courses";
-import { SectionHeading } from "@/components/section-heading";
 import { IconBook, IconChart, IconShield } from "@/components/icons";
 import { HomeHeroCarousel } from "@/components/home-hero-carousel";
 
@@ -11,8 +10,9 @@ export default async function HomePage({ params }: Props) {
   const { locale } = await params;
   setRequestLocale(locale);
   const t = await getTranslations("home");
-  const tc = await getTranslations("courses");
-  const featured = courses.slice(0, 5);
+  
+  // 恢复截取 5 个精选课程
+  const featured = courses.slice(0, 5); 
   const featuredCoverMap: Record<CourseCategory, string> = {
     trial: "/免费试听--状态--锁定、解锁.png",
     practical: "/系统课程--状态--锁定、解锁.png",
@@ -33,155 +33,158 @@ export default async function HomePage({ params }: Props) {
       icon: IconBook,
       title: t("pillar1Title"),
       desc: t("pillar1Desc"),
-      accent: "from-blue-500 to-indigo-600",
     },
     {
       icon: IconChart,
       title: t("pillar2Title"),
       desc: t("pillar2Desc"),
-      accent: "from-amber-500 to-orange-600",
     },
     {
       icon: IconShield,
       title: t("pillar3Title"),
       desc: t("pillar3Desc"),
-      accent: "from-emerald-500 to-teal-600",
     },
   ];
 
   const heroBanners = ["/banner1.png", "/banner2.png", "/banner3.png", "/banner4.png", "/banner5.png"];
 
   return (
-    <div>
-      {/* Hero:左文案 + 右轮播 + 统一背景 */}
-      <section className="ui-enter relative overflow-hidden border-b border-slate-200/80 bg-gradient-to-br from-slate-900 via-[#0f1b2d] to-slate-900 text-white">
-        <div className="hero-grid pointer-events-none absolute inset-0 z-0 opacity-40" />
-        <div className="pointer-events-none absolute -right-16 top-16 z-0 h-72 w-72 rounded-full bg-blue-500/18 blur-3xl" />
-        <div className="pointer-events-none absolute -left-20 bottom-8 z-0 h-64 w-64 rounded-full bg-amber-500/12 blur-3xl" />
+    <div className="font-sans text-slate-800">
+      
+      {/* ================= HERO 区块 (背景色:极浅灰蓝色) ================= */}
+      <section className="ui-enter relative overflow-hidden bg-[#f6f8fb] pb-20 pt-16 lg:pt-24 border-b border-slate-200/50">
+        <div
+          className="pointer-events-none absolute inset-0 z-0 opacity-90"
+          style={{
+            backgroundImage:
+              "linear-gradient(180deg, rgba(246,248,251,0.25) 0%, rgba(246,248,251,0.45) 100%), url('/bannerBg.png')",
+            backgroundSize: "cover",
+            backgroundPosition: "center",
+          }}
+        />
+        <div className="pointer-events-none absolute -right-32 top-0 z-0 h-[600px] w-[600px] rounded-full bg-sky-100/50 blur-3xl" />
+        <div className="pointer-events-none absolute -left-32 bottom-0 z-0 h-[500px] w-[500px] rounded-full bg-amber-50/50 blur-3xl" />
 
-        <div className="site-container relative z-10 grid gap-10 py-16 md:grid-cols-2 md:items-center md:py-20 lg:gap-14">
+        <div className="site-container relative z-10 grid gap-12 md:grid-cols-2 md:items-center lg:gap-16">
           <div className="max-w-xl md:pr-4">
-            <p className="text-sm font-semibold tracking-wide text-amber-300/95">
-              {t("heroEyebrow")}
-            </p>
-            <h1 className="font-serif mt-4 text-4xl font-bold leading-[1.12] tracking-tight text-white md:text-5xl lg:text-[3.15rem]">
+            <h1 className="font-serif mt-4 text-4xl font-extrabold leading-[1.15] tracking-tight text-slate-900 md:text-5xl lg:text-6xl">
+              <span className="block text-slate-800 text-3xl md:text-4xl lg:text-5xl mb-2 font-sans tracking-wide">SYSTEMATIC</span>
+              <span className="block text-slate-800 text-3xl md:text-4xl lg:text-5xl mb-4 font-sans tracking-wide">TRADING EDUCATION</span>
               {t("heroTitle")}
             </h1>
-            <p className="mt-5 max-w-lg text-base leading-relaxed text-slate-200 md:text-lg">
+            <p className="mt-6 max-w-[480px] text-base leading-relaxed text-slate-500 md:text-lg">
               {t("heroSubtitle")}
             </p>
-            <div className="mt-8 flex flex-wrap items-center gap-4">
+            <div className="mt-10 flex flex-wrap items-center gap-4">
               <Link
                 href="/courses"
-                className="ui-interactive-btn inline-flex min-w-[130px] items-center justify-center rounded-full bg-gradient-to-r from-amber-400 to-amber-500 px-7 py-3 text-sm font-bold text-[var(--navy)] shadow-xl shadow-amber-500/20 transition hover:from-amber-300 hover:to-amber-400"
+                className="ui-interactive-btn inline-flex min-w-[140px] items-center justify-center rounded-full bg-sky-500 px-8 py-3.5 text-sm font-bold tracking-wide text-white shadow-lg shadow-sky-400/30 transition hover:bg-sky-600"
               >
-                {t("ctaCourses")}
+                {t("ctaCourses") || "GET STARTED"}
               </Link>
               <Link
                 href="/about"
-                className="ui-interactive-btn inline-flex min-w-[130px] items-center justify-center rounded-full border border-white/35 bg-white/8 px-7 py-3 text-sm font-semibold text-white transition hover:border-white/55 hover:bg-white/12"
+                className="ui-interactive-btn inline-flex min-w-[140px] items-center justify-center rounded-full bg-amber-400 px-8 py-3.5 text-sm font-bold tracking-wide text-white shadow-lg shadow-amber-400/30 transition hover:bg-amber-500"
               >
-                {t("ctaAbout")}
+                {t("ctaAbout") || "LEARN MORE"}
               </Link>
             </div>
           </div>
 
-          <div className="relative w-full md:justify-self-end md:pl-4">
-            <div className="w-full md:max-w-[720px]">
-            <HomeHeroCarousel images={heroBanners} />
+          <div className="relative w-full md:justify-self-end">
+            <div className="relative w-full rounded-[2rem] shadow-2xl shadow-slate-300/40 ring-1 ring-slate-200 bg-white p-3">
+              <div className="overflow-hidden rounded-2xl">
+                <HomeHeroCarousel images={heroBanners} />
+              </div>
             </div>
           </div>
         </div>
 
-        {/* 数据条 */}
-        <div className="relative z-10 border-t border-white/10 bg-black/20">
-          <div className="site-container grid grid-cols-2 gap-6 py-8 md:grid-cols-4">
-            {stats.map((s) => (
-              <div key={s.label} className="text-center md:text-left">
-                <p className="font-serif text-3xl font-bold text-white md:text-4xl">{s.value}</p>
-                <p className="mt-1 text-sm text-slate-400">{s.label}</p>
+        {/* 数据条 - 悬浮在 Hero 底部 */}
+        <div className="relative z-20 site-container mt-16">
+          <div className="grid grid-cols-2 gap-8 rounded-[2rem] bg-white p-8 shadow-sm ring-1 ring-slate-100 md:grid-cols-4 lg:px-12">
+            {stats.map((s, idx) => (
+              <div key={s.label} className="flex flex-col items-center justify-center text-center md:flex-row md:justify-start md:text-left md:gap-4">
+                <div className="mb-2 h-10 w-10 shrink-0 rounded-full bg-slate-50 flex items-center justify-center shadow-inner md:mb-0">
+                  <span className={idx % 2 === 0 ? "text-amber-400" : "text-sky-400"}>●</span>
+                </div>
+                <div>
+                  <p className="font-serif text-2xl font-bold text-slate-800 md:text-3xl">{s.value}</p>
+                  <p className="mt-1 text-xs font-medium text-slate-500 uppercase tracking-wider">{s.label}</p>
+                </div>
               </div>
             ))}
           </div>
         </div>
       </section>
 
-      {/* 三大支柱 */}
-      <section className="ui-enter ui-enter-delay-1 site-container section-block">
-        <SectionHeading
-          eyebrow={t("pillarsEyebrow")}
-          title={t("pillarsTitle")}
-          align="center"
-        />
-        <div className="mt-14 grid gap-8 md:grid-cols-3">
-          {pillars.map((p) => {
-            const Icon = p.icon;
-            return (
-            <div
-              key={p.title}
-              className="ui-interactive-card group shadow-card rounded-3xl border border-slate-200/90 bg-white p-8"
-            >
-              <div
-                className={`flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-br ${p.accent} text-white shadow-lg`}
-              >
-                <Icon className="h-7 w-7" aria-hidden />
-              </div>
-              <h3 className="font-serif mt-6 text-xl font-bold text-[var(--navy)]">{p.title}</h3>
-              <p className="mt-3 text-sm leading-relaxed text-slate-600">{p.desc}</p>
-            </div>
-            );
-          })}
+      {/* ================= 三大支柱 (Learning Path) (背景色:纯白) ================= */}
+      <section className="ui-enter ui-enter-delay-1 bg-white py-24 border-b border-slate-100">
+        <div className="site-container">
+          <div className="text-center mb-14">
+            <h2 className="font-serif text-3xl font-bold text-slate-900 md:text-4xl">学习路径</h2>
+          </div>
+          <div className="grid gap-6 md:grid-cols-3">
+            {pillars.map((p, idx) => {
+              const Icon = p.icon;
+              const iconColor = idx === 0 ? "text-sky-500" : idx === 1 ? "text-amber-500" : "text-teal-500";
+              const bgColor = idx === 0 ? "bg-sky-50" : idx === 1 ? "bg-amber-50" : "bg-teal-50";
+              
+              return (
+                <div
+                  key={p.title}
+                  className="ui-interactive-card group flex flex-col items-center text-center rounded-[2rem] bg-[#f8fafc] px-8 py-12 transition-all duration-300 hover:bg-white hover:shadow-xl hover:shadow-slate-200/50 hover:-translate-y-1 ring-1 ring-slate-100"
+                >
+                  <div className={`mb-6 flex h-[72px] w-[72px] items-center justify-center rounded-[1.5rem] shadow-sm ${bgColor} ${iconColor} transition-transform duration-300 group-hover:scale-110`}>
+                    <Icon className="h-9 w-9" aria-hidden />
+                  </div>
+                  <h3 className="mb-4 font-serif text-xl font-bold text-slate-900">{p.title}</h3>
+                  <p className="text-sm leading-relaxed text-slate-500">{p.desc}</p>
+                </div>
+              );
+            })}
+          </div>
         </div>
       </section>
 
-      {/* 精选课程 */}
-      <section className="ui-enter ui-enter-delay-2 border-y border-slate-200/90 bg-gradient-to-b from-slate-50/80 to-white py-20">
+      {/* ================= 精选课程 (Featured Courses) (背景色:浅石板色) ================= */}
+      <section className="ui-enter ui-enter-delay-2 bg-[#f4f7fb] py-24">
         <div className="site-container">
-          <div className="flex flex-col items-start justify-between gap-6 md:flex-row md:items-end">
-            <div className="min-w-0 flex-1">
-              <SectionHeading
-                eyebrow={t("featuredEyebrow")}
-                title={t("featuredTitle")}
-                align="left"
-              />
-            </div>
-            <Link
-              href="/courses"
-              className="ui-interactive-btn shrink-0 rounded-full border-2 border-blue-600 px-6 py-2.5 text-sm font-bold text-blue-700 transition hover:bg-blue-600 hover:text-white"
-            >
-              {t("viewAll")}
-            </Link>
+          <div className="mb-14 flex flex-col items-center text-center gap-4">
+            <h2 className="font-serif text-3xl font-bold text-slate-900 md:text-4xl">精选课程</h2>
+            <p className="text-slate-500 max-w-xl">系统化课程体系,带您从入门到精通建立稳健的交易逻辑。</p>
           </div>
 
-          <div className="mt-12 grid gap-8 md:grid-cols-2 lg:grid-cols-3">
+          {/* 使用 Flex 布局完美适配 5 个课程(上3下2居中排布) */}
+          <div className="flex flex-wrap justify-center gap-6">
             {featured.map((c) => (
               <Link
                 key={c.slug}
                 href={`/courses?cat=${c.category}`}
-                className="ui-interactive-card group shadow-card overflow-hidden rounded-3xl border border-slate-200/90 bg-white"
+                // 计算宽度:在大屏幕上三分之一宽度减去间距,中等屏幕二分之一,确保 5 个元素能漂亮地折行居中
+                className="w-full sm:w-[calc(50%-12px)] lg:w-[calc(33.333%-16px)] ui-interactive-card group flex flex-col overflow-hidden rounded-3xl bg-white border border-slate-200/60 transition-all duration-300 hover:shadow-xl hover:shadow-slate-300/40 hover:-translate-y-1"
               >
-                <div className="relative h-36 overflow-hidden">
-                  {/* eslint-disable-next-line @next/next/no-img-element */}
-                  <img
-                    src={featuredCoverMap[c.category]}
-                    alt={c.title}
-                    className="absolute inset-0 h-full w-full object-cover transition duration-500 group-hover:scale-105"
-                  />
-                  <span className="absolute right-4 top-4 rounded-full bg-white/95 px-3 py-1 text-xs font-bold text-slate-800 shadow-sm">
-                    {tc("lessons", { count: c.lessonCount })}
-                  </span>
+                <div className="relative aspect-[4/3] overflow-hidden bg-slate-100 p-2">
+                  <div className="w-full h-full rounded-2xl overflow-hidden relative">
+                    {/* eslint-disable-next-line @next/next/no-img-element */}
+                    <img
+                      src={featuredCoverMap[c.category]}
+                      alt={c.title}
+                      className="absolute inset-0 h-full w-full object-cover transition duration-700 group-hover:scale-110"
+                    />
+                  </div>
                 </div>
-                <div className="p-6">
-                  <h3 className="font-serif text-lg font-bold text-[var(--navy)] transition group-hover:text-blue-700">
+                <div className="flex flex-1 flex-col p-6">
+                  <h3 className="font-serif text-[15px] font-bold text-slate-900 leading-snug uppercase tracking-wide group-hover:text-sky-600 transition-colors">
                     {c.title}
                   </h3>
-                  <p className="mt-2 line-clamp-2 text-sm leading-relaxed text-slate-600">
+                  <p className="mt-3 line-clamp-2 text-xs leading-relaxed text-slate-500">
                     {c.subtitle}
                   </p>
-                  <span className="mt-4 inline-flex items-center text-sm font-semibold text-blue-600">
-                    {tc("detail")}
-                    <span className="ml-1 transition group-hover:translate-x-0.5">→</span>
-                  </span>
+                  <div className="mt-auto pt-5 flex items-center text-xs font-bold text-slate-400 uppercase tracking-wide group-hover:text-sky-600 transition-colors">
+                    查看详情
+                    <span className="ml-1.5 transition-transform duration-300 group-hover:translate-x-1">→</span>
+                  </div>
                 </div>
               </Link>
             ))}
@@ -189,31 +192,36 @@ export default async function HomePage({ params }: Props) {
         </div>
       </section>
 
-      {/* CTA 带 */}
-      <section className="ui-enter ui-enter-delay-3 site-container section-block">
-        <div className="relative overflow-hidden rounded-[2rem] bg-gradient-to-r from-blue-700 via-blue-800 to-indigo-900 px-8 py-14 text-center text-white shadow-xl shadow-blue-900/20 md:px-16">
-          <div className="pointer-events-none absolute -right-24 -top-24 h-64 w-64 rounded-full bg-white/10 blur-3xl" />
-          <div className="pointer-events-none absolute -bottom-16 -left-16 h-48 w-48 rounded-full bg-amber-400/20 blur-3xl" />
-          <h2 className="font-serif relative text-2xl font-bold md:text-3xl">{t("ctaBandTitle")}</h2>
-          <p className="relative mx-auto mt-4 max-w-2xl text-slate-200">
-            {t("ctaBandSubtitle")}
-          </p>
-          <div className="relative mt-10 flex flex-wrap justify-center gap-4">
-            <Link
-              href="/courses"
-              className="ui-interactive-btn inline-flex rounded-full bg-white px-8 py-3.5 text-sm font-bold text-blue-900 shadow-lg transition hover:bg-amber-50"
-            >
-              {t("ctaBandPrimary")}
-            </Link>
-            <Link
-              href="/contact"
-              className="ui-interactive-btn inline-flex rounded-full border-2 border-white/40 px-8 py-3.5 text-sm font-semibold text-white transition hover:bg-white/10"
-            >
-              {t("ctaBandSecondary")}
-            </Link>
+      {/* ================= CTA 带 (背景色:纯白) ================= */}
+      <section className="ui-enter ui-enter-delay-3 bg-white py-24">
+        <div className="site-container">
+          {/* CTA 内部卡片使用淡蓝色渐变,与页面主体区分 */}
+          <div className="relative overflow-hidden rounded-[2.5rem] bg-gradient-to-br from-[#f8fafc] to-[#eef2f6] border border-slate-100 px-8 py-16 text-center shadow-lg shadow-slate-200/30 md:px-16">
+            <p className="text-sm font-bold tracking-widest text-sky-600 uppercase mb-4">
+              READY TO START YOUR SYSTEMATIC TRADING JOURNEY?
+            </p>
+            <h2 className="font-serif text-2xl font-bold text-slate-900 md:text-3xl">{t("ctaBandTitle")}</h2>
+            <p className="mx-auto mt-4 max-w-2xl text-slate-500 text-sm md:text-base">
+              {t("ctaBandSubtitle")}
+            </p>
+            <div className="mt-10 flex flex-wrap justify-center gap-5">
+              <Link
+                href="/courses"
+                className="ui-interactive-btn inline-flex rounded-full bg-sky-500 px-10 py-3.5 text-sm font-bold tracking-wide text-white shadow-lg shadow-sky-500/20 transition hover:bg-sky-600"
+              >
+                {t("ctaBandPrimary") || "立即开启"}
+              </Link>
+              <Link
+                href="/contact"
+                className="ui-interactive-btn inline-flex rounded-full bg-amber-400 px-10 py-3.5 text-sm font-bold tracking-wide text-white shadow-lg shadow-amber-400/20 transition hover:bg-amber-500"
+              >
+                {t("ctaBandSecondary") || "了解更多"}
+              </Link>
+            </div>
           </div>
         </div>
       </section>
+      
     </div>
   );
-}
+}

+ 68 - 43
src/components/site-footer.tsx

@@ -8,94 +8,119 @@ export async function SiteFooter() {
   const year = new Date().getFullYear();
 
   return (
-    <footer className="relative mt-auto overflow-hidden rounded-t-[2rem] bg-[var(--navy)] text-slate-300 shadow-[0_-12px_48px_rgba(15,23,42,0.12)]">
-      <div
-        className="pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-amber-400/40 to-transparent"
-        aria-hidden
-      />
-      <div className="from-background absolute -top-px left-0 right-0 h-8 bg-gradient-to-b to-transparent opacity-90" />
+    <footer className="relative mt-auto overflow-hidden rounded-t-[2.5rem] border-t border-white/5 bg-[#0a1120] text-slate-300 shadow-[0_-20px_50px_rgba(0,0,0,0.5)]">
+      {/* 底部沉浸式光晕装饰 */}
+      <div className="pointer-events-none absolute left-1/2 top-0 h-[300px] w-[800px] -translate-x-1/2 rounded-full bg-[#b89458]/10 blur-[120px]" />
+      <div className="pointer-events-none absolute left-0 top-0 h-[1px] w-full bg-gradient-to-r from-transparent via-[#b89458]/30 to-transparent" />
 
-      <div className="site-container section-block-compact relative pb-16 pt-10 sm:pb-10 sm:pt-12">
-        <div className="grid gap-8 lg:grid-cols-4 lg:gap-10">
-          <div className="lg:col-span-1">
-            <p className="font-serif text-xl font-bold text-white">金策弘论社</p>
-            <p className="mt-3 text-sm leading-relaxed text-slate-400">{t("tagline")}</p>
-            <p className="mt-5 text-xs text-slate-500">{t("rights", { year })}</p>
-            <LocaleSwitcher />
+      <div className="site-container relative z-10 pb-16 pt-16 sm:pb-12 sm:pt-20">
+        <div className="grid gap-12 lg:grid-cols-4 lg:gap-10">
+          
+          {/* 左侧:品牌与版权 */}
+          <div className="lg:col-span-1 flex flex-col h-full">
+            <div className="flex items-center gap-3">
+              <div className="h-6 w-1.5 rounded-full bg-gradient-to-b from-[#f3deae] to-[#b89458]" />
+              <p className="font-serif text-2xl font-bold text-white tracking-wide">金策弘论社</p>
+            </div>
+            <p className="mt-4 text-sm leading-relaxed text-slate-400 font-medium">
+              {t("tagline")}
+            </p>
+            
+            <div className="mt-auto pt-8">
+              <div className="mb-6">
+                <LocaleSwitcher />
+              </div>
+              <p className="text-xs font-medium text-slate-500 tracking-wide uppercase">
+                {t("rights", { year })}
+              </p>
+            </div>
           </div>
-          <div className="grid grid-cols-3 gap-5 border-t border-white/10 pt-6 lg:col-span-3 lg:border-0 lg:pt-0">
+
+          {/* 右侧:链接矩阵 */}
+          <div className="grid grid-cols-2 gap-8 border-t border-white/5 pt-8 sm:grid-cols-3 lg:col-span-3 lg:border-0 lg:pt-0 lg:pl-10">
+            
+            {/* 快速导航 */}
             <div>
-              <p className="text-xs font-bold uppercase tracking-[0.15em] text-amber-400/90">
+              <p className="text-[11px] font-bold uppercase tracking-[0.2em] text-[#b89458] mb-5">
                 {t("quick")}
               </p>
-              <ul className="mt-3 space-y-2.5 text-sm">
+              <ul className="space-y-3.5 text-sm font-medium">
                 <li>
-                  <Link href="/courses" className="transition hover:text-white">
+                  <Link href="/courses" className="text-slate-400 transition-colors hover:text-[#f3deae]">
                     {tc("title")}
                   </Link>
                 </li>
                 <li>
-                  <Link href="/faq" className="transition hover:text-white">
+                  <Link href="/faq" className="text-slate-400 transition-colors hover:text-[#f3deae]">
                     {t("faq")}
                   </Link>
                 </li>
                 <li>
-                  <Link href="/purchase-guarantee" className="transition hover:text-white">
+                  <Link href="/purchase-guarantee" className="text-slate-400 transition-colors hover:text-[#f3deae]">
                     {t("guarantee")}
                   </Link>
                 </li>
                 <li>
-                  <Link href="/contact" className="transition hover:text-white">
+                  <Link href="/contact" className="text-slate-400 transition-colors hover:text-[#f3deae]">
                     {t("contactUs")}
                   </Link>
                 </li>
               </ul>
             </div>
+
+            {/* 法律条款 */}
             <div>
-              <p className="text-xs font-bold uppercase tracking-[0.15em] text-amber-400/90">
+              <p className="text-[11px] font-bold uppercase tracking-[0.2em] text-[#b89458] mb-5">
                 {t("legal")}
               </p>
-              <ul className="mt-3 space-y-2.5 text-sm">
+              <ul className="space-y-3.5 text-sm font-medium">
                 <li>
-                  <Link href="/legal/terms" className="transition hover:text-white">
+                  <Link href="/legal/terms" className="text-slate-400 transition-colors hover:text-[#f3deae]">
                     {t("terms")}
                   </Link>
                 </li>
                 <li>
-                  <Link href="/legal/privacy" className="transition hover:text-white">
+                  <Link href="/legal/privacy" className="text-slate-400 transition-colors hover:text-[#f3deae]">
                     {t("privacy")}
                   </Link>
                 </li>
                 <li>
-                  <Link href="/legal/copyright" className="transition hover:text-white">
+                  <Link href="/legal/copyright" className="text-slate-400 transition-colors hover:text-[#f3deae]">
                     {t("copyright")}
                   </Link>
                 </li>
               </ul>
             </div>
-            <div>
-              <p className="text-xs font-bold uppercase tracking-[0.15em] text-amber-400/90">
+
+            {/* 联系我们 */}
+            <div className="col-span-2 sm:col-span-1">
+              <p className="text-[11px] font-bold uppercase tracking-[0.2em] text-[#b89458] mb-5">
                 {t("contact")}
               </p>
-              <p className="mt-3 text-sm leading-relaxed text-slate-400">
-                {t("phone")}
-                <br />
-                <span className="text-slate-200">{t("phoneValue")}</span>
-              </p>
-              <p className="mt-3 text-sm leading-relaxed text-slate-400">
-                {t("email")}
-                <br />
-                <a
-                  href={`mailto:${t("emailValue")}`}
-                  className="break-all text-slate-200 underline-offset-2 transition hover:text-white hover:underline"
-                >
-                  {t("emailValue")}
-                </a>
-              </p>
+              
+              <div className="space-y-5">
+                <div>
+                  <p className="text-xs text-slate-500 mb-1.5">{t("phone")}</p>
+                  <p className="text-sm font-bold text-white tracking-wide">
+                    {t("phoneValue")}
+                  </p>
+                </div>
+                
+                <div>
+                  <p className="text-xs text-slate-500 mb-1.5">{t("email")}</p>
+                  <a
+                    href={`mailto:${t("emailValue")}`}
+                    className="inline-block text-sm font-bold text-white break-all transition-colors hover:text-[#f3deae]"
+                  >
+                    {t("emailValue")}
+                  </a>
+                </div>
+              </div>
             </div>
+
           </div>
         </div>
       </div>
     </footer>
   );
-}
+}

+ 189 - 52
src/components/site-header.tsx

@@ -8,6 +8,7 @@ import { COURSE_CATEGORIES } from "@/data/courses";
 import type { UserSession } from "@/lib/auth-types";
 import { useAuth } from "@/providers/auth-provider";
 import { IconSpark } from "@/components/icons";
+import { fetchCustomUserInfo, updateUserInfo } from "@/lib/user-info-api";
 
 function avatarInitial(name: string): string {
   const trimmed = name.trim();
@@ -19,9 +20,11 @@ function avatarInitial(name: string): string {
 function UserAvatarMenu({
   user,
   onLogout,
+  onEditInfo,
 }: {
   user: UserSession;
   onLogout: () => void;
+  onEditInfo: () => void;
 }) {
   const t = useTranslations("nav");
   const ta = useTranslations("account");
@@ -71,13 +74,24 @@ function UserAvatarMenu({
           >
             {t("accountSettings")}
           </Link>
+          <button
+            type="button"
+            role="menuitem"
+            className="w-full px-4 py-2.5 text-left text-sm font-medium text-slate-800 transition hover:bg-slate-50"
+            onClick={() => {
+              setMenuOpen(false);
+              onEditInfo();
+            }}
+          >
+            修改信息
+          </button>
           <Link
             href="/account/withdraw-apply"
             role="menuitem"
             className="block px-4 py-2.5 text-sm font-medium text-slate-800 transition hover:bg-slate-50"
             onClick={() => setMenuOpen(false)}
           >
-            提款申请
+            领取申请
           </Link>
           <div className="my-0.5 border-t border-slate-100" aria-hidden />
           <button
@@ -103,7 +117,14 @@ export function SiteHeader() {
   const ta = useTranslations("account");
   const [open, setOpen] = useState(false);
   const [mega, setMega] = useState<string | null>(null);
-  const { user, logout, isReady } = useAuth();
+  const { user, logout, isReady, updateProfile } = useAuth();
+  const [editInfoOpen, setEditInfoOpen] = useState(false);
+  const [editName, setEditName] = useState("");
+  const [editPhone, setEditPhone] = useState("");
+  const [editIdentity, setEditIdentity] = useState("");
+  const [editSubmitting, setEditSubmitting] = useState(false);
+  const [editError, setEditError] = useState<string | null>(null);
+  const [logoutConfirmOpen, setLogoutConfirmOpen] = useState(false);
   const handleLogout = () => {
     logout();
     if (typeof window !== "undefined") {
@@ -111,6 +132,48 @@ export function SiteHeader() {
     }
   };
 
+  const openEditInfo = () => {
+    if (!user) return;
+    setEditError(null);
+    setEditName(user.name ?? "");
+    setEditPhone(user.phone ?? "");
+    setEditIdentity(user.identity ?? "");
+    setEditInfoOpen(true);
+  };
+
+  const closeEditInfo = () => {
+    setEditInfoOpen(false);
+    setEditSubmitting(false);
+    setEditError(null);
+  };
+
+  const submitEditInfo = async () => {
+    const name = editName.trim();
+    const phone = editPhone.trim();
+    const identity = editIdentity.trim();
+    if (!name) {
+      setEditError("请输入姓名");
+      return;
+    }
+    setEditSubmitting(true);
+    setEditError(null);
+    try {
+      await updateUserInfo({ name, phone, identity });
+      const info = await fetchCustomUserInfo();
+      updateProfile({
+        name: info.name || name,
+        phone: info.phone || phone,
+        identity: info.identity || identity,
+      });
+      closeEditInfo();
+      if (typeof window !== "undefined") window.location.reload();
+    } catch (e) {
+      setEditError((e as Error)?.message || "修改失败,请稍后重试");
+    } finally {
+      setEditSubmitting(false);
+    }
+  };
+
   useEffect(() => {
     document.body.style.overflow = open ? "hidden" : "";
     return () => {
@@ -189,60 +252,25 @@ export function SiteHeader() {
               )}
             </div>
 
-            <div
-              className="relative"
-              onMouseEnter={() => setMega("about")}
-              onMouseLeave={() => setMega(null)}
+            <Link
+              href="/courses"
+              className="rounded-xl px-4 py-2.5 text-sm font-semibold text-slate-600 transition hover:bg-slate-50 hover:text-[var(--navy)]"
             >
-              <button
-                type="button"
-                className={cn(
-                  "rounded-xl px-4 py-2.5 text-sm font-semibold transition",
-                  mega === "about"
-                    ? "bg-blue-50 text-blue-800"
-                    : "text-slate-600 hover:bg-slate-50 hover:text-[var(--navy)]",
-                )}
-              >
-                {t("about")}
-              </button>
-              {mega === "about" && (
-                <div className="absolute left-0 top-full z-20 pt-2">
-                  <div className="min-w-[200px] rounded-2xl border border-slate-100 bg-white py-2 shadow-xl shadow-slate-900/10 ring-1 ring-slate-900/5">
-                    <Link
-                      href="/about#ip"
-                      className="block px-4 py-2.5 text-sm font-medium text-slate-700 hover:bg-blue-50/80"
-                    >
-                      {t("aboutSub.ip")}
-                    </Link>
-                    <Link
-                      href="/about#philosophy"
-                      className="block px-4 py-2.5 text-sm font-medium text-slate-700 hover:bg-blue-50/80"
-                    >
-                      {t("aboutSub.philosophy")}
-                    </Link>
-                    <Link
-                      href="/about#media"
-                      className="block px-4 py-2.5 text-sm font-medium text-slate-700 hover:bg-blue-50/80"
-                    >
-                      {t("aboutSub.media")}
-                    </Link>
-                  </div>
-                </div>
-              )}
-            </div>
+              {t("purchase")}
+            </Link>
 
             <Link
-              href="/faq"
+              href="/about"
               className="rounded-xl px-4 py-2.5 text-sm font-semibold text-slate-600 transition hover:bg-slate-50 hover:text-[var(--navy)]"
             >
-              {t("faq")}
+              {t("about")}
             </Link>
 
             <Link
-              href="/courses"
+              href="/faq"
               className="rounded-xl px-4 py-2.5 text-sm font-semibold text-slate-600 transition hover:bg-slate-50 hover:text-[var(--navy)]"
             >
-              {t("purchase")}
+              {t("faq")}
             </Link>
             <Link
               href="/account"
@@ -259,7 +287,11 @@ export function SiteHeader() {
                 aria-hidden
               />
             ) : user ? (
-              <UserAvatarMenu user={user} onLogout={handleLogout} />
+              <UserAvatarMenu
+                user={user}
+                onLogout={() => setLogoutConfirmOpen(true)}
+                onEditInfo={openEditInfo}
+              />
             ) : (
               <>
                 <Link
@@ -291,6 +323,79 @@ export function SiteHeader() {
         </div>
 
       </div>
+      {editInfoOpen && (
+        <div className="fixed inset-0 z-[95] flex items-center justify-center bg-slate-900/45 p-4 backdrop-blur-[2px]">
+          <div className="w-full max-w-md overflow-hidden rounded-3xl bg-white shadow-2xl ring-1 ring-slate-900/10">
+            <div className="flex items-center justify-between border-b border-slate-200 px-6 py-4">
+              <h3 className="text-base font-bold text-[var(--navy)]">修改信息</h3>
+              <button
+                type="button"
+                className="h-9 w-9 rounded-full text-xl leading-none text-slate-600 transition hover:bg-slate-100"
+                aria-label="Close"
+                onClick={closeEditInfo}
+                disabled={editSubmitting}
+              >
+                ×
+              </button>
+            </div>
+            <div className="px-6 py-5">
+              {editError ? (
+                <div className="mb-4 rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm font-medium text-rose-700">
+                  {editError}
+                </div>
+              ) : null}
+
+              <div className="space-y-4">
+                <div>
+                  <label className="text-sm font-semibold text-slate-700">姓名</label>
+                  <input
+                    value={editName}
+                    onChange={(e) => setEditName(e.target.value)}
+                    className="mt-2 w-full rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition focus:border-blue-300 focus:ring-2 focus:ring-blue-100"
+                    placeholder="请输入姓名"
+                  />
+                </div>
+                <div>
+                  <label className="text-sm font-semibold text-slate-700">手机号</label>
+                  <input
+                    value={editPhone}
+                    onChange={(e) => setEditPhone(e.target.value)}
+                    className="mt-2 w-full rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition focus:border-blue-300 focus:ring-2 focus:ring-blue-100"
+                    placeholder="请输入手机号"
+                  />
+                </div>
+                <div>
+                  <label className="text-sm font-semibold text-slate-700">证件号</label>
+                  <input
+                    value={editIdentity}
+                    onChange={(e) => setEditIdentity(e.target.value)}
+                    className="mt-2 w-full rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 outline-none transition focus:border-blue-300 focus:ring-2 focus:ring-blue-100"
+                    placeholder="请输入证件号"
+                  />
+                </div>
+              </div>
+            </div>
+            <div className="flex gap-3 border-t border-slate-200 bg-slate-50 px-6 py-4">
+              <button
+                type="button"
+                className="flex-1 rounded-xl border border-slate-200 bg-white py-3 text-sm font-semibold text-slate-800 transition hover:bg-slate-100 disabled:opacity-50"
+                onClick={closeEditInfo}
+                disabled={editSubmitting}
+              >
+                取消
+              </button>
+              <button
+                type="button"
+                className="flex-1 rounded-xl bg-blue-600 py-3 text-sm font-semibold text-white shadow-sm transition hover:bg-blue-700 disabled:opacity-50"
+                onClick={submitEditInfo}
+                disabled={editSubmitting}
+              >
+                {editSubmitting ? "提交中..." : "确认修改"}
+              </button>
+            </div>
+          </div>
+        </div>
+      )}
       <div
         className={cn(
           "fixed inset-0 z-[90] lg:hidden",
@@ -337,11 +442,10 @@ export function SiteHeader() {
               </Link>
               <Link
                 href="/about"
-                className="flex items-center justify-between border-b border-slate-200/90 py-3 text-2xl font-semibold leading-snug text-slate-900 transition-colors hover:text-blue-700"
+                className="border-b border-slate-200/90 py-3 text-2xl font-semibold leading-snug text-slate-900 transition-colors hover:text-blue-700"
                 onClick={() => setOpen(false)}
               >
-                <span>{t("about")}</span>
-                <span className="text-xl text-slate-400">+</span>
+                {t("about")}
               </Link>
               <Link
                 href="/faq"
@@ -384,14 +488,14 @@ export function SiteHeader() {
                     className="rounded-xl border border-slate-200 py-3 text-center text-sm font-semibold text-slate-800 transition hover:bg-slate-50"
                     onClick={() => setOpen(false)}
                   >
-                    提款申请
+                    领取申请
                   </Link>
                   <button
                     type="button"
                     className="rounded-xl bg-slate-800 py-3 text-center text-sm font-semibold text-white transition hover:bg-slate-900"
                     onClick={() => {
                       setOpen(false);
-                      handleLogout();
+                      setLogoutConfirmOpen(true);
                     }}
                   >
                     {ta("logout")}
@@ -418,6 +522,39 @@ export function SiteHeader() {
             </div>
           </aside>
       </div>
+
+      {logoutConfirmOpen && (
+        <div className="fixed inset-0 z-[98] flex items-center justify-center bg-slate-900/45 p-4 backdrop-blur-[2px]">
+          <div className="w-full max-w-sm overflow-hidden rounded-3xl bg-white shadow-2xl ring-1 ring-slate-900/10">
+            <div className="px-6 py-6 text-center">
+              <h3 className="text-lg font-bold text-[var(--navy)]">确认退出登录?</h3>
+              <p className="mt-2 text-sm font-medium text-slate-500">
+                退出后将清空本地缓存信息。
+              </p>
+            </div>
+            <div className="flex gap-3 border-t border-slate-200 bg-slate-50 px-6 py-4">
+              <button
+                type="button"
+                className="flex-1 rounded-xl border border-slate-200 bg-white py-3 text-sm font-semibold text-slate-800 transition hover:bg-slate-100"
+                onClick={() => setLogoutConfirmOpen(false)}
+              >
+                取消
+              </button>
+              <button
+                type="button"
+                className="flex-1 rounded-xl bg-slate-900 py-3 text-sm font-semibold text-white transition hover:bg-slate-950"
+                onClick={() => {
+                  setLogoutConfirmOpen(false);
+                  handleLogout();
+                }}
+              >
+                确认退出
+              </button>
+            </div>
+          </div>
+        </div>
+      )}
     </header>
   );
 }
+

+ 15 - 0
src/components/top-loader.tsx

@@ -0,0 +1,15 @@
+"use client";
+
+import NextTopLoader from "nextjs-toploader";
+
+export function TopLoader() {
+  return (
+    <NextTopLoader
+      color="#b89458"
+      height={3}
+      showSpinner={false}
+      zIndex={9999}
+    />
+  );
+}
+

+ 2 - 0
src/lib/auth-types.ts

@@ -17,6 +17,8 @@ import { SPEND_THRESHOLD_USD } from "./quiz-rules";
 export type UserSession = {
   email: string;
   name: string;
+  phone?: string;
+  identity?: string;
   /** ISO:首次累计消费达到门槛的时间(仅本地 Mock) */
   thresholdReachedAt: string | null;
   orders: MockOrder[];

+ 71 - 0
src/lib/balance-record-api.ts

@@ -0,0 +1,71 @@
+import { apiPost } from "@/lib/api";
+
+export type BalanceRecord = {
+  id: string;
+  amount: number;
+  /** 1: 取款 2: 奖励 */
+  type: 1 | 2;
+  addTime: string;
+};
+
+function toNum(value: unknown): number | null {
+  if (typeof value === "number" && Number.isFinite(value)) return value;
+  if (typeof value === "string" && value.trim()) {
+    const n = Number(value);
+    if (Number.isFinite(n)) return n;
+  }
+  return null;
+}
+
+function pickList(raw: unknown): unknown[] {
+  if (!raw || typeof raw !== "object") return [];
+  const o = raw as Record<string, unknown>;
+  const inner = o.data ?? o.list ?? o.rows ?? o.records;
+  if (Array.isArray(inner)) return inner;
+  if (inner && typeof inner === "object") {
+    const x = inner as Record<string, unknown>;
+    if (Array.isArray(x.list)) return x.list;
+    if (Array.isArray(x.records)) return x.records;
+    if (Array.isArray(x.rows)) return x.rows;
+  }
+  return [];
+}
+
+function toBinaryType(value: unknown): 1 | 2 {
+  const n = typeof value === "number" ? value : Number(value);
+  return n === 2 ? 2 : 1;
+}
+
+export async function fetchBalanceRecordList(page?: {
+  current?: number;
+  row?: number;
+}): Promise<BalanceRecord[]> {
+  const current =
+    page?.current !== undefined && Number.isFinite(Number(page.current))
+      ? Math.max(1, Number(page.current))
+      : 1;
+  const row =
+    page?.row !== undefined && Number.isFinite(Number(page.row))
+      ? Math.max(1, Number(page.row))
+      : 20;
+
+  const raw = await apiPost<unknown>("/custom/balance/recoed/search/list", {
+    page: { current, row },
+  });
+
+  const list = pickList(raw);
+  const out: BalanceRecord[] = [];
+  for (const item of list) {
+    if (!item || typeof item !== "object") continue;
+    const o = item as Record<string, unknown>;
+    const id = String(o.id ?? o.serial ?? o.orderNo ?? out.length + 1);
+    out.push({
+      id,
+      amount: toNum(o.amount ?? o.money ?? o.balance) ?? 0,
+      type: toBinaryType(o.type ?? o.recordType ?? o.bizType),
+      addTime: String(o.addTime ?? o.createTime ?? o.time ?? ""),
+    });
+  }
+  return out;
+}
+

+ 41 - 0
src/lib/user-info-api.ts

@@ -0,0 +1,41 @@
+import { apiPost } from "@/lib/api";
+
+export type CustomUserInfo = {
+  name: string;
+  phone: string;
+  identity: string;
+  email?: string;
+};
+
+export async function updateUserInfo(input: {
+  name: string;
+  phone: string;
+  identity: string;
+}): Promise<void> {
+  await apiPost("/custom/update/info", {
+    name: input.name,
+    phone: input.phone,
+    identity: input.identity,
+  });
+}
+
+function pickString(v: unknown): string {
+  return typeof v === "string" ? v.trim() : String(v ?? "").trim();
+}
+
+export async function fetchCustomUserInfo(): Promise<CustomUserInfo> {
+  const raw = await apiPost<unknown>("/custom/info", {});
+  const root = raw && typeof raw === "object" ? (raw as Record<string, unknown>) : {};
+  const data =
+    root.data && typeof root.data === "object" && root.data !== null
+      ? (root.data as Record<string, unknown>)
+      : root;
+
+  return {
+    name: pickString(data.name ?? data.nickname ?? root.name ?? root.nickname),
+    phone: pickString(data.phone ?? data.mobile ?? root.phone ?? root.mobile),
+    identity: pickString(data.identity ?? data.idCard ?? root.identity ?? root.idCard),
+    email: pickString(data.email ?? data.loginName ?? root.email ?? root.loginName) || undefined,
+  };
+}
+

+ 1 - 1
src/lib/withdrawal-api.ts

@@ -57,7 +57,7 @@ export async function fetchWithdrawalList(page: { current: number; row: number }
         : String(statusRaw ?? "处理中").trim() || "处理中";
     const addTime = String(o.addTime ?? o.createTime ?? o.applyTime ?? "");
     const payTime = String(o.payTime ?? o.finishTime ?? o.arrivalTime ?? "");
-    const details = String(o.details ?? o.channelName ?? o.remark ?? "提款申请");
+    const details = String(o.details ?? o.channelName ?? o.remark ?? "领取申请");
     out.push({
       id,
       serial,

+ 39 - 4
src/providers/auth-provider.tsx

@@ -23,6 +23,7 @@ import { ApiError, setApiAuthToken } from "@/lib/api";
 import { loginWithPassword } from "@/lib/auth-api";
 import { isRegisterPasswordValid } from "@/lib/password-rules";
 import { registerWithEmail } from "@/lib/register-api";
+import { fetchCustomUserInfo } from "@/lib/user-info-api";
 
 type AuthContextValue = {
   user: UserSession | null;
@@ -39,7 +40,9 @@ type AuthContextValue = {
     code: string;
   }) => Promise<{ ok: boolean; error?: string; message?: string }>;
   logout: () => void;
-  updateProfile: (patch: Partial<Pick<UserSession, "name" | "scholarship">>) => void;
+  updateProfile: (
+    patch: Partial<Pick<UserSession, "name" | "phone" | "identity" | "scholarship">>,
+  ) => void;
   addMockOrder: (order: Omit<MockOrder, "id" | "createdAt">) => void;
   /** 本地演示:将门槛达成时间设为 181 天前,用于验证问答解锁 */
   demoUnlockQuizCountdown: () => void;
@@ -56,6 +59,8 @@ function newUserSession(
   return {
     email,
     name,
+    phone: "",
+    identity: "",
     thresholdReachedAt,
     orders: seedOrders,
     scholarship: {},
@@ -89,7 +94,19 @@ export function AuthProvider({ children }: { children: ReactNode }) {
           password,
         );
         if (token) setApiAuthToken(token);
-        persist(newUserSession(email.trim(), displayName));
+        const base = newUserSession(email.trim(), displayName);
+        try {
+          const info = await fetchCustomUserInfo();
+          persist({
+            ...base,
+            email: info.email || base.email,
+            name: info.name || base.name,
+            phone: info.phone || base.phone,
+            identity: info.identity || base.identity,
+          });
+        } catch {
+          persist(base);
+        }
         return { ok: true };
       } catch (e) {
         const message = e instanceof ApiError ? e.message : "登录失败";
@@ -128,7 +145,19 @@ export function AuthProvider({ children }: { children: ReactNode }) {
           password: input.password,
         });
         if (token) setApiAuthToken(token);
-        persist(newUserSession(input.email, input.name.trim() || "学员"));
+        const base = newUserSession(input.email.trim(), input.name.trim() || "学员");
+        try {
+          const info = await fetchCustomUserInfo();
+          persist({
+            ...base,
+            email: info.email || base.email,
+            name: info.name || base.name,
+            phone: info.phone || base.phone,
+            identity: info.identity || base.identity,
+          });
+        } catch {
+          persist(base);
+        }
         return { ok: true };
       } catch (e) {
         const message = e instanceof ApiError ? e.message : "注册失败";
@@ -144,12 +173,18 @@ export function AuthProvider({ children }: { children: ReactNode }) {
   }, [persist]);
 
   const updateProfile = useCallback(
-    (patch: Partial<Pick<UserSession, "name" | "scholarship">>) => {
+    (
+      patch: Partial<
+        Pick<UserSession, "name" | "phone" | "identity" | "scholarship">
+      >,
+    ) => {
       if (!user) return;
       persist({
         ...user,
         ...patch,
         name: patch.name ?? user.name,
+        phone: patch.phone ?? user.phone,
+        identity: patch.identity ?? user.identity,
         scholarship: { ...user.scholarship, ...patch.scholarship },
       });
     },