Copy the handoff tokens.css into web/src/styles/tokens.css verbatim except the Google Fonts @import, replaced by @font-face rules for self-hosted Bagel Fat One (400) and Figtree (400/600/700) woff2 files, committed with their OFL licence texts. Base styles set the page background, text colour, Figtree body and the accent focus outline. npm test now runs lint:colors, which fails on any hex colour literal in web/src outside tokens.css. npm run build ends with check:dist-fonts, which fails if dist references fonts.googleapis.com or fonts.gstatic.com. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
33 lines
1.1 KiB
JavaScript
33 lines
1.1 KiB
JavaScript
// Fails when the production build references Google Fonts: fonts are
|
|
// self-hosted, so dist must never point at fonts.googleapis.com or
|
|
// fonts.gstatic.com.
|
|
import { readFileSync, readdirSync } from 'node:fs'
|
|
import { join, relative } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const distDir = fileURLToPath(new URL('../dist', import.meta.url))
|
|
const hosts = ['fonts.googleapis.com', 'fonts.gstatic.com']
|
|
|
|
function* files(dir) {
|
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
const path = join(dir, entry.name)
|
|
if (entry.isDirectory()) yield* files(path)
|
|
else yield path
|
|
}
|
|
}
|
|
|
|
const violations = []
|
|
for (const path of files(distDir)) {
|
|
const content = readFileSync(path, 'latin1')
|
|
for (const host of hosts) {
|
|
if (content.includes(host)) violations.push(`${relative(distDir, path)}: ${host}`)
|
|
}
|
|
}
|
|
|
|
if (violations.length > 0) {
|
|
console.error('Production build references Google Fonts; fonts must be self-hosted:')
|
|
for (const v of violations) console.error(` ${v}`)
|
|
process.exit(1)
|
|
}
|
|
console.log('check:dist-fonts: dist makes no Google Fonts requests')
|