high priority medium complexity frontend pending frontend specialist Tier 3

Acceptance Criteria

ElevatedButtonThemeData, FilledButtonThemeData, OutlinedButtonThemeData, TextButtonThemeData, InputDecorationTheme, CardTheme, and ChipTheme are all produced by dedicated factory methods — no ad-hoc theme construction in other files
Minimum touch target size of 48×48 dp (WCAG 2.5.5) is enforced on all button themes via minimumSize or tapTargetSize constraints sourced from the sizing token
BorderRadius values in CardTheme, InputDecorationTheme, and ChipTheme are sourced from token (e.g., tokens.radiusMd) — no BorderRadius.circular(literal) calls inside factories
Padding EdgeInsets in all component themes are sourced from spacing tokens — no EdgeInsets.symmetric(literal) calls inside factories
Elevation values in CardTheme and ElevatedButtonThemeData are sourced from elevation tokens
All color references inside component themes use MaterialStateProperty that resolves against the ColorScheme passed in — no Color literals
A grep for hardcoded hex patterns (0xFF, Color(0x)) in the factory file returns zero matches
Toggling high-contrast mode via accessibility_preferences changes InputDecorationTheme border color from the outline token to the high-contrast outline token without requiring a hot restart

Technical Requirements

frameworks
Flutter
Material 3
Riverpod
apis
Flutter component theme APIs (ElevatedButtonThemeData, InputDecorationTheme, CardTheme, ChipTheme)
MaterialStateProperty API
DesignTokenProvider interface (internal)
data models
accessibility_preferences
performance requirements
All factories are pure functions — same token input always produces identical output
Factory invocations are O(1) — no loops or async work
security requirements
Component themes must not expose any mutable state — all returned objects are deeply immutable
ui components
ElevatedButton
FilledButton
OutlinedButton
TextButton
TextField
Card
Chip
InputDecorator

Execution Context

Execution Tier
Tier 3

Tier 3 - 413 tasks

Can start after Tier 2 completes

Integration Task

Handles integration between different epics or system components. Requires coordination across multiple development streams.

Implementation Notes

Organise factories as static methods on a ComponentThemeFactory class, each accepting a ColorScheme and DesignTokenProvider. For MaterialStateProperty-based colors (e.g., disabled state), define a sealed class or extension to avoid repetitive MaterialStateProperty.resolveWith boilerplate. The DesignTokenProvider should expose typed getters (double radius(TokenRadius), EdgeInsets spacing(TokenSpacing), double elevation(TokenElevation)) rather than raw keys to prevent typos. For InputDecorationTheme, ensure the focusedBorder uses the primary color token at full opacity and the enabledBorder uses outline token at 0.5 opacity — this aligns with Blindeforbundet and NHF's high-contrast requirements.

ChipTheme must set labelStyle from the text theme's labelMedium role, not a hardcoded TextStyle.

Testing Requirements

Unit tests (flutter_test): (1) each factory returns a non-null theme object, (2) changing a spacing token changes the button padding, (3) changing the radius token changes card border radius, (4) minimum touch target 48 dp is present in button minimumSize, (5) no Color literals exist in factory output (inspect via reflection/toString). Widget tests: render each component type with the produced theme and verify tap targets meet 48×48 dp via tester.getSize(). One golden snapshot per component type at default and high-contrast tokens to catch visual regressions. 85% coverage target on the factory file.

Component
Accessible Theme Builder
infrastructure medium
Epic Risks (2)
high impact low prob scope

One or more of the four partner organisations may supply brand primary colors that cannot be paired with any standard foreground at 4.5:1 contrast (for example, a mid-range hue that is too light for dark text and too dark for white text). Rejecting these colors programmatically could cause a political dispute with the organisation and delay the feature.

Mitigation & Contingency

Mitigation: Before implementation begins, run all four organisations' existing brand primary colors through the contrast-ratio-validator against both white (#FFFFFF) and a near-black (#1A1A1A). Share the results with each organisation's contact person ahead of the theme builder sprint so any problematic colors can be adjusted collaboratively with advance notice.

Contingency: If an organisation insists on a non-compliant brand color, produce a compliant near-match (lightened or darkened along the hue's luminance axis) and present both options with contrast ratio evidence. Document the adjusted token in the manifest with an explicit note that the original brand color was non-compliant, and obtain written sign-off from the organisation.

medium impact medium prob scope

Flutter's ThemeData contains over 30 component theme properties. If the theme-builder only addresses the most common ones (Button, InputDecoration, Card) and leaves others at Flutter defaults, downstream feature teams may unknowingly use default-themed widgets that do not meet sizing or contrast requirements.

Mitigation & Contingency

Mitigation: Produce a full inventory of all ThemeData component theme properties and map each to either a token-driven override or an explicit pass-through decision documented in the theme builder code. Prioritise the inventory by frequency of use in the existing codebase (identified via Grep). Include a check in the CI lint runner that flags widgets using Flutter default component themes not covered by the theme builder.

Contingency: If the full inventory scope exceeds the sprint budget, ship with the highest-frequency components covered and add a tracked backlog item for each uncovered component theme, pairing with a temporary lint suppression comment that includes the backlog reference.