Level A & AA criteria
50 criteria in total — 30 at Level A and 20 at Level AA. Every criterion is listed, including those not applicable to plotview, with the justification stated inline.
Status legend: Supports Partial Does Not Support Not Applicable
| SC # | Criterion | Level | Status | Notes / Evidence |
|---|---|---|---|---|
| 1.1.1 | Non-text Content | A | Partial | Extensive ARIA labeling on interactive elements (85+ aria-labels across 56 files). SVG box-plot components get role="button" + aria-label with value ranges (boxPlotElement.js). Sonification (beta) provides a non-text audio alternative to visual data. Gap: the sonification control buttons themselves are missing aria-label; some decorative icons lack aria-hidden="true". Target: Q3 2026. |
| 1.2.1 | Audio-only and Video-only (Prerecorded) | A | Not Applicable | Plotview contains no prerecorded audio-only or video-only content. Tutorial videos referenced on the marketing accessibility page are outside the plotview tool surface. |
| 1.2.2 | Captions (Prerecorded) | A | Not Applicable | No prerecorded synchronized media is embedded in plotview. |
| 1.2.3 | Audio Description or Media Alternative (Prerecorded) | A | Not Applicable | No prerecorded video content in plotview. |
| 1.2.4 | Captions (Live) | AA | Not Applicable | No live media in plotview. |
| 1.2.5 | Audio Description (Prerecorded) | AA | Not Applicable | No prerecorded video content. |
| 1.3.1 | Info and Relationships | A | Partial | ARIA roles, headings (topMarginView.js), and labels convey structure; role="slider", role="button", role="menu", role="option", role="status" used throughout. Gap: toolbar is missing role="navigation" landmark (TuvaDataTools.jsx); some decorative icons lack aria-hidden="true". Target: Q3 2026. |
| 1.3.2 | Meaningful Sequence | A | Supports | DOM and reading order follow the visual flow; tab order follows source order. Grid navigation announces "HeaderName, CellValue" in reading order via ScreenReaderAnnouncer (gridAccessibility.js). |
| 1.3.3 | Sensory Characteristics | A | Supports | Instructions do not rely on shape, size, visual location, or color alone. Keyboard shortcuts use named modifiers and have a searchable written reference (KeyboardShortcutsPopup.jsx). |
| 1.3.4 | Orientation | AA | Supports | Plotview works in both portrait and landscape; layout reflows. No orientation lock is imposed. |
| 1.3.5 | Identify Input Purpose | AA | Not Applicable | Plotview does not collect the kinds of personal information (name, email, phone, address, etc.) enumerated in WCAG 1.3.5's applicable input-purpose list. Form inputs (e.g., derived-attribute name, formula) do not map to those categories. |
| 1.4.1 | Use of Color | A | Supports | Three data-color schemes selectable in the Accessibility Card: Standard, Colorblind Safe, and Grayscale (src/utils/constants.js). Legends, labels, and axis text accompany color so information is never color-only. |
| 1.4.2 | Audio Control | A | Supports | Sonification (beta) audio is user-initiated (never auto-plays) and has Play, Pause, Stop, Restart, and Volume controls (SonificationSettingsComponent.jsx). |
| 1.4.3 | Contrast (Minimum) | AA | Supports | Primary text in the default theme hits 19.25:1 (#3d4146 on #fff), well above the 4.5:1 requirement. Reverse Contrast theme (white on black) inverts the palette. OS-level "High Contrast" preference is honored via @media (prefers-contrast: high) (_a11y.scss). |
| 1.4.4 | Resize Text | AA | Supports | Users can raise font size from 14pt up to 32pt (~2.3×) via the Accessibility Card; case (dot) size is also adjustable (3–80 px). Preferences persist via Dyn.preferences. |
| 1.4.5 | Images of Text | AA | Supports | Informational text is rendered as live text. Chart labels, axis tick labels, legends, and button captions are real text — not rasterized images. |
| 1.4.10 | Reflow | AA | Partial | Responsive layout reflows on narrow viewports and the toolbar collapses on smaller widths. Gap: reflow has not been formally tested at 320 CSS px width / 400% zoom; some data-dense plots may need horizontal scroll as an allowed exception (2D content). Target: Q3 2026. |
| 1.4.11 | Non-text Contrast | AA | Supports | UI component borders, button backgrounds, and focus indicators meet 3:1 contrast (focus style: outline: 3px solid #4A90E2, outline-offset: 2px; high-contrast mode upgrades to 4px). Themes defined centrally in _themes.scss. |
| 1.4.12 | Text Spacing | AA | Partial | Layout uses relative units and tolerates increased line-height in most areas. Gap: not formally tested against the four 1.4.12 requirements (line-height 1.5×, paragraph 2×, letter-spacing 0.12em, word-spacing 0.16em); no user-facing text-spacing control. Target: Q3 2026. |
| 1.4.13 | Content on Hover or Focus | AA | Supports | Tooltips and popovers are dismissible (Escape), hoverable without disappearing, and persist until dismissed or focus moves away. |
| 2.1.1 | Keyboard | A | Partial | Full keyboard coverage for toolbar, menus, Accessibility Card, and attribute placement via 40+ platform-aware shortcuts (src/utils/keymap.js); PlainButton ensures custom buttons activate on Enter/Space. Gaps: SVG plot element tabIndex is commented out in dotPlotElement.js:283; some handlers use deprecated onKeyPress instead of onKeyDown; IncrDecrInput missing arrow-key handlers. Target: Q3 2026. |
| 2.1.2 | No Keyboard Trap | A | Partial | No keyboard traps observed in tested flows; Escape routes focus to dismiss controls, and a double-escape pattern exits nested grid focus (gridAccessibility.js:110-133). Gap: AccessibilitySettingsComponent modal doesn't bidirectionally trap focus — Tab can leave the modal while it's open. Target: Q3 2026. |
| 2.1.4 | Character Key Shortcuts | A | Supports | Keyboard shortcuts use modifier keys (Alt, Shift, Ctrl, Meta) — not bare letter keys — so speech-input users don't trigger shortcuts accidentally (src/utils/keymap.js). |
| 2.2.1 | Timing Adjustable | A | Not Applicable | Plotview has no time-limited interactions. Analysis sessions do not expire, and no timed tasks are imposed on the user. |
| 2.2.2 | Pause, Stop, Hide | A | Supports | The only moving content in plotview is chart-transition animation, which the user can disable via the "Animate Graphs" toggle in the Accessibility Card (AccessibilitySettingsComponent.jsx). No auto-advancing carousels or auto-updating content. |
| 2.3.1 | Three Flashes or Below Threshold | A | Supports | No flashing content in plotview. Graph transitions are smooth fades/slides, below the 3-flashes-per-second threshold, and can be disabled entirely. |
| 2.4.1 | Bypass Blocks | A | Does Not Support | No skip-to-main-content link exists in the plotview shell. Planned remediation: add an sr-only skip link at the top of TuvaDataTools.jsx. Target: Q2 2026. |
| 2.4.2 | Page Titled | A | Supports | The embedding page provides a descriptive <title> (e.g., "Lesson Name — Tuva"). Document titles are not suppressed by plotview. |
| 2.4.3 | Focus Order | A | Partial | DOM-order tab sequence is logical across toolbar, case card, and plot area. Focus jump shortcuts (Shift+P, Shift+C, Shift+M, Shift+T, Shift+X/Y/L) let users reach regions directly. Gap: modal dialog focus-trap is unidirectional — see 2.1.2. Target: Q3 2026. |
| 2.4.4 | Link Purpose (In Context) | A | Supports | Interactive controls have accessible names that describe their purpose. Link/button text is descriptive, not generic ("click here"-style phrasing is not used). |
| 2.4.5 | Multiple Ways | AA | Supports | Features are reachable via toolbar click, keyboard shortcut, or in-app menu. The Accessibility Card is reachable via toolbar icon or Alt+Z; keyboard shortcuts popup via icon or Ctrl+/. |
| 2.4.6 | Headings and Labels | AA | Supports | Headings describe topic or purpose; labels describe the control. Plot regions use role="heading" + aria-level (topMarginView.js). Accessibility panel uses aria-level="1" on its primary heading. |
| 2.4.7 | Focus Visible | AA | Supports | Focus indicator: outline: 3px solid #4A90E2 with outline-offset: 2px, upgrading to 4px solid currentColor in high-contrast mode. Focus rings use inset box-shadow where overflow: hidden would clip a standard outline (_a11y.scss:23-35, _toolbar.scss). |
| 2.5.1 | Pointer Gestures | A | Supports | All functionality operable with single-pointer actions. No path-based or multi-point gestures are required. Drag-and-drop interactions have keyboard alternatives (see 2.5.7 on the 2.2 page). |
| 2.5.2 | Pointer Cancellation | A | Supports | Click and drag interactions trigger on pointer up, allowing users to abort by dragging off-target before release. |
| 2.5.3 | Label in Name | A | Supports | Accessible names include the visible label text. Toggle controls use aria-label that embeds the visible caption plus state (e.g., "Animate Graphs, checked, checkbox"). |
| 2.5.4 | Motion Actuation | A | Not Applicable | Plotview has no device-motion or user-motion-triggered functionality (no shake-to-undo, no tilt). |
| 3.1.1 | Language of Page | A | Partial | All user-facing strings route through Dyn.loc() with 10+ language PO files (src/locale/). Gap: the root <html lang> attribute is not set on the standalone entry HTML in this repo; consumers embedding plotview should ensure lang is set on their host page. Target: Q3 2026. |
| 3.1.2 | Language of Parts | AA | Not Applicable | Plotview renders in a single language at a time (user-selected via preference). Inline mixed-language content is not authored. |
| 3.2.1 | On Focus | A | Supports | Receiving focus does not change context, open popups, or submit forms. Focus simply reveals the focus indicator. |
| 3.2.2 | On Input | A | Supports | Changing a form value (e.g., font-size dropdown) applies the preference without submitting a form or navigating — consistent with the user's expectation. |
| 3.2.3 | Consistent Navigation | AA | Supports | Toolbar structure, menu ordering, and help access remain consistent across views (plotview, table view, etc.). The Accessibility Card and Keyboard Shortcuts popup are always reachable from the same toolbar position. |
| 3.2.4 | Consistent Identification | AA | Supports | Icons and controls that share function across the interface use consistent labels and visual treatment (e.g., the "more" overflow menu is always "⋯"; undo/redo icons are consistent). |
| 3.3.1 | Error Identification | A | Partial | The derived-attribute formula editor surfaces errors inline as the user types. Gap: error messages are not consistently associated with form fields via aria-describedby, and focus does not move to the first error on submit. Target: Q3 2026. |
| 3.3.2 | Labels or Instructions | A | Supports | Form controls and toggles in the Accessibility Card, derived-attribute editor, and filter panels have associated visible labels and, where needed, instructional help text. |
| 3.3.3 | Error Suggestion | AA | Partial | The formula editor suggests corrections for recognizable syntax errors. Gap: error suggestions are not provided systematically across all form fields; not audited row-by-row. Target: Q3 2026. |
| 3.3.4 | Error Prevention (Legal, Financial, Data) | AA | Not Applicable | Plotview is a data-analysis tool. It does not process legal commitments, financial transactions, or make irreversible data modifications — user actions are reversible via undo/redo. |
| 4.1.1 | Parsing | A | Supports | Markup is generated by React and passes validation; no duplicate ids or malformed tag nesting observed. Note: this criterion was removed in WCAG 2.2 (obsolete — modern browsers tolerate invalid markup). Even within WCAG 2.1, the practical consensus among accessibility practitioners is that this criterion is effectively moot for applications built on modern component frameworks (React, Vue, etc.) that generate well-formed markup by construction. |
| 4.1.2 | Name, Role, Value | A | Partial | Extensive ARIA usage (85+ aria-labels across 56 files); roles include button, menu, menuitem, option, slider, status; state attributes aria-expanded, aria-haspopup, aria-selected, aria-pressed, aria-disabled. Gap: sonification control buttons lack aria-label — they have no accessible name. Target: Q3 2026. |
| 4.1.3 | Status Messages | AA | Supports | Dynamic content updates announce via live region: ScreenReaderAnnouncer with aria-live="assertive", aria-atomic="true", role="status" (gridAccessibility.js:6-43). Grid cell navigation announces "HeaderName, CellValue" on move. |