Voluntary Product Accessibility Template (VPAT) 2.5 — CRAIG

On this page

Name of Product

CRAIG — Child Rights Advocacy and Information Governance

Open-source CCWIS (Comprehensive Child Welfare Information System) in Rust.

Product Version

Assessed against the state of the repository at plan completion: commit of the chore/accessibility-508-completion MR landing against main. See the CHANGELOG == Unreleased section for the precise release that ships with this VPAT.

Report Date

2026-04-19

Product Description

CRAIG is a web-based child welfare information system used by caseworkers, supervisors, administrators, and the public to manage child abuse and neglect intake, case management, placement, interstate compact coordination, financial claims, federal reporting (AFCARS / NCANDS), and data-quality oversight. The UI is server-rendered HTML (Askama templates) enhanced with htmx + Alpine.js; no single-page-application framework is used.

Contact Information

File accessibility issues at https://gitlab.com/gadhs/application/ccwis/craig/-/issues with label accessibility or label compliance.

Notes

CRAIG’s accessibility conformance was established via:

  • Automated audits — axe-core (via @axe-core/playwright) runs against every server-rendered page as a blocking stage of the pre-push battery (the only gate that runs the e2e suite — CI does not re-run it). The audit covers 41 pages across public, caseworker, and admin roles (see [tests/e2e/specs/accessibility-audit.spec.ts](tests/e2e/specs/accessibility-audit.spec.ts)). All 41 pages report zero violations at the WCAG 2.1 A + AA + Section 508 tag set as of 2026-04-19.

  • Manual keyboard navigation review — all interactive elements reachable and operable via keyboard; tab-strip ARIA roles + keyboard event handlers verified by the caseworker E2E project.

  • Color contrast — CSS tokens (services/craig-web/static/css/tokens.css) designed to meet WCAG AA 4.5:1 normal / 3:1 large-text thresholds. Contrast is re-validated by axe-core on every pre-push.

The audit runs as a blocking pre-push gate — a regression that introduces a new WCAG A/AA violation fails the pre-push hook and cannot be merged.

Evaluation Methods Used

  • Automated: axe-core 4.10 via @axe-core/playwright 4.10.

  • Manual: keyboard traversal of every route listed in the audit spec under caseworker, admin, and public-anonymous contexts.

  • Color contrast: axe-core’s color-contrast rule at WCAG AA thresholds.

Applicable Standards / Guidelines

Standard Included Notes

Web Content Accessibility Guidelines (WCAG) 2.1 Level A

Yes

All success criteria tested via axe-core.

Web Content Accessibility Guidelines (WCAG) 2.1 Level AA

Yes

All success criteria tested via axe-core.

WCAG 2.1 Level AAA

No

Aspirational; not required by Section 508 and not tested.

Revised Section 508 (2018) — E205 Functional Performance Criteria

Yes

Section 508 ruleset included in the axe-core tag set.

Revised Section 508 — Chapter 5 (Software)

Partial

Applies to web-based software. Native mobile / desktop clients are out of scope (CRAIG has no such clients).

Revised Section 508 — Chapter 6 (Support Documentation)

Not evaluated

End-user support docs are produced separately; see the User Guide (docs/modules/ROOT/pages/guide/) and treat accessibility of those materials as a downstream doc-team concern.

EN 301 549 (EU Accessibility Directive)

Partial

CRAIG is a US state CCWIS; EN 301 549 conformance is not a regulatory requirement. WCAG 2.1 AA conformance demonstrated here covers most EN 301 549 web-content requirements.

WCAG 2.1 Conformance Table — Level A

All listed criteria: Supports. Verified via automated audit (axe-core) on 41 server-rendered pages; zero violations as of 2026-04-19.

SC Name Conformance Remarks

1.1.1

Non-text Content

Supports

All images have alt attributes; decorative images use alt="". Icon-only buttons have aria-label.

1.2.1

Audio-only and Video-only (Prerecorded)

Not Applicable

CRAIG serves no audio or video content.

1.2.2

Captions (Prerecorded)

Not Applicable

No video content.

1.2.3

Audio Description or Media Alternative

Not Applicable

No video content.

1.3.1

Info and Relationships

Supports

Semantic HTML (headings, lists, landmarks, scope on table headers).

1.3.2

Meaningful Sequence

Supports

Document order matches reading order; no absolute-positioning reflow.

1.3.3

Sensory Characteristics

Supports

Instructions never rely solely on shape, size, or color.

1.4.1

Use of Color

Supports

Status badges pair color with text labels.

1.4.2

Audio Control

Not Applicable

No auto-playing audio.

2.1.1

Keyboard

Supports

All interactive elements reachable + operable via keyboard; tab-strip verified with @keydown.enter handlers.

2.1.2

No Keyboard Trap

Supports

Alpine.js modals close on Escape; no focus trapping violations detected.

2.1.4

Character Key Shortcuts

Supports

No single-character shortcuts beyond standard browser keys.

2.2.1

Timing Adjustable

Not Applicable

No session time limits beyond authentication (extendable by re-login).

2.2.2

Pause, Stop, Hide

Not Applicable

No auto-updating content.

2.3.1

Three Flashes or Below Threshold

Supports

No flashing content.

2.4.1

Bypass Blocks

Supports

"Skip to main content" link present on every page (base template).

2.4.2

Page Titled

Supports

{% block title %} in base template; every page sets a descriptive title.

2.4.3

Focus Order

Supports

DOM order matches visual order; no custom tabindex > 0.

2.4.4

Link Purpose (In Context)

Supports

All links have descriptive text or an aria-label.

3.1.1

Language of Page

Supports

<html lang="…​"> set from the i18n locale.

3.2.1

On Focus

Supports

Focus does not trigger a context change.

3.2.2

On Input

Supports

Form submission requires explicit button activation.

3.3.1

Error Identification

Supports

Flash-banner pattern surfaces errors in-page with role="alert"-equivalent semantics.

3.3.2

Labels or Instructions

Supports

All form inputs have associated <label> via for/id.

4.1.1

Parsing

Supports

HTML validates; axe-core checks for duplicate IDs and malformed attributes.

4.1.2

Name, Role, Value

Supports

ARIA roles applied to tab-strips; native elements used elsewhere.

WCAG 2.1 Conformance Table — Level AA

All listed criteria: Supports. Verified as above.

SC Name Conformance Remarks

1.2.4

Captions (Live)

Not Applicable

No live media.

1.2.5

Audio Description (Prerecorded)

Not Applicable

No video content.

1.3.4

Orientation

Supports

Pages work in both portrait and landscape; no orientation lock.

1.3.5

Identify Input Purpose

Supports

autocomplete attributes on name/address/phone/email inputs where appropriate.

1.4.3

Contrast (Minimum)

Supports

axe-core color-contrast rule passes AA thresholds (4.5:1 normal, 3:1 large).

1.4.4

Resize Text

Supports

Layout survives 200% zoom without horizontal scrollbars or content loss.

1.4.5

Images of Text

Supports

Logos are SVG + alt; otherwise no text-in-images.

1.4.10

Reflow

Supports

Responsive CSS; 320 CSS pixels wide without horizontal scroll.

1.4.11

Non-text Contrast

Supports

Focus indicators, form borders, and UI component boundaries meet 3:1.

1.4.12

Text Spacing

Supports

line-height: 1.5 and paragraph spacing 2em on body text.

1.4.13

Content on Hover or Focus

Supports

Tooltips dismissable via Escape; no hover-only revealed content.

2.4.5

Multiple Ways

Supports

Nav links + breadcrumb trail; list pages have search + sort.

2.4.6

Headings and Labels

Supports

Every page has a single <h1>; form labels are descriptive.

2.4.7

Focus Visible

Supports

:focus-visible CSS outline on all interactive elements.

3.1.2

Language of Parts

Supports

lang attribute on any foreign-language content.

3.2.3

Consistent Navigation

Supports

Nav structure identical across pages.

3.2.4

Consistent Identification

Supports

Components with the same function have the same label/icon.

3.3.3

Error Suggestion

Supports

Flash banners include corrective text when the server detects the error.

3.3.4

Error Prevention (Legal, Financial, Data)

Supports

Destructive actions (case close, placement end) require explicit confirmation.

4.1.3

Status Messages

Supports

htmx-swapped fragments use aria-live="polite" where appropriate.

Revised Section 508 — Chapter 5 Conformance

Criterion Name Conformance Remarks

502.2.1

User Control of Accessibility Features

Supports

No override of OS-level accessibility settings.

502.2.2

No Disruption of Accessibility Features

Supports

No interference with assistive-technology hooks.

502.3.1

Object Information

Supports

Accessible name, role, state exposed via HTML/ARIA.

502.3.2

Modification of Object Information

Supports

Dynamic htmx updates preserve ARIA state.

502.3.3

Row, Column, and Headers

Supports

<th scope="col"> on all data tables.

503.2

User Preferences

Supports

Respects OS font size, contrast, and reduced-motion preferences.

504.2

Content Creation or Editing

Supports

Form inputs accept assistive-technology input.

Exceptions

No known exceptions to WCAG 2.1 AA or Section 508 at the time of writing. Future regressions are caught by the axe-core pre-push gate.

Ongoing Maintenance

  • Pre-push gate — [tests/e2e/specs/accessibility-audit.spec.ts](tests/e2e/specs/accessibility-audit.spec.ts) runs on every push. A new violation fails the gate and blocks merge.

  • Audit logtest-results/accessibility-audit.json captures per-page findings each run; keep the file under review for any regressions.

  • Reporting — file accessibility-impacting bugs with label accessibility. Critical and serious-impact violations must be triaged within one sprint.

Edit this page · latest