Files
novalon-website/src/app/(marketing)/_archive/home-content-v4.tsx
T
张翔 8def296301 chore(cleanup): 清理废弃组件与旧版本归档
- 删除 detail-v2 旧版叙事组件
- 删除 narrative 旧版区块组件
- 删除 theme-toggle 主题切换与 theme-context 上下文
- 删除 detail-data-proof/service-value/solution-value 旧版组件
- 删除 home-content-v2/v3 旧版首页
- 归档旧版营销页面内容至 _archive 目录
2026-07-07 06:54:10 +08:00

1044 lines
42 KiB
TypeScript

'use client';
import { useState, useEffect, useRef } from 'react';
import { motion, useScroll, useTransform } from 'framer-motion';
import { StaticLink } from '@/components/ui/static-link';
import { useReducedMotion } from '@/hooks/use-reduced-motion';
import {
ArrowRight, ChevronRight,
BarChart3, Cpu, Globe, Factory, ShoppingCart, Stethoscope,
GraduationCap, Building, ArrowUpRight,
} from 'lucide-react';
// ============================================================
// Design Tokens — Consulting Grade
// ============================================================
const TOKENS = {
ink: '#0F1419',
inkLight: '#1A2332',
inkSurface: '#1E2938',
gold: '#B8944C',
goldDim: 'rgba(184,148,76,0.18)',
goldText: '#C9A84C',
red: '#C41E3A',
redHover: '#A01830',
redGlow: 'rgba(196,30,58,0.18)',
white: '#FFFFFF',
cream: '#FAF8F5',
creamDark: '#F3F0EB',
gray50: '#F8F9FA',
gray100: '#F1F3F5',
gray200: '#E9ECEF',
gray300: '#DEE2E6',
gray400: '#ADB5BD',
gray500: '#868E96',
gray600: '#495057',
gray700: '#343A40',
} as const;
// Animation easing — natural deceleration (quint-out)
const EASE = [0.22, 1, 0.36, 1] as const;
// ============================================================
// Shared Tailwind utility classes for Mobile First
// ============================================================
const SECTION_PADDING = 'py-20 md:py-36 lg:py-44';
const CONTAINER = 'max-w-[1280px] mx-auto px-5 sm:px-8 lg:px-16';
const TOUCH_TARGET = 'min-h-[44px] min-w-[44px]';
const TAP_FEEDBACK = 'active:scale-[0.98] transition-transform duration-150';
// ============================================================
// Data
// ============================================================
const STRATEGIC_QUESTIONS = [
{
question: '我们的数字化投入,是否真正带来了业务增长?',
description: '许多企业在数字化上投入巨大,却难以量化 ROI。我们帮助您建立可衡量的数字化价值评估体系,让每一分投入都可见、可追踪、可优化。',
link: '/services/consulting',
},
{
question: '数据资产已经积累多年,但如何让它真正驱动决策?',
description: '数据是新时代的石油,但未经提炼无法使用。我们从数据治理到 AI 应用,帮助您构建从数据到洞察到行动的完整闭环。',
link: '/products',
},
{
question: '技术团队和业务团队,如何打破沟通壁垒?',
description: '技术不懂业务痛点,业务不懂技术可能——这是数字化转型最常见的死结。我们用复合型团队和标准化方法论,架起两端的桥梁。',
link: '/solutions',
},
{
question: '面对 AI 浪潮,我们的企业准备好了吗?',
description: 'AI 不是选择题,而是必答题。我们从 AI 成熟度评估到场景落地,帮助您找到最适合的 AI 应用路径,避免盲目跟风。',
link: '/services/ai',
},
];
const CASE_STUDIES = [
{
industry: '制造业',
title: '某大型制造企业 ERP 升级',
context: '原有系统无法支撑业务增长,数据孤岛严重,生产排程效率低下。',
impact: [{ value: '40%', label: '生产效率提升' }, { value: '60%', label: '数据准确率提升' }],
quote: '睿新团队不仅完成了系统升级,更帮助我们建立了数据驱动的运营体系。',
author: 'CTO,某上市制造企业',
image: 'https://images.unsplash.com/photo-1581091226825-a6a2a5aee158?w=800&q=80',
},
{
industry: '零售业',
title: '连锁零售全渠道数字化',
context: '线上线下数据割裂,库存管理混乱,会员体系无法统一。',
impact: [{ value: '25%', label: '营收增长' }, { value: '50%', label: '库存周转优化' }],
quote: '从咨询到落地,睿新团队展现出了超出预期的专业能力和责任心。',
author: 'CEO,某区域零售龙头',
image: 'https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?w=800&q=80',
},
{
industry: '金融业',
title: '金融机构风控平台建设',
context: '监管要求升级,传统风控手段无法满足实时性要求,合规成本高企。',
impact: [{ value: '70%', label: '风控响应提速' }, { value: '99.9%', label: '系统可用性' }],
quote: '睿新的技术方案让我们在监管检查中获得了高度评价。',
author: '风控总监,某持牌金融机构',
image: 'https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=800&q=80',
},
];
const INSIGHTS = [
{
tag: '白皮书',
title: '2026 中国企业数字化转型趋势报告',
desc: '基于 500+ 企业调研数据,深度解读制造业、零售业、金融业的数字化转型路径与 ROI 分析。',
type: 'featured' as const,
image: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=800&q=80',
},
{
tag: '案例研究',
title: '从数据孤岛到智能决策:一家制造企业的三年数字化之路',
desc: '深度复盘某上市制造企业如何通过分阶段数字化实现 40% 效率提升。',
type: 'featured' as const,
image: 'https://images.unsplash.com/photo-1504384308090-c894fdcc538d?w=800&q=80',
},
{
tag: '观点',
title: 'AI 时代,中小企业如何避免"为了数字化而数字化"',
desc: '从投入产出比出发,讨论中小企业在 AI 浪潮中的务实策略。',
date: '2026-06-15',
},
{
tag: '方法论',
title: '数字化转型的四个阶段:评估、规划、实施、优化',
desc: '我们总结的经过 500+ 项目验证的数字化转型方法论。',
date: '2026-06-08',
},
{
tag: '行业洞察',
title: '制造业数字化转型的五大误区',
desc: '避开常见陷阱,让数字化投入真正转化为业务价值。',
date: '2026-05-28',
},
];
const INDUSTRIES = [
{ icon: Factory, name: '制造业', count: '120+ 案例' },
{ icon: ShoppingCart, name: '零售业', count: '80+ 案例' },
{ icon: Building, name: '金融业', count: '60+ 案例' },
{ icon: Stethoscope, name: '医疗健康', count: '40+ 案例' },
{ icon: GraduationCap, name: '教育', count: '30+ 案例' },
{ icon: Globe, name: '政务', count: '50+ 案例' },
{ icon: BarChart3, name: '能源', count: '35+ 案例' },
{ icon: Cpu, name: '科技', count: '90+ 案例' },
];
const TRUST_SIGNALS = [
{ number: '12', unit: '年', label: '行业深耕', desc: '核心团队平均从业经验 12 年以上' },
{ number: '500', unit: '+', label: '企业客户', desc: '覆盖制造、零售、金融、政务等多个行业' },
{ number: '98', unit: '%', label: '客户续约率', desc: '年度客户续约率行业领先' },
{ number: '150', unit: '+', label: '专业顾问', desc: '技术+业务复合型团队' },
{ number: '6', unit: '款', label: '自研产品', desc: '覆盖数据、协同、AI 等核心领域' },
{ number: '30', unit: '天', label: '平均交付周期', desc: '敏捷迭代,快速验证业务价值' },
];
const PROCESS_STEPS = [
{ step: '01', title: '需求诊断', desc: '深入业务场景,精准定位痛点与机会点' },
{ step: '02', title: '方案设计', desc: '量身定制技术路径与实施路线图' },
{ step: '03', title: '敏捷交付', desc: '快速迭代、持续验证,确保方案可落地' },
{ step: '04', title: '效果评估', desc: '基于数据量化评估,确保 ROI 可衡量' },
{ step: '05', title: '长期陪跑', desc: '持续优化迭代,陪伴企业长期成长' },
];
// ============================================================
// Hooks
// ============================================================
function useCountUp(end: number, duration = 2000, startCounting: boolean) {
const [count, setCount] = useState(0);
const frameRef = useRef<number>(0);
useEffect(() => {
if (!startCounting) return;
const startTime = performance.now();
const animate = (now: number) => {
const progress = Math.min((now - startTime) / duration, 1);
// ease-out cubic
const eased = 1 - Math.pow(1 - progress, 3);
setCount(Math.floor(end * eased));
if (progress < 1) {
frameRef.current = requestAnimationFrame(animate);
} else {
setCount(end);
}
};
frameRef.current = requestAnimationFrame(animate);
return () => cancelAnimationFrame(frameRef.current);
}, [end, duration, startCounting]);
return count;
}
// ============================================================
// Sub-components
// ============================================================
function SectionHeader({ label, title, highlight, desc, light = false }: {
label: string;
title: string;
highlight?: string;
desc?: string;
light?: boolean;
}) {
return (
<div className="mb-12 md:mb-16 lg:mb-20">
<div
className="text-[10px] tracking-[4px] uppercase font-medium mb-4 md:mb-5"
style={{ color: light ? 'rgba(255,255,255,0.4)' : TOKENS.goldText }}
>
{label}
</div>
<h2
className="font-serif text-[clamp(28px,6vw,52px)] font-bold leading-[1.1] tracking-[-1px] mb-4 md:mb-5"
style={{ color: light ? TOKENS.white : TOKENS.ink }}
>
{title}{highlight && <span style={{ color: TOKENS.red }}>{highlight}</span>}
</h2>
{desc && (
<p
className="text-[15px] leading-relaxed max-w-[480px]"
style={{ color: light ? 'rgba(255,255,255,0.35)' : TOKENS.gray500 }}
>
{desc}
</p>
)}
</div>
);
}
function FadeInView({ children, className = '', delay = 0 }: {
children: React.ReactNode;
className?: string;
delay?: number;
}) {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
className={className}
initial={shouldReduceMotion ? {} : { opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-40px' }}
transition={{ duration: 0.6, delay, ease: EASE }}
>
{children}
</motion.div>
);
}
// ============================================================
// Module 1: Hero — Mobile First
// ============================================================
function HeroSection() {
const shouldReduceMotion = useReducedMotion();
const heroRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: heroRef,
offset: ['start start', 'end start'],
});
const opacity = useTransform(scrollYProgress, [0, 0.6], [1, 0]);
const scale = useTransform(scrollYProgress, [0, 0.6], [1, 0.95]);
const y = useTransform(scrollYProgress, [0, 0.6], [0, 30]);
return (
<section
ref={heroRef}
className="relative min-h-[100svh] flex items-center overflow-hidden"
style={{ background: TOKENS.ink }}
>
{/* Hero Image Background */}
<div className="absolute inset-0 z-0">
<img
src="https://images.unsplash.com/photo-1497366216548-37526070297c?w=1800&q=85"
alt=""
className="w-full h-full object-cover"
loading="eager"
style={{ opacity: 0.35 }}
/>
{/* Gradient overlays */}
<div className="absolute inset-0" style={{
background: `linear-gradient(135deg, ${TOKENS.ink} 0%, transparent 50%, ${TOKENS.ink} 100%)`,
}} />
<div className="absolute inset-0" style={{
background: `radial-gradient(ellipse 60% 50% at 50% 40%, rgba(196,30,58,0.12), transparent 70%)`,
}} />
</div>
{/* Grid texture overlay */}
<div
className="absolute inset-0 z-[1] pointer-events-none opacity-[0.025]"
style={{
backgroundImage: `linear-gradient(rgba(255,255,255,0.5) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.5) 1px, transparent 1px)`,
backgroundSize: '60px 60px',
maskImage: 'radial-gradient(ellipse 70% 60% at 50% 40%, black 30%, transparent 70%)',
}}
/>
{/* Content */}
<motion.div
className="relative z-10 w-full max-w-[1280px] mx-auto px-5 sm:px-8 lg:px-16 py-24 md:py-32"
style={{ opacity, scale, y }}
>
<div className="max-w-[720px]">
{/* Eyebrow */}
<motion.div
className="text-[10px] sm:text-[11px] tracking-[4px] sm:tracking-[5px] uppercase font-medium mb-6 md:mb-8"
style={{ color: TOKENS.goldText }}
initial={shouldReduceMotion ? {} : { opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.1, ease: EASE }}
>
企业数字化转型
</motion.div>
{/* Title — fluid clamp: 36px mobile → 88px desktop */}
<motion.h1
className="font-serif text-[clamp(36px,10vw,88px)] font-black leading-[1.04] tracking-[-1.5px] sm:tracking-[-2.5px] text-white mb-6 md:mb-8"
initial={shouldReduceMotion ? {} : { opacity: 0, y: 24 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 0.2, ease: EASE }}
>
让每一次数字化<br />
<span style={{ color: TOKENS.red }}>转型</span>掷地有声
</motion.h1>
{/* Subtitle */}
<motion.p
className="text-[15px] sm:text-lg leading-relaxed max-w-[500px] mb-3 md:mb-4 font-light"
style={{ color: 'rgba(255,255,255,0.4)' }}
initial={shouldReduceMotion ? {} : { opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.35, ease: EASE }}
>
12 年深耕,为 500+ 中国企业提供从战略到落地的全链路数字化服务
</motion.p>
{/* Strategic Question */}
<motion.p
className="font-serif text-[14px] sm:text-base italic mb-10 md:mb-12"
style={{ color: 'rgba(255,255,255,0.2)' }}
initial={shouldReduceMotion ? {} : { opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.45, ease: EASE }}
>
您的企业,准备好迎接下一阶段的增长了吗?
</motion.p>
{/* CTAs — touch-friendly */}
<motion.div
className="flex flex-col sm:flex-row gap-3 sm:gap-5 items-start sm:items-center mb-12 md:mb-20"
initial={shouldReduceMotion ? {} : { opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.55, ease: EASE }}
>
<StaticLink
href="/contact"
className={`${TOUCH_TARGET} ${TAP_FEEDBACK} inline-flex items-center justify-center gap-2.5 px-6 sm:px-8 py-3.5 text-sm font-medium text-white rounded-sm transition-all duration-300 hover:-translate-y-0.5`}
style={{ background: TOKENS.red }}
onMouseEnter={e => {
e.currentTarget.style.background = TOKENS.redHover;
e.currentTarget.style.boxShadow = `0 8px 32px ${TOKENS.redGlow}`;
}}
onMouseLeave={e => {
e.currentTarget.style.background = TOKENS.red;
e.currentTarget.style.boxShadow = 'none';
}}
>
预约咨询
<ArrowRight className="w-4 h-4" />
</StaticLink>
<StaticLink
href="/services"
className={`${TOUCH_TARGET} inline-flex items-center gap-2 text-sm font-normal transition-all duration-300 border-b hover:border-white/25`}
style={{ color: 'rgba(255,255,255,0.45)', borderColor: 'rgba(255,255,255,0.1)', padding: '12px 0' }}
>
了解我们的方法
</StaticLink>
</motion.div>
{/* Metrics Row */}
<motion.div
className="flex gap-8 md:gap-16 flex-wrap"
initial={shouldReduceMotion ? {} : { opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.7, ease: EASE }}
>
{[
{ value: '12', unit: '', label: '年行业深耕' },
{ value: '500', unit: '+', label: '企业客户信任' },
{ value: '98', unit: '%', label: '客户年度续约率' },
].map(item => (
<div key={item.label} className="flex flex-col">
<div className="font-serif text-[28px] sm:text-[32px] md:text-[36px] font-bold text-white leading-none mb-1 tracking-[-1px]">
{item.value}
<span style={{ color: TOKENS.red, fontSize: '0.5em' }}>{item.unit}</span>
</div>
<div className="text-[10px] sm:text-[11px] tracking-[1px]" style={{ color: 'rgba(255,255,255,0.25)' }}>
{item.label}
</div>
</div>
))}
</motion.div>
</div>
</motion.div>
{/* Scroll indicator — hidden on mobile */}
<div className="absolute bottom-8 md:bottom-10 left-1/2 -translate-x-1/2 z-10 hidden md:flex flex-col items-center gap-2.5">
<div className="w-px h-10 relative overflow-hidden" style={{ background: 'rgba(255,255,255,0.06)' }}>
<motion.div
className="absolute top-0 left-0 w-full h-[20%]"
style={{ background: 'rgba(255,255,255,0.2)' }}
animate={{ y: [0, 30, 0] }}
transition={{ duration: 2.5, repeat: Infinity, ease: 'easeInOut' }}
/>
</div>
<span className="text-[9px] tracking-[4px]" style={{ color: 'rgba(255,255,255,0.1)' }}>SCROLL</span>
</div>
</section>
);
}
// ============================================================
// Module 2: Strategic Questions — Mobile First
// ============================================================
function StrategicQuestionsSection() {
return (
<section className={SECTION_PADDING} style={{ background: TOKENS.white }}>
<div className={CONTAINER}>
<FadeInView>
<SectionHeader
label="Strategic Questions"
title="我们帮助您回答"
highlight="关键问题"
desc="在启动任何数字化项目之前,先问对问题"
/>
</FadeInView>
<div>
{STRATEGIC_QUESTIONS.map((item, i) => (
<FadeInView key={i} delay={i * 0.08}>
<div
className="md:grid md:grid-cols-2 border-b relative overflow-hidden group"
style={{ borderColor: TOKENS.gray200 }}
>
{/* Left accent bar — visible on hover via CSS */}
<div
className="absolute left-0 top-0 bottom-0 w-[3px] transition-transform duration-500 origin-top hidden md:block"
style={{ background: TOKENS.red, transform: 'scaleY(0)' }}
onMouseEnter={e => { e.currentTarget.style.transform = 'scaleY(1)'; }}
/>
{/* Question */}
<div className="py-6 md:py-12 lg:py-16 md:pr-12 lg:pr-16 flex flex-col justify-center">
<h3
className="font-serif text-[18px] sm:text-[20px] md:text-[clamp(20px,3vw,28px)] font-bold leading-[1.35] md:leading-[1.3] tracking-[-0.3px] md:tracking-[-0.5px]"
style={{ color: TOKENS.ink }}
>
{item.question}
</h3>
</div>
{/* Answer */}
<div
className="pb-6 md:py-12 lg:py-16 md:pl-12 lg:pl-16 md:border-l flex flex-col justify-center"
style={{ borderColor: TOKENS.gray200 }}
>
<p className="text-[14px] sm:text-[15px] leading-relaxed mb-5 md:mb-7" style={{ color: TOKENS.gray500 }}>
{item.description}
</p>
<StaticLink
href={item.link}
className={`${TOUCH_TARGET} inline-flex items-center gap-2 text-[13px] font-medium transition-all duration-300 group/link`}
style={{ color: TOKENS.ink }}
onMouseEnter={e => {
e.currentTarget.style.color = TOKENS.red;
e.currentTarget.style.gap = '14px';
}}
onMouseLeave={e => {
e.currentTarget.style.color = TOKENS.ink;
e.currentTarget.style.gap = '8px';
}}
>
了解详情
<ChevronRight className="w-3.5 h-3.5 transition-transform duration-300 group-hover/link:translate-x-1" />
</StaticLink>
</div>
</div>
</FadeInView>
))}
</div>
</div>
</section>
);
}
// ============================================================
// Module 3: Case Studies — Mobile First
// ============================================================
function CaseStudiesSection() {
const [activeIndex, setActiveIndex] = useState(0);
return (
<section className={SECTION_PADDING} style={{ background: TOKENS.ink }}>
<div className={CONTAINER}>
<FadeInView>
<SectionHeader
label="Client Results"
title="案例"
highlight="成果"
desc="不以项目上线为终点,以客户业务改善为衡量标准"
light
/>
</FadeInView>
{/* Case Cards Grid */}
<div
className="grid lg:grid-cols-2 gap-0 mb-2 rounded-sm overflow-hidden"
style={{ background: 'rgba(255,255,255,0.03)' }}
>
{CASE_STUDIES.map((cs, i) => (
<FadeInView key={i} delay={i * 0.1}>
<div
className={`${TAP_FEEDBACK} relative overflow-hidden cursor-pointer transition-all duration-500 p-6 sm:p-8 md:p-10 lg:p-14 flex flex-col group`}
style={{ background: i === activeIndex ? TOKENS.inkLight : TOKENS.inkSurface }}
onClick={() => setActiveIndex(i)}
onMouseEnter={() => setActiveIndex(i)}
>
{/* Top accent line */}
<div
className="absolute top-0 left-0 right-0 h-[2px] transition-opacity duration-500"
style={{
background: `linear-gradient(90deg, transparent, ${TOKENS.red}, transparent)`,
opacity: i === activeIndex ? 1 : 0,
}}
/>
{/* Background image */}
<div
className="absolute inset-0 transition-opacity duration-500"
style={{ opacity: i === activeIndex ? 0.08 : 0.03 }}
>
<img src={cs.image} alt="" className="w-full h-full object-cover" loading="lazy" />
</div>
<div className="relative z-10 flex flex-col flex-1">
<div
className="text-[10px] tracking-[3px] uppercase font-medium mb-4 md:mb-5"
style={{ color: TOKENS.goldText }}
>
{cs.industry}
</div>
<h3 className="font-serif text-[19px] sm:text-[22px] font-bold leading-[1.3] tracking-[-0.3px] text-white mb-3 md:mb-4">
{cs.title}
</h3>
<p
className="text-[13px] sm:text-[14px] leading-relaxed mb-6 md:mb-8 flex-1"
style={{ color: 'rgba(255,255,255,0.35)' }}
>
{cs.context}
</p>
{/* Impact Numbers */}
<div
className="grid grid-cols-2 gap-4 sm:gap-6 pt-5 md:pt-7 mb-5 md:mb-7 border-t"
style={{ borderColor: 'rgba(255,255,255,0.06)' }}
>
{cs.impact.map((imp, j) => (
<div key={j}>
<div className="font-serif text-[32px] sm:text-[38px] md:text-[42px] font-bold leading-none mb-1 md:mb-1.5 tracking-[-1.5px] text-white">
{imp.value}
</div>
<div className="text-[10px] sm:text-[11px]" style={{ color: 'rgba(255,255,255,0.25)' }}>
{imp.label}
</div>
</div>
))}
</div>
{/* Quote */}
<blockquote
className="text-[13px] leading-relaxed italic mb-2 md:mb-3"
style={{ color: 'rgba(255,255,255,0.45)' }}
>
&ldquo;{cs.quote}&rdquo;
</blockquote>
<cite className="text-[11px] sm:text-[12px] not-italic" style={{ color: 'rgba(255,255,255,0.5)' }}>
{cs.author}
</cite>
</div>
</div>
</FadeInView>
))}
</div>
{/* View all link */}
<FadeInView delay={0.3}>
<div className="text-center mt-8 md:mt-12">
<StaticLink
href="/solutions"
className={`${TOUCH_TARGET} inline-flex items-center gap-2 text-[13px] font-medium transition-all duration-300 group`}
style={{ color: 'rgba(255,255,255,0.5)' }}
onMouseEnter={e => { e.currentTarget.style.color = TOKENS.white; }}
onMouseLeave={e => { e.currentTarget.style.color = 'rgba(255,255,255,0.5)'; }}
>
查看全部案例
<ArrowRight className="w-3.5 h-3.5 transition-transform duration-300 group-hover:translate-x-1" />
</StaticLink>
</div>
</FadeInView>
</div>
</section>
);
}
// ============================================================
// Module 4: Insights — Mobile First
// ============================================================
function InsightsSection() {
return (
<section className={SECTION_PADDING} style={{ background: TOKENS.white }}>
<div className={CONTAINER}>
<FadeInView>
<SectionHeader
label="Insights"
title="思想"
highlight="洞察"
desc="基于 500+ 项目实践的研究成果与行业观点"
/>
</FadeInView>
{/* Featured Insights */}
<div className="grid md:grid-cols-2 gap-4 sm:gap-6 mb-6 md:mb-8">
{INSIGHTS.filter(i => i.type === 'featured').map((insight, i) => (
<FadeInView key={i} delay={i * 0.1}>
<div
className={`${TAP_FEEDBACK} relative overflow-hidden group cursor-pointer flex flex-col justify-end min-h-[260px] sm:min-h-[300px] md:min-h-[360px] p-8 sm:p-10 md:p-12 lg:p-14 rounded-sm`}
style={{ background: TOKENS.ink }}
>
{/* Background Image */}
<img
src={insight.image}
alt=""
className="absolute inset-0 w-full h-full object-cover transition-transform duration-700 group-hover:scale-105"
style={{ opacity: 0.3 }}
loading="lazy"
/>
{/* Gradient Overlay */}
<div
className="absolute inset-0"
style={{
background: `radial-gradient(ellipse 60% 40% at 30% 70%, rgba(196,30,58,0.15), transparent),
radial-gradient(ellipse 40% 30% at 70% 20%, rgba(184,148,76,0.08), transparent)`,
}}
/>
<div className="relative z-10">
<div
className="text-[10px] tracking-[3px] uppercase font-medium mb-4 md:mb-5"
style={{ color: TOKENS.goldText }}
>
{insight.tag}
</div>
<h3 className="font-serif text-[20px] sm:text-[24px] md:text-[26px] font-bold leading-[1.3] text-white mb-2 md:mb-3">
{insight.title}
</h3>
<p
className="text-[13px] sm:text-[14px] leading-relaxed max-w-[400px] mb-5 md:mb-6"
style={{ color: 'rgba(255,255,255,0.4)' }}
>
{insight.desc}
</p>
<span
className={`${TOUCH_TARGET} text-[12px] inline-flex items-center gap-1.5 transition-all duration-300 group-hover:text-white`}
style={{ color: 'rgba(255,255,255,0.5)' }}
>
阅读全文
<ArrowUpRight className="w-3 h-3" />
</span>
</div>
</div>
</FadeInView>
))}
</div>
{/* Secondary Insights Grid */}
<div className="grid sm:grid-cols-2 md:grid-cols-3 gap-px rounded-sm overflow-hidden" style={{ background: TOKENS.gray200 }}>
{INSIGHTS.filter(i => !i.type).map((insight, i) => (
<FadeInView key={i} delay={i * 0.06}>
<div
className={`${TAP_FEEDBACK} p-6 sm:p-8 md:p-10 transition-all duration-400 group cursor-pointer flex flex-col`}
style={{ background: TOKENS.white }}
onMouseEnter={e => { e.currentTarget.style.background = TOKENS.cream; }}
onMouseLeave={e => { e.currentTarget.style.background = TOKENS.white; }}
>
<div
className="text-[10px] tracking-[2px] uppercase font-medium mb-3 md:mb-4"
style={{ color: TOKENS.goldText }}
>
{insight.tag}
</div>
<h4
className="font-serif text-[16px] sm:text-[17px] font-semibold leading-[1.5] mb-2"
style={{ color: TOKENS.ink }}
>
{insight.title}
</h4>
<p
className="text-[13px] leading-relaxed flex-1 mb-4 md:mb-5"
style={{ color: TOKENS.gray500 }}
>
{insight.desc}
</p>
{insight.date && (
<div className="text-[11px]" style={{ color: TOKENS.gray400 }}>
{insight.date}
</div>
)}
</div>
</FadeInView>
))}
</div>
</div>
</section>
);
}
// ============================================================
// Module 5: Industry Selector — Mobile First
// ============================================================
function IndustrySelectorSection() {
return (
<section className={SECTION_PADDING} style={{ background: TOKENS.cream }}>
<div className={CONTAINER}>
<FadeInView>
<SectionHeader
label="Industries"
title="行业"
highlight="专长"
desc="深入行业场景,理解业务逻辑,提供真正落地的解决方案"
/>
</FadeInView>
<FadeInView delay={0.1}>
<p
className="font-serif text-[18px] sm:text-[20px] md:text-[22px] font-semibold mb-8 md:mb-10 leading-relaxed"
style={{ color: TOKENS.ink }}
>
选择您的行业,<span style={{ color: TOKENS.red }}>查看相关案例与解决方案</span>
</p>
</FadeInView>
<div className="grid grid-cols-2 sm:grid-cols-4 gap-px rounded-sm overflow-hidden" style={{ background: TOKENS.gray300 }}>
{INDUSTRIES.map((ind, i) => (
<FadeInView key={i} delay={i * 0.04}>
<div
className={`${TAP_FEEDBACK} relative overflow-hidden py-8 sm:py-10 px-4 sm:px-6 text-center cursor-pointer transition-all duration-400 group`}
style={{ background: TOKENS.white }}
onMouseEnter={e => {
e.currentTarget.style.background = TOKENS.ink;
}}
onMouseLeave={e => {
e.currentTarget.style.background = TOKENS.white;
}}
>
<div className="relative z-10">
<ind.icon
className="w-7 h-7 sm:w-8 sm:h-8 mx-auto mb-2 sm:mb-3 transition-transform duration-400 group-hover:scale-110"
style={{ color: TOKENS.ink }}
onMouseEnter={e => { e.currentTarget.style.color = TOKENS.white; }}
onMouseLeave={e => { e.currentTarget.style.color = TOKENS.ink; }}
/>
<div
className="text-[13px] sm:text-[14px] font-medium transition-colors duration-400"
style={{ color: TOKENS.ink }}
onMouseEnter={e => { e.currentTarget.style.color = TOKENS.white; }}
onMouseLeave={e => { e.currentTarget.style.color = TOKENS.ink; }}
>
{ind.name}
</div>
<div
className="text-[10px] sm:text-[11px] mt-1 sm:mt-1.5 transition-colors duration-400"
style={{ color: TOKENS.gray400 }}
onMouseEnter={e => { e.currentTarget.style.color = 'rgba(255,255,255,0.4)'; }}
onMouseLeave={e => { e.currentTarget.style.color = TOKENS.gray400; }}
>
{ind.count}
</div>
</div>
</div>
</FadeInView>
))}
</div>
</div>
</section>
);
}
// ============================================================
// Module 6: Trust Signals — Mobile First
// ============================================================
function TrustSection() {
const [inView, setInView] = useState(false);
const sectionRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = sectionRef.current;
if (!el) return;
const observer = new IntersectionObserver(
([entry]) => { if (entry?.isIntersecting) { setInView(true); observer.disconnect(); } },
{ threshold: 0.1 }
);
observer.observe(el);
return () => observer.disconnect();
}, []);
return (
<section ref={sectionRef} className={SECTION_PADDING} style={{ background: TOKENS.white }}>
<div className={CONTAINER}>
<FadeInView>
<SectionHeader
label="Trust"
title="为什么"
highlight="选择我们"
desc="数字会说话,信任是合作的基础"
/>
</FadeInView>
<div className="grid grid-cols-2 md:grid-cols-3 gap-px rounded-sm overflow-hidden" style={{ background: TOKENS.gray200 }}>
{TRUST_SIGNALS.map((item, i) => (
<div
key={i}
className="py-10 sm:py-12 md:py-14 px-4 sm:px-6 md:px-8 text-center transition-all duration-400 hover:bg-[var(--color-bg-hover)]"
style={{ background: TOKENS.white }}
>
<div
className="font-serif text-[clamp(36px,8vw,64px)] font-bold leading-none mb-1 md:mb-2 tracking-[-2px]"
style={{ color: TOKENS.ink }}
>
{inView ? <CountUpNumber end={parseInt(item.number)} /> : item.number}
<span style={{ color: TOKENS.red, fontSize: '0.4em' }}>{item.unit}</span>
</div>
<div
className="text-[12px] sm:text-[13px] font-medium mb-3 md:mb-4 tracking-[0.5px]"
style={{ color: TOKENS.gray500 }}
>
{item.label}
</div>
<div className="text-[12px] sm:text-[13px] leading-relaxed" style={{ color: TOKENS.gray400 }}>
{item.desc}
</div>
</div>
))}
</div>
</div>
</section>
);
}
function CountUpNumber({ end }: { end: number }) {
const count = useCountUp(end, 2000, true);
return <>{count}</>;
}
// ============================================================
// Module 7: Process — Mobile First
// ============================================================
function ProcessSection() {
return (
<section className={SECTION_PADDING} style={{ background: TOKENS.cream }}>
<div className={CONTAINER}>
<FadeInView>
<SectionHeader
label="Process"
title="交付"
highlight="流程"
desc="标准化方法论,确保每个项目科学推进、高效交付"
/>
</FadeInView>
{/* Mobile: stacked with connecting line; Desktop: 5-column grid */}
<div className="md:grid md:grid-cols-5">
{PROCESS_STEPS.map((step, i) => (
<FadeInView key={i} delay={i * 0.08}>
<div
className="relative py-6 sm:py-8 md:py-10 px-4 sm:px-6 transition-all duration-400 hover:bg-white/60 group"
style={{
borderRight: 'none',
borderBottom: `1px solid ${TOKENS.gray300}`,
}}
>
{/* Mobile: left border connecting line */}
<div className="md:hidden absolute left-0 top-0 bottom-0 w-[2px]"
style={{ background: TOKENS.gray200 }}
/>
{/* Mobile: active dot */}
<div className="md:hidden absolute left-[-4px] top-8 w-[10px] h-[10px] rounded-full"
style={{ background: TOKENS.red }}
/>
<div
className="font-serif text-[clamp(40px,8vw,64px)] font-bold leading-none mb-3 md:mb-5 tracking-[-2px]"
style={{ color: 'rgba(0,0,0,0.03)' }}
>
{step.step}
</div>
<h3
className="font-serif text-[17px] sm:text-[19px] font-semibold mb-2 md:mb-2.5"
style={{ color: TOKENS.ink }}
>
{step.title}
</h3>
<p className="text-[13px] sm:text-[14px] leading-relaxed" style={{ color: TOKENS.gray500 }}>
{step.desc}
</p>
{/* Desktop: right arrow connector */}
{i < 4 && (
<div
className="hidden md:block absolute right-[-14px] top-1/2 -translate-y-1/2 text-[22px]"
style={{ color: TOKENS.gray300 }}
>
<ChevronRight />
</div>
)}
</div>
</FadeInView>
))}
</div>
</div>
</section>
);
}
// ============================================================
// Module 8: CTA — Mobile First
// ============================================================
function CTASection() {
return (
<section
className="relative py-28 md:py-44 lg:py-56 text-center overflow-hidden"
style={{ background: TOKENS.ink }}
>
{/* Background atmosphere */}
<div className="absolute inset-0 pointer-events-none">
<div
className="absolute w-[400px] sm:w-[600px] md:w-[900px] h-[400px] sm:h-[600px] md:h-[900px] rounded-full blur-[80px] sm:blur-[120px] md:blur-[140px] opacity-[0.08]"
style={{
background: `radial-gradient(circle, rgba(196,30,58,0.5), transparent 70%)`,
top: '-30%', right: '-15%',
}}
/>
<div
className="absolute w-[300px] sm:w-[450px] md:w-[600px] h-[300px] sm:h-[450px] md:h-[600px] rounded-full blur-[80px] sm:blur-[100px] md:blur-[120px] opacity-[0.06]"
style={{
background: `radial-gradient(circle, rgba(184,148,76,0.4), transparent 70%)`,
bottom: '-20%', left: '-10%',
}}
/>
</div>
<div className="relative z-10 max-w-[640px] mx-auto px-5 sm:px-8">
<FadeInView>
<div
className="text-[10px] tracking-[4px] uppercase font-medium mb-5 md:mb-6"
style={{ color: TOKENS.goldText }}
>
Let&apos;s Talk
</div>
<h2
className="font-serif text-[clamp(32px,7vw,60px)] font-bold leading-[1.08] tracking-[-1.5px] text-white mb-5 md:mb-6"
>
准备好让每一次数字化<br />
<span style={{ color: TOKENS.red }}>转型</span>掷地有声了吗?
</h2>
<p
className="text-[15px] sm:text-base leading-relaxed max-w-[420px] mx-auto mb-10 md:mb-12 font-light"
style={{ color: 'rgba(255,255,255,0.35)' }}
>
预约一次免费咨询,让我们了解您的业务挑战,一起探讨数字化转型的最优路径。
</p>
<div className="flex flex-col sm:flex-row gap-3 sm:gap-4 justify-center">
<StaticLink
href="/contact"
className={`${TOUCH_TARGET} ${TAP_FEEDBACK} inline-flex items-center justify-center gap-2.5 px-7 sm:px-9 py-3.5 text-sm font-medium text-white rounded-sm transition-all duration-300 hover:-translate-y-0.5`}
style={{ background: TOKENS.red }}
onMouseEnter={e => {
e.currentTarget.style.background = TOKENS.redHover;
e.currentTarget.style.boxShadow = `0 8px 32px ${TOKENS.redGlow}`;
}}
onMouseLeave={e => {
e.currentTarget.style.background = TOKENS.red;
e.currentTarget.style.boxShadow = 'none';
}}
>
预约免费咨询
<ArrowRight className="w-4 h-4" />
</StaticLink>
<StaticLink
href="/products"
className={`${TOUCH_TARGET} ${TAP_FEEDBACK} inline-flex items-center justify-center gap-2 px-7 sm:px-9 py-3.5 text-sm font-normal rounded-sm transition-all duration-300`}
style={{
color: 'rgba(255,255,255,0.45)',
border: '1px solid rgba(255,255,255,0.1)',
}}
onMouseEnter={e => {
e.currentTarget.style.borderColor = 'rgba(255,255,255,0.25)';
e.currentTarget.style.color = 'rgba(255,255,255,0.8)';
}}
onMouseLeave={e => {
e.currentTarget.style.borderColor = 'rgba(255,255,255,0.1)';
e.currentTarget.style.color = 'rgba(255,255,255,0.45)';
}}
>
浏览产品矩阵
</StaticLink>
</div>
</FadeInView>
</div>
</section>
);
}
// ============================================================
// Main Export
// ============================================================
export default function HomeContentV4() {
return (
<main className="min-h-screen">
<HeroSection />
<StrategicQuestionsSection />
<CaseStudiesSection />
<InsightsSection />
<IndustrySelectorSection />
<TrustSection />
<ProcessSection />
<CTASection />
</main>
);
}