NFR-A11Y-2 has three clauses and this branch closes one of them. The other two
— WCAG AA contrast on non-canvas UI, and platform font scaling honoured
without clipping — are now measured and reasoned about rather than left as two
sentences in the requirements register that nobody had checked.
Contrast is measured, not estimated. Every ink against every surface it is
drawn on, by the WCAG 2 formula, and the result is narrower and more specific
than "the palette is dark": `ink` and `warn-ink` pass everywhere, the inverted
cases on the near-white fills are the best-contrasting text in the application
at 18.6, and exactly two tokens fail. `ink-faint` reaches 4.5:1 on no surface
at all — 3.97 at its best — and it is the ink for every caption, every section
name and every count. `rule` reaches 3:1 on none either, and it is the border
of every button, field and panel, so an unfilled secondary button is a 1.4:1
outline on a 1.2:1 ground.
Neither is an oversight, which is why they belong here rather than in a bug
list. They fall out of the palette's own argument: a bright surround biases how
a photograph is judged and hue is banned outright, so all the signalling is
luminance and the luminance is deliberately spent on the image. "Text you are
meant to skip" and "text everyone can read" are in real tension. The fix is a
re-derived ink scale and a stronger rule, both of which change how the
application looks beside a photograph — a screenshot and an opinion, not a
patch, and not something to do blind.
Font scaling is the more interesting entry because the obvious fix is wrong. It
is not a multiplier on the type sizes: the layout rests on constants that are
not derived from them — control-height, touch-target, rail-entry-height,
panel-width, and a dozen fixed heights written at their call sites — and
scaling the type alone clips against every one, silently, because Slint elides
rather than errors. The colour mixer is the sharpest case, thirty-six controls
in a 360px column sized so a track and a swatch and a readout share a line.
So the entry sets out the four pieces in dependency order, and notes that the
first is nearly built already: `live-style` makes `build.rs` emit `in-out`
theme tokens that Rust writes at startup, which is exactly the mechanism a
scale factor needs.
Both entries carry the falsifiable condition this document asks for, and the
contrast table is the baseline a later measurement compares against.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>