Files
dalcode-website/docs/superpowers/plans/2026-05-23-website-redesign.md
T
2026-05-30 14:00:38 +08:00

81 KiB
Raw Blame History

DAL Website Redesign Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Transform dalcode-website from a single-product Webflow-template site into a product-matrix platform site for DAL Code, DAL CLI, DAL Office, and DeepAILab API Platform.

Architecture: Replace webflow.css (11K lines) with Tailwind utility classes. Keep GSAP for scroll animations, remove Lottie. Remove next-themes (dark-only). Retain next-intl for zh-CN/en bilingual support. All new content goes through i18n message files.

Tech Stack: Next.js 16.2.4, React 19, Tailwind CSS 4, GSAP 3, next-intl 4, React Hook Form + Zod

Key constraint: All copy must be smart, polished, and sophisticated — not generic/cheap-sounding. The user explicitly said "文案一定要智能灵活,不要太 low".

AGENTS.md warning: Next.js 16 may have breaking API changes. Before writing any code, check node_modules/next/dist/docs/ for current conventions. Key findings from review: page.tsx, layout.tsx, not-found.tsx conventions unchanged. middleware is deprecated in favor of proxy.


File Structure

New files

app/
├── globals.css                    (REWRITE — pure Tailwind, no webflow refs)
├── code/page.tsx                  (DAL Code product page)
├── cli/page.tsx                   (DAL CLI product page)
├── office/page.tsx                (DAL Office page)
├── platform/page.tsx              (API Platform page)
├── pricing/page.tsx               (Unified pricing page)

components/
├── Header.tsx                     (REWRITE — new nav with Products dropdown)
├── Footer.tsx                     (REWRITE — 4-column layout)
├── GsapAnimations.tsx             (MODIFY — update selectors for new sections)
├── ScrollReveal.tsx               (NEW — reusable scroll-reveal wrapper)
├── home/
│   ├── HeroSection.tsx            (REWRITE)
│   ├── ProductEcosystem.tsx       (NEW — 2×2 product cards)
│   ├── WorkflowSteps.tsx          (NEW — 3-step Intent/Build/Ship)
│   ├── FeatureGrid.tsx            (NEW — 8-feature grid)
│   ├── EcosystemSection.tsx       (NEW — DeepAILab platform)
│   ├── BottomCta.tsx              (NEW — bottom CTA)
│   ├── FaqSection.tsx             (NEW — accordion FAQ)
│   └── index.ts                   (REWRITE — export new components)

lib/
├── site-content.ts                (REWRITE — new data structures)

Files to delete

app/webflow.css                    (11K lines, replaced by Tailwind)
components/ThemeToggle.tsx         (no more theme switching)
components/LottiePlayer.tsx        (removing Lottie)
components/home/IntegrationsSection.tsx  (replaced by ProductEcosystem)
components/home/PrinciplesSection.tsx    (replaced by WorkflowSteps)
components/home/BlogPreviewSection.tsx   (removed from homepage)
components/home/CtaSection.tsx           (replaced by BottomCta)

Message files to rewrite

messages/zh-CN.json                (full rewrite with new content)
messages/en.json                   (full rewrite with new content)

Task 1: Foundation — Remove webflow.css, set up dark Tailwind base

Files:

  • Delete: app/webflow.css

  • Rewrite: app/globals.css

  • Modify: app/layout.tsx

  • Delete: components/ThemeToggle.tsx

  • Delete: components/LottiePlayer.tsx

  • Step 1: Create the new globals.css

Replace the entire app/globals.css with a Tailwind-first dark theme foundation:

@import "tailwindcss";

@theme {
  --color-bg-primary: #0a0a0a;
  --color-bg-secondary: #111111;
  --color-bg-card: #161616;
  --color-bg-card-hover: #1a1a1a;
  --color-border: #222222;
  --color-border-hover: #333333;
  --color-text-primary: #f0f0f0;
  --color-text-secondary: #a0a0a0;
  --color-text-muted: #666666;
  --color-accent: #6366f1;
  --color-accent-hover: #818cf8;
  --color-accent-glow: rgba(99, 102, 241, 0.15);
  --font-sans: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
  --font-display: var(--font-inter-tight), var(--font-sans);
}

html {
  scroll-behavior: smooth;
}

body {
  @apply bg-bg-primary text-text-primary antialiased;
  font-family: var(--font-sans);
}

::selection {
  @apply bg-accent/30 text-text-primary;
}

/* Scrollbar */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--color-border-hover); }

/* Shared animation classes used by GSAP */
.reveal-up {
  opacity: 0;
  transform: translateY(40px);
}

.reveal-visible {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

/* Glow effect for cards */
.card-glow {
  position: relative;
}
.card-glow::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, transparent, var(--color-accent-glow), transparent);
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.card-glow:hover::before {
  opacity: 1;
}

/* Stagger children animation delay */
.stagger-children > * {
  opacity: 0;
  transform: translateY(20px);
}
  • Step 2: Update layout.tsx — remove webflow.css, ThemeProvider, Lottie

Replace app/layout.tsx:

import type { Metadata } from "next"
import { Inter, Inter_Tight } from "next/font/google"
import { NextIntlClientProvider } from "next-intl"
import { getLocale, getMessages } from "next-intl/server"
import Header from "@/components/Header"
import Footer from "@/components/Footer"
import GsapAnimations from "@/components/GsapAnimations"
import { SITE_BRAND, SITE_DESCRIPTION, SITE_NAME } from "@/lib/site-content"
import "./globals.css"

const inter = Inter({
  subsets: ["latin"],
  weight: ["400", "500", "600", "700"],
  variable: "--font-inter",
  display: "swap",
})

const interTight = Inter_Tight({
  subsets: ["latin"],
  weight: ["400", "500", "600", "700"],
  variable: "--font-inter-tight",
  display: "swap",
})

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000"

export const metadata: Metadata = {
  metadataBase: new URL(SITE_URL),
  title: {
    default: SITE_BRAND,
    template: `%s | ${SITE_NAME}`,
  },
  description: SITE_DESCRIPTION,
  icons: {
    icon: "/favicon.ico",
    apple: "/assets/dalcode-app-icon-192.png",
  },
  openGraph: {
    type: "website",
    siteName: SITE_BRAND,
    title: SITE_BRAND,
    description: SITE_DESCRIPTION,
  },
}

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  const locale = await getLocale()
  const messages = await getMessages()

  return (
    <NextIntlClientProvider locale={locale} messages={messages}>
      <html
        lang={locale}
        className={`${inter.variable} ${interTight.variable}`}
      >
        <body className={inter.className}>
          <Header />
          <main>{children}</main>
          <Footer />
          <GsapAnimations />
        </body>
      </html>
    </NextIntlClientProvider>
  )
}
  • Step 3: Delete obsolete files
rm app/webflow.css
rm components/ThemeToggle.tsx
rm components/LottiePlayer.tsx
rm components/RevealObserver.tsx
rm components/PageTransition.tsx
  • Step 4: Verify build compiles
cd /Users/leon/本地开发项目/claude-code/dalcode-website && npx next build 2>&1 | tail -20

Expected: Build may fail due to import references in other files. That's OK — we'll fix them in subsequent tasks. The goal here is that globals.css and layout.tsx are correct.

  • Step 5: Commit
git add -A
git commit -m "chore: remove webflow.css and theme toggle, set up dark Tailwind foundation"

Task 2: i18n Content — Rewrite all message files

Files:

  • Rewrite: messages/zh-CN.json
  • Rewrite: messages/en.json

The copy below is the heart of the redesign. Every string must be polished — no filler, no "lorem ipsum energy".

  • Step 1: Write zh-CN.json
{
  "site": {
    "name": "DAL",
    "brand": "DAL by DeepAILab",
    "tagline": "The Open AI Development Platform",
    "description": "从想法到产品的完整 AI 开发平台。自由选模型,全链路覆盖,一个账号搞定一切。"
  },
  "nav": {
    "products": "产品",
    "docs": "文档",
    "pricing": "定价",
    "blog": "博客",
    "community": "社区",
    "downloads": "下载",
    "signIn": "登录",
    "toggleMenu": "切换菜单",
    "productItems": {
      "code": { "name": "DAL Code", "tagline": "AI 原生开发环境" },
      "cli": { "name": "DAL CLI", "tagline": "终端里的 AI 搭档" },
      "office": { "name": "DAL Office", "tagline": "AI 文档工作台" },
      "platform": { "name": "API Platform", "tagline": "统一 AI 开发者平台" }
    }
  },
  "hero": {
    "badge": "by DeepAILab",
    "headline": "开放的 AI 开发平台",
    "subheadline": "从想法到产品,自由选模型,从代码到文档全覆盖。一个账号,完整生态。",
    "ctaPrimary": "下载 DAL Code",
    "ctaSecondary": "安装 CLI",
    "cliCommand": "curl -fsSL https://cli.deepailab.ai/install | bash"
  },
  "ecosystem": {
    "label": "PRODUCT ECOSYSTEM",
    "title": "一个平台,覆盖 AI 开发全场景",
    "products": {
      "code": {
        "name": "DAL Code",
        "tagline": "AI 原生开发环境",
        "description": "不只是写代码的编辑器,而是从需求澄清到工程交付的完整工作台。",
        "features": ["Intent Capture", "Mission Mode", "多模型路由"],
        "cta": "了解 DAL Code"
      },
      "cli": {
        "name": "DAL CLI",
        "tagline": "终端里的 AI 开发搭档",
        "description": "轻量、快速、管道友好。在终端里完成从 Agent 任务到代码交付的全流程。",
        "features": ["Agent 执行", "管道集成", "轻量高速"],
        "cta": "了解 DAL CLI"
      },
      "office": {
        "name": "DAL Office",
        "tagline": "AI 驱动的文档工作台",
        "description": "用 AI 生成和编辑文档、表格、演示文稿——开发者的工作不只有代码。",
        "features": ["Word", "Excel", "PPT"],
        "cta": "了解 DAL Office"
      },
      "platform": {
        "name": "API Platform",
        "tagline": "统一 AI 开发者平台",
        "description": "模型聚合、智能路由、成本优化——所有 DAL 产品背后的基础设施。",
        "features": ["模型聚合", "智能路由", "API 折扣"],
        "cta": "探索平台"
      }
    }
  },
  "workflow": {
    "label": "HOW IT WORKS",
    "title": "不是更好的 prompt,是更好的工作方式",
    "steps": {
      "intent": {
        "number": "01",
        "name": "INTENT",
        "title": "先把需求想清楚",
        "description": "AI 主动采访你,用结构化问题把模糊想法变成可执行的工程需求——不是等你写出完美的 prompt。"
      },
      "build": {
        "number": "02",
        "name": "BUILD",
        "title": "智能拆解,并行执行",
        "description": "Agent 自动分解任务,为每个子任务选择最优模型,多线并行推进——你监督方向,它负责落地。"
      },
      "ship": {
        "number": "03",
        "name": "SHIP",
        "title": "代码、测试、文档一起交付",
        "description": "不只是输出代码片段。测试、文档同步生成,关键操作需要你的审批,结果全程可追溯。"
      }
    }
  },
  "features": {
    "label": "EVERYTHING YOU NEED",
    "title": "为认真做产品的开发者而建",
    "items": {
      "routing": {
        "title": "多模型智能路由",
        "description": "同一工作流里,不同子任务自动匹配最优模型。质量、速度、成本不再是单选题。"
      },
      "skills": {
        "title": "Skills 引擎",
        "description": "把工程经验封装成可复用的引导式工作流。不是 prompt 模板,是方法论的产品化。"
      },
      "mission": {
        "title": "Mission Mode",
        "description": "复杂任务自动拆解,进度实时可见,断点可续跑。长任务终于不再是黑盒。"
      },
      "byok": {
        "title": "自带 API Key",
        "description": "用你自己的 API Key 接入任何模型。不被平台绑定,完全掌控成本和数据流向。"
      },
      "context": {
        "title": "上下文引擎",
        "description": "五层智能压缩,让百万行项目也能保持上下文连贯。大项目不再是 AI 的盲区。"
      },
      "audit": {
        "title": "审批与审计",
        "description": "危险操作需人工确认,每一步操作可追溯可审计。给个人效率,给团队安全感。"
      },
      "rag": {
        "title": "知识库接入",
        "description": "连接你的私有文档和知识库,AI 的回答基于你的真实上下文,而不是通用训练数据。"
      },
      "cost": {
        "title": "成本透明化",
        "description": "每次 AI 交互的成本实时可见。花了多少、省了多少,用数据说话。"
      }
    }
  },
  "platform": {
    "label": "ONE PLATFORM, ONE ACCOUNT",
    "title": "DeepAILab — 连接一切的 AI 开发者平台",
    "advantages": {
      "account": {
        "title": "一个账号",
        "description": "登录一次,Code、CLI、Office、API Platform 全部打通。无缝切换,统一管理。"
      },
      "discount": {
        "title": "API 折扣",
        "description": "通过平台调用主流模型,费率优于直连。用得越多,省得越多。"
      },
      "dashboard": {
        "title": "成本仪表盘",
        "description": "跨产品的用量统计和成本拆解,一目了然。告别月底账单惊喜。"
      }
    },
    "cta": "探索 DeepAILab 平台"
  },
  "bottomCta": {
    "headline": "准备好用新方式开发了吗?",
    "subheadline": "从一次 Intent 采访开始,让 AI 先帮你想清楚要做什么。",
    "ctaPrimary": "下载 DAL Code",
    "ctaSecondary": "安装 CLI"
  },
  "faq": {
    "label": "FAQ",
    "title": "常见问题",
    "items": {
      "vsCursor": {
        "q": "DAL Code 和 Cursor / Windsurf 有什么不同?",
        "a": "Cursor 和 Windsurf 的核心是让你写更好的代码。DAL Code 的起点更早——它先帮你把需求想清楚,再把任务拆解、执行和交付。同时,DAL 不绑定单一模型,支持多模型智能路由和自带 API Key。"
      },
      "vsClaude": {
        "q": "DAL CLI 和 Claude Code CLI 有什么不同?",
        "a": "Claude Code 绑定 Anthropic 模型生态。DAL CLI 支持多模型路由,可以用你自己的 API Key,并且和 DAL Code、DAL Office 共享同一个账号和工作流体系。"
      },
      "byok": {
        "q": "我可以用自己的 API Key 吗?",
        "a": "可以。DAL 支持接入你自己的 API Key,包括 OpenAI、Anthropic、Google 等主流提供商。你也可以使用 DeepAILab 平台提供的 API 折扣。"
      },
      "apiDiscount": {
        "q": "DeepAILab API 折扣怎么计算?",
        "a": "通过 DeepAILab 平台统一调用模型 API,费率低于各厂商直连价格。具体折扣取决于用量层级,详见定价页面。"
      },
      "models": {
        "q": "支持哪些 AI 模型?",
        "a": "支持 Claude (Opus/Sonnet/Haiku)、GPT 系列、Gemini 系列等 20+ 主流模型,并持续接入新模型。Smart Routing 会根据任务类型自动选择最合适的模型。"
      },
      "enterprise": {
        "q": "支持企业私有化部署吗?",
        "a": "私有化部署、SSO、审计日志和自定义安全策略是产品路线的重点方向。如果你的团队有明确需求,欢迎联系我们从一个具体场景开始落地。"
      }
    }
  },
  "footer": {
    "newsletter": {
      "placeholder": "输入邮箱,订阅产品动态",
      "submit": "订阅",
      "success": "已订阅。",
      "error": "订阅失败,请重试。"
    },
    "groups": {
      "products": "产品",
      "resources": "资源",
      "community": "社区",
      "company": "公司"
    },
    "links": {
      "code": "DAL Code",
      "cli": "DAL CLI",
      "office": "DAL Office",
      "apiPlatform": "API Platform",
      "pricing": "定价",
      "docs": "文档",
      "blog": "博客",
      "changelog": "更新日志",
      "faq": "FAQ",
      "discord": "Discord",
      "github": "GitHub",
      "twitter": "X / Twitter",
      "about": "关于",
      "careers": "加入我们",
      "contact": "联系"
    },
    "copyright": "© 2026 DeepAILab. All rights reserved.",
    "privacy": "隐私政策",
    "terms": "服务条款"
  },
  "codePage": {
    "hero": {
      "label": "DAL CODE",
      "headline": "不只是编辑器,是 AI 工程工作台",
      "subheadline": "从需求采访到代码交付,一个工作台覆盖完整开发流程。Intent Capture 让 AI 先帮你想清楚要做什么,Mission Mode 让复杂任务自动拆解执行。",
      "cta": "下载 DAL Code"
    }
  },
  "cliPage": {
    "hero": {
      "label": "DAL CLI",
      "headline": "终端里的 AI 开发搭档",
      "subheadline": "轻量、快速、管道友好。在你熟悉的终端环境里,用 Agent 完成从需求到代码的全流程。",
      "cta": "安装 DAL CLI",
      "cliCommand": "curl -fsSL https://cli.deepailab.ai/install | bash"
    }
  },
  "officePage": {
    "hero": {
      "label": "DAL OFFICE",
      "headline": "AI 驱动的文档工作台",
      "subheadline": "开发者的工作不只有代码。用 AI 生成和编辑 Word 文档、Excel 表格、PPT 演示文稿——和 DAL Code 无缝协作。",
      "cta": "了解 DAL Office"
    }
  },
  "platformPage": {
    "hero": {
      "label": "API PLATFORM",
      "headline": "所有 DAL 产品背后的 AI 基础设施",
      "subheadline": "模型聚合、智能路由、成本优化、用量分析——一个平台,为所有 AI 开发场景提供统一的基础能力。",
      "cta": "探索 API Platform"
    }
  },
  "pricingPage": {
    "hero": {
      "label": "PRICING",
      "headline": "简单透明的定价",
      "subheadline": "从个人开发者到企业团队,选择适合你的方案。"
    }
  },
  "about": {
    "hero": {
      "label": "ABOUT",
      "headline": "我们在构建下一代 AI 开发基础设施",
      "subheadline": "DeepAILab 相信 AI 开发工具应该是开放的、可组合的、为开发者真正服务的。"
    }
  },
  "contact": {
    "hero": {
      "label": "CONTACT",
      "headline": "和我们聊聊你的真实场景",
      "subheadline": "无论是产品试用、企业方案还是生态合作,从一个具体场景开始。"
    }
  },
  "blog": {
    "hero": {
      "label": "BLOG",
      "headline": "产品思考与工程实践",
      "subheadline": "关于 AI 开发工具、多模型路由、工程工作流的深度内容。"
    }
  },
  "common": {
    "learnMore": "了解更多",
    "getStarted": "开始使用",
    "comingSoon": "即将推出",
    "backToHome": "返回首页"
  }
}
  • Step 2: Write en.json
{
  "site": {
    "name": "DAL",
    "brand": "DAL by DeepAILab",
    "tagline": "The Open AI Development Platform",
    "description": "The complete AI development platform. Choose your models, cover the full workflow, one account for everything."
  },
  "nav": {
    "products": "Products",
    "docs": "Docs",
    "pricing": "Pricing",
    "blog": "Blog",
    "community": "Community",
    "downloads": "Downloads",
    "signIn": "Sign In",
    "toggleMenu": "Toggle menu",
    "productItems": {
      "code": { "name": "DAL Code", "tagline": "AI-native development environment" },
      "cli": { "name": "DAL CLI", "tagline": "Your AI partner in the terminal" },
      "office": { "name": "DAL Office", "tagline": "AI-powered document workspace" },
      "platform": { "name": "API Platform", "tagline": "Unified AI developer platform" }
    }
  },
  "hero": {
    "badge": "by DeepAILab",
    "headline": "The Open AI Development Platform",
    "subheadline": "From idea to production. Choose your models, cover the full workflow from code to docs. One account, complete ecosystem.",
    "ctaPrimary": "Download DAL Code",
    "ctaSecondary": "Install CLI",
    "cliCommand": "curl -fsSL https://cli.deepailab.ai/install | bash"
  },
  "ecosystem": {
    "label": "PRODUCT ECOSYSTEM",
    "title": "One platform, every AI development scenario",
    "products": {
      "code": {
        "name": "DAL Code",
        "tagline": "AI-native development environment",
        "description": "More than a code editor — a complete workspace from requirements clarification to engineering delivery.",
        "features": ["Intent Capture", "Mission Mode", "Multi-model Routing"],
        "cta": "Explore DAL Code"
      },
      "cli": {
        "name": "DAL CLI",
        "tagline": "Your AI development partner in the terminal",
        "description": "Lightweight, fast, pipeline-friendly. Run agent tasks and ship code from your terminal.",
        "features": ["Agent Execution", "Pipeline Integration", "Lightweight"],
        "cta": "Explore DAL CLI"
      },
      "office": {
        "name": "DAL Office",
        "tagline": "AI-powered document workspace",
        "description": "Generate and edit documents, spreadsheets, and presentations with AI — because developers do more than write code.",
        "features": ["Word", "Excel", "PPT"],
        "cta": "Explore DAL Office"
      },
      "platform": {
        "name": "API Platform",
        "tagline": "Unified AI developer platform",
        "description": "Model aggregation, smart routing, cost optimization — the infrastructure behind every DAL product.",
        "features": ["Model Aggregation", "Smart Routing", "API Discounts"],
        "cta": "Explore Platform"
      }
    }
  },
  "workflow": {
    "label": "HOW IT WORKS",
    "title": "Not a better prompt. A better workflow.",
    "steps": {
      "intent": {
        "number": "01",
        "name": "INTENT",
        "title": "Clarify what you're building",
        "description": "AI interviews you with structured questions, turning vague ideas into actionable engineering requirements — no perfect prompt needed."
      },
      "build": {
        "number": "02",
        "name": "BUILD",
        "title": "Decompose and execute in parallel",
        "description": "Agents break down tasks, select the optimal model for each subtask, and execute in parallel — you steer, they build."
      },
      "ship": {
        "number": "03",
        "name": "SHIP",
        "title": "Code, tests, and docs — delivered together",
        "description": "Not just code snippets. Tests and documentation generated in sync, critical actions require your approval, full audit trail."
      }
    }
  },
  "features": {
    "label": "EVERYTHING YOU NEED",
    "title": "Built for developers who ship",
    "items": {
      "routing": {
        "title": "Multi-model Smart Routing",
        "description": "Each subtask automatically matched to the optimal model. Quality, speed, and cost are no longer trade-offs."
      },
      "skills": {
        "title": "Skills Engine",
        "description": "Engineering experience packaged as reusable guided workflows. Not prompt templates — methodology as a product."
      },
      "mission": {
        "title": "Mission Mode",
        "description": "Complex tasks decomposed automatically, progress visible in real time, resume from any breakpoint."
      },
      "byok": {
        "title": "Bring Your Own Key",
        "description": "Connect your own API keys from any provider. No vendor lock-in, full control over cost and data flow."
      },
      "context": {
        "title": "Context Engine",
        "description": "Five-layer intelligent compression keeps context coherent across million-line projects."
      },
      "audit": {
        "title": "Approval & Audit",
        "description": "Critical actions require human confirmation. Every step traceable, every decision auditable."
      },
      "rag": {
        "title": "Knowledge Integration",
        "description": "Connect your private docs and knowledge bases. AI answers grounded in your real context, not generic training data."
      },
      "cost": {
        "title": "Cost Transparency",
        "description": "Real-time cost visibility for every AI interaction. See what you spend and what you save."
      }
    }
  },
  "platform": {
    "label": "ONE PLATFORM, ONE ACCOUNT",
    "title": "DeepAILab — The AI developer platform that connects everything",
    "advantages": {
      "account": {
        "title": "One Account",
        "description": "Sign in once. Code, CLI, Office, and API Platform — all connected, all managed from one place."
      },
      "discount": {
        "title": "API Discounts",
        "description": "Access leading models through the platform at better rates than direct connections."
      },
      "dashboard": {
        "title": "Cost Dashboard",
        "description": "Cross-product usage analytics and cost breakdown at a glance. No more billing surprises."
      }
    },
    "cta": "Explore DeepAILab Platform"
  },
  "bottomCta": {
    "headline": "Ready to build the new way?",
    "subheadline": "Start with an Intent interview. Let AI help you figure out what to build.",
    "ctaPrimary": "Download DAL Code",
    "ctaSecondary": "Install CLI"
  },
  "faq": {
    "label": "FAQ",
    "title": "Frequently Asked Questions",
    "items": {
      "vsCursor": {
        "q": "How is DAL Code different from Cursor or Windsurf?",
        "a": "Cursor and Windsurf focus on helping you write better code. DAL Code starts earlier — it helps you clarify what to build before decomposing, executing, and delivering the work. It also supports multi-model routing and bring-your-own API keys."
      },
      "vsClaude": {
        "q": "How is DAL CLI different from Claude Code?",
        "a": "Claude Code is tied to the Anthropic model ecosystem. DAL CLI supports multi-model routing, your own API keys, and shares the same account and workflow system with DAL Code and DAL Office."
      },
      "byok": {
        "q": "Can I use my own API keys?",
        "a": "Yes. DAL supports connecting your own API keys from OpenAI, Anthropic, Google, and other major providers. You can also take advantage of DeepAILab platform API discounts."
      },
      "apiDiscount": {
        "q": "How do DeepAILab API discounts work?",
        "a": "Calling model APIs through the DeepAILab platform costs less than connecting to providers directly. Exact discounts depend on your usage tier — see the pricing page for details."
      },
      "models": {
        "q": "Which AI models are supported?",
        "a": "We support Claude (Opus/Sonnet/Haiku), GPT series, Gemini series, and 20+ other leading models, with new models added continuously. Smart Routing automatically selects the best model for each task."
      },
      "enterprise": {
        "q": "Do you support enterprise private deployment?",
        "a": "Private deployment, SSO, audit logs, and custom security policies are priority items on our roadmap. If your team has specific requirements, contact us to start with a concrete use case."
      }
    }
  },
  "footer": {
    "newsletter": {
      "placeholder": "Your email for product updates",
      "submit": "Subscribe",
      "success": "Subscribed.",
      "error": "Failed to subscribe. Please try again."
    },
    "groups": {
      "products": "Products",
      "resources": "Resources",
      "community": "Community",
      "company": "Company"
    },
    "links": {
      "code": "DAL Code",
      "cli": "DAL CLI",
      "office": "DAL Office",
      "apiPlatform": "API Platform",
      "pricing": "Pricing",
      "docs": "Docs",
      "blog": "Blog",
      "changelog": "Changelog",
      "faq": "FAQ",
      "discord": "Discord",
      "github": "GitHub",
      "twitter": "X / Twitter",
      "about": "About",
      "careers": "Careers",
      "contact": "Contact"
    },
    "copyright": "© 2026 DeepAILab. All rights reserved.",
    "privacy": "Privacy",
    "terms": "Terms"
  },
  "codePage": {
    "hero": {
      "label": "DAL CODE",
      "headline": "Not just an editor. An AI engineering workspace.",
      "subheadline": "From requirements interview to code delivery, one workspace covering the complete development workflow. Intent Capture helps you think clearly, Mission Mode handles the heavy lifting.",
      "cta": "Download DAL Code"
    }
  },
  "cliPage": {
    "hero": {
      "label": "DAL CLI",
      "headline": "Your AI development partner in the terminal",
      "subheadline": "Lightweight, fast, pipeline-friendly. Use agents to go from requirements to shipped code, right in your terminal.",
      "cta": "Install DAL CLI",
      "cliCommand": "curl -fsSL https://cli.deepailab.ai/install | bash"
    }
  },
  "officePage": {
    "hero": {
      "label": "DAL OFFICE",
      "headline": "AI-powered document workspace",
      "subheadline": "Developers do more than write code. Generate and edit Word documents, Excel spreadsheets, and PowerPoint presentations with AI — seamlessly connected to DAL Code.",
      "cta": "Explore DAL Office"
    }
  },
  "platformPage": {
    "hero": {
      "label": "API PLATFORM",
      "headline": "The AI infrastructure behind every DAL product",
      "subheadline": "Model aggregation, smart routing, cost optimization, usage analytics — one platform providing unified capabilities for every AI development scenario.",
      "cta": "Explore API Platform"
    }
  },
  "pricingPage": {
    "hero": {
      "label": "PRICING",
      "headline": "Simple, transparent pricing",
      "subheadline": "From individual developers to enterprise teams, choose the plan that fits."
    }
  },
  "about": {
    "hero": {
      "label": "ABOUT",
      "headline": "Building next-generation AI development infrastructure",
      "subheadline": "DeepAILab believes AI development tools should be open, composable, and built to genuinely serve developers."
    }
  },
  "contact": {
    "hero": {
      "label": "CONTACT",
      "headline": "Tell us about your real-world scenario",
      "subheadline": "Whether it's a product trial, enterprise deployment, or ecosystem partnership — start with a concrete use case."
    }
  },
  "blog": {
    "hero": {
      "label": "BLOG",
      "headline": "Product thinking and engineering practice",
      "subheadline": "Deep dives on AI development tools, multi-model routing, and engineering workflows."
    }
  },
  "common": {
    "learnMore": "Learn more",
    "getStarted": "Get started",
    "comingSoon": "Coming soon",
    "backToHome": "Back to home"
  }
}
  • Step 3: Commit
git add messages/
git commit -m "feat: rewrite i18n content for platform redesign"

Task 3: Site content data + ScrollReveal component

Files:

  • Rewrite: lib/site-content.ts

  • Create: components/ScrollReveal.tsx

  • Step 1: Rewrite lib/site-content.ts

export const SITE_NAME = "DAL"
export const SITE_BRAND = "DAL by DeepAILab"
export const SITE_TAGLINE = "The Open AI Development Platform"
export const SITE_DESCRIPTION =
  "从想法到产品的完整 AI 开发平台。自由选模型,全链路覆盖,一个账号搞定一切。"

export interface NavProductItem {
  key: string
  href: string
}

export const NAV_PRODUCT_ITEMS: NavProductItem[] = [
  { key: "code", href: "/code" },
  { key: "cli", href: "/cli" },
  { key: "office", href: "/office" },
  { key: "platform", href: "/platform" },
]

export interface FooterGroup {
  key: string
  links: { key: string; href: string; external?: boolean }[]
}

export const FOOTER_GROUPS: FooterGroup[] = [
  {
    key: "products",
    links: [
      { key: "code", href: "/code" },
      { key: "cli", href: "/cli" },
      { key: "office", href: "/office" },
      { key: "apiPlatform", href: "/platform" },
      { key: "pricing", href: "/pricing" },
    ],
  },
  {
    key: "resources",
    links: [
      { key: "docs", href: "/docs" },
      { key: "blog", href: "/blog" },
      { key: "changelog", href: "/coming-soon" },
      { key: "faq", href: "/#faq" },
    ],
  },
  {
    key: "community",
    links: [
      { key: "discord", href: "https://discord.gg/deepailab", external: true },
      { key: "github", href: "https://github.com/deepailab", external: true },
      { key: "twitter", href: "https://x.com/deepailab", external: true },
    ],
  },
  {
    key: "company",
    links: [
      { key: "about", href: "/about" },
      { key: "careers", href: "/careers" },
      { key: "contact", href: "/contact" },
    ],
  },
]

export const PRODUCT_KEYS = ["code", "cli", "office", "platform"] as const
export type ProductKey = (typeof PRODUCT_KEYS)[number]

export const PRODUCT_ICONS: Record<ProductKey, string> = {
  code: "/assets/icons/product-code.svg",
  cli: "/assets/icons/product-cli.svg",
  office: "/assets/icons/product-office.svg",
  platform: "/assets/icons/product-platform.svg",
}

export const PRODUCT_HREFS: Record<ProductKey, string> = {
  code: "/code",
  cli: "/cli",
  office: "/office",
  platform: "/platform",
}

export const WORKFLOW_STEPS = ["intent", "build", "ship"] as const
export type WorkflowStep = (typeof WORKFLOW_STEPS)[number]

export const FEATURE_KEYS = [
  "routing", "skills", "mission", "byok",
  "context", "audit", "rag", "cost",
] as const
export type FeatureKey = (typeof FEATURE_KEYS)[number]

export const FEATURE_ICONS: Record<FeatureKey, string> = {
  routing: "⚡",
  skills: "🧩",
  mission: "🎯",
  byok: "🔑",
  context: "🧠",
  audit: "🛡️",
  rag: "📚",
  cost: "📊",
}

export const PLATFORM_ADVANTAGE_KEYS = ["account", "discount", "dashboard"] as const

export const FAQ_KEYS = [
  "vsCursor", "vsClaude", "byok", "apiDiscount", "models", "enterprise",
] as const
  • Step 2: Create ScrollReveal component

Create components/ScrollReveal.tsx:

"use client"

import { useEffect, useRef } from "react"

interface ScrollRevealProps {
  children: React.ReactNode
  className?: string
  delay?: number
  as?: keyof HTMLElementTagNameMap
}

export default function ScrollReveal({
  children,
  className = "",
  delay = 0,
  as: Tag = "div" as any,
}: ScrollRevealProps) {
  const ref = useRef<HTMLElement>(null)

  useEffect(() => {
    const el = ref.current
    if (!el) return

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setTimeout(() => {
            el.classList.add("reveal-visible")
          }, delay)
          observer.unobserve(el)
        }
      },
      { threshold: 0.1 },
    )
    observer.observe(el)
    return () => observer.disconnect()
  }, [delay])

  return (
    <Tag ref={ref} className={`reveal-up ${className}`}>
      {children}
    </Tag>
  )
}
  • Step 3: Commit
git add lib/site-content.ts components/ScrollReveal.tsx
git commit -m "feat: add new site content data and ScrollReveal component"

Task 4: Header — New navigation with Products dropdown

Files:

  • Rewrite: components/Header.tsx

  • Step 1: Write new Header.tsx

"use client"

import { useState, useEffect, useCallback } from "react"
import Image from "next/image"
import Link from "next/link"
import { usePathname } from "next/navigation"
import { useTranslations } from "next-intl"
import LocaleSwitcher from "@/components/LocaleSwitcher"
import { NAV_PRODUCT_ITEMS } from "@/lib/site-content"

export default function Header() {
  const t = useTranslations("nav")
  const [mobileOpen, setMobileOpen] = useState(false)
  const [productsOpen, setProductsOpen] = useState(false)
  const [scrolled, setScrolled] = useState(false)
  const pathname = usePathname()

  const closeAll = useCallback(() => {
    setMobileOpen(false)
    setProductsOpen(false)
  }, [])

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 20)
    window.addEventListener("scroll", onScroll, { passive: true })
    return () => window.removeEventListener("scroll", onScroll)
  }, [])

  useEffect(() => { closeAll() }, [pathname, closeAll])

  const navLinks = [
    { href: "/docs", label: t("docs") },
    { href: "/pricing", label: t("pricing") },
    { href: "/blog", label: t("blog") },
  ]

  return (
    <header
      className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
        scrolled
          ? "bg-bg-primary/80 backdrop-blur-xl border-b border-border"
          : "bg-transparent"
      }`}
    >
      <div className="max-w-7xl mx-auto px-6 h-16 flex items-center justify-between">
        {/* Logo */}
        <Link href="/" className="flex items-center gap-2" onClick={closeAll}>
          <Image
            src="/assets/dalcode-app-icon.svg"
            width={32}
            height={32}
            alt="DAL"
          />
          <span className="font-display font-semibold text-lg text-text-primary">
            DAL
          </span>
        </Link>

        {/* Desktop Nav */}
        <nav className="hidden md:flex items-center gap-1">
          {/* Products Dropdown */}
          <div
            className="relative"
            onMouseEnter={() => setProductsOpen(true)}
            onMouseLeave={() => setProductsOpen(false)}
          >
            <button
              type="button"
              className="px-3 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors flex items-center gap-1"
              onClick={() => setProductsOpen((v) => !v)}
            >
              {t("products")}
              <svg width="12" height="12" viewBox="0 0 12 12" fill="none" className={`transition-transform ${productsOpen ? "rotate-180" : ""}`}>
                <path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </button>

            {productsOpen && (
              <div className="absolute top-full left-0 pt-2">
                <div className="bg-bg-card border border-border rounded-xl p-2 min-w-[240px] shadow-2xl">
                  {NAV_PRODUCT_ITEMS.map((item) => (
                    <Link
                      key={item.key}
                      href={item.href}
                      className="flex flex-col gap-0.5 px-3 py-2.5 rounded-lg hover:bg-bg-card-hover transition-colors"
                      onClick={closeAll}
                    >
                      <span className="text-sm font-medium text-text-primary">
                        {t(`productItems.${item.key}.name`)}
                      </span>
                      <span className="text-xs text-text-muted">
                        {t(`productItems.${item.key}.tagline`)}
                      </span>
                    </Link>
                  ))}
                </div>
              </div>
            )}
          </div>

          {navLinks.map((link) => (
            <Link
              key={link.href}
              href={link.href}
              className={`px-3 py-2 text-sm transition-colors ${
                pathname === link.href
                  ? "text-text-primary"
                  : "text-text-secondary hover:text-text-primary"
              }`}
            >
              {link.label}
            </Link>
          ))}
        </nav>

        {/* Right side */}
        <div className="hidden md:flex items-center gap-3">
          <LocaleSwitcher />
          <Link
            href="/contact"
            className="text-sm text-text-secondary hover:text-text-primary transition-colors"
          >
            {t("signIn")}
          </Link>
          <Link
            href="/code"
            className="px-4 py-2 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors"
          >
            {t("downloads")}
          </Link>
        </div>

        {/* Mobile hamburger */}
        <button
          type="button"
          className="md:hidden p-2"
          onClick={() => setMobileOpen((v) => !v)}
          aria-label={t("toggleMenu")}
        >
          <div className="w-5 flex flex-col gap-1.5">
            <span className={`block h-px bg-text-primary transition-all ${mobileOpen ? "rotate-45 translate-y-[3.5px]" : ""}`} />
            <span className={`block h-px bg-text-primary transition-all ${mobileOpen ? "-rotate-45 -translate-y-[3.5px]" : ""}`} />
          </div>
        </button>
      </div>

      {/* Mobile menu */}
      {mobileOpen && (
        <div className="md:hidden bg-bg-primary border-t border-border">
          <div className="px-6 py-4 flex flex-col gap-2">
            {NAV_PRODUCT_ITEMS.map((item) => (
              <Link
                key={item.key}
                href={item.href}
                className="py-2 text-sm text-text-secondary hover:text-text-primary"
                onClick={closeAll}
              >
                {t(`productItems.${item.key}.name`)}
              </Link>
            ))}
            <hr className="border-border my-2" />
            {navLinks.map((link) => (
              <Link
                key={link.href}
                href={link.href}
                className="py-2 text-sm text-text-secondary hover:text-text-primary"
                onClick={closeAll}
              >
                {link.label}
              </Link>
            ))}
            <hr className="border-border my-2" />
            <Link
              href="/code"
              className="py-2 text-sm font-medium text-accent"
              onClick={closeAll}
            >
              {t("downloads")}
            </Link>
            <LocaleSwitcher />
          </div>
        </div>
      )}
    </header>
  )
}
  • Step 2: Verify Header renders
cd /Users/leon/本地开发项目/claude-code/dalcode-website && PORT=55132 npx next dev &
sleep 5
curl -s http://localhost:55132 | head -50
  • Step 3: Commit
git add components/Header.tsx
git commit -m "feat: new Header with Products dropdown and dark theme"

Files:

  • Rewrite: components/Footer.tsx

  • Step 1: Write new Footer.tsx

"use client"

import Image from "next/image"
import Link from "next/link"
import { useTranslations } from "next-intl"
import NewsletterForm from "@/components/NewsletterForm"
import LocaleSwitcher from "@/components/LocaleSwitcher"
import { FOOTER_GROUPS } from "@/lib/site-content"

export default function Footer() {
  const t = useTranslations("footer")

  return (
    <footer className="border-t border-border bg-bg-primary">
      <div className="max-w-7xl mx-auto px-6">
        {/* Top: logo + newsletter */}
        <div className="py-12 flex flex-col md:flex-row justify-between items-start gap-8">
          <div className="flex items-center gap-2">
            <Image src="/assets/dalcode-app-icon.svg" width={28} height={28} alt="DAL" />
            <span className="font-display font-semibold text-text-primary">DAL</span>
          </div>
          <div className="w-full md:w-80">
            <NewsletterForm />
          </div>
        </div>

        {/* Link columns */}
        <div className="grid grid-cols-2 md:grid-cols-4 gap-8 pb-12">
          {FOOTER_GROUPS.map((group) => (
            <div key={group.key}>
              <h3 className="text-xs font-semibold uppercase tracking-wider text-text-muted mb-4">
                {t(`groups.${group.key}`)}
              </h3>
              <ul className="flex flex-col gap-2.5">
                {group.links.map((link) => (
                  <li key={link.key}>
                    <Link
                      href={link.href}
                      className="text-sm text-text-secondary hover:text-text-primary transition-colors"
                      {...(link.external ? { target: "_blank", rel: "noopener noreferrer" } : {})}
                    >
                      {t(`links.${link.key}`)}
                    </Link>
                  </li>
                ))}
              </ul>
            </div>
          ))}
        </div>

        {/* Bottom bar */}
        <div className="border-t border-border py-6 flex flex-col md:flex-row justify-between items-center gap-4 text-xs text-text-muted">
          <p>{t("copyright")}</p>
          <div className="flex items-center gap-6">
            <Link href="/privacy" className="hover:text-text-secondary transition-colors">
              {t("privacy")}
            </Link>
            <Link href="/terms" className="hover:text-text-secondary transition-colors">
              {t("terms")}
            </Link>
            <LocaleSwitcher />
          </div>
        </div>
      </div>
    </footer>
  )
}
  • Step 2: Commit
git add components/Footer.tsx
git commit -m "feat: new Footer with 4-column layout"

Task 6: Homepage sections — Hero + ProductEcosystem

Files:

  • Rewrite: components/home/HeroSection.tsx

  • Create: components/home/ProductEcosystem.tsx

  • Step 1: Write new HeroSection.tsx

"use client"

import Link from "next/link"
import { useTranslations } from "next-intl"
import ScrollReveal from "@/components/ScrollReveal"

export default function HeroSection() {
  const t = useTranslations("hero")

  return (
    <section className="relative min-h-screen flex items-center justify-center overflow-hidden pt-16">
      {/* Background gradient */}
      <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,var(--color-accent-glow)_0%,transparent_70%)]" />

      <div className="relative z-10 max-w-4xl mx-auto px-6 text-center">
        <ScrollReveal>
          <span className="inline-block px-3 py-1 text-xs font-medium text-accent border border-accent/30 rounded-full mb-8">
            {t("badge")}
          </span>
        </ScrollReveal>

        <ScrollReveal delay={100}>
          <h1 className="font-display text-5xl md:text-7xl font-bold tracking-tight text-text-primary leading-[1.1]">
            {t("headline")}
          </h1>
        </ScrollReveal>

        <ScrollReveal delay={200}>
          <p className="mt-6 text-lg md:text-xl text-text-secondary max-w-2xl mx-auto leading-relaxed">
            {t("subheadline")}
          </p>
        </ScrollReveal>

        <ScrollReveal delay={300}>
          <div className="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4">
            <Link
              href="/code"
              className="px-6 py-3 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors"
            >
              {t("ctaPrimary")}
            </Link>
            <Link
              href="/cli"
              className="px-6 py-3 text-sm font-medium text-text-primary border border-border hover:border-border-hover rounded-lg transition-colors"
            >
              {t("ctaSecondary")}
            </Link>
          </div>
        </ScrollReveal>

        <ScrollReveal delay={400}>
          <div className="mt-6 inline-flex items-center gap-2 px-4 py-2 bg-bg-card border border-border rounded-lg font-mono text-sm text-text-muted">
            <span className="text-accent">$</span>
            <span>{t("cliCommand")}</span>
            <button
              type="button"
              className="ml-2 text-text-muted hover:text-text-primary transition-colors"
              onClick={() => navigator.clipboard.writeText(t("cliCommand"))}
              aria-label="Copy command"
            >
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
                <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
              </svg>
            </button>
          </div>
        </ScrollReveal>

        {/* Product screenshot placeholder */}
        <ScrollReveal delay={500}>
          <div className="mt-16 rounded-xl border border-border bg-bg-card overflow-hidden shadow-2xl">
            <div className="aspect-video flex items-center justify-center text-text-muted">
              <div className="text-center">
                <div className="text-4xl mb-2"></div>
                <p className="text-sm">Product screenshot</p>
              </div>
            </div>
          </div>
        </ScrollReveal>
      </div>
    </section>
  )
}
  • Step 2: Write ProductEcosystem.tsx
"use client"

import Link from "next/link"
import { useTranslations } from "next-intl"
import ScrollReveal from "@/components/ScrollReveal"
import { PRODUCT_KEYS, PRODUCT_HREFS } from "@/lib/site-content"

export default function ProductEcosystem() {
  const t = useTranslations("ecosystem")

  return (
    <section className="py-32 px-6">
      <div className="max-w-6xl mx-auto">
        <ScrollReveal>
          <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
            {t("label")}
          </p>
          <h2 className="font-display text-3xl md:text-5xl font-bold text-text-primary">
            {t("title")}
          </h2>
        </ScrollReveal>

        <div className="mt-16 grid grid-cols-1 md:grid-cols-2 gap-4">
          {PRODUCT_KEYS.map((key, i) => (
            <ScrollReveal key={key} delay={i * 100}>
              <Link
                href={PRODUCT_HREFS[key]}
                className="group block p-8 rounded-xl border border-border bg-bg-card hover:bg-bg-card-hover hover:border-border-hover transition-all card-glow"
              >
                <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-3">
                  {t(`products.${key}.name`)}
                </p>
                <h3 className="font-display text-xl font-semibold text-text-primary mb-2">
                  {t(`products.${key}.tagline`)}
                </h3>
                <p className="text-sm text-text-secondary mb-6 leading-relaxed">
                  {t(`products.${key}.description`)}
                </p>
                <div className="flex flex-wrap gap-2 mb-6">
                  {(t.raw(`products.${key}.features`) as string[]).map((f: string) => (
                    <span key={f} className="px-2 py-1 text-xs text-text-muted border border-border rounded-md">
                      {f}
                    </span>
                  ))}
                </div>
                <span className="text-sm text-accent group-hover:underline">
                  {t(`products.${key}.cta`)} 
                </span>
              </Link>
            </ScrollReveal>
          ))}
        </div>
      </div>
    </section>
  )
}
  • Step 3: Commit
git add components/home/HeroSection.tsx components/home/ProductEcosystem.tsx
git commit -m "feat: new Hero and ProductEcosystem sections"

Task 7: Homepage sections — WorkflowSteps + FeatureGrid

Files:

  • Create: components/home/WorkflowSteps.tsx

  • Create: components/home/FeatureGrid.tsx

  • Step 1: Write WorkflowSteps.tsx

"use client"

import { useTranslations } from "next-intl"
import ScrollReveal from "@/components/ScrollReveal"
import { WORKFLOW_STEPS } from "@/lib/site-content"

export default function WorkflowSteps() {
  const t = useTranslations("workflow")

  return (
    <section className="py-32 px-6 bg-bg-secondary">
      <div className="max-w-6xl mx-auto">
        <ScrollReveal>
          <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
            {t("label")}
          </p>
          <h2 className="font-display text-3xl md:text-5xl font-bold text-text-primary max-w-2xl">
            {t("title")}
          </h2>
        </ScrollReveal>

        <div className="mt-16 grid grid-cols-1 md:grid-cols-3 gap-6">
          {WORKFLOW_STEPS.map((step, i) => (
            <ScrollReveal key={step} delay={i * 150}>
              <div className="relative p-8 rounded-xl border border-border bg-bg-card h-full">
                <span className="font-display text-6xl font-bold text-border">
                  {t(`steps.${step}.number`)}
                </span>
                <p className="mt-4 text-xs font-semibold uppercase tracking-widest text-accent">
                  {t(`steps.${step}.name`)}
                </p>
                <h3 className="mt-2 font-display text-xl font-semibold text-text-primary">
                  {t(`steps.${step}.title`)}
                </h3>
                <p className="mt-3 text-sm text-text-secondary leading-relaxed">
                  {t(`steps.${step}.description`)}
                </p>
                {/* Screenshot placeholder */}
                <div className="mt-6 rounded-lg border border-border bg-bg-secondary aspect-video flex items-center justify-center">
                  <span className="text-xs text-text-muted">Screenshot</span>
                </div>
              </div>
            </ScrollReveal>
          ))}
        </div>

        {/* Connecting line */}
        <div className="hidden md:flex items-center justify-center mt-8 gap-2">
          {WORKFLOW_STEPS.map((_, i) => (
            <div key={i} className="flex items-center">
              <div className="w-3 h-3 rounded-full border-2 border-accent bg-bg-primary" />
              {i < WORKFLOW_STEPS.length - 1 && (
                <div className="w-32 h-px bg-gradient-to-r from-accent to-border" />
              )}
            </div>
          ))}
        </div>
      </div>
    </section>
  )
}
  • Step 2: Write FeatureGrid.tsx
"use client"

import { useTranslations } from "next-intl"
import ScrollReveal from "@/components/ScrollReveal"
import { FEATURE_KEYS, FEATURE_ICONS } from "@/lib/site-content"

export default function FeatureGrid() {
  const t = useTranslations("features")

  return (
    <section className="py-32 px-6">
      <div className="max-w-6xl mx-auto">
        <ScrollReveal>
          <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
            {t("label")}
          </p>
          <h2 className="font-display text-3xl md:text-5xl font-bold text-text-primary">
            {t("title")}
          </h2>
        </ScrollReveal>

        <div className="mt-16 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
          {FEATURE_KEYS.map((key, i) => (
            <ScrollReveal key={key} delay={i * 80}>
              <div className="p-6 rounded-xl border border-border bg-bg-card hover:bg-bg-card-hover hover:border-border-hover transition-all card-glow h-full">
                <span className="text-2xl">{FEATURE_ICONS[key]}</span>
                <h3 className="mt-4 font-display text-base font-semibold text-text-primary">
                  {t(`items.${key}.title`)}
                </h3>
                <p className="mt-2 text-sm text-text-secondary leading-relaxed">
                  {t(`items.${key}.description`)}
                </p>
              </div>
            </ScrollReveal>
          ))}
        </div>
      </div>
    </section>
  )
}
  • Step 3: Commit
git add components/home/WorkflowSteps.tsx components/home/FeatureGrid.tsx
git commit -m "feat: add WorkflowSteps and FeatureGrid homepage sections"

Task 8: Homepage sections — EcosystemSection + BottomCta + FaqSection

Files:

  • Create: components/home/EcosystemSection.tsx

  • Create: components/home/BottomCta.tsx

  • Create: components/home/FaqSection.tsx

  • Step 1: Write EcosystemSection.tsx

"use client"

import Link from "next/link"
import { useTranslations } from "next-intl"
import ScrollReveal from "@/components/ScrollReveal"
import { PLATFORM_ADVANTAGE_KEYS } from "@/lib/site-content"

export default function EcosystemSection() {
  const t = useTranslations("platform")

  return (
    <section className="py-32 px-6 bg-gradient-to-b from-bg-secondary to-[#0d0518]">
      <div className="max-w-6xl mx-auto">
        <ScrollReveal>
          <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
            {t("label")}
          </p>
          <h2 className="font-display text-3xl md:text-5xl font-bold text-text-primary max-w-3xl">
            {t("title")}
          </h2>
        </ScrollReveal>

        {/* Architecture diagram */}
        <ScrollReveal delay={200}>
          <div className="mt-16 flex justify-center">
            <div className="relative">
              {/* Center node */}
              <div className="w-40 h-40 rounded-2xl border-2 border-accent bg-bg-card flex flex-col items-center justify-center text-center">
                <span className="text-sm font-semibold text-accent">DeepAILab</span>
                <span className="text-xs text-text-muted mt-1">Platform</span>
              </div>
              {/* Branch nodes positioned absolutely */}
              {(["Code", "CLI", "Office", "API"] as const).map((name, i) => {
                const positions = [
                  "-top-20 left-1/2 -translate-x-1/2",
                  "top-1/2 -right-28 -translate-y-1/2",
                  "-bottom-20 left-1/2 -translate-x-1/2",
                  "top-1/2 -left-28 -translate-y-1/2",
                ]
                return (
                  <div key={name} className={`absolute ${positions[i]} px-3 py-2 rounded-lg border border-border bg-bg-card text-xs text-text-secondary`}>
                    {name}
                  </div>
                )
              })}
            </div>
          </div>
        </ScrollReveal>

        {/* Advantage cards */}
        <div className="mt-20 grid grid-cols-1 md:grid-cols-3 gap-4">
          {PLATFORM_ADVANTAGE_KEYS.map((key, i) => (
            <ScrollReveal key={key} delay={i * 100}>
              <div className="p-6 rounded-xl border border-border bg-bg-card/50 backdrop-blur-sm">
                <h3 className="font-display text-lg font-semibold text-text-primary">
                  {t(`advantages.${key}.title`)}
                </h3>
                <p className="mt-2 text-sm text-text-secondary leading-relaxed">
                  {t(`advantages.${key}.description`)}
                </p>
              </div>
            </ScrollReveal>
          ))}
        </div>

        <ScrollReveal delay={400}>
          <div className="mt-12 text-center">
            <a
              href="https://deepailab.ai"
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex items-center gap-2 px-6 py-3 text-sm font-medium text-accent border border-accent/30 hover:border-accent rounded-lg transition-colors"
            >
              {t("cta")}
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <path d="M7 17L17 7M17 7H7M17 7V17" />
              </svg>
            </a>
          </div>
        </ScrollReveal>
      </div>
    </section>
  )
}
  • Step 2: Write BottomCta.tsx
"use client"

import Link from "next/link"
import { useTranslations } from "next-intl"
import ScrollReveal from "@/components/ScrollReveal"

export default function BottomCta() {
  const t = useTranslations("bottomCta")
  const hero = useTranslations("hero")

  return (
    <section className="relative py-32 px-6 overflow-hidden">
      <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,var(--color-accent-glow)_0%,transparent_70%)]" />

      <div className="relative z-10 max-w-3xl mx-auto text-center">
        <ScrollReveal>
          <h2 className="font-display text-3xl md:text-5xl font-bold text-text-primary">
            {t("headline")}
          </h2>
        </ScrollReveal>

        <ScrollReveal delay={100}>
          <p className="mt-6 text-lg text-text-secondary">
            {t("subheadline")}
          </p>
        </ScrollReveal>

        <ScrollReveal delay={200}>
          <div className="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4">
            <Link
              href="/code"
              className="px-6 py-3 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors"
            >
              {t("ctaPrimary")}
            </Link>
            <Link
              href="/cli"
              className="px-6 py-3 text-sm font-medium text-text-primary border border-border hover:border-border-hover rounded-lg transition-colors"
            >
              {t("ctaSecondary")}
            </Link>
          </div>
        </ScrollReveal>

        <ScrollReveal delay={300}>
          <div className="mt-6 inline-flex items-center gap-2 px-4 py-2 bg-bg-card border border-border rounded-lg font-mono text-sm text-text-muted">
            <span className="text-accent">$</span>
            <span>{hero("cliCommand")}</span>
          </div>
        </ScrollReveal>
      </div>
    </section>
  )
}
  • Step 3: Write FaqSection.tsx
"use client"

import { useState } from "react"
import { useTranslations } from "next-intl"
import ScrollReveal from "@/components/ScrollReveal"
import { FAQ_KEYS } from "@/lib/site-content"

export default function FaqSection() {
  const t = useTranslations("faq")
  const [openIndex, setOpenIndex] = useState<number | null>(null)

  return (
    <section id="faq" className="py-32 px-6 bg-bg-secondary">
      <div className="max-w-3xl mx-auto">
        <ScrollReveal>
          <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
            {t("label")}
          </p>
          <h2 className="font-display text-3xl md:text-5xl font-bold text-text-primary">
            {t("title")}
          </h2>
        </ScrollReveal>

        <div className="mt-12 flex flex-col divide-y divide-border">
          {FAQ_KEYS.map((key, i) => (
            <ScrollReveal key={key} delay={i * 60}>
              <div>
                <button
                  type="button"
                  className="w-full py-5 flex items-center justify-between text-left group"
                  onClick={() => setOpenIndex(openIndex === i ? null : i)}
                >
                  <span className="text-base font-medium text-text-primary group-hover:text-accent transition-colors pr-4">
                    {t(`items.${key}.q`)}
                  </span>
                  <svg
                    width="20"
                    height="20"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    className={`flex-shrink-0 text-text-muted transition-transform ${openIndex === i ? "rotate-45" : ""}`}
                  >
                    <path d="M12 5v14M5 12h14" />
                  </svg>
                </button>
                {openIndex === i && (
                  <div className="pb-5 text-sm text-text-secondary leading-relaxed">
                    {t(`items.${key}.a`)}
                  </div>
                )}
              </div>
            </ScrollReveal>
          ))}
        </div>
      </div>
    </section>
  )
}
  • Step 4: Commit
git add components/home/EcosystemSection.tsx components/home/BottomCta.tsx components/home/FaqSection.tsx
git commit -m "feat: add EcosystemSection, BottomCta, and FaqSection"

Task 9: Wire up homepage + delete old components

Files:

  • Rewrite: app/page.tsx

  • Rewrite: components/home/index.ts

  • Delete: components/home/IntegrationsSection.tsx

  • Delete: components/home/PrinciplesSection.tsx

  • Delete: components/home/BlogPreviewSection.tsx

  • Delete: components/home/CtaSection.tsx

  • Step 1: Rewrite components/home/index.ts

export { default as HeroSection } from "./HeroSection"
export { default as ProductEcosystem } from "./ProductEcosystem"
export { default as WorkflowSteps } from "./WorkflowSteps"
export { default as FeatureGrid } from "./FeatureGrid"
export { default as EcosystemSection } from "./EcosystemSection"
export { default as BottomCta } from "./BottomCta"
export { default as FaqSection } from "./FaqSection"
  • Step 2: Rewrite app/page.tsx
import type { Metadata } from "next"
import {
  HeroSection,
  ProductEcosystem,
  WorkflowSteps,
  FeatureGrid,
  EcosystemSection,
  BottomCta,
  FaqSection,
} from "@/components/home"
import { SITE_BRAND, SITE_DESCRIPTION } from "@/lib/site-content"

export const metadata: Metadata = {
  title: SITE_BRAND,
  description: SITE_DESCRIPTION,
  openGraph: {
    title: SITE_BRAND,
    description: SITE_DESCRIPTION,
  },
}

export default function HomePage() {
  return (
    <>
      <HeroSection />
      <ProductEcosystem />
      <WorkflowSteps />
      <FeatureGrid />
      <EcosystemSection />
      <BottomCta />
      <FaqSection />
    </>
  )
}
  • Step 3: Delete old components
rm components/home/IntegrationsSection.tsx
rm components/home/PrinciplesSection.tsx
rm components/home/BlogPreviewSection.tsx
rm components/home/CtaSection.tsx
  • Step 4: Verify homepage loads

Start dev server, navigate to http://localhost:55132, take a screenshot and verify all 7 sections render.

  • Step 5: Commit
git add -A
git commit -m "feat: wire up new homepage sections, remove old components"

Task 10: Subpages — /code, /cli, /office, /platform, /pricing

Files:

  • Create: app/code/page.tsx

  • Create: app/cli/page.tsx

  • Create: app/office/page.tsx

  • Create: app/platform/page.tsx

  • Create: app/pricing/page.tsx

  • Step 1: Write app/code/page.tsx

import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"
import Link from "next/link"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("codePage.hero")
  return { title: t("headline") }
}

export default async function CodePage() {
  const t = await getTranslations("codePage.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
          {t("label")}
        </p>
        <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
          {t("headline")}
        </h1>
        <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
          {t("subheadline")}
        </p>
        <div className="mt-10">
          <Link
            href="/contact"
            className="px-6 py-3 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors"
          >
            {t("cta")}
          </Link>
        </div>
        <div className="mt-16 rounded-xl border border-border bg-bg-card overflow-hidden">
          <div className="aspect-video flex items-center justify-center text-text-muted">
            <p className="text-sm">DAL Code product screenshots coming soon</p>
          </div>
        </div>
      </div>
    </section>
  )
}
  • Step 2: Write app/cli/page.tsx
import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"
import Link from "next/link"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("cliPage.hero")
  return { title: t("headline") }
}

export default async function CliPage() {
  const t = await getTranslations("cliPage.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
          {t("label")}
        </p>
        <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
          {t("headline")}
        </h1>
        <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
          {t("subheadline")}
        </p>
        <div className="mt-10 flex flex-col items-center gap-4">
          <div className="inline-flex items-center gap-2 px-4 py-2 bg-bg-card border border-border rounded-lg font-mono text-sm text-text-muted">
            <span className="text-accent">$</span>
            <span>{t("cliCommand")}</span>
          </div>
        </div>
        <div className="mt-16 rounded-xl border border-border bg-bg-card overflow-hidden">
          <div className="aspect-video flex items-center justify-center text-text-muted bg-[#1a1a2e]">
            <div className="font-mono text-sm text-left max-w-md">
              <p><span className="text-accent">$</span> dal init</p>
              <p className="text-text-muted mt-1">Initializing DAL CLI...</p>
              <p className="text-green-400 mt-1"> Connected to DeepAILab Platform</p>
              <p className="text-text-muted mt-1">Ready. Type `dal` to get started.</p>
            </div>
          </div>
        </div>
      </div>
    </section>
  )
}
  • Step 3: Write app/office/page.tsx
import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"
import Link from "next/link"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("officePage.hero")
  return { title: t("headline") }
}

export default async function OfficePage() {
  const t = await getTranslations("officePage.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
          {t("label")}
        </p>
        <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
          {t("headline")}
        </h1>
        <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
          {t("subheadline")}
        </p>
        <div className="mt-10">
          <Link
            href="/contact"
            className="px-6 py-3 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors"
          >
            {t("cta")}
          </Link>
        </div>
        <div className="mt-16 grid grid-cols-1 md:grid-cols-3 gap-4">
          {(["Word", "Excel", "PPT"] as const).map((name) => (
            <div key={name} className="p-8 rounded-xl border border-border bg-bg-card">
              <h3 className="font-display text-lg font-semibold text-text-primary">{name}</h3>
              <p className="mt-2 text-sm text-text-muted">Coming soon</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  )
}
  • Step 4: Write app/platform/page.tsx
import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("platformPage.hero")
  return { title: t("headline") }
}

export default async function PlatformPage() {
  const t = await getTranslations("platformPage.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
          {t("label")}
        </p>
        <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
          {t("headline")}
        </h1>
        <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
          {t("subheadline")}
        </p>
        <div className="mt-10">
          <a
            href="https://deepailab.ai"
            target="_blank"
            rel="noopener noreferrer"
            className="inline-flex items-center gap-2 px-6 py-3 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors"
          >
            {t("cta")}
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <path d="M7 17L17 7M17 7H7M17 7V17" />
            </svg>
          </a>
        </div>
      </div>
    </section>
  )
}
  • Step 5: Write app/pricing/page.tsx
import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("pricingPage.hero")
  return { title: t("headline") }
}

export default async function PricingPage() {
  const t = await getTranslations("pricingPage.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
          {t("label")}
        </p>
        <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
          {t("headline")}
        </h1>
        <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
          {t("subheadline")}
        </p>
        <div className="mt-16 text-text-muted text-sm">
          Pricing details coming soon
        </div>
      </div>
    </section>
  )
}
  • Step 6: Commit
git add app/code/ app/cli/ app/office/ app/platform/ app/pricing/
git commit -m "feat: add product subpages (code, cli, office, platform, pricing)"

Task 11: Update existing subpages (about, blog, contact, careers) for dark theme

Files:

  • Modify: app/about/page.tsx
  • Modify: app/blog/page.tsx
  • Modify: app/contact/page.tsx
  • Modify: app/careers/page.tsx
  • Modify: app/coming-soon/page.tsx
  • Modify: app/not-found.tsx

These pages currently use webflow CSS classes. They need to be converted to Tailwind. Since they are secondary pages, we use a minimal hero + content pattern consistent with the new subpages.

  • Step 1: Rewrite app/about/page.tsx
import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("about.hero")
  return { title: t("headline") }
}

export default async function AboutPage() {
  const t = await getTranslations("about.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
          {t("label")}
        </p>
        <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
          {t("headline")}
        </h1>
        <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
          {t("subheadline")}
        </p>
      </div>
    </section>
  )
}
  • Step 2: Rewrite app/blog/page.tsx
import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("blog.hero")
  return { title: t("headline") }
}

export default async function BlogPage() {
  const t = await getTranslations("blog.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
          {t("label")}
        </p>
        <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
          {t("headline")}
        </h1>
        <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
          {t("subheadline")}
        </p>
      </div>
    </section>
  )
}
  • Step 3: Rewrite app/contact/page.tsx
import type { Metadata } from "next"
import { getTranslations } from "next-intl/server"
import ContactForm from "@/components/ContactForm"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("contact.hero")
  return { title: t("headline") }
}

export default async function ContactPage() {
  const t = await getTranslations("contact.hero")

  return (
    <section className="min-h-screen pt-32 pb-20 px-6">
      <div className="max-w-4xl mx-auto">
        <div className="text-center">
          <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">
            {t("label")}
          </p>
          <h1 className="font-display text-4xl md:text-6xl font-bold text-text-primary leading-tight">
            {t("headline")}
          </h1>
          <p className="mt-6 text-lg text-text-secondary max-w-2xl mx-auto leading-relaxed">
            {t("subheadline")}
          </p>
        </div>
        <div className="mt-16 max-w-xl mx-auto">
          <ContactForm />
        </div>
      </div>
    </section>
  )
}
  • Step 4: Simplify app/careers/page.tsx, app/coming-soon/page.tsx, app/not-found.tsx

Apply the same pattern: minimal hero with label + headline + description, using Tailwind classes, no webflow references.

For not-found.tsx:

import Link from "next/link"

export default function NotFound() {
  return (
    <section className="min-h-screen pt-32 pb-20 px-6 flex items-center">
      <div className="max-w-xl mx-auto text-center">
        <p className="text-xs font-semibold uppercase tracking-widest text-accent mb-4">404</p>
        <h1 className="font-display text-4xl font-bold text-text-primary">Page not found</h1>
        <p className="mt-4 text-text-secondary">The page you're looking for doesn't exist or has been moved.</p>
        <div className="mt-8">
          <Link href="/" className="px-6 py-3 text-sm font-medium bg-accent hover:bg-accent-hover text-white rounded-lg transition-colors">
            Back to home
          </Link>
        </div>
      </div>
    </section>
  )
}
  • Step 5: Delete old about/blog/contact subcomponents that use webflow classes
rm -rf components/about/
rm -rf components/blog/
rm -rf components/contact/
  • Step 6: Commit
git add -A
git commit -m "feat: rewrite all subpages for dark Tailwind theme"

Task 12: Update GsapAnimations + NewsletterForm + LocaleSwitcher

Files:

  • Modify: components/GsapAnimations.tsx

  • Modify: components/NewsletterForm.tsx

  • Modify: components/LocaleSwitcher.tsx

  • Step 1: Simplify GsapAnimations.tsx

Remove marquee, counter, and button hover init (no longer needed). Keep scroll reveal and smooth scroll:

"use client"

import { useEffect } from "react"

export default function GsapAnimations() {
  useEffect(() => {
    let ctx: ReturnType<typeof import("gsap").gsap.context> | null = null

    import("gsap").then(async ({ gsap }) => {
      const { ScrollTrigger } = await import("gsap/ScrollTrigger")
      gsap.registerPlugin(ScrollTrigger)

      ctx = gsap.context(() => {
        ScrollTrigger.batch(".reveal-up:not(.reveal-visible)", {
          onEnter: (batch) =>
            gsap.to(batch, {
              opacity: 1,
              y: 0,
              stagger: 0.1,
              duration: 0.6,
              ease: "power2.out",
              overwrite: true,
            }),
        })
      })
    })

    return () => { ctx?.revert() }
  }, [])

  return null
}
  • Step 2: Update NewsletterForm.tsx to use Tailwind

The existing form needs its webflow classes replaced with Tailwind. Update the component to use:

  • bg-bg-card border border-border for input

  • bg-accent text-white for submit button

  • Use useTranslations("footer.newsletter") for all strings

  • Step 3: Update LocaleSwitcher.tsx to use Tailwind

Replace webflow classes with:

  • text-sm text-text-muted hover:text-text-primary styling

  • Simple <select> or button toggle between zh-CN and en

  • Step 4: Commit

git add components/GsapAnimations.tsx components/NewsletterForm.tsx components/LocaleSwitcher.tsx
git commit -m "refactor: update GsapAnimations, NewsletterForm, LocaleSwitcher for new design"

Task 13: Update ContactForm for dark theme

Files:

  • Modify: components/ContactForm.tsx

  • Step 1: Update ContactForm to use Tailwind classes

Replace all webflow CSS classes with Tailwind equivalents:

  • Inputs: w-full px-4 py-3 bg-bg-card border border-border rounded-lg text-text-primary placeholder:text-text-muted focus:border-accent focus:outline-none
  • Labels: text-sm text-text-secondary
  • Submit button: w-full px-6 py-3 bg-accent hover:bg-accent-hover text-white font-medium rounded-lg transition-colors
  • Error messages: text-xs text-red-400

Keep all existing React Hook Form + Zod validation logic unchanged.

  • Step 2: Commit
git add components/ContactForm.tsx
git commit -m "refactor: update ContactForm for dark Tailwind theme"

Task 14: Full build verification + browser test

Files: None (verification only)

  • Step 1: Run TypeScript check
cd /Users/leon/本地开发项目/claude-code/dalcode-website && npx tsc --noEmit 2>&1 | tail -30

Expected: No type errors.

  • Step 2: Run Next.js build
npx next build 2>&1 | tail -30

Expected: Build succeeds with all pages generated.

  • Step 3: Start dev server and verify in browser
PORT=55132 npx next dev &

Navigate to http://localhost:55132 and verify:

  • Homepage: all 7 sections render (Hero, ProductEcosystem, WorkflowSteps, FeatureGrid, EcosystemSection, BottomCta, FAQ)

  • Navigation: Products dropdown works, all links navigate correctly

  • Subpages: /code, /cli, /office, /platform, /pricing, /about, /blog, /contact all load

  • Footer: 4-column layout renders correctly

  • Language switch: toggle between zh-CN and en

  • Mobile: responsive layout works at mobile breakpoints

  • Scroll animations: sections fade in on scroll

  • Step 4: Take screenshots of key pages

Screenshot homepage, /code, /cli pages and verify visual quality.

  • Step 5: Final commit if any fixes needed
git add -A
git commit -m "fix: address build and visual issues from full verification"