feat(marketing): 重构营销页面与四层叙事组件体系
- 重构 About、Contact、Team 等静态营销页面 - 重构 News 新闻列表与详情页 - 重构 Products 产品目录、详情与独立产品页面 - 重构 Services 与 Solutions 服务/解决方案页面 - 重构 Detail 四层叙事组件 (Hero → Value → Trust → CTA) - 重构 Sections 页面区块组件 (Hero, CTA, SocialProof, WhyUs 等) - 新增 SectionHeader、ServiceCard、CaseCard 等可复用组件
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
'use client';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
import {
|
||||
CheckCircle2,
|
||||
Zap,
|
||||
Clock,
|
||||
Users,
|
||||
Award,
|
||||
TrendingUp,
|
||||
type LucideIcon,
|
||||
} from 'lucide-react';
|
||||
import { TiltCard, InkGlowCard } from './micro-interactions';
|
||||
import { SectionHeader, InkDivider } from './brand-elements';
|
||||
import type { Service } from '@/lib/constants/services';
|
||||
|
||||
interface ServiceValueSectionProps {
|
||||
service: Service;
|
||||
}
|
||||
|
||||
export function ServiceValueSection({ service }: ServiceValueSectionProps) {
|
||||
const icons: LucideIcon[] = [Zap, Clock, Users, Award, TrendingUp];
|
||||
|
||||
return (
|
||||
<section className="relative bg-white py-24 lg:py-32 overflow-hidden">
|
||||
<div className="container-wide relative">
|
||||
<SectionHeader
|
||||
badge="专业服务"
|
||||
title={`为什么选择我们的${service.title}?`}
|
||||
subtitle={service.overview}
|
||||
icon={Zap}
|
||||
/>
|
||||
|
||||
<div className="mt-16">
|
||||
<div className="flex items-center gap-4 mb-8">
|
||||
<div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-[#C41E3A] to-[#99182d] flex items-center justify-center shadow-md shadow-brand/20">
|
||||
<Zap className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold text-ink">核心能力</h3>
|
||||
<p className="text-sm text-text-muted mt-0.5">我们提供的服务特色</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{service.features.map((feature, index) => {
|
||||
const Icon = icons[index % icons.length]!;
|
||||
|
||||
return (
|
||||
<InkGlowCard
|
||||
key={feature}
|
||||
active={index === 0}
|
||||
className="group p-6 hover:border-brand/20"
|
||||
>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{
|
||||
delay: index * 0.08,
|
||||
duration: 0.5,
|
||||
ease: [0.22, 1, 0.36, 1] as const,
|
||||
}}
|
||||
>
|
||||
<div className="flex items-start gap-4">
|
||||
<div
|
||||
className={`shrink-0 w-11 h-11 rounded-xl flex items-center justify-center transition-all duration-300 shadow-sm ${
|
||||
index === 0
|
||||
? 'bg-gradient-to-br from-[#C41E3A] to-[#99182d] text-white'
|
||||
: 'bg-bg-secondary text-text-secondary group-hover:from-[#C41E3A] group-hover:to-[#99182d] group-hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<Icon className="w-5.5 h-5.5" />
|
||||
</div>
|
||||
<p className="text-sm font-medium text-text-secondary leading-relaxed pt-2">
|
||||
{feature.split(':')[1] || feature}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</InkGlowCard>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-80px' }}
|
||||
transition={{ duration: 0.75, delay: 0.3 }}
|
||||
className="mt-16"
|
||||
>
|
||||
<InkDivider variant="subtle" />
|
||||
|
||||
<div className="flex items-center gap-4 mb-8">
|
||||
<div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-green-500 to-emerald-600 flex items-center justify-center shadow-md shadow-green-500/20">
|
||||
<Award className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold text-ink">服务优势</h3>
|
||||
<p className="text-sm text-text-muted mt-0.5">选择我们的理由</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-5">
|
||||
{service.benefits.map((benefit, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, x: index % 2 === 0 ? -20 : 20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{
|
||||
delay: 0.4 + index * 0.06,
|
||||
duration: 0.5,
|
||||
ease: [0.22, 1, 0.36, 1] as const,
|
||||
}}
|
||||
className="group p-6 rounded-2xl bg-bg-secondary border border-border-primary hover:border-brand/30 hover:shadow-md hover:-translate-y-1 transition-all duration-300"
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="w-5 h-5 text-green-600 mt-0.5 shrink-0 group-hover:scale-110 transition-transform" />
|
||||
<p className="text-sm font-medium text-text-secondary leading-relaxed">{benefit}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{service.process && service.process.length > 0 && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 32 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: '-80px' }}
|
||||
transition={{ duration: 0.75, delay: 0.45 }}
|
||||
className="mt-20"
|
||||
>
|
||||
<InkDivider variant="decorative" />
|
||||
|
||||
<div className="text-center mb-12">
|
||||
<h3 className="text-2xl md:text-3xl font-bold tracking-tight text-ink">
|
||||
服务流程
|
||||
</h3>
|
||||
<p className="text-text-secondary mt-3">标准化流程保障服务质量</p>
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute left-8 top-0 bottom-0 w-0.5 bg-gradient-to-b from-[#C41E3A] via-blue-400 to-green-400 hidden md:block" />
|
||||
|
||||
<div className="space-y-6">
|
||||
{service.process.map((step, index) => (
|
||||
<motion.div
|
||||
key={step}
|
||||
initial={{ opacity: 0, x: -30 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{
|
||||
delay: 0.5 + index * 0.1,
|
||||
duration: 0.55,
|
||||
ease: [0.22, 1, 0.36, 1] as const,
|
||||
}}
|
||||
className="relative flex gap-6 group"
|
||||
>
|
||||
<div className="relative z-10 shrink-0">
|
||||
<div className="w-16 h-16 rounded-full bg-white border-4 border-brand flex items-center justify-center shadow-md group-hover:scale-110 transition-transform duration-300">
|
||||
<span className="text-lg font-bold text-brand">{String(index + 1).padStart(2, '0')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TiltCard
|
||||
tiltAmount={5}
|
||||
glareEnable={false}
|
||||
className="flex-1 p-6 rounded-2xl bg-white border border-border-primary hover:border-brand/30 hover:shadow-md transition-all"
|
||||
>
|
||||
<h4 className="font-bold text-ink mb-2">
|
||||
{step.split(':')[0]}
|
||||
</h4>
|
||||
<p className="text-sm text-text-secondary leading-relaxed">
|
||||
{step.split(':')[1] || step}
|
||||
</p>
|
||||
</TiltCard>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user