Brand tile colors as generated stylesheet (CSP blocks inline styles), footer credit link

This commit is contained in:
Aurealibe
2026-07-10 04:31:15 +01:00
parent 5f3528cce1
commit 710854510b
7 changed files with 260 additions and 18 deletions
+30
View File
@@ -40,3 +40,33 @@ writeFileSync(new URL('../src/icons.generated.ts', import.meta.url), out)
console.log(
`icons: ${found.length} embedded, ${missing.length} missing${missing.length ? ` (${missing.join(', ')})` : ''}`,
)
// Brand tile colors as a GENERATED STYLESHEET (not inline style attributes:
// the production CSP is style-src 'self', which blocks style= attributes).
// Tile ink is picked by WCAG contrast against the brand color — white ink
// fails on several light brands.
function luminance(hex) {
const n = hex.replace('#', '')
const [r, g, b] = [0, 2, 4].map((i) => {
const c = parseInt(n.slice(i, i + 2), 16) / 255
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4
})
return 0.2126 * r + 0.7152 * g + 0.0722 * b
}
function inkFor(hex) {
const L = luminance(hex)
return 1.05 / (L + 0.05) >= (L + 0.05) / 0.05 ? '#faf7ee' : '#14161a'
}
const tools = JSON.parse(readFileSync(new URL('../src/data/tools.json', import.meta.url), 'utf8'))
const rules = tools
.filter((t) => t.color)
.map((t) => `#${t.id} .tool-logo {\n background: ${t.color};\n color: ${inkFor(t.color)};\n}`)
const css = `/* AUTO-GENERATED by scripts/gen-icons.mjs — do not edit.
Brand tile background + WCAG-picked ink per tool (from tools.json).
A stylesheet, not style= attributes: the CSP (style-src 'self')
blocks inline styles in production. */
${rules.join('\n')}
`
writeFileSync(new URL('../src/styles/brands.generated.css', import.meta.url), css)
console.log(`brands: ${rules.length} tile rules → src/styles/brands.generated.css`)