Dogfood 审计(31 路由 × 多视口,Playwright 9 维探针)发现的阻断级问题全部闭环: P1 29 → 0,对比度违规页 29 → 0。 对比度 - footer: text-gray-500 硬编码 → text-text-hint 令牌(#6B7280 在 #0A0E14 上仅 4:1,需 4.5:1),1 行改动全站 29 页生效 - brand-content / team-content 副文案 text-text-secondary/70 → /80 (4.35:1 → 5.74:1,视觉几乎无变化) - brand-content 里程碑标签在 bg-tertiary 上 text-text-muted → text-text-secondary (4.34:1 → 9.45:1) 装饰元素豁免 - 大号服务编号(about 01-03、team 01-05 等)加 aria-hidden="true",WCAG 1.4.3 对装饰内容不适用,无需强行提亮 - 同时补修 product-detail / solution-detail 的客户名首字占位(同类 text-text-muted/10,因容器为渐变背景属探针盲区、从未报出) - 副文案与里程碑标签属真实语义内容,走提对比度而非 aria-hidden —— 隐藏它们 等于把公司简介与成立年份从屏幕阅读器中删除 移动端布局 - MobileTabBar 为 fixed bottom-0 高 64px,给 main / [role="main"] / footer 补 calc(64px + env(safe-area-inset-bottom)) 安全区,解决正文与页脚被遮挡 - 注意 marketing layout 使用 div[role="main"] 而非真 <main> 元素,选择器须 同时匹配两者 触控与令牌 - ERP 专题链接加 py-0.5(23px → 27px,达 WCAG 2.2 AA 2.5.8 的 24px) - solution-service-card: shadow-blue-500/20 → shadow-brand(纳入 --shadow-* 令牌) Refs: UI_UX_UE_AUDIT_2026-09-01.md
172 lines
7.0 KiB
TypeScript
172 lines
7.0 KiB
TypeScript
'use client';
|
|
|
|
import { StaticLink } from '@/components/ui/static-link';
|
|
import Image from 'next/image';
|
|
import { Mail, MapPin } from 'lucide-react';
|
|
import { useSiteConfig } from '@/lib/site-config';
|
|
|
|
export function Footer() {
|
|
const config = useSiteConfig();
|
|
const productItems = (config.megaDropdown.products ?? [])
|
|
.flatMap(group => group.items)
|
|
.filter(item => item.href !== '#');
|
|
|
|
const solutionItems = (config.megaDropdown.solutions ?? [])
|
|
.flatMap(group => group.items);
|
|
|
|
return (
|
|
<footer className="bg-dark-bg text-white relative overflow-hidden" data-testid="footer" role="contentinfo">
|
|
<div className="max-w-container mx-auto px-4 sm:px-6 lg:px-10">
|
|
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-12 gap-10 lg:gap-12 py-16 lg:py-20">
|
|
<div data-testid="card-brand" className="col-span-2 lg:col-span-4">
|
|
<div className="mb-6">
|
|
<StaticLink href="/" className="inline-block group" aria-label="返回首页">
|
|
<Image
|
|
src="/logo-white.svg"
|
|
alt={config.name}
|
|
width={180}
|
|
height={45}
|
|
className="w-auto h-10 md:h-12 transition-transform duration-normal ease-out group-hover:scale-[1.02]"
|
|
loading="eager"
|
|
priority
|
|
/>
|
|
</StaticLink>
|
|
</div>
|
|
<p className="text-gray-300 text-sm leading-relaxed max-w-md">
|
|
{config.slogan && (
|
|
<>
|
|
<span className="block text-gray-200 font-medium mb-2">{config.slogan}</span>
|
|
</>
|
|
)}
|
|
{config.description}
|
|
</p>
|
|
</div>
|
|
|
|
<div data-testid="card-products" className="lg:col-span-2">
|
|
<div className="font-semibold text-sm mb-5 text-white tracking-widest uppercase">产品</div>
|
|
<ul className="space-y-3 [&_li]:p-0 [&_li]:m-0 [&_li]:static [&_li::before]:hidden">
|
|
{productItems.map((item) => (
|
|
<li key={item.id}>
|
|
<StaticLink
|
|
href={item.href}
|
|
className="text-gray-300 hover:text-white transition-colors duration-200 text-sm whitespace-nowrap"
|
|
>
|
|
{item.title}
|
|
</StaticLink>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
|
|
<div data-testid="card-solutions" className="lg:col-span-2">
|
|
<div className="font-semibold text-sm mb-5 text-white tracking-widest uppercase">解决方案</div>
|
|
<ul className="space-y-3 [&_li]:p-0 [&_li]:m-0 [&_li]:static [&_li::before]:hidden">
|
|
{solutionItems.map((item) => (
|
|
<li key={item.id}>
|
|
<StaticLink
|
|
href={item.href}
|
|
className="text-gray-300 hover:text-white transition-colors duration-200 text-sm whitespace-nowrap"
|
|
>
|
|
{item.title}
|
|
</StaticLink>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
|
|
<div data-testid="card-contact" className="col-span-2 lg:col-span-4">
|
|
<div className="font-semibold text-sm mb-5 text-white tracking-widest uppercase">联系我们</div>
|
|
<ul className="space-y-4 mb-8 [&_li]:p-0 [&_li]:m-0 [&_li]:static [&_li::before]:hidden">
|
|
<li className="flex items-start gap-3">
|
|
<MapPin className="w-4 h-4 text-gray-400 mt-0.5 shrink-0" />
|
|
<span className="text-gray-300 text-sm leading-relaxed">{config.address}</span>
|
|
</li>
|
|
<li className="flex items-start gap-3">
|
|
<Mail className="w-4 h-4 text-gray-400 mt-0.5 shrink-0" />
|
|
<a
|
|
href={`mailto:${config.email}`}
|
|
className="text-gray-300 hover:text-white transition-colors duration-200 text-sm"
|
|
>
|
|
{config.email}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
<div className="flex gap-6">
|
|
<div>
|
|
<p className="text-xs text-gray-400 mb-3 tracking-wide">关注公众号</p>
|
|
<div className="inline-block p-2 border border-gray-800 bg-gray-900">
|
|
<Image
|
|
src="/images/qrcode.webp"
|
|
alt="微信公众号二维码"
|
|
width={96}
|
|
height={96}
|
|
className="w-24 h-24"
|
|
loading="lazy"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<p className="text-xs text-gray-400 mb-3 tracking-wide">业务咨询</p>
|
|
<div className="inline-block p-2 border border-gray-800 bg-gray-900">
|
|
<Image
|
|
src="/images/wechat-business-qr.webp"
|
|
alt="业务咨询微信二维码"
|
|
width={96}
|
|
height={96}
|
|
className="w-24 h-24"
|
|
loading="lazy"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="border-t border-gray-800 pt-6 pb-[calc(8rem+env(safe-area-inset-bottom,0px))] md:pb-8">
|
|
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-6 mb-6">
|
|
<p className="text-gray-300 text-xs">
|
|
© {new Date().getFullYear()} {config.name}. 版权所有.
|
|
</p>
|
|
<div className="flex gap-6">
|
|
<StaticLink href="/privacy" className="text-gray-300 hover:text-white text-xs transition-colors duration-200">
|
|
隐私政策
|
|
</StaticLink>
|
|
<StaticLink href="/terms" className="text-gray-300 hover:text-white text-xs transition-colors duration-200">
|
|
服务条款
|
|
</StaticLink>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex flex-col sm:flex-row justify-center items-center gap-2 sm:gap-4 pt-4 text-[0.8125rem]">
|
|
<a
|
|
href="https://beian.miit.gov.cn/"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="text-gray-300 hover:text-white transition-colors duration-200 inline-flex items-center"
|
|
>
|
|
{config.icp}
|
|
</a>
|
|
<span className="hidden sm:inline text-text-hint">|</span>
|
|
<a
|
|
href="https://beian.mps.gov.cn/#/query/webSearch?code=51010602003285"
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
className="text-gray-300 hover:text-white transition-colors duration-200 inline-flex items-center gap-1.5"
|
|
>
|
|
<Image
|
|
src="/images/beian-icon.png"
|
|
alt="公安备案"
|
|
width={14}
|
|
height={14}
|
|
className="w-3.5 h-3.5 opacity-80"
|
|
loading="lazy"
|
|
/>
|
|
{config.police}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
);
|
|
}
|