Documentation · guide 8 of 10
Accessibility
This is docs/08-accessibility.md, one of the ten guides that ship inside the AlumDeck zip under docs/, as written for release 2.0.0. The same guide opens inside the admin, from the ? link in a screen's header or from System, Help.
AlumDeck aims for WCAG 2.2 level AA on the public site and the member area, and checks the admin panel's own screens too. This guide covers five things:
- what was checked, and how (release 2.0.0);
- what was fixed;
- what is still open;
- an accessibility statement you can adapt and publish;
- a draft Accessibility Conformance Report (VPAT 2.5, WCAG edition) that says honestly where the product stands.
The admin panel is built on Filament. Its controls come from Filament, and our own screens use Filament's components. Every admin screen is checked automatically as well.
What was checked, and how
Automatic checks on every page. Every public page and every member page was rendered: 102 pages, signed out and signed in. Each one was checked for the same things:
- the page has a language (
lang) and a writing direction (dir); - one
mainlandmark, and a skip link to it before anything else; - one
h1, and no heading level skipped; - a text alternative on every image;
- a name on every form field, button and link;
- unique ids, and
aria-labelledbypointing at ids that exist; - no positive
tabindex; - a title on every frame.
The same checks run in the test suite (tests/Feature/i18n_AccessibilityTest.php) on the busiest public and member pages, in English and right to left. A regression fails the build.
Colour. The packaged palette was measured. Every text and background pair the views use reaches 4.5:1 or better. The weakest pair is brass-600 on cream-200, at 5.05:1. The lowest body-text pair is ink-500 on cream-50, at 7.68:1.
Code review of the views and the site's stylesheets:
- landmarks, heading order and labels;
- focus styles (
:focus-visible); - the skip link;
- the custom widgets: the menus, account menu, search pop-up, reactions, lightbox, cookie settings and install sheet, which all use
aria-expanded,aria-pressed,aria-controlsand close on Escape; - touch targets (44 px, enforced by earlier tests);
- reduced motion.
Four more checks (each one is a test, so a regression fails the build):
- Form errors. Every error message in the public and member views (about 240) has an id, and its field points at it (
aria-describedby) and says it is invalid (aria-invalid). A real failed submit is checked end to end. Long forms (about 20, from joining and the profile to event registration and the shop checkout) open with an error summary: announced, focused, one link per problem (tests/Feature/i18n3_FormErrorsTest.php). - The admin panel. Every admin screen (about 190) is rendered and given the checks above: language, one
h1, heading order, alt text, labels, names, unique ids, ARIA references, no positivetabindex(tests/Feature/i18n3_AdminAccessibilityTest.php). Filament's own components that fail a static check are listed below. - Keyboard. Every view and stylesheet is scanned: nothing reacts to a click without being reachable by Tab, no positive
tabindex, every pop-up that announces open/closed (aria-expanded) closes with Escape, and a focus ring is never removed without a visible replacement (tests/Feature/i18n3_KeyboardTest.php). - Touch targets of the admin's own controls, the footer widgets, the cookie banner and short labels: 44 x 44 px on touch screens, by growing the area that takes the tap, never the control (
tests/Feature/i18n3_TouchTargetsTest.php).
Names and roles, checked by the supplier on the main journeys (release 2.0.0). Sign in, join, donate, event registration, the directory, the profile, and an admin list and edit screen (members and events) were rendered, signed out and signed in, and every control was checked for its name and its role (WCAG 4.1.2): links, buttons, fields and anything with an ARIA widget role have a name; every role is a real ARIA role and carries its required state (aria-checked on a switch, aria-expanded on a combobox); state values are valid; nothing clickable lacks a control role or keyboard access; radio buttons and check boxes that share a name are a named group; nothing focusable is hidden with aria-hidden; dialogs and repeated navigation landmarks are named. 20 pages, 2,109 elements. It found that the header's two menus (wide and narrow screens) were unnamed navigation landmarks; they are now named "Main menu". The only remaining failures are in Filament's own components (Known gaps, item 8) (tests/Feature/trust_NamesAndRolesTest.php).
Not done yet. Names and roles were checked by the supplier; no screen-reader testing has been done. There was no test with screen readers (NVDA, JAWS, VoiceOver, TalkBack), no keyboard-only walk through every flow in a real browser, and no test with users with disabilities. The keyboard checks above read the code; they do not press keys. Those are the next step, and they are what a formal audit would add.
What was fixed in release 2.0.0
- The mobile menu button now has a name without JavaScript. It was named only by Alpine.js, so before the script ran (or if it failed) screen readers heard "button".
- Status messages are announced. The green confirmation bar ("Language saved.", "Saved.") now has
role="status"(WCAG 4.1.3). - Reduced motion covers the whole site. Anyone who asks their system for less motion now gets no transitions or animations anywhere. Before, only a few components respected the setting (WCAG 2.3.3).
- Language of each page. Every page states its language and direction. A right-to-left page (Arabic, Hebrew, Persian, Urdu and others) is laid out right to left, and arrows turn round. In the language menu, each language's name is marked with its own language (WCAG 3.1.1, 3.1.2).
- Decorative arrows are silent. Arrows beside link text ("All news", "Next") are hidden from screen readers, which used to read "right arrow".
- Form errors are tied to their fields (
aria-describedby,aria-invalid), and long forms open with an error summary that is announced (role="alert"), takes focus and links to each field. - Header sub-menus open by keyboard. A menu item with sub-links opened only on hover, so its sub-links could not be reached with Tab. It now opens when it gets focus, and Escape closes it and returns focus to the item (WCAG 2.1.1).
- Admin screens. The Help page had two
h1s (the guide's headings now sit under the screen's title). Payment settings and Page copy gave two sections the same id. The product tour's Next button had no name until its script ran. A post without categories left an empty link in the posts table. - One header and one heading size for sub-pages and form pages in the member area, with the heading above the form card instead of inside it, and one style for empty lists and for status labels.
- Touch targets of the admin's own links and buttons, the footer widgets, the cookie banner's link and short labels ("All", "Edit", "X").
Known gaps
- Form errors on short forms. Every field points at its own error, but only the long forms have the announced summary. On a one- or two-field form a screen reader user hears the error when they reach the field.
- Timing.
- A ticket reservation is held for a set time (Settings > Events, jobs & volunteering), with the time shown on the page.
- The admin session ends after 60 idle minutes with no warning.
- The giving-day clock updates every second and cannot be paused.
- Sticky header and focus. On small screens the sticky header can partly cover a focused element near the top of the window (WCAG 2.4.11).
- Content added by your team. Alt text for uploaded photos, captions for embedded videos, link wording in news posts and the accessibility of attached documents all depend on what is entered. Every image field has an alt-text box; fill it in.
- Colours you choose. Settings > Theme & colours lets you change the site colours. A choice with poor contrast is not blocked.
- Documents we generate (PDF receipts, invoices, the membership card) are not tagged PDFs.
- The member map is a pointer-oriented map. The same members are listed on the directory page, which is fully keyboard and screen reader friendly.
- The admin panel relies on Filament for keyboard and screen reader support. Reordering by drag and drop has up and down buttons on most screens, but not on all of them. The automatic checks find these in Filament's own components (not AlumDeck's), on the screens that use them:
- the rich text editor's panel close button (Blocks, Merge tags) has no name;
- the markdown editor's source box has no label of its own (the editor shows the field's label);
- the search boxes, a multi-select tag's remove button and the date picker's button get their names only when Filament's script runs; a static check cannot confirm them;
- the menu group headings, collapsible section headings and the backdrop of the mobile menu react to a click without being controls; each has its own named button that does the same by keyboard.
Accessibility statement (template)
Copy this to a page on your site (Publishing > Pages) and fill in the square brackets. Many countries require a statement like this for public bodies. It is good practice for everyone else.
Accessibility statement for [site name]
[Association name] wants everyone to be able to use this website: the public pages and the members area. We aim to meet the Web Content Accessibility Guidelines (WCAG) 2.2 at level AA.
How accessible this site is. Most of the site works with a keyboard and with text enlarged to 200%, and its controls are named for screen readers (the supplier checked names and roles; no screen-reader testing has been done). You can change the site's language in your profile. Right-to-left languages are supported. We know some parts are not fully accessible yet:
- on short forms, an error is read out when you reach its field rather than straight away;
- some older photos and documents may not have text descriptions;
- PDF receipts and membership cards are not tagged for screen readers;
- [anything your own content adds].
Tell us about a problem. If you cannot use part of this site, or you need something in another format, contact [name or role] at [email address] or use the [contact form link]. We will reply within [number] working days.
Enforcement. [If your country has an enforcement body, name it and how to contact it.]
How we tested. This statement was prepared on [date]. The software's supplier checked it automatically and by review against WCAG 2.2 AA (see the supplier's conformance report). [Say here whether you have tested your own content or commissioned an audit.] We review this statement every [twelve] months.
Accessibility Conformance Report - draft
Based on VPAT 2.5 Rev (WCAG edition).
- Product: AlumDeck 2.0.0. Public site and member area; the admin panel is noted separately.
- Report date: 3 October 2026 (first draft 26 September 2026).
- Evaluation methods:
- automatic checks of the rendered HTML of 102 public and member pages and about 190 admin screens;
- a rendered failed form submit, and a scan of every error message and its field;
- a scan of every view and stylesheet for keyboard access and focus visibility;
- a colour contrast calculation for the packaged palette;
- a code review of the views, stylesheets and scripts;
- names and roles checked by the supplier on the main journeys (sign in, join, donate, event registration, directory, profile, an admin list and edit screen).
- Not used: assistive technology testing and user testing. No screen-reader testing has been done.
- Draft status: this is a supplier's draft, not an independent audit. The terms follow the VPAT definitions:
- Supports;
- Partially Supports (some functionality does not meet the criterion);
- Does Not Support;
- Not Applicable.
Table 1: WCAG 2.2 Level A
| Criterion | Conformance | Remarks |
|---|---|---|
| 1.1.1 Non-text Content | Partially Supports | Every image in the product's own templates has alt text, and decorative icons are hidden. Alt text for uploaded images depends on what editors enter. |
| 1.2.1 Audio-only and Video-only (Prerecorded) | Not Applicable | The product ships no media. Media added by an association is its own content. |
| 1.2.2 Captions (Prerecorded) | Not Applicable | As 1.2.1. Embedded players (YouTube, Vimeo) support captions provided by the uploader. |
| 1.2.3 Audio Description or Media Alternative | Not Applicable | As 1.2.1. |
| 1.3.1 Info and Relationships | Supports | Landmarks, heading order, labels, and fieldsets with legends are all in place and checked automatically. Each form error is tied to its field (aria-describedby, aria-invalid); a scan checks every one. |
| 1.3.2 Meaningful Sequence | Supports | The reading order follows the source. Right-to-left pages use logical properties. |
| 1.3.3 Sensory Characteristics | Supports | Instructions do not rely on shape, position or sound. |
| 2.1.1 Keyboard | Partially Supports | Native controls, and custom widgets that work by keyboard (Escape closes them); header sub-menus open on focus. A scan finds no click-only element in any view. The member map is pointer-oriented, and the directory offers the same information. Some admin drag-to-reorder lists have no buttons. |
| 2.1.2 No Keyboard Trap | Supports | Dialogs and menus close with Escape. |
| 2.1.4 Character Key Shortcuts | Supports | The only shortcuts are admin ones, and they use a modifier key (Ctrl/Cmd+K, Ctrl/Cmd+S). |
| 2.2.1 Timing Adjustable | Partially Supports | Ticket holds are shown and can be restarted. The admin idle timeout gives no warning. |
| 2.2.2 Pause, Stop, Hide | Partially Supports | The giving-day countdown updates every second and cannot be paused. Nothing moves or blinks elsewhere. |
| 2.3.1 Three Flashes or Below Threshold | Supports | Nothing flashes. |
| 2.4.1 Bypass Blocks | Supports | A skip link to the main content is the first thing on every page (tested). |
| 2.4.2 Page Titled | Supports | Every page has a descriptive title, in the reader's language. |
| 2.4.3 Focus Order | Supports | Focus follows the source order, and there is no positive tabindex in any view (tested). After a failed submit, focus moves to the error summary, and its links move focus to the field. |
| 2.4.4 Link Purpose (In Context) | Supports | Short link texts ("View", "See it") sit in a context that names the item. |
| 2.5.1 Pointer Gestures | Supports | No multipoint or path gestures are required. The map has zoom buttons. |
| 2.5.2 Pointer Cancellation | Supports | Native click behaviour. |
| 2.5.3 Label in Name | Supports | Accessible names begin with the visible label. |
| 2.5.4 Motion Actuation | Not Applicable | No motion input. |
| 3.1.1 Language of Page | Supports | lang and dir on every page, following the reader's language (tested). |
| 3.2.1 On Focus | Supports | Focus never changes the context. |
| 3.2.2 On Input | Supports | Changing a field never submits a form or moves the page without a button, except the language and filter controls, which say what they do. |
| 3.2.6 Consistent Help | Supports | The contact link is in the same place on every page. |
| 3.3.1 Error Identification | Supports | Errors are described in text next to the field and tied to it; the field is marked invalid. Long forms list every error in a summary at the top. |
| 3.3.2 Labels or Instructions | Supports | Every field has a visible label. Required fields and formats are stated. |
| 3.3.7 Redundant Entry | Supports | Forms keep what was typed after an error. Known details are filled in for members. |
| 4.1.2 Name, Role, Value | Partially Supports | Every control in the product's templates and admin screens has a name (tested), except a few in Filament's own components (see Admin panel). Names and roles checked by the supplier on the main journeys: roles are valid, widget roles carry their state, grouped options are named (tested). No screen-reader testing has been done. |
Table 2: WCAG 2.2 Level AA
| Criterion | Conformance | Remarks |
|---|---|---|
| 1.2.4 Captions (Live) | Not Applicable | No live media. |
| 1.2.5 Audio Description (Prerecorded) | Not Applicable | As 1.2.1. |
| 1.3.4 Orientation | Supports | Layouts work in both orientations. |
| 1.3.5 Identify Input Purpose | Partially Supports | Personal fields such as name, email, phone and date of birth carry autocomplete tokens on the main forms, but not on every form. |
| 1.4.3 Contrast (Minimum) | Supports | Every packaged text colour reaches 4.5:1 or better (lowest 5.05:1). Colours an association sets itself are not checked. |
| 1.4.4 Resize Text | Supports | Text is sized in rem, and pages work at 200%. |
| 1.4.5 Images of Text | Supports | No images of text in the product. |
| 1.4.10 Reflow | Supports | Mobile-first layouts work at 320 CSS px without horizontal scrolling. |
| 1.4.11 Non-text Contrast | Partially Supports | Focus outlines and buttons meet 3:1. Some field borders and dividers are lighter. |
| 1.4.12 Text Spacing | Supports | No fixed-height text containers in the product's templates. |
| 1.4.13 Content on Hover or Focus | Supports | Pop-ups stay while hovered and close with Escape. |
| 2.4.5 Multiple Ways | Supports | Navigation, site search and a sitemap. |
| 2.4.6 Headings and Labels | Supports | Descriptive headings and labels. |
| 2.4.7 Focus Visible | Supports | A visible focus style on every interactive element (:focus-visible). |
| 2.4.11 Focus Not Obscured (Minimum) | Partially Supports | On small screens the sticky header can partly cover a focused element near the top. |
| 2.5.7 Dragging Movements | Partially Supports | Some admin reorder lists are drag-only. There is no dragging on the public site or in the member area. |
| 2.5.8 Target Size (Minimum) | Supports | Targets are at least 44 px on touch layouts, including the admin's own controls, footer widgets, cookie banner and short labels (tested). |
| 3.1.2 Language of Parts | Partially Supports | Language names in the language menu are marked. Content that members write in another language is not. |
| 3.2.3 Consistent Navigation | Supports | The same header, member menu and footer on every page. |
| 3.2.4 Consistent Identification | Supports | The same functions have the same names throughout. |
| 3.3.3 Error Suggestion | Supports | Messages say how to put the entry right. |
| 3.3.4 Error Prevention (Legal, Financial, Data) | Supports | Payments are confirmed on the provider's page. Deletion requests need a tick box to confirm. Registrations can be reviewed before paying. |
| 3.3.8 Accessible Authentication (Minimum) | Supports | Password managers and paste work. Sign-in by emailed link is offered. The optional bot check (Turnstile) is not a cognitive test. |
| 4.1.3 Status Messages | Partially Supports | Confirmations are role="status". On long forms the error summary is announced (role="alert"); on short forms the error is not announced by itself. |
Admin panel
The admin panel uses Filament 5. Its forms, tables, modals and notifications follow Filament's own accessibility support. AlumDeck's screens add their own labels (translated) and use Filament components; the custom parts are the dashboard widgets, the Getting started checklist and product tours, the Help pages, the import and report pages and the admin themes.
Every admin screen (about 190) passes the automatic checks listed under "What was checked": AlumDeck's own markup has no failures. The remaining static failures are in Filament's own components (Known gaps, item 8). No screen reader or keyboard walk-through of the panel has been done, so this report makes no conformance claim for the admin panel beyond those checks.
Guide 8 of 10
Keep reading
The ten guides ship together in the zip, in this order.
Stuck on something this guide does not cover?
Write to the people who build AlumDeck through the contact form. We aim to reply within one working day, Monday to Friday: a target, not a guarantee.