Files
pi-imgen/tests/contrast-check.typ
T
mozempk 5d27417c54 fix(render): resolve ink contrast per surface, not once per poster
templates/lib.typ gains WCAG luminance/contrast-ratio/ink-on and a
surface-aware palette-of(). framed and split place type on flat colour and
were inheriting an ink measured against the artwork, rendering white on
cream at 1.15:1. Now computed per surface: 18.34:1 on the regression
fixture. Accent held to the same bar with fallback to ink.

Adds tests/contrast-check.typ, run per fixture by the harness.
35/35 render combos and 7/7 contrast assertions pass.
2026-08-27 09:33:08 +02:00

44 lines
1.6 KiB
Typst

// Asserts that the kernel picks a legible ink for every surface a template can use.
//
// This is the regression guard for the blocker where the artwork-measured ink was used
// for text sitting on flat colour, producing white-on-cream at 1.15:1.
//
// typst compile tests/contrast-check.typ out.pdf --input specfile=/tests/fixtures/x.json --root .
//
// Compiles silently on success; panics with the offending ratio on failure.
#import "/templates/lib.typ": palette-of, contrast-ratio, MIN-CONTRAST
#let spec = json(sys.inputs.specfile)
#let name = spec.at("slug", default: "?")
#let problems = ()
// 1. Text on the flat page background must clear the bar.
#let on-bg = palette-of(spec, surface: "bg")
#let r-ink = contrast-ratio(on-bg.ink, on-bg.bg)
#if r-ink < MIN-CONTRAST {
problems.push("ink su bg = " + repr(r-ink))
}
// 2. The accent is held to the same bar - palette-of drops it back to ink if it fails,
// so a failure here means that substitution is broken.
#let r-acc = contrast-ratio(on-bg.accent, on-bg.bg)
#if r-acc < MIN-CONTRAST {
problems.push("accent su bg = " + repr(r-acc))
}
// 3. An arbitrary flat panel colour must also resolve to something legible.
#let on-accent = palette-of(spec, surface: on-bg.accent)
#let r-panel = contrast-ratio(on-accent.ink, on-bg.accent)
#if r-panel < MIN-CONTRAST {
problems.push("ink su pannello accent = " + repr(r-panel))
}
#if problems.len() > 0 {
panic("contrasto insufficiente [" + name + "]: " + problems.join("; ")
+ " (minimo " + repr(MIN-CONTRAST) + ":1)")
}
#set page(width: 40mm, height: 10mm, margin: 2mm)
ok