Skip to main content

VPAT 2.4 — WCAG 2.1 AA

Voluntary Product Accessibility Template — self-assessment. Independent third-party audit scheduled for 2026-Q3.

Product name: R2 Digital Library

Version / Date: Current production build, assessed April 29, 2026

Standards: WCAG 2.1 Levels A and AA · Section 508 (36 CFR Part 1194) · EN 301 549 V3.2.1

Evaluation methods: Automated (axe-core, Lighthouse, Pa11y), manual keyboard-only testing, NVDA + VoiceOver screen-reader testing, 200% zoom verification, reduced-motion / high-contrast mode verification.

Contact: accessibility@r2library.com

WCAG 2.1 Success Criteria

RefSuccess CriterionLevelConformanceRemarks & Explanations
1.1.1Non-text ContentASupportsAll non-decorative images provide alt text. Decorative icons use aria-hidden="true". PDF covers include metadata-derived alt text.
1.2.1Audio-only and Video-only (Prerecorded)ANot ApplicablePlatform does not host audio-only or video-only content. Publisher-provided multimedia carries responsibility with the publisher.
1.2.2Captions (Prerecorded)ANot ApplicableSee 1.2.1.
1.2.3Audio Description or Media AlternativeANot ApplicableSee 1.2.1.
1.3.1Info and RelationshipsASupportsSemantic HTML throughout: headings, lists, labels, landmark regions. Data tables use proper thead/tbody/th scope.
1.3.2Meaningful SequenceASupportsDOM order matches visual order for all primary workflows. Tested with screen-reader virtual cursor.
1.3.3Sensory CharacteristicsASupportsInstructions do not rely solely on color, shape, or spatial position. "Click the red button" type copy is banned in code review.
1.3.4OrientationAASupportsResponsive design works in both portrait and landscape; no orientation lock.
1.3.5Identify Input PurposeAASupportsAll common inputs carry appropriate autocomplete attributes (name, email, tel, organization, etc.).
1.4.1Use of ColorASupportsColor is never the sole means of conveying information. Status badges pair color with icon + text label; form errors include text + icon + aria-invalid.
1.4.2Audio ControlANot ApplicableNo auto-playing audio or video.
1.4.3Contrast (Minimum)AASupportsAll text meets 4.5:1 on default palette. Verified via automated contrast tooling on every page render; CI blocks regressions.
1.4.4Resize TextAASupportsText resizes to 200% without loss of content or functionality. No fixed-height containers that clip resized text.
1.4.5Images of TextAASupportsText is never rendered as images except in publisher-supplied book pages (content provenance); reader interface text is always live text.
1.4.10ReflowAASupportsContent reflows at 320 CSS pixel widths without horizontal scrolling. Reader chapter view reflows cleanly; fixed-layout PDFs maintain pan-and-zoom.
1.4.11Non-text ContrastAASupportsUI components and graphical objects meet 3:1 against adjacent colors. Focus indicators verified at 3:1.
1.4.12Text SpacingAASupportsText spacing overrides (line-height 1.5, paragraph-spacing 2×, letter-spacing 0.12×, word-spacing 0.16×) do not break layout.
1.4.13Content on Hover or FocusAASupportsTooltips and popovers are dismissible, hoverable, and persistent (don't disappear on focus move).
2.1.1KeyboardASupportsAll functionality operable via keyboard. Reader pagination (arrow keys), TOC navigation, search, bookmarks, annotations all keyboard-reachable.
2.1.2No Keyboard TrapAPartially SupportsPrimary workflows have no keyboard traps. A small number of admin-only confirmation dialogs use native browser confirm() which behaves correctly but is not a proper focus-trapped modal; replacement in progress.
2.1.4Character Key ShortcutsASupportsSingle-key shortcuts in the reader (/, +, -) are only active when the reader surface has focus; no platform-wide single-key shortcuts.
2.2.1Timing AdjustableASupportsNo timed interactions except session timeouts, which display a warning and can be extended.
2.2.2Pause, Stop, HideASupportsNo auto-updating content that is not user-initiated. Toast notifications auto-dismiss on 6s but respect prefers-reduced-motion and can be manually dismissed.
2.3.1Three Flashes or Below ThresholdASupportsNo content flashes more than three times per second.
2.4.1Bypass BlocksASupportsEvery page starts with a "Skip to main content" link (see apps/web/src/app/[locale]/(library)/layout.tsx).
2.4.2Page TitledASupportsEvery page has a unique, descriptive title via Next.js Metadata API.
2.4.3Focus OrderASupportsFocus order matches DOM order. No use of positive tabindex.
2.4.4Link Purpose (In Context)ASupportsLink text + surrounding context convey purpose. No "click here" or "read more" without context.
2.4.5Multiple WaysAASupportsContent reachable via browse, search, A–Z index, publisher directory, journals index, disciplines, MeSH, and sitemap.
2.4.6Headings and LabelsAASupportsHeadings and form labels are descriptive and unique within their context.
2.4.7Focus VisibleAASupportsAll interactive elements have a visible focus indicator (2px ring at Level AA contrast). outline:none not used without a focus:ring replacement.
2.5.1Pointer GesturesASupportsNo multi-point or path-based gestures required. Reader pagination is single-pointer or keyboard.
2.5.2Pointer CancellationASupportsDestructive actions fire on mouseup, not mousedown; no functionality triggered solely on down-event.
2.5.3Label in NameASupportsAccessible name contains visible label text for all interactive controls.
2.5.4Motion ActuationANot ApplicableNo functionality depends on device motion or user motion.
3.1.1Language of PageASupportshtml lang attribute set per locale (en, es, fr, etc.) via next-intl middleware.
3.1.2Language of PartsAASupportsInline language changes use lang attribute. Medical terminology (Latin, Greek roots in Tabers Dictionary) carries lang tags.
3.2.1On FocusASupportsNo context change on focus alone.
3.2.2On InputASupportsNo unexpected context change on input. Form submissions are explicit (button click or Enter on submit field).
3.2.3Consistent NavigationAASupportsLibrary, admin, publisher, and platform shells each have a consistent navigation order across their pages.
3.2.4Consistent IdentificationAASupportsComponents with the same function are consistently identified across pages (e.g. "Save" is always labeled "Save").
3.3.1Error IdentificationASupportsForm validation errors are identified in text, associated with the offending field via aria-describedby, and announced via role="alert".
3.3.2Labels or InstructionsASupportsAll form inputs have visible labels. Optional fields explicitly marked. Required fields indicated in label + via required attribute + aria-required.
3.3.3Error SuggestionAASupportsValidation errors include suggestions ("Password must be at least 8 characters", "Please enter a valid work email address").
3.3.4Error Prevention (Legal, Financial, Data)AASupportsDestructive actions (access-policy changes, team removal, subscription cancellation) require typed-slug confirmation or a two-step flow.
4.1.1ParsingASupportsValid HTML output enforced via React JSX; duplicate IDs prevented in component design. (Note: WCAG 2.2 removed this criterion; included for back-compat with evaluators.)
4.1.2Name, Role, ValueASupportsAll custom components (tabs, dialogs, disclosures) expose name, role, and value through ARIA or native elements.
4.1.3Status MessagesAASupportsStatus messages use role="status" (for non-urgent, e.g. toast confirmations) or role="alert" (for form validation errors + destructive-action warnings).

Conformance summary

Of 48 WCAG 2.1 A + AA criteria evaluated on the primary patron workflows and administrative dashboards:

  • 42Supports
  • 1Partially Supports
  • 5Not Applicable

"Partially Supports" remediation tickets are tracked in our internal accessibility backlog with target completion dates. We publish a revised VPAT after every release that clears or adds a remediation item.

Request a countersigned PDFAccessibility statement