Aegix Global, LLC
AIM Web — VPAT 2.5
Last reviewed 2026-04-03VPAT 2.5 - Aegix AIM (Active Incident Management Web App)
Product Information
| Field | Value |
|---|---|
| Product Name | Aegix AIM Web |
| Product Version | Current (as of 2026-04-07) |
| Product Description | Active Incident Management web application for real-time safety alerts, map-based situational awareness, chat, visitor management, and incident reporting |
| Report Date | 2026-04-07 |
| Contact | Aegix Global |
| Evaluation Methods | Code review, static analysis against WCAG 2.1 AA criteria, eslint-plugin-jsx-a11y, @axe-core/react |
| Applicable Standards | WCAG 2.1 Level AA, Section 508 (Revised) |
Conformance Level Key
| Term | Description |
|---|---|
| Supports | The functionality of the product has at least one method that meets the criterion without known defects or meets with equivalent facilitation |
| Partially Supports | Some functionality of the product does not meet the criterion |
| Does Not Support | The majority of product functionality does not meet the criterion |
| Not Applicable | The criterion is not relevant to the product |
Application Overview
Aegix AIM is a large-scale React 19 application (~562 source files) with the following major functional areas:
- Alert Management - Real-time alert creation, status tracking, and response coordination
- Maps - Interactive floorplan/map views with MapsIndoors and Mahere providers
- Chat - Real-time messaging with mentions and threads
- Admin - User management, alert type configuration, SSO settings
- Reporting - Incident reports, roster management, and drill history
- Visitors - Visitor check-in and management
- Settings - User profile, notification preferences, accessibility toggle
Notable: AIM includes a custom accessibility module (src/modules/accessiblility/) with Web Speech API integration for screen reader announcements. This is an opt-in feature toggled in settings, complementing standard ARIA live regions.
Table 1: WCAG 2.1 Report
Principle 1: Perceivable
| Criteria | Conformance Level | Remarks and Explanations |
|---|---|---|
| 1.1.1 Non-text Content (Level A) | Partially Supports | Map toolbar buttons have aria-labels. Logo images have alt text. Map marker popups now have descriptive alt text (location name and timestamp). Chat message images have descriptive alt text. Camera stream drawer has sr-only description for screen readers. Some icon-only buttons in admin panels may still lack text alternatives. |
| 1.2.1 Audio-only and Video-only (Level A) | Partially Supports | Camera stream drawer provides live video feeds with sr-only text description of camera name and status. Alert audio plays for notifications. |
| 1.2.2 Captions (Prerecorded) (Level A) | Not Applicable | No prerecorded audio/video content. |
| 1.2.3 Audio Description or Media Alternative (Level A) | Not Applicable | No prerecorded video content. |
| 1.2.4 Captions (Live) (Level AA) | Does Not Support | Live camera streams in CameraStreamDrawer have no captions. Live captions on security camera feeds are not feasible; documented as a known limitation. |
| 1.2.5 Audio Description (Level AA) | Not Applicable | No prerecorded video content. |
| 1.3.1 Info and Relationships (Level A) | Supports | InputField component uses Field.Root, Field.Label with htmlFor, aria-describedby linking to error messages, and aria-invalid. Settings FormField component has the same associations. ReportStepField has proper label elements with htmlFor, aria-label on radio/checkbox groups, and aria-describedby linking to errors. DataTable has scope="col" on column headers and aria-sort on sortable columns. AlertTypeForm alert name Input has aria-label. Login page inputs have aria-label attributes. |
| 1.3.2 Meaningful Sequence (Level A) | Supports | DOM order reflects visual order. Layout uses sidebar + main content pattern with consistent ordering. |
| 1.3.3 Sensory Characteristics (Level A) | Partially Supports | Map-based features rely on visual/spatial perception. Room status colors on maps convey safety information. The speakAccessibility module provides auditory alternatives when enabled. |
| 1.3.4 Orientation (Level AA) | Supports | No orientation lock. Responsive design via Chakra UI breakpoints. |
| 1.3.5 Identify Input Purpose (Level AA) | Supports | Login form has autoComplete for email, password, given-name, family-name, and tel. Admin addUser form has autoComplete on all fields (given-name, family-name, tel, email, new-password). Settings editUser form has autoComplete on all fields. changePassword has autoComplete=“new-password”. UserDetailSection has autoComplete on name and email fields. ProfileComponent password reset has autoComplete=“new-password”. |
| 1.4.1 Use of Color (Level A) | Partially Supports | Map room status relies primarily on color (safe=green, unsafe=red). Alert severity uses color as primary differentiator. Chat message types distinguished by background color. The accessibility speech module partially mitigates this when enabled. |
| 1.4.2 Audio Control (Level A) | Supports | Alert audio has mute/unmute toggle in navbar. Audio state is managed centrally via AudioProvider (ADR-054). |
| 1.4.3 Contrast (Minimum) (Level AA) | Supports | Theme tokens updated for AA compliance: text.tertiary darkened to gray.700, text.action to teal.700/safe.700 (light mode), text.danger to red.700 (light) / darkRed.200 (dark). surface.menuSelect opacity increased from 8% to 15%. |
| 1.4.4 Resize Text (Level AA) | Partially Supports | Map component uses fixed height calc(100vh - 64px). Most other content supports text resizing via Chakra UI responsive props. |
| 1.4.5 Images of Text (Level AA) | Supports | No images of text. All text rendered as HTML. |
| 1.4.10 Reflow (Level AA) | Partially Supports | Map views have fixed dimensions. Chat sidebar has fixed width. Most other content reflows correctly. |
| 1.4.11 Non-text Contrast (Level AA) | Supports | Focus indicators use 2px solid outlines with border-action color token across all interactive elements. Global *:focus-visible CSS rule provides consistent focus visibility. |
| 1.4.12 Text Spacing (Level AA) | Partially Supports | No explicit handling for increased text spacing. Truncated text in tables and badges may clip. |
| 1.4.13 Content on Hover or Focus (Level AA) | Partially Supports | Map popup content appears on marker click (not hover). Some tooltips may not persist on focus. |
Principle 2: Operable
| Criteria | Conformance Level | Remarks and Explanations | |
|---|---|---|---|
| 2.1.1 Keyboard (Level A) | Partially Supports | Login password toggle converted to keyboard-accessible button with aria-label. Forgot password link converted to button element. DataTable sortable headers have Enter/Space key handlers. ExportMenu single-item rendered as semantic button. Chat map icon button is keyboard accessible. Chat image preview, document download, and avatar clicks all converted to keyboard-operable elements (semantic buttons or role=“button” with Enter/Space handlers). Admin form delete buttons (role/site removal) are semantic buttons with aria-labels. UserDetailSection edit button converted to semantic button. NotificationOverlay dismiss and “Later” buttons converted to semantic buttons. Map interactions (pan, zoom, marker selection) remain mouse-dependent. | |
| 2.1.2 No Keyboard Trap (Level A) | Partially Supports | Dialog components use Chakra’s Dialog.Root with focus management. Some modal stacking in alert flow (LocationModal, MapModal, StatusModal) may create complex focus management challenges. | |
| 2.1.4 Character Key Shortcuts (Level A) | Supports | No single-character keyboard shortcuts. | |
| 2.2.1 Timing Adjustable (Level A) | Supports | No time limits on user interactions. Alert notifications persist until acknowledged. | |
| 2.2.2 Pause, Stop, Hide (Level A) | Supports | Real-time alert updates and map status changes are essential safety content. Per WCAG 2.2.2 exception, real-time content where the information would be invalidated by pausing is exempt. AIM’s real-time updates serve mission-critical safety purposes. | |
| 2.3.1 Three Flashes or Below (Level A) | Supports | No flashing content. Alert visual indicators use steady states. | |
| 2.3.3 Animation from Interactions (Level AAA) | Supports | Global prefers-reduced-motion CSS rule disables all animations and transitions when user preference is set. | |
| 2.4.1 Bypass Blocks (Level A) | Supports | Skip-to-content link added as first focusable element in AppLayout. Main content area identified with id="main-content". Link becomes visible on focus with proper styling and z-index. | |
| 2.4.2 Page Titled (Level A) | Supports | Dynamic page titles implemented via usePageTitle hook on key routes: Alerts, Map, Chat, Admin Users, Admin Alert Types, Incidents, Visitors, Sign In. Titles follow “{Page} \ | Aegix AIM” pattern. useDocumentTitleBadge adds notification count. |
| 2.4.3 Focus Order (Level A) | Partially Supports | Standard DOM-based focus order. Modal stacking in alert flow needs focus management verification. Map toolbar has logical focus order. | |
| 2.4.4 Link Purpose (In Context) (Level A) | Partially Supports | Navigation links have descriptive text. Some table row links rely on context from surrounding data. | |
| 2.4.5 Multiple Ways (Level AA) | Partially Supports | Sidebar navigation and direct URL routing available. No search functionality for page navigation. | |
| 2.4.6 Headings and Labels (Level AA) | Partially Supports | Page headers use descriptive titles. Form labels properly associated in InputField, FormField, and TextAreaField components. AlertTypeForm name input has aria-label. | |
| 2.4.7 Focus Visible (Level AA) | Supports | Visible focus indicators restored across shared theme: button recipe, checkbox recipe, sidebar links, dialog close button, export menu items, image lightbox close button. Global *:focus-visible CSS rule provides fallback. | |
| 2.5.1 Pointer Gestures (Level A) | Partially Supports | Map interactions use pan (drag) and pinch-zoom gestures without single-pointer alternatives. Standard UI interactions use simple clicks. | |
| 2.5.2 Pointer Cancellation (Level A) | Supports | Standard click events. | |
| 2.5.3 Label in Name (Level A) | Partially Supports | Map toolbar buttons have aria-labels matching visual purpose. ExportMenu has descriptive aria-label. Some icon-only buttons elsewhere may not match. | |
| 2.5.4 Motion Actuation (Level A) | Not Applicable | No motion-based interactions. |
Principle 3: Understandable
| Criteria | Conformance Level | Remarks and Explanations |
|---|---|---|
| 3.1.1 Language of Page (Level A) | Supports | present in index.html. |
| 3.1.2 Language of Parts (Level AA) | Supports | English throughout. No mixed-language content. |
| 3.2.1 On Focus (Level A) | Supports | No unexpected context changes on focus. |
| 3.2.2 On Input (Level A) | Supports | Input changes don’t trigger unexpected navigation. SSO check on email submit is user-initiated. |
| 3.2.3 Consistent Navigation (Level AA) | Supports | Sidebar navigation consistent across all views. Navbar actions consistent. |
| 3.2.4 Consistent Identification (Level AA) | Supports | ButtonAX, InputField, and DialogComponent used consistently. |
| 3.3.1 Error Identification (Level A) | Supports | InputField and FormField components show error text with role="alert", linked to inputs via aria-describedby. Inputs marked with aria-invalid when in error state. PhoneInputField, TextAreaField, and ReportStepField follow the same pattern. |
| 3.3.2 Labels or Instructions (Level A) | Supports | InputField, FormField, TextAreaField, PhoneInputField, SearchInputField, and ReportStepField all have proper labels. Login page inputs have aria-labels. AlertTypeForm name has aria-label. ReportStepField uses htmlFor on text fields and aria-label on radio/checkbox groups. |
| 3.3.3 Error Suggestion (Level AA) | Partially Supports | Login shows descriptive errors. Form validation messages exist but could be more descriptive in some admin forms. |
| 3.3.4 Error Prevention (Legal, Financial, Data) (Level AA) | Partially Supports | ConfirmModal component exists for destructive actions. Alert end and incident actions use confirmation dialogs. Mobile consent dialog in addUser provides clear confirmation flow. |
Principle 4: Robust
| Criteria | Conformance Level | Remarks and Explanations |
|---|---|---|
| 4.1.1 Parsing (Level A) | Supports | React generates valid HTML. JSX enforced by TypeScript/ESLint. eslint-plugin-jsx-a11y configured for ongoing enforcement. |
| 4.1.2 Name, Role, Value (Level A) | Partially Supports | Map toolbar uses proper IconButton with aria-label. DialogComponent provides semantic dialog structure. DataTable sortable headers have aria-sort and keyboard handlers. ExportMenu uses semantic button with aria-label. Chat map icon is a proper button. Admin delete buttons use semantic buttons with aria-labels. Some clickable elements in chat messages and older components still use or without roles. |
| 4.1.3 Status Messages (Level AA) | Supports | Alert activation/deactivation changes announced via aria-live="assertive" in SocketMessageRouter. NotificationOverlay uses role="alertdialog" with aria-live="assertive" announcing title, body, and available actions. SettingsTable announces result count changes via aria-live="polite" after filtering. Chat message container has role="log" with aria-live="polite". Custom speakAccessibility module provides additional speech announcements when enabled. Toast notifications via Chakra toaster provide visual status. |
Section 508 Functional Performance Criteria
| Criteria | Conformance Level | Remarks |
|---|---|---|
| 302.1 Without Vision | Partially Supports | Form labels properly associated with aria-describedby error linkage. Dynamic page titles announce route changes. Chat container has role=“log” for screen readers. LiveRegion component available. Custom speech-based accessibility mode provides additional announcements. Map-based features remain largely inaccessible without vision. |
| 302.2 With Limited Vision | Supports | Text resizing generally works. Color contrast improved across theme tokens in both light and dark modes. Focus indicators visible with 2px solid outlines on all interactive elements. Reduced-motion support available. |
| 302.3 Without Perception of Color | Partially Supports | Map room status and chat message types still rely on color. Alert severity uses color as primary differentiator. Speech module partially mitigates when enabled. |
| 302.4 Without Hearing | Partially Supports | Alert audio has visual indicators. Live camera streams have no captions (documented as known limitation). |
| 302.5 With Limited Hearing | Partially Supports | Audio alerts have mute controls and visual fallbacks. |
| 302.6 Without Speech | Supports | No speech input required. |
| 302.7 With Limited Manipulation | Partially Supports | Keyboard support improved across login, forms, tables, chat, and admin. Focus indicators visible. Skip navigation available. Map interactions still require mouse/touch. |
| 302.8 With Limited Reach and Strength | Partially Supports | Standard input methods supported. Map features may require fine motor control. |
| 302.9 With Limited Language, Cognitive, and Learning Abilities | Partially Supports | Consistent navigation and layout. Dynamic page titles aid orientation. Real-time alerts may create cognitive load. ConfirmModal helps prevent errors. |
Summary
Overall Conformance Level: Partially Supports WCAG 2.1 AA
Aegix AIM has undergone significant accessibility remediation (2026-04-07) with improvements across form accessibility, keyboard navigation, focus visibility, color contrast, and tooling.
Resolved Issues (2026-04-07)
- Focus indicators — Visible 2px solid focus rings restored across shared theme (button, checkbox, sidebar, dialog, export menu, image lightbox). Global
*:focus-visibleCSS rule as fallback. - Skip navigation — Skip-to-content link in AppLayout with
id="main-content"on main element. - Login accessibility — Password toggle is keyboard accessible with aria-label. Forgot password is a proper button. Inputs have aria-labels.
- Form error associations — InputField, TextAreaField, PhoneInputField, FormField all have
aria-invalid,aria-describedby, androle="alert"on errors. - Autocomplete attributes — Added to login, admin addUser, admin changePassword, and settings editUser forms.
- Dynamic page titles —
usePageTitlehook on 8 routes (Alerts, Map, Chat, Admin Users, Admin Alert Types, Incidents, Visitors, Sign In). - Table accessibility — DataTable has
scope="col",aria-sort, and keyboard-operable sortable headers. - Color contrast — Theme tokens updated: text.tertiary (gray.700), text.action (teal.700/safe.700), text.danger (red.700/darkRed.200), menuSelect (15% opacity).
- Reduced motion — Global
prefers-reduced-motionCSS rule. - Map alt text — Detection images have descriptive alt with location name/timestamp.
- Chat accessibility — Message container has
role="log"witharia-live="polite". Map icon is keyboard accessible. Image alt text improved. - Camera stream — sr-only text description for screen readers.
- Accessibility tooling — eslint-plugin-jsx-a11y configured, @axe-core/react for dev auditing, cypress-axe for e2e tests, Lighthouse CI workflow.
- LiveRegion component — Reusable component for screen reader announcements.
- ReportStepField accessibility — Full ARIA treatment on incident report dynamic form fields: labels, aria-describedby, aria-invalid, role=“alert” errors, aria-label on radio/checkbox groups and “Other” inputs.
- UserDetailSection — Edit button converted to semantic button with aria-label. autoComplete on name/email fields.
- ProfileComponent — autoComplete=“new-password” on password reset fields.
- ARIA live regions wired — Alert count changes announced via assertive live region in SocketMessageRouter. NotificationOverlay uses
role="alertdialog"with assertive announcement of title, body, and actions; dismiss/later buttons keyboard accessible. SettingsTable announces result count changes via polite live region. - Chat keyboard navigation — Image preview, document download, and avatar click in both sent and received message components converted to keyboard-operable elements with aria-labels.
Remaining Items
- Map non-visual alternatives (1.1.1, 1.3.3, 2.1.1) — Interactive maps require visual/spatial perception with no keyboard or tabular alternative. Requires UX design for room status list view.
- Color-only status indicators (1.4.1) — Map room status, alert severity, and chat message types still depend on color.
- Map keyboard navigation (2.1.1) — Map pan/zoom/marker selection is mouse-dependent.
- Live captions (1.2.4) — Camera streams have no captions; documented as infeasible for security camera feeds.
- Manual testing — Screen reader testing (NVDA/VoiceOver), browser zoom 200%, Windows High Contrast mode verification still needed.
See the accompanying implementation plan (implementation-plan-aegix-aim.md) for the full remediation roadmap.