critical priority low complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

CertificationStatusBadge wraps its content in a `Semantics` widget with a non-empty `label` string for all three states
Active state semantics label: 'Certification valid until {formatted date}' (e.g., '12 March 2026')
Expiring soon semantics label: 'Certification expiring in {N} days, expires {formatted date}'
Expired state semantics label: 'Certification expired {N} days ago' or 'Certification expired on {formatted date}'
Date formatting uses a locale-aware formatter (e.g., `DateFormat.yMMMMd()` from intl package) — not raw DateTime.toString()
WCAG 2.2 AA minimum contrast ratio of 4.5:1 is verified for text-on-background in all three badge states and documented in a code comment referencing the token pair names
`Semantics(excludeSemantics: true)` is applied to any purely decorative child elements (e.g., color dots) within the badge to avoid redundant announcements
Manual VoiceOver (iOS) and TalkBack (Android) testing confirms correct announcement — result documented in PR description

Technical Requirements

frameworks
Flutter
intl (DateFormat)
data models
CertificationStatus (enum)
DateTime
performance requirements
Semantics label string must be built lazily — avoid unnecessary string construction when accessibility services are not active if performance profiling reveals a cost
security requirements
Semantics labels must not expose personally identifiable information beyond what is already visible on screen
ui components
Semantics (Flutter core widget)
CertificationStatusBadge (parent widget from task-003)

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Add a private `_buildSemanticsLabel(CertificationStatus status, DateTime expiry, DateTime now)` function that returns the human-readable string. Use `DateFormat.yMMMMd('en')` for consistent English date formatting — do not use `.toString()` on DateTime. For WCAG contrast verification, use a contrast checker tool (e.g., WebAIM or a Flutter contrast plugin) against the design token hex values. Document the contrast ratios in a comment block above the token definitions: `// active badge: #XXXXXX on #XXXXXX = 5.2:1 (AA pass)`.

The accessibility requirement is especially critical given the project's target user base — blind and hearing-impaired users per the Blindeforbundet and HLF workshop requirements.

Testing Requirements

Widget tests: (1) `tester.getSemantics(find.byType(CertificationStatusBadge))` returns a SemanticsNode with a non-empty label for each of the three states, (2) expired semantics label contains 'expired', (3) active semantics label contains the formatted date string, (4) expiring_soon label contains 'days'. Also write a static analysis test or linter rule to assert that no `Container` with a background color inside the badge uses a color with contrast ratio below 4.5:1 against its foreground text color — this can be a documented manual verification step if automated contrast tooling is not available in the project.

Component
Certification Status Badge
ui low
Epic Risks (2)
medium impact medium prob dependency

The org labels system may not yet have label keys defined for peer mentor detail screen terminology (role labels, section headings), requiring additions to the label key registry that must be coordinated with the admin configuration team.

Mitigation & Contingency

Mitigation: Audit existing label keys in the terminology system before starting OrgLabelsProvider integration. Submit required new label keys for admin configuration in parallel with component implementation.

Contingency: If label keys are not available at integration time, use hardcoded English fallbacks with a clear TODO for admin configuration, ensuring the widget renders correctly while keys are being provisioned.

high impact low prob technical

The design token semantic colors (warning, error surface) may not meet WCAG 2.2 AA 4.5:1 contrast ratio when rendered on the app's background surface tokens, requiring design system changes that affect the entire app.

Mitigation & Contingency

Mitigation: Run contrast ratio validation on the token palette during Epic 1 design token implementation. Flag any failing pairs to the design system owner before building UI components that depend on them.

Contingency: If tokens fail contrast requirements, define supplementary high-contrast override tokens specific to alert and badge contexts that meet AA without modifying the global palette.