Files
novalon-website/src/components/sections/home-solutions-section.tsx
T
张翔 4066c82939 fix: 系统性解决青柳隶书体'份'字不显示的问题
根本原因:
- 青柳隶书体字体文件中'份'字(U+4EFD)的绘制指令数量为0
- 虽然字符映射表包含该字符,但字形数据为空,导致无法渲染

解决方案:
- 修改CSS字体回退链,添加Ma Shan Zheng作为主要回退字体
- 当青柳隶书体无法渲染'份'字时,浏览器自动使用Ma Shan Zheng字体
- 保持青柳隶书体的整体风格,同时确保所有字符都能正常显示

修改文件:
- src/app/globals.css: 更新.font-calligraphy类的字体回退链
- src/components/sections/home-solutions-section.tsx: 恢复使用font-calligraphy类

验证结果:
- 字体文件分析确认'份'字绘制指令数量为0
- Ma Shan Zheng字体包含完整的'身'和'份'字绘制数据
- 本地测试验证'身份'两个字都能正常显示
2026-04-22 07:49:09 +08:00

107 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import { motion } from 'framer-motion';
import { useInView } from 'framer-motion';
import { useRef } from 'react';
import { StaticLink } from '@/components/ui/static-link';
import { Button } from '@/components/ui/button';
import { ArrowRight, Lightbulb, Cpu, Users } from 'lucide-react';
const SOLUTIONS_OVERVIEW = [
{
icon: Lightbulb,
title: '参谋伙伴',
subtitle: '数字化转型咨询',
description: '帮您看清前路,迈对第一步。用行业智慧洞察趋势,用理性分析避开陷阱。',
points: ['行业趋势洞察报告', '成熟度评估', '实施路径规划'],
},
{
icon: Cpu,
title: '技术伙伴',
subtitle: '信息技术解决方案',
description: '让技术真正为业务服务。不追逐"最火"的技术,只选择"最对"的技术。',
points: ['业务场景调研', '技术方案定制', '敏捷交付迭代'],
},
{
icon: Users,
title: '同行伙伴',
subtitle: '长期陪跑服务',
description: '交付只是开始,陪伴才是常态。项目上线那天,是我们真正成为伙伴的开始。',
points: ['专属客户成功经理', '季度业务复盘', '7×24小时响应'],
},
];
export function HomeSolutionsSection() {
const ref = useRef(null);
const isInView = useInView(ref, { once: true, margin: '-100px' });
return (
<section id="solutions" role="region" aria-labelledby="solutions-heading" className="py-24 bg-[#F5F7FA] relative overflow-hidden" ref={ref}>
<div className="absolute top-1/2 right-0 w-[400px] h-[400px] bg-[rgba(196,30,58,0.02)] rounded-full blur-3xl" />
<div className="container-wide relative z-10">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6 }}
className="text-center max-w-3xl mx-auto mb-16"
>
<h2 id="solutions-heading" className="text-4xl md:text-5xl font-bold text-[#1C1C1C] mb-6">
三种角色,一种<span className="text-[#C41E3A] font-calligraphy">身份</span>
</h2>
<p className="text-lg text-[#5C5C5C]">
您的数字化转型成长伙伴——从战略咨询到技术落地,再到长期陪跑
</p>
</motion.div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{SOLUTIONS_OVERVIEW.map((item, idx) => {
const Icon = item.icon;
return (
<motion.div
key={item.title}
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, delay: 0.1 + idx * 0.15 }}
>
<div className="bg-white rounded-2xl p-8 border border-[#E5E5E5] hover:border-[#C41E3A]/30 hover:shadow-lg transition-all duration-300 h-full flex flex-col">
<div className="w-14 h-14 bg-[#C41E3A] rounded-2xl flex items-center justify-center mb-6">
<Icon className="w-7 h-7 text-white" />
</div>
<h3 className="text-xl font-bold text-[#1C1C1C] mb-1">{item.title}</h3>
<p className="text-sm text-[#C41E3A] font-medium mb-3">{item.subtitle}</p>
<p className="text-sm text-[#5C5C5C] leading-relaxed mb-6 flex-1">{item.description}</p>
<ul className="space-y-2">
{item.points.map((point, i) => (
<li key={i} className="flex items-start gap-2 text-sm text-[#1C1C1C]">
<div className="w-1.5 h-1.5 bg-[#C41E3A] rounded-full mt-1.5 shrink-0" />
{point}
</li>
))}
</ul>
</div>
</motion.div>
);
})}
</div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.6, delay: 0.5 }}
className="mt-12 text-center"
>
<Button
size="lg"
asChild
>
<StaticLink href="/solutions">
了解完整解决方案
<ArrowRight className="ml-2 w-4 h-4" />
</StaticLink>
</Button>
</motion.div>
</div>
</section>
);
}