Three things a page says with colour alone, and one it barely says: the field border, the current navigation link, a finished calendar event, and focus on a field #274
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo#274
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
From an accessibility read of the stylesheet and templates on 2026-09-18. axe runs over every page in both themes and passes; none of this is text contrast, which is what axe measures. Ratios below are computed from the
inktokens inassets/css/app.css:53-75.Field boundaries are about 1.5:1 in both themes
assets/css/app.css:255-260(field-input:border-ink-300 bg-white,dark:border-ink-700 dark:bg-ink-950), applied to every input, select and textarea by the base rule, tobtn-secondary(:268-271) and to the table filters inpartials/table/head.html:80-122.The border is the only thing that says this is a field, and SC 1.4.11 (non-text contrast, AA) wants 3:1 for that boundary. Nothing handles
prefers-contrast: moreeither. Hurts low-vision users on every form.Fix: a per-theme field-border token that clears 3:1 (light around L 0.65;
ink-500's dark value already does) onfield-inputandbtn-secondary, darker again underprefers-contrast: more. A unit test that reads the tokens and computes the ratio would hold it, the way the theme tests read the palette.Focus on a field is the weakest cue in the application
app.css:258setsfocus:outline-hidden, which discards the base 2px brand-500 outline every button, link and summary keeps (:211-213), and leaves a one-pixel border change plus a ring at 20% alpha, about 1.2:1 against white. The forced-colours rule (:811-819, #227) restores an outline only in high-contrast mode. SC 2.4.7 passes by a hair; the controls people type into get the faintest indicator. Fix: an opaque ring (focus-visible:ring-2 focus-visible:ring-brand-500), or keep the base outline with offset 0 on fields.The current navigation link is marked by colour only, and not marked at all for a screen reader
partials/nav_links.html:9-10renders the active item as a class alone (nav_active_names,core/templatetags/postulo.py:435-442); the style isbg-ink-100on a white header, 1.1:1, orbg-ink-800onink-900, 1.2:1. Noaria-current. The sidebar (partials/sidebar.html:16) and the calendar's view switcher do it right. SC 1.4.1 and 4.1.2: colour-blind and low-vision users cannot see which section they are in, screen readers are not told, and forced colours drop the highlight entirely. Fix: emitaria-current="page"innav_links.html, and give the active link a non-colour cue, weight or a 2px bottom border, which forced colours repaint. A test intests/test_navigation.pythat the active item carriesaria-current.A done reminder or a cancelled interview is conveyed by a strike-through and fading
applications/calendar.html:14-19(#204): a muted event getsline-through opacity-60; the hidden prefix says only "Interview:" or "Reminder:", and in compact modeevent.detailis dropped. At 60% opacity over white the 12px text lands at about 3.1:1 (SC 1.4.3), and nothing tells a screen reader the event is over (SC 1.3.1). axe only sees the contrast if the fixture calendar holds a muted event. Fix: dropopacity-60, keep the strike, add ansr-onlyword for the state.Small, while there
The required-field asterisk in
partials/field.html:11(text-red-600) has no dark variant, about 3.8:1 on theink-900card, and nothing on the page says what it means;dark:text-red-400and a "(required)" in the label or a once-per-form line.