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.
44 lines
1.6 KiB
Typst
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
|