high priority medium complexity infrastructure pending infrastructure specialist Tier 0

Acceptance Criteria

The module reads all color pairs defined in the design token system and computes relative luminance per WCAG 2.2 formula (sRGB linearisation, Y = 0.2126R + 0.7152G + 0.0722B)
Contrast ratios are computed as (L1 + 0.05) / (L2 + 0.05) where L1 ≥ L2
Any foreground/background pair below 4.5:1 used for normal text is flagged as a WCAG 2.2 AA violation
Any pair below 3:1 used for large text (≥ 18 pt / 14 pt bold) or UI component boundaries is flagged as a violation
The module outputs a structured Dart object / JSON report listing: token pair names, hex values, computed ratio, WCAG level achieved (AAA / AA / AA-large / fail), and a suggested fix if available
Alpha-transparent colors are resolved against their expected background before ratio computation — the module accepts a background color override for transparent token evaluation
The report is written to a file (e.g., `.wcag/contrast-report.json`) and also printed as human-readable output with pass/fail counts
All current design token color pairs in the app pass with no regressions after this module is integrated into the CI pipeline

Technical Requirements

frameworks
Flutter
flutter_test
Dart
data models
DesignToken (color name, hex/ARGB value, usage context: text/background/ui-component)
ContrastResult (tokenPair, foreground, background, ratio, wcagLevel, isViolation, suggestedFix)
performance requirements
Full design token palette evaluation must complete in under 2 seconds for up to 500 color pairs
Module should run as a Dart script (dart run tool/wcag_checker.dart) with no Flutter engine dependency for CI use
security requirements
The checker must not read or log any runtime user data — it operates only on static design tokens

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Implement as a standalone Dart CLI tool in `tool/wcag_checker.dart` that imports the design token definitions. Export the `ContrastEvaluator` class separately so it can be unit tested and reused by the touch-target validator (task-013). Implement relative luminance as a pure function: convert sRGB 0–255 to 0.0–1.0, apply the piecewise linearisation (≤ 0.04045 → /12.92, else ((val+0.055)/1.055)^2.4), then apply the luminance weights. For alpha blending, use the Porter-Duff `source-over` composite: `blended = alpha * foreground + (1-alpha) * background` per channel.

Store design tokens as a Dart map (token name → Color) sourced from the same constants file used by the app (`src/design_tokens.dart` or equivalent) to ensure the checker always reflects the live token set. Structure the JSON report as `{ violations: [], passes: [], summary: { total, passing, failing, aaViolations, aaaViolations } }`. Add a Makefile / npm script target `check:wcag-contrast` that runs the tool and exits with code 1 if any violations are found, enabling CI blocking.

Testing Requirements

Write Dart unit tests (dart test or flutter_test) that: (1) provide known color pairs with known contrast ratios and assert the module computes the correct ratio to two decimal places; (2) provide a pair at exactly 4.5:1 and assert it is marked AA pass, then at 4.49:1 and assert it is marked fail; (3) provide an alpha-transparent foreground and assert the ratio is computed against the resolved background; (4) provide a full mock token palette and assert the structured report contains the correct violation count; (5) assert the JSON report is valid and parseable. Aim for 100% branch coverage of luminance and ratio computation. Include a snapshot test comparing the report output for a fixed token set so regressions are caught.

Component
WCAG 2.2 AA Compliance Checker
infrastructure medium
Epic Risks (3)
high impact high prob integration

Flutter does not natively enforce a focus trap within a bottom sheet or modal dialog in the semantic tree — VoiceOver and TalkBack can navigate outside the sheet to background content. Implementing a reliable focus trap requires overriding the semantic tree, which may conflict with the existing modal helper infrastructure in the app and require changes to shared components beyond this feature's scope.

Mitigation & Contingency

Mitigation: Prototype the focus trap on the first modal sheet implementation before building the remaining sheets. Evaluate Flutter's ExcludeSemantics and BlockSemantics widgets as the trap mechanism, and coordinate with the team owning the shared modal helpers to agree on a non-breaking integration point before writing production code.

Contingency: If a complete semantic focus trap cannot be implemented without breaking existing modal patterns, implement a partial solution using FocusScope with autofocus on the modal's first element and a prominent 'Return to main content' semantic action, documenting the deviation from WCAG 2.4.3 with a scheduled remediation item.

high impact medium prob technical

The activity wizard uses BLoC state management and the UI rebuilds the entire step widget subtree on transition. If the semantic tree is traversed by VoiceOver before the build cycle settles, focus may land on a stale or partially rendered step, causing the wrong step label or progress value to be announced. This is particularly problematic for blind users who cannot visually verify the announcement against the screen.

Mitigation & Contingency

Mitigation: Coordinate ActivityWizardStepSemantics with FocusManagementService (from the core services epic) to delay focus placement until the post-build callback confirms the new step's semantic tree is complete. Write integration tests using the AccessibilityTestHarness that assert the full announcement sequence across all five wizard steps.

Contingency: If post-build focus delay is insufficient due to async BLoC emission timing, add an explicit semantic notification barrier in the wizard cubit that emits a 'step ready' event only after the new widget tree has been marked as built, decoupling the announcement trigger from the raw state transition.

medium impact medium prob scope

Automated WCAG contrast ratio checking on widget tree snapshots may produce false positives for gradient backgrounds, dark-mode overrides, or design token overrides that are resolved at runtime but appear as unresolvable colours at static analysis time. Excessive false positives would erode team trust in the CI gate, leading to suppression rules that also mask real violations.

Mitigation & Contingency

Mitigation: Scope the WCAGComplianceChecker to check only solid-colour backgrounds in the first iteration, explicitly excluding gradients from contrast checks with documented rationale. Design the check output to distinguish 'undetermined' (gradient/unknown) from 'fail' (solid colour below threshold) so the team can take targeted action on genuine failures only.

Contingency: If false positive rates exceed 20% of reported violations during initial CI runs, switch the CI gate from a hard build failure to a warning annotation on the pull request, combined with a mandatory manual review step, until the checker's rule set has been tuned to match actual design token values.