fix(a11y): 无障碍与 lint 修复(对比度/alt 属性/触控目标收窄)+ Geist 本地字体系统
This commit is contained in:
@@ -193,7 +193,8 @@ export default function MediaPage() {
|
||||
|
||||
{items.length === 0 && !loading && (
|
||||
<div className="text-center py-16 bg-white rounded-lg border border-dashed border-gray-300">
|
||||
<Image className="w-12 h-12 mx-auto mb-4 text-gray-300" />
|
||||
{/* eslint-disable-next-line jsx-a11y/alt-text -- lucide Image 图标(装饰性 SVG,非 <img>),aria-hidden 表明装饰意图 */}
|
||||
<Image aria-hidden="true" className="w-12 h-12 mx-auto mb-4 text-gray-300" />
|
||||
<h3 className="text-sm font-medium text-gray-900 mb-1">暂无媒体文件</h3>
|
||||
<p className="text-sm text-gray-500 mb-4">上传图片、文档等资源,即可在内容编辑中使用</p>
|
||||
<label className="inline-flex items-center gap-2 bg-gray-900 text-white rounded-lg px-4 py-2 text-sm font-medium hover:bg-gray-800 cursor-pointer transition-colors">
|
||||
|
||||
+2
-2
@@ -81,7 +81,7 @@ export default function Error({
|
||||
href="/contact"
|
||||
className="flex items-center p-4 bg-[var(--color-bg-primary)] rounded-lg hover:shadow-md transition-shadow group"
|
||||
>
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mr-4 group-hover:bg-[var(--color-challenge-isolation-hover)] transition-colors">
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mr-4 group-hover:bg-[var(--color-brand-soft)] transition-colors">
|
||||
<AlertTriangle className="w-5 h-5 text-[var(--color-brand)]" />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
@@ -94,7 +94,7 @@ export default function Error({
|
||||
href="/services"
|
||||
className="flex items-center p-4 bg-[var(--color-bg-primary)] rounded-lg hover:shadow-md transition-shadow group"
|
||||
>
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mr-4 group-hover:bg-[var(--color-challenge-isolation-hover)] transition-colors">
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mr-4 group-hover:bg-[var(--color-brand-soft)] transition-colors">
|
||||
<RefreshCw className="w-5 h-5 text-[var(--color-brand)]" />
|
||||
</div>
|
||||
<div className="text-left">
|
||||
|
||||
+26
-1
@@ -1,4 +1,5 @@
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import localFont from "next/font/local";
|
||||
import "./globals.css";
|
||||
import { Suspense } from "react";
|
||||
import { GoogleAnalyticsWrapper } from "@/components/analytics/GoogleAnalyticsWrapper";
|
||||
@@ -18,6 +19,26 @@ import { SiteConfigProvider, type SiteConfig, type NavigationItem, type MegaDrop
|
||||
import { COMPANY_INFO, BRAND_NARRATIVE, type BrandPillar } from "@/lib/constants/company";
|
||||
import { NAVIGATION_V2, MEGA_DROPDOWN_DATA } from "@/lib/constants/navigation";
|
||||
|
||||
/**
|
||||
* 拉丁字形使用 Geist(本地 woff2,无网络请求);
|
||||
* 中文由 globals.css 的 --font-sans 回退到 PingFang SC / 微软雅黑。
|
||||
* 这样英文数字有设计字体,中文又不需下载数 MB 的 CJK 字重。
|
||||
* 两者总重 140KB,display: swap 不阻塞首屏。
|
||||
*/
|
||||
const geistSans = localFont({
|
||||
src: "./fonts/geist-sans.woff2",
|
||||
variable: "--font-geist-sans",
|
||||
display: "swap",
|
||||
preload: true,
|
||||
});
|
||||
|
||||
const geistMono = localFont({
|
||||
src: "./fonts/geist-mono.woff2",
|
||||
variable: "--font-geist-mono",
|
||||
display: "swap",
|
||||
preload: false,
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL("https://www.novalon.cn"),
|
||||
title: {
|
||||
@@ -143,7 +164,11 @@ export default async function RootLayout({
|
||||
};
|
||||
|
||||
return (
|
||||
<html lang="zh-CN" className="scroll-smooth" suppressHydrationWarning>
|
||||
<html
|
||||
lang="zh-CN"
|
||||
className={`scroll-smooth ${geistSans.variable} ${geistMono.variable}`}
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<head>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
|
||||
@@ -47,7 +47,7 @@ export function NotFoundContent() {
|
||||
href="/products"
|
||||
className="flex flex-col items-center p-4 bg-[var(--color-bg-primary)] rounded-lg hover:shadow-md transition-shadow group"
|
||||
>
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-challenge-isolation-hover)] transition-colors">
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-brand-soft)] transition-colors">
|
||||
<Search className="w-4 h-4 text-[var(--color-brand)]" />
|
||||
</div>
|
||||
<span className="font-medium text-sm text-[var(--color-text-primary)]">产品</span>
|
||||
@@ -57,7 +57,7 @@ export function NotFoundContent() {
|
||||
href="/solutions"
|
||||
className="flex flex-col items-center p-4 bg-[var(--color-bg-primary)] rounded-lg hover:shadow-md transition-shadow group"
|
||||
>
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-challenge-isolation-hover)] transition-colors">
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-brand-soft)] transition-colors">
|
||||
<Search className="w-4 h-4 text-[var(--color-brand)]" />
|
||||
</div>
|
||||
<span className="font-medium text-sm text-[var(--color-text-primary)]">解决方案</span>
|
||||
@@ -67,7 +67,7 @@ export function NotFoundContent() {
|
||||
href="/about"
|
||||
className="flex flex-col items-center p-4 bg-[var(--color-bg-primary)] rounded-lg hover:shadow-md transition-shadow group"
|
||||
>
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-challenge-isolation-hover)] transition-colors">
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-brand-soft)] transition-colors">
|
||||
<Search className="w-4 h-4 text-[var(--color-brand)]" />
|
||||
</div>
|
||||
<span className="font-medium text-sm text-[var(--color-text-primary)]">关于我们</span>
|
||||
@@ -77,7 +77,7 @@ export function NotFoundContent() {
|
||||
href="/contact"
|
||||
className="flex flex-col items-center p-4 bg-[var(--color-bg-primary)] rounded-lg hover:shadow-md transition-shadow group"
|
||||
>
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-challenge-isolation-hover)] transition-colors">
|
||||
<div className="w-9 h-9 bg-[var(--color-brand-bg)] rounded-lg flex items-center justify-center mb-2 group-hover:bg-[var(--color-brand-soft)] transition-colors">
|
||||
<Search className="w-4 h-4 text-[var(--color-brand)]" />
|
||||
</div>
|
||||
<span className="font-medium text-sm text-[var(--color-text-primary)]">联系我们</span>
|
||||
|
||||
@@ -136,16 +136,16 @@ function PrivacyContent() {
|
||||
我们使用 Cookie 和类似技术来提供、保护和改进我们的服务。Cookie 是存储在您设备上的小型文本文件,帮助我们识别您的设备、记住您的偏好设置。
|
||||
</p>
|
||||
<div className="overflow-x-auto mb-6">
|
||||
<table className="min-w-full border border-[var(--color-border)] rounded-lg">
|
||||
<table className="min-w-full border border-[var(--color-border-primary)] rounded-lg">
|
||||
<thead className="bg-[var(--color-bg-tertiary)]">
|
||||
<tr>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border)]">Cookie 类型</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border)]">用途</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border)]">持续时间</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border)]">是否必需</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border-primary)]">Cookie 类型</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border-primary)]">用途</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border-primary)]">持续时间</th>
|
||||
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--color-text-primary)] border-b border-[var(--color-border-primary)]">是否必需</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-[var(--color-border)]">
|
||||
<tbody className="divide-y divide-[var(--color-border-primary)]">
|
||||
<tr>
|
||||
<td className="px-4 py-3 text-sm text-[var(--color-text-muted)]">必要 Cookie</td>
|
||||
<td className="px-4 py-3 text-sm text-[var(--color-text-muted)]">网站基本功能运行</td>
|
||||
@@ -248,7 +248,7 @@ export default async function PrivacyPolicyPage() {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<div className="bg-gradient-to-br from-[var(--color-brand)] via-[var(--color-brand)]/80 to-[var(--color-hero-dark-end)] py-20">
|
||||
<div className="bg-gradient-to-br from-[var(--color-brand)] via-[var(--color-brand)]/80 to-[var(--color-brand-section)] py-20">
|
||||
<div className="container-wide">
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">
|
||||
{heroTitle}
|
||||
|
||||
@@ -193,7 +193,7 @@ export default async function TermsOfServicePage() {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<div className="bg-gradient-to-br from-[var(--color-brand)] via-[var(--color-brand)]/80 to-[var(--color-hero-dark-end)] py-20">
|
||||
<div className="bg-gradient-to-br from-[var(--color-brand)] via-[var(--color-brand)]/80 to-[var(--color-brand-section)] py-20">
|
||||
<div className="container-wide">
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-white mb-4">
|
||||
{heroTitle}
|
||||
|
||||
Reference in New Issue
Block a user