fix(a11y): de uitleg uit een lege lijst was de slechtst leesbare tekst (#779) #786

Merged
brenno merged 1 commit from fix/palet-contrast-779 into main 2026-07-24 16:06:18 +00:00
Owner

Closes #779.

Correctie op het issue

Het issue noemde 3,31:1 voor de zoekhint. Dat getal klopte niet voor die
hint: ik had tegen surface2 gemeten, en het zoekveld staat op bg. Nagemeten
tegen de échte ondergrond is de hint 4,12:1.

De bevinding wordt daar niet kleiner van, maar wel scherper: textDim haalt als
tekst op geen enkel oppervlak van dit palet de 4,5:1 — tussen 3,31 (op
surface2) en 4,24 (op bgDeepest). Het is dus geen randgeval van één veld
maar een token dat structureel de verkeerde lat draagt.

Wat het was

textDim kleurde twee soorten dingen:

Rol Aantal Lat Haalt
iconen (sluiten, zoeken, wissen, filter) 7 3:1 (WCAG 1.4.11) ✓ overal
tekst 7 4,5:1 (WCAG 1.4.3) ✗ nergens

De zeven tekstplekken zijn de zoekhint, de tagvoortgang, twee beschrijvingshints
en — de vervelendste — de twee lege-toestandregels: "Zet het filter uit om alles
weer te zien"
en "Gebruik Bladeren om afbeeldingen van elke locatie te
kiezen"
. De zin die iemand uit een lege lijst moet helpen, was de slechtst
leesbare tekst in het venster.

Wat het nu is

De zeven tekstgebruiken nemen textMuted — dat haalt op elk van de zeven
oppervlakken ten minste 4,95:1 en blijft ruim onderscheidbaar van text (10,6).
De hint leest dus nog steeds als hint; dat is de eis uit #583.

Wat overblijft heet iconDim. De naam draagt de regel, want een textDim
die geen tekst mag kleuren is een val voor de volgende die hem pakt — dezelfde
overweging als BrandLogo in #735.

De oorzaak zat een laag hoger

Beide losstaande donkere paletten — de kiezer én de presentatiemodus — staan
bewust buiten AppTheme, en dáárom zondert de rauwe-kleurratchet ze uit. Die
uitzondering is verdedigbaar. Wat niemand had gezien is dat ze daarmee ook
buiten elke contrastmeting vielen: ze kwamen in geen enkel testbestand voor.

test/standalone_palette_contrast_test.dart dekt nu beide, in de vorm van
appearance_contrast.dart (#750): per token de rol, per rol de lat, gemeten
tegen elk oppervlak waar het écht op ligt. Plus de witte labels op de gekleurde
vullingen — dezelfde klasse als het knoplabel dat in #750 op 2,54:1 bleek te
staan, en tot nu toe nergens gemeten.

De presentatiemodus bleek in orde (9,0–15,7:1). Dat is geen reden om hem eruit
te laten: er hield niets dat zo.

Tegenproef

Mutatie Wat rood werd
de hint terug op de icoonkleur de bronwacht, met bestand en regelnummer
textMuted verdonkerd naar de oude waarde "textMuted is tekst en zakt hier onder de AA-lat"
successStrong licht gemaakt {successStrong: 1.38} — het witte label

Er staat ook een toets die vastlegt dat iconDim de tékstlat niet haalt. Die
is er bewust: trekt iemand die waarde ooit op, dan valt hij, en dan is de vraag
of iconDim en textMuted nog twee tinten zijn of één.

Wat er níét in zit

De vijf tokens die het issue als "lager dan 4,5" noemde behalve textDim
accentStrong, dangerStrong, successStrong, danger — zijn nagelopen op
gebruik en het zijn vullingen (backgroundColor:). Die tegen de bodytekst-lat
leggen is de categoriefout die de helft van #606's basislijn vulde. Wat er bij een
vulling wél toe doet is het label eróp, en dát is nu wel gemeten.

Ook niet: de oppervlakken zelf met eigen ogen bekeken. Dat hoort bij #780.

Poorten

make check exit 0. Geen l10n (geen nieuwe zichtbare tekst), geen
afhankelijkheid, geen SBOM-gevolg. docs/ACCESSIBILITY.md en SOURCE_MAP.md bij.

Closes #779. ## Correctie op het issue Het issue noemde **3,31:1** voor de zoekhint. Dat getal klopte niet voor die hint: ik had tegen `surface2` gemeten, en het zoekveld staat op `bg`. Nagemeten tegen de échte ondergrond is de hint **4,12:1**. De bevinding wordt daar niet kleiner van, maar wel scherper: `textDim` haalt als tekst op **geen enkel** oppervlak van dit palet de 4,5:1 — tussen 3,31 (op `surface2`) en 4,24 (op `bgDeepest`). Het is dus geen randgeval van één veld maar een token dat structureel de verkeerde lat draagt. ## Wat het was `textDim` kleurde **twee soorten dingen**: | Rol | Aantal | Lat | Haalt | |---|---|---|---| | iconen (sluiten, zoeken, wissen, filter) | 7 | 3:1 (WCAG 1.4.11) | ✓ overal | | tekst | 7 | 4,5:1 (WCAG 1.4.3) | ✗ nergens | De zeven tekstplekken zijn de zoekhint, de tagvoortgang, twee beschrijvingshints en — de vervelendste — de twee lege-toestandregels: *"Zet het filter uit om alles weer te zien"* en *"Gebruik Bladeren om afbeeldingen van elke locatie te kiezen"*. De zin die iemand uit een lege lijst moet helpen, was de slechtst leesbare tekst in het venster. ## Wat het nu is De zeven tekstgebruiken nemen `textMuted` — dat haalt op elk van de zeven oppervlakken ten minste 4,95:1 en blijft ruim onderscheidbaar van `text` (10,6). De hint leest dus nog steeds als hint; dat is de eis uit #583. Wat overblijft heet **`iconDim`**. De naam draagt de regel, want een `textDim` die geen tekst mag kleuren is een val voor de volgende die hem pakt — dezelfde overweging als `BrandLogo` in #735. ## De oorzaak zat een laag hoger Beide losstaande donkere paletten — de kiezer én de presentatiemodus — staan bewust buiten `AppTheme`, en dáárom zondert de rauwe-kleurratchet ze uit. Die uitzondering is verdedigbaar. Wat niemand had gezien is dat ze daarmee ook buiten **elke** contrastmeting vielen: ze kwamen in geen enkel testbestand voor. `test/standalone_palette_contrast_test.dart` dekt nu beide, in de vorm van `appearance_contrast.dart` (#750): per token de rol, per rol de lat, gemeten tegen elk oppervlak waar het écht op ligt. Plus de witte labels op de gekleurde vullingen — dezelfde klasse als het knoplabel dat in #750 op 2,54:1 bleek te staan, en tot nu toe nergens gemeten. De presentatiemodus bleek in orde (9,0–15,7:1). Dat is geen reden om hem eruit te laten: er hield niets dat zo. ## Tegenproef | Mutatie | Wat rood werd | |---|---| | de hint terug op de icoonkleur | de bronwacht, met bestand en regelnummer | | `textMuted` verdonkerd naar de oude waarde | "textMuted is tekst en zakt hier onder de AA-lat" | | `successStrong` licht gemaakt | `{successStrong: 1.38}` — het witte label | Er staat ook een toets die vastlegt dat `iconDim` de tékstlat *niet* haalt. Die is er bewust: trekt iemand die waarde ooit op, dan valt hij, en dan is de vraag of `iconDim` en `textMuted` nog twee tinten zijn of één. ## Wat er níét in zit De vijf tokens die het issue als "lager dan 4,5" noemde behalve `textDim` — `accentStrong`, `dangerStrong`, `successStrong`, `danger` — zijn nagelopen op gebruik en het zijn **vullingen** (`backgroundColor:`). Die tegen de bodytekst-lat leggen is de categoriefout die de helft van #606's basislijn vulde. Wat er bij een vulling wél toe doet is het label eróp, en dát is nu wel gemeten. Ook niet: de oppervlakken zelf met eigen ogen bekeken. Dat hoort bij #780. ## Poorten `make check` exit 0. Geen l10n (geen nieuwe zichtbare tekst), geen afhankelijkheid, geen SBOM-gevolg. `docs/ACCESSIBILITY.md` en `SOURCE_MAP.md` bij.
brenno force-pushed fix/palet-contrast-779 from 3ff066b09d
Some checks failed
ci / gate (pull_request) Failing after 1h28m18s
to 839cca6dde
All checks were successful
scans / scans (pull_request) Successful in 3m19s
2026-07-24 16:06:03 +00:00
Compare
brenno merged commit fc2d0a94de into main 2026-07-24 16:06:18 +00:00
Sign in to join this conversation.
No description provided.