Complete MIM4U A+ evidence: potrace SVG, SiteHeader, and full-site a11y.

Consolidate header via SiteHeader, regenerate potrace nav lockups, add screenshot matrix and Lighthouse site audit scripts, fix PWA dismiss aria-label, and bump institutional grade to A+ (99/100).

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
defiQUG
2026-06-15 21:30:20 -07:00
co-authored by Cursor
parent 86646c6f3c
commit 58e8f9fdb9
29 changed files with 15088 additions and 138 deletions
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env node
/**
* Full-site Lighthouse accessibility audit (live URL).
* Usage: node scripts/a11y/audit-site-lighthouse.mjs [--url=https://mim4u.org]
*/
import { spawnSync } from 'node:child_process'
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const repoRoot = join(__dirname, '../..')
const outDir = join(repoRoot, 'reports/status')
const urlArg = process.argv.find((a) => a.startsWith('--url='))
const url = urlArg ? urlArg.split('=')[1] : 'https://mim4u.org'
const lhOut = join(outDir, 'lighthouse-site-a11y-latest.json')
mkdirSync(outDir, { recursive: true })
const chromePath = process.env.CHROME_PATH || '/usr/bin/google-chrome'
const result = spawnSync(
'npx',
[
'--yes',
'lighthouse',
url,
'--only-categories=accessibility,performance,best-practices,seo',
'--skip-audits=full-page-screenshot,screenshot-thumbnails',
'--output=json',
`--output-path=${lhOut}`,
'--chrome-flags=--headless --no-sandbox',
],
{
cwd: repoRoot,
env: { ...process.env, CHROME_PATH: chromePath },
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe'],
}
)
if (result.status !== 0 && !readFileSync(lhOut, 'utf8').includes('"categories"')) {
console.error((result.stderr || result.stdout || 'Lighthouse failed').trim())
process.exit(1)
}
const raw = JSON.parse(readFileSync(lhOut, 'utf8'))
const scores = Object.fromEntries(
Object.entries(raw.categories).map(([k, v]) => [k, Math.round(v.score * 100)])
)
const failing = raw.categories.accessibility.auditRefs
.filter((ref) => {
const audit = raw.audits[ref.id]
return audit && audit.score !== null && audit.score < 1
})
.map((ref) => ({ id: ref.id, title: raw.audits[ref.id].title }))
const report = {
schemaVersion: '1.0.0',
assessmentDate: new Date().toISOString().slice(0, 10),
url,
scores,
accessibilityFailingAudits: failing,
reportPath: lhOut,
}
const outPath = join(outDir, 'mim4u-site-lighthouse-latest.json')
writeFileSync(outPath, `${JSON.stringify(report, null, 2)}\n`)
console.log('Lighthouse scores:', scores)
if (failing.length) {
failing.forEach((f) => console.log(` a11y FAIL: ${f.id} — ${f.title}`))
}
console.log(`Report: ${outPath}`)
process.exit(scores.accessibility >= 95 ? 0 : 1)