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:
@@ -50,6 +50,9 @@ convert "$OUT/logo-horizontal-nav.png" -quality 88 -define webp:method=6 "$OUT/l
|
||||
|
||||
convert "$symbol" -trim +repage -background none -resize 512x512\> PNG32:"$OUT/logo-symbol-nav.png"
|
||||
|
||||
echo "Tracing nav lockups to SVG (potrace)..."
|
||||
node "$MIM_ROOT/scripts/brand/trace-nav-svg.mjs"
|
||||
|
||||
echo "Exporting square PNG/WebP..."
|
||||
convert "$square" -strip "$OUT/logo-square.png"
|
||||
convert "$square" -quality 88 -define webp:method=6 "$OUT/logo-square.webp"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Trace nav PNG lockups to SVG via potrace (high-fidelity paths from approved raster).
|
||||
* Usage: node scripts/brand/trace-nav-svg.mjs
|
||||
*/
|
||||
import { promises as fs } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import potrace from 'potrace'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const brandDir = path.join(__dirname, '../../public/brand')
|
||||
|
||||
const traces = [
|
||||
{
|
||||
input: 'logo-horizontal-nav.png',
|
||||
output: 'logo-horizontal-nav.svg',
|
||||
title: 'Miracles in Motion Foundation',
|
||||
potrace: {
|
||||
color: 'auto',
|
||||
background: 'transparent',
|
||||
turdSize: 2,
|
||||
optTolerance: 0.2,
|
||||
threshold: 180,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: 'logo-symbol-nav.png',
|
||||
output: 'logo-symbol-nav.svg',
|
||||
title: 'Miracles in Motion Foundation symbol',
|
||||
potrace: {
|
||||
color: 'auto',
|
||||
background: 'transparent',
|
||||
turdSize: 2,
|
||||
optTolerance: 0.15,
|
||||
threshold: 200,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
function tracePng(inputPath, options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
potrace.trace(inputPath, options, (err, svg) => {
|
||||
if (err) reject(err)
|
||||
else resolve(svg)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function normalizeSvg(svg, title) {
|
||||
let out = svg.replace(/<\?xml[^>]*>\s*/i, '')
|
||||
if (!out.includes('aria-hidden')) {
|
||||
out = out.replace(/<svg\b/, '<svg role="img" aria-hidden="true"')
|
||||
}
|
||||
if (!out.includes('<title>')) {
|
||||
out = out.replace(/<svg([^>]*)>/, `<svg$1>\n <title>${title}</title>`)
|
||||
}
|
||||
return out.trim() + '\n'
|
||||
}
|
||||
|
||||
async function main() {
|
||||
for (const job of traces) {
|
||||
const inputPath = path.join(brandDir, job.input)
|
||||
const outputPath = path.join(brandDir, job.output)
|
||||
await fs.access(inputPath)
|
||||
const raw = await tracePng(inputPath, job.potrace)
|
||||
const svg = normalizeSvg(raw, job.title)
|
||||
await fs.writeFile(outputPath, svg)
|
||||
console.log(`Wrote ${job.output} (${svg.length} bytes)`)
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
Reference in New Issue
Block a user