import { Inter, Noto_Sans_SC, IBM_Plex_Mono } from "next/font/google"; /** * 站点字体系统(next/font 自托管)。 * * 设计规范(DESIGN.md)要求: * - Inter → 英文 / UI 正文 * - Noto Sans SC → 中文 * - IBM Plex Mono → 代码(规范原文为 Geist Mono,本项目按需求改用 IBM Plex Mono) * * 说明:next/font/google 在 `next build` 阶段下载字体文件并自托管到 * `.next/static/media`,运行时不会向 Google 发起请求,也不产生 FOUT/CLS。 * 每个字体都显式配置 `fallback`(含 `adjustFontFallback`),保证在字体 * 尚未加载或加载失败时,回退栈与目标字体的度量尽量接近。 */ /** 英文 / UI 主字体:Inter */ export const fontInter = Inter({ variable: "--font-inter", subsets: ["latin", "latin-ext"], weight: ["400", "500", "600", "700"], style: ["normal"], display: "swap", preload: true, fallback: [ "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Helvetica Neue", "Arial", "sans-serif", ], adjustFontFallback: true, }); /** * 中文字体:Noto Sans SC * * 该字族在 Google Fonts 上是按权重分片的(非可变字体),因此显式声明需要 * 的 4 个权重,由 next/font 生成 unicode-range 分片,浏览器只下载用到的子集。 */ export const fontNotoSansSC = Noto_Sans_SC({ variable: "--font-noto-sans-sc", subsets: ["latin"], weight: ["400", "500", "600", "700"], style: ["normal"], display: "swap", // 中文字体体积大、子集多,禁用预载以免抢占首屏关键资源。 preload: false, fallback: [ "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", "WenQuanYi Micro Hei", "sans-serif", ], adjustFontFallback: false, }); /** 代码字体:IBM Plex Mono */ export const fontIbmPlexMono = IBM_Plex_Mono({ variable: "--font-ibm-plex-mono", subsets: ["latin", "latin-ext"], weight: ["400", "500", "600"], style: ["normal"], display: "swap", preload: true, fallback: [ "SFMono-Regular", "SF Mono", "Menlo", "Consolas", "Liberation Mono", "Courier New", "monospace", ], adjustFontFallback: true, }); /** 挂到 上的字体变量类名。 */ export const fontVariables = [ fontInter.variable, fontNotoSansSC.variable, fontIbmPlexMono.variable, ].join(" ");