- 16 个可执行任务 - 完整的代码实现 - 明确的测试步骤 - 清晰的提交信息 - 遵循 TDD、DRY、YAGNI 原则
31 KiB
Novalon 官网重新设计实施计划
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: 将 Novalon 官网从现有设计升级为数字未来风设计,包括配色系统、UI 组件、页面布局、动效和响应式适配的全面升级。
Architecture: 采用渐进式升级策略,从核心配色系统开始,逐步更新 UI 组件、页面布局、动效和响应式适配。使用 Tailwind CSS v4 的 CSS 变量系统实现主题切换,使用 Framer Motion 实现动效,使用 AntV 生态实现数据可视化。
Tech Stack: Next.js 16, React 19, TypeScript, Tailwind CSS v4, Framer Motion, AntV (G2/G6/L7/S2), Lucide React
Phase 1: 核心配色系统
Task 1: 更新 CSS 变量 - 深色模式配色
Files:
- Modify:
src/app/globals.css:1-200
Step 1: 备份当前配色变量
cp src/app/globals.css src/app/globals.css.backup
Step 2: 更新深色模式配色变量
在 .dark 类中更新配色变量:
.dark {
--color-bg-primary: #0A0A0A;
--color-bg-secondary: #141414;
--color-bg-tertiary: #1A1A1A;
--color-bg-hover: #242424;
--color-text-primary: #FAFAFA;
--color-text-secondary: #D4D4D4;
--color-text-tertiary: #A3A3A3;
--color-text-muted: #737373;
--color-border-primary: #262626;
--color-border-secondary: #333333;
--color-border-accent: #404040;
--color-accent: #FAFAFA;
--color-accent-hover: #E5E5E5;
--color-accent-light: #D4D4D4;
--color-link: #D4D4D4;
--color-link-hover: #FAFAFA;
--color-brand-primary: #C41E3A;
--color-brand-primary-hover: #A01830;
--color-brand-primary-light: #E04A68;
--color-brand-primary-lighter: #F08C9F;
--color-brand-primary-bg: #1A0F11;
--color-tech-blue: #00D9FF;
--color-tech-blue-hover: #00B8D9;
--color-tech-blue-light: #33E1FF;
--color-tech-purple: #A855F7;
--color-tech-purple-hover: #9333EA;
--color-tech-purple-light: #C084FC;
--color-tech-cyan: #06B6D4;
--color-success: #22C55E;
--color-success-bg: #052E16;
--color-warning: #F59E0B;
--color-warning-bg: #1C1917;
--color-info: #0EA5E9;
--color-info-bg: #0C2D48;
--color-error: #EF4444;
--color-error-bg: #1C1917;
}
Step 3: 更新浅色模式配色变量
在 :root 中更新配色变量:
:root {
--color-bg-primary: #FFFFFF;
--color-bg-secondary: #FAFAFA;
--color-bg-tertiary: #F5F5F5;
--color-bg-hover: #F0F0F0;
--color-text-primary: #171717;
--color-text-secondary: #525252;
--color-text-tertiary: #737373;
--color-text-muted: #A3A3A3;
--color-border-primary: #E5E5E5;
--color-border-secondary: #F0F0F0;
--color-border-accent: #D4D4D4;
--color-accent: #171717;
--color-accent-hover: #262626;
--color-accent-light: #404040;
--color-link: #525252;
--color-link-hover: #171717;
--color-brand-primary: #C41E3A;
--color-brand-primary-hover: #A01830;
--color-brand-primary-light: #D4244A;
--color-brand-primary-lighter: #E04A68;
--color-brand-primary-bg: #FEF2F4;
--color-tech-blue: #00D9FF;
--color-tech-blue-hover: #00B8D9;
--color-tech-blue-light: #33E1FF;
--color-tech-purple: #A855F7;
--color-tech-purple-hover: #9333EA;
--color-tech-purple-light: #C084FC;
--color-tech-cyan: #06B6D4;
--color-success: #16A34A;
--color-success-bg: #F0FDF4;
--color-warning: #D97706;
--color-warning-bg: #FFFBEB;
--color-info: #0284C7;
--color-info-bg: #F0F9FF;
--color-error: #DC2626;
--color-error-bg: #FEF2F2;
}
Step 4: 验证配色变量
在浏览器中打开网站,切换深色/浅色模式,检查配色是否正确应用。
Step 5: 提交更改
git add src/app/globals.css
git commit -m "feat: 更新核心配色系统 - 深色/浅色模式
- 更新深色模式配色变量(科技蓝、紫色、印章红)
- 更新浅色模式配色变量
- 添加新的科技色彩变量
- 保持品牌色一致性"
Task 2: 更新 colors.ts 文件
Files:
- Modify:
src/lib/colors.ts:1-69
Step 1: 更新品牌色彩定义
export const brandColors = {
primary: {
600: '#C41E3A',
700: '#A01830',
500: '#D4244A',
400: '#E04A68',
100: '#FEF2F4',
},
tech: {
blue: {
600: '#00D9FF',
700: '#00B8D9',
500: '#33E1FF',
},
purple: {
600: '#A855F7',
700: '#9333EA',
500: '#C084FC',
},
cyan: {
600: '#06B6D4',
},
},
neutral: {
900: '#0A0A0A',
800: '#141414',
700: '#1A1A1A',
600: '#242424',
500: '#333333',
400: '#404040',
300: '#737373',
200: '#A3A3A3',
100: '#D4D4D4',
50: '#FAFAFA',
0: '#FFFFFF',
},
success: {
600: '#16A34A',
100: '#F0FDF4',
},
warning: {
600: '#D97706',
100: '#FFFBEB',
},
info: {
600: '#0284C7',
100: '#F0F9FF',
},
error: {
600: '#DC2626',
100: '#FEF2F2',
},
} as const;
export const colorValues = {
primary: '#C41E3A',
primaryHover: '#A01830',
primaryLight: '#D4244A',
primaryBg: '#FEF2F4',
techBlue: '#00D9FF',
techBlueHover: '#00B8D9',
techBlueLight: '#33E1FF',
techPurple: '#A855F7',
techPurpleHover: '#9333EA',
techPurpleLight: '#C084FC',
techCyan: '#06B6D4',
textPrimary: '#FAFAFA',
textSecondary: '#D4D4D4',
textTertiary: '#A3A3A3',
textMuted: '#737373',
bgPrimary: '#0A0A0A',
bgSecondary: '#141414',
bgTertiary: '#1A1A1A',
bgHover: '#242424',
border: '#262626',
borderHover: '#333333',
success: '#16A34A',
successBg: '#F0FDF4',
warning: '#D97706',
warningBg: '#FFFBEB',
info: '#0284C7',
infoBg: '#F0F9FF',
error: '#DC2626',
errorBg: '#FEF2F2',
} as const;
export const gradients = {
primary: 'linear-gradient(135deg, #00D9FF 0%, #A855F7 100%)',
reverse: 'linear-gradient(135deg, #A855F7 0%, #00D9FF 100%)',
glow: 'radial-gradient(circle, rgba(0, 217, 255, 0.15) 0%, transparent 70%)',
glowPurple: 'radial-gradient(circle, rgba(168, 85, 247, 0.15) 0%, transparent 70%)',
} as const;
export type BrandColor = typeof brandColors;
export type ColorValue = typeof colorValues;
export type Gradient = typeof gradients;
Step 2: 验证类型定义
运行 TypeScript 编译检查:
npm run build
Expected: 无类型错误
Step 3: 提交更改
git add src/lib/colors.ts
git commit -m "feat: 更新色彩系统定义
- 添加科技蓝、紫色、青色色彩系列
- 更新中性色系列
- 添加渐变色定义
- 完善类型定义"
Task 3: 创建渐变色工具函数
Files:
- Create:
src/lib/gradients.ts
Step 1: 创建渐变色工具函数
import { gradients } from './colors';
export const getGradientStyle = (type: keyof typeof gradients) => {
return {
background: gradients[type],
};
};
export const getGlowStyle = (color: 'blue' | 'purple', opacity: number = 0.15) => {
const colorValue = color === 'blue' ? '0, 217, 255' : '168, 85, 247';
return {
background: `radial-gradient(circle, rgba(${colorValue}, ${opacity}) 0%, transparent 70%)`,
};
};
export const getBorderGradientStyle = () => {
return {
borderImage: `${gradients.primary} 1`,
};
};
export const getTextGradientStyle = () => {
return {
background: gradients.primary,
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text',
};
};
Step 2: 创建测试文件
import { getGradientStyle, getGlowStyle, getTextGradientStyle } from '../gradients';
describe('gradients utilities', () => {
test('getGradientStyle returns correct gradient', () => {
const style = getGradientStyle('primary');
expect(style.background).toContain('linear-gradient');
});
test('getGlowStyle returns correct glow for blue', () => {
const style = getGlowStyle('blue', 0.2);
expect(style.background).toContain('rgba(0, 217, 255, 0.2)');
});
test('getGlowStyle returns correct glow for purple', () => {
const style = getGlowStyle('purple', 0.1);
expect(style.background).toContain('rgba(168, 85, 247, 0.1)');
});
test('getTextGradientStyle returns correct text gradient', () => {
const style = getTextGradientStyle();
expect(style.WebkitBackgroundClip).toBe('text');
expect(style.WebkitTextFillColor).toBe('transparent');
});
});
Step 3: 运行测试
npm test -- src/lib/gradients.test.ts
Expected: 所有测试通过
Step 4: 提交更改
git add src/lib/gradients.ts src/lib/gradients.test.ts
git commit -m "feat: 添加渐变色工具函数
- 创建渐变色样式生成函数
- 创建光晕效果生成函数
- 创建文字渐变效果函数
- 添加单元测试"
Phase 2: UI 组件更新
Task 4: 更新按钮组件
Files:
- Modify:
src/components/ui/button.tsx
Step 1: 更新按钮样式变体
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-tech-blue)] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-[var(--color-brand-primary)] text-white hover:bg-[var(--color-brand-primary-hover)] hover:shadow-[0_0_20px_rgba(196,30,58,0.4)] hover:-translate-y-0.5 active:scale-[0.98]",
secondary:
"bg-gradient-to-br from-[var(--color-tech-blue)] to-[var(--color-tech-purple)] text-white hover:shadow-[0_0_20px_rgba(0,217,255,0.3)] hover:-translate-y-0.5 active:scale-[0.98]",
outline:
"border border-[var(--color-tech-blue)] bg-transparent text-[var(--color-tech-blue)] hover:bg-[rgba(0,217,255,0.1)] hover:shadow-[0_0_20px_rgba(0,217,255,0.2)]",
ghost:
"text-[var(--color-text-secondary)] hover:bg-[rgba(255,255,255,0.05)] hover:text-[var(--color-text-primary)]",
link:
"text-[var(--color-tech-blue)] underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-12 rounded-lg px-6 text-base",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }
Step 2: 测试按钮组件
在浏览器中打开网站,检查按钮样式是否正确应用。
Step 3: 提交更改
git add src/components/ui/button.tsx
git commit -m "feat: 更新按钮组件样式
- 更新默认按钮为印章红色
- 添加科技蓝渐变次要按钮
- 更新轮廓按钮样式
- 添加悬停发光效果
- 添加点击缩放反馈"
Task 5: 更新卡片组件
Files:
- Modify:
src/components/ui/card.tsx
Step 1: 更新卡片样式
import * as React from "react"
import { cn } from "@/lib/utils"
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-xl border border-[var(--color-border-primary)] bg-[var(--color-bg-tertiary)] text-[var(--color-text-primary)] transition-all duration-300 hover:border-[var(--color-tech-blue)] hover:shadow-[0_0_30px_rgba(0,217,255,0.15)] hover:-translate-y-1",
className
)}
{...props}
/>
))
Card.displayName = "Card"
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight text-[var(--color-text-primary)]",
className
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-[var(--color-text-secondary)]", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
Step 2: 测试卡片组件
在浏览器中打开网站,检查卡片样式是否正确应用。
Step 3: 提交更改
git add src/components/ui/card.tsx
git commit -m "feat: 更新卡片组件样式
- 更新卡片背景色为深灰
- 添加悬停边框发光效果
- 添加悬停上移动画
- 更新文字颜色变量"
Task 6: 更新导航栏组件
Files:
- Modify:
src/components/layout/header.tsx
Step 1: 更新导航栏样式
在导航栏组件中添加新的样式类:
// 在 header.tsx 中更新导航栏样式
<header className="fixed top-0 left-0 right-0 z-50 h-16 bg-[rgba(10,10,10,0.8)] backdrop-blur-xl border-b border-[var(--color-border-primary)]">
{/* 导航内容 */}
</header>
Step 2: 更新导航链接样式
// 更新导航链接样式
<a className="text-[var(--color-text-secondary)] hover:text-[var(--color-tech-blue)] transition-colors duration-200 relative group">
{link.name}
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-[var(--color-tech-blue)] transition-all duration-200 group-hover:w-full" />
</a>
Step 3: 测试导航栏
在浏览器中打开网站,检查导航栏样式是否正确应用。
Step 4: 提交更改
git add src/components/layout/header.tsx
git commit -m "feat: 更新导航栏样式
- 更新导航栏背景为半透明深色
- 添加模糊效果
- 更新导航链接悬停效果
- 添加下划线动画"
Phase 3: 页面布局优化
Task 7: 更新 Hero 区域
Files:
- Modify:
src/components/sections/hero-section.tsx
Step 1: 更新 Hero 区域背景
<section className="relative min-h-screen flex items-center justify-center bg-[var(--color-bg-primary)] overflow-hidden">
{/* 网格背景 */}
<div className="absolute inset-0 opacity-[0.03]" style={{
backgroundImage: 'linear-gradient(var(--color-tech-blue) 1px, transparent 1px), linear-gradient(90deg, var(--color-tech-blue) 1px, transparent 1px)',
backgroundSize: '50px 50px'
}} />
{/* 光晕效果 */}
<div className="absolute top-1/4 left-1/4 w-96 h-96 rounded-full opacity-10" style={{
background: 'radial-gradient(circle, rgba(0, 217, 255, 0.15) 0%, transparent 70%)'
}} />
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 rounded-full opacity-10" style={{
background: 'radial-gradient(circle, rgba(168, 85, 247, 0.15) 0%, transparent 70%)'
}} />
{/* 内容 */}
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Hero 内容 */}
</div>
</section>
Step 2: 更新 Hero 文案样式
<h1 className="text-5xl md:text-6xl lg:text-7xl font-bold text-[var(--color-text-primary)] mb-6">
睿新致遠,智创未来
</h1>
<p className="text-xl md:text-2xl text-[var(--color-text-secondary)] mb-8 max-w-2xl">
以科技创新驱动企业数字化转型,打造智慧未来
</p>
Step 3: 测试 Hero 区域
在浏览器中打开网站,检查 Hero 区域样式是否正确应用。
Step 4: 提交更改
git add src/components/sections/hero-section.tsx
git commit -m "feat: 更新 Hero 区域设计
- 添加网格背景
- 添加科技蓝和紫色光晕效果
- 更新文案样式
- 优化布局结构"
Task 8: 创建粒子效果组件
Files:
- Create:
src/components/effects/particles.tsx
Step 1: 创建粒子效果组件
'use client';
import { useEffect, useRef } from 'react';
import { motion } from 'framer-motion';
interface Particle {
x: number;
y: number;
size: number;
speedX: number;
speedY: number;
color: string;
}
export function Particles() {
const canvasRef = useRef<HTMLCanvasElement>(null);
const particlesRef = useRef<Particle[]>([]);
const animationRef = useRef<number>();
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
const resizeCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// 初始化粒子
const particleCount = 50;
const colors = ['#00D9FF', '#A855F7', '#06B6D4'];
for (let i = 0; i < particleCount; i++) {
particlesRef.current.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 3 + 1,
speedX: (Math.random() - 0.5) * 0.5,
speedY: (Math.random() - 0.5) * 0.5,
color: colors[Math.floor(Math.random() * colors.length)],
});
}
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
particlesRef.current.forEach((particle) => {
particle.x += particle.speedX;
particle.y += particle.speedY;
if (particle.x < 0 || particle.x > canvas.width) particle.speedX *= -1;
if (particle.y < 0 || particle.y > canvas.height) particle.speedY *= -1;
ctx.beginPath();
ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
ctx.fillStyle = particle.color;
ctx.fill();
});
animationRef.current = requestAnimationFrame(animate);
};
animate();
return () => {
window.removeEventListener('resize', resizeCanvas);
if (animationRef.current) {
cancelAnimationFrame(animationRef.current);
}
};
}, []);
return (
<canvas
ref={canvasRef}
className="absolute inset-0 pointer-events-none"
style={{ opacity: 0.6 }}
/>
);
}
Step 2: 在 Hero 区域中使用粒子效果
import { Particles } from '@/components/effects/particles';
export function HeroSection() {
return (
<section className="relative min-h-screen">
<Particles />
{/* 其他内容 */}
</section>
);
}
Step 3: 测试粒子效果
在浏览器中打开网站,检查粒子效果是否正常运行。
Step 4: 提交更改
git add src/components/effects/particles.tsx src/components/sections/hero-section.tsx
git commit -m "feat: 添加粒子效果组件
- 创建 Canvas 粒子动画
- 使用科技蓝、紫色、青色粒子
- 添加粒子漂浮动画
- 在 Hero 区域中集成"
Task 9: 创建数字计数动画组件
Files:
- Create:
src/components/effects/count-up.tsx
Step 1: 创建数字计数动画组件
'use client';
import { useEffect, useRef, useState } from 'react';
import { useInView } from 'framer-motion';
interface CountUpProps {
end: number;
duration?: number;
prefix?: string;
suffix?: string;
className?: string;
}
export function CountUp({ end, duration = 2000, prefix = '', suffix = '', className }: CountUpProps) {
const ref = useRef<HTMLSpanElement>(null);
const isInView = useInView(ref, { once: true });
const [count, setCount] = useState(0);
useEffect(() => {
if (!isInView) return;
let startTime: number;
let animationFrame: number;
const animate = (currentTime: number) => {
if (!startTime) startTime = currentTime;
const progress = Math.min((currentTime - startTime) / duration, 1);
setCount(Math.floor(progress * end));
if (progress < 1) {
animationFrame = requestAnimationFrame(animate);
}
};
animationFrame = requestAnimationFrame(animate);
return () => {
if (animationFrame) {
cancelAnimationFrame(animationFrame);
}
};
}, [isInView, end, duration]);
return (
<span ref={ref} className={className}>
{prefix}{count.toLocaleString()}{suffix}
</span>
);
}
Step 2: 在数据卡片中使用计数动画
import { CountUp } from '@/components/effects/count-up';
export function DataCard() {
return (
<div className="p-6 rounded-xl border border-[var(--color-border-primary)] bg-[var(--color-bg-tertiary)]">
<CountUp end={1000} suffix="+" className="text-4xl font-bold text-[var(--color-tech-blue)]" />
<p className="text-[var(--color-text-secondary)] mt-2">服务客户</p>
</div>
);
}
Step 3: 测试计数动画
在浏览器中打开网站,检查计数动画是否正常运行。
Step 4: 提交更改
git add src/components/effects/count-up.tsx
git commit -m "feat: 添加数字计数动画组件
- 创建 CountUp 组件
- 支持前缀、后缀
- 支持自定义持续时间
- 使用 Intersection Observer 触发"
Phase 4: 动效与交互
Task 10: 创建滚动揭示 Hook
Files:
- Create:
src/hooks/use-scroll-reveal.ts
Step 1: 创建滚动揭示 Hook
import { useEffect, useRef, useState } from 'react';
export function useScrollReveal<T extends HTMLElement>(threshold = 0.1) {
const ref = useRef<T>(null);
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const element = ref.current;
if (!element) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
observer.unobserve(element);
}
},
{ threshold }
);
observer.observe(element);
return () => {
observer.unobserve(element);
};
}, [threshold]);
return { ref, isVisible };
}
Step 2: 创建滚动揭示组件
'use client';
import { motion } from 'framer-motion';
import { useScrollReveal } from '@/hooks/use-scroll-reveal';
interface ScrollRevealProps {
children: React.ReactNode;
className?: string;
delay?: number;
}
export function ScrollReveal({ children, className, delay = 0 }: ScrollRevealProps) {
const { ref, isVisible } = useScrollReveal<HTMLDivElement>();
return (
<motion.div
ref={ref}
initial={{ opacity: 0, y: 30 }}
animate={isVisible ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
transition={{ duration: 0.6, delay, ease: [0.16, 1, 0.3, 1] }}
className={className}
>
{children}
</motion.div>
);
}
Step 3: 在页面中使用滚动揭示
import { ScrollReveal } from '@/components/effects/scroll-reveal';
export function ProductsSection() {
return (
<section>
<ScrollReveal>
<h2>产品矩阵</h2>
</ScrollReveal>
<div className="grid grid-cols-3 gap-6">
{products.map((product, index) => (
<ScrollReveal key={product.id} delay={index * 0.1}>
<ProductCard product={product} />
</ScrollReveal>
))}
</div>
</section>
);
}
Step 4: 提交更改
git add src/hooks/use-scroll-reveal.ts src/components/effects/scroll-reveal.tsx
git commit -m "feat: 添加滚动揭示动效
- 创建 useScrollReveal Hook
- 创建 ScrollReveal 组件
- 支持延迟动画
- 使用 Intersection Observer"
Task 11: 创建光晕脉动组件
Files:
- Create:
src/components/effects/glow-pulse.tsx
Step 1: 创建光晕脉动组件
'use client';
import { motion } from 'framer-motion';
interface GlowPulseProps {
color: 'blue' | 'purple';
size?: number;
className?: string;
}
export function GlowPulse({ color, size = 400, className }: GlowPulseProps) {
const colorValue = color === 'blue' ? '0, 217, 255' : '168, 85, 247';
return (
<motion.div
className={`rounded-full pointer-events-none ${className}`}
style={{
width: size,
height: size,
background: `radial-gradient(circle, rgba(${colorValue}, 0.15) 0%, transparent 70%)`,
}}
animate={{
scale: [1, 1.15, 1],
opacity: [0.1, 0.15, 0.1],
}}
transition={{
duration: 4,
repeat: Infinity,
ease: 'easeInOut',
}}
/>
);
}
Step 2: 在 Hero 区域中使用光晕脉动
import { GlowPulse } from '@/components/effects/glow-pulse';
export function HeroSection() {
return (
<section className="relative">
<GlowPulse color="blue" size={400} className="absolute top-1/4 left-1/4" />
<GlowPulse color="purple" size={400} className="absolute bottom-1/4 right-1/4" />
{/* 其他内容 */}
</section>
);
}
Step 3: 提交更改
git add src/components/effects/glow-pulse.tsx
git commit -m "feat: 添加光晕脉动组件
- 创建 GlowPulse 组件
- 支持蓝色和紫色光晕
- 添加脉动动画
- 可自定义大小"
Phase 5: 响应式适配
Task 12: 优化移动端导航
Files:
- Modify:
src/components/layout/mobile-menu.tsx
Step 1: 更新移动端菜单样式
import { motion } from 'framer-motion';
export function MobileMenu() {
return (
<motion.div
initial={{ opacity: 0, x: '100%' }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: '100%' }}
transition={{ duration: 0.2 }}
className="fixed inset-0 z-50 bg-[var(--color-bg-primary)]"
>
<div className="flex flex-col h-full">
{/* 菜单项 */}
<nav className="flex-1 px-6 py-8">
{links.map((link) => (
<a
key={link.href}
href={link.href}
className="block py-4 text-lg text-[var(--color-text-primary)] hover:text-[var(--color-tech-blue)] transition-colors"
>
{link.name}
</a>
))}
</nav>
</div>
</motion.div>
);
}
Step 2: 测试移动端导航
在移动设备或浏览器开发者工具中测试移动端导航。
Step 3: 提交更改
git add src/components/layout/mobile-menu.tsx
git commit -m "feat: 优化移动端导航
- 更新移动端菜单背景色
- 添加滑入动画
- 优化菜单项样式
- 改善触摸体验"
Task 13: 优化响应式布局
Files:
- Modify:
src/app/(marketing)/page.tsx
Step 1: 更新首页响应式布局
export default function HomePage() {
return (
<main>
{/* Hero */}
<section className="min-h-screen flex items-center">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 w-full">
{/* 内容 */}
</div>
</section>
{/* 产品矩阵 */}
<section className="py-20 md:py-24 lg:py-32">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 lg:gap-8">
{/* 产品卡片 */}
</div>
</div>
</section>
</main>
);
}
Step 2: 测试响应式布局
在不同设备尺寸下测试页面布局。
Step 3: 提交更改
git add src/app/\(marketing\)/page.tsx
git commit -m "feat: 优化响应式布局
- 更新 Section 间距
- 优化网格布局断点
- 改善移动端体验
- 统一内边距规范"
Phase 6: 性能优化与测试
Task 14: 添加性能监控
Files:
- Create:
src/components/analytics/performance-monitor.tsx
Step 1: 创建性能监控组件
'use client';
import { useEffect } from 'react';
export function PerformanceMonitor() {
useEffect(() => {
if (typeof window === 'undefined') return;
// 监控 Web Vitals
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log('[Performance]', entry.name, entry.duration);
});
});
observer.observe({ entryTypes: ['measure', 'navigation'] });
return () => observer.disconnect();
}, []);
return null;
}
Step 2: 在布局中添加性能监控
import { PerformanceMonitor } from '@/components/analytics/performance-monitor';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<PerformanceMonitor />
{children}
</body>
</html>
);
}
Step 3: 提交更改
git add src/components/analytics/performance-monitor.tsx src/app/layout.tsx
git commit -m "feat: 添加性能监控
- 创建性能监控组件
- 监控 Web Vitals 指标
- 输出性能日志"
Task 15: 运行性能测试
Files:
- Test:
e2e-tests/tests/test_performance.py
Step 1: 运行 Lighthouse 测试
npx lighthouse http://localhost:3000 --output=json --output-path=./lighthouse-report.json
Expected: 性能分数 ≥ 90
Step 2: 运行 E2E 性能测试
pytest e2e-tests/tests/test_performance.py -v
Expected: 所有测试通过
Step 3: 提交测试报告
git add lighthouse-report.json
git commit -m "test: 添加性能测试报告
- 运行 Lighthouse 测试
- 验证性能指标
- 确保性能分数达标"
最终验收
Task 16: 全面测试与验收
Step 1: 运行所有测试
npm run build
npm run lint
pytest e2e-tests/ -v
Expected: 所有测试通过,无错误
Step 2: 视觉验收
在浏览器中检查:
- 配色方案是否符合设计
- 组件样式是否正确
- 动效是否流畅
- 响应式布局是否正常
Step 3: 性能验收
检查 Lighthouse 报告:
- Performance ≥ 90
- Accessibility ≥ 95
- Best Practices ≥ 90
- SEO ≥ 90
Step 4: 提交最终版本
git add .
git commit -m "feat: 完成 Novalon 官网重新设计
✅ 核心配色系统升级
✅ UI 组件更新
✅ 页面布局优化
✅ 动效与交互增强
✅ 响应式适配完善
✅ 性能优化完成
通过所有测试和验收标准"
总结
本实施计划将 Novalon 官网重新设计方案分解为 16 个可执行任务,每个任务都包含:
- 明确的文件路径
- 完整的代码实现
- 具体的测试步骤
- 清晰的提交信息
遵循 TDD、DRY、YAGNI 原则,确保高质量交付。
预计完成时间: 2-3 个工作日
下一步: 选择执行方式