Define ThemeBuilder interface and data contracts
epic-visual-design-accessibility-theme-integration-task-001 — Define the Dart abstract interface and data classes for the AccessibleThemeBuilder, including OrgBrandingConfig (brand colors, logo asset paths, org identifier enum for NHF, Blindeforbundet, HLF, Barnekreftforeningen), ThemeBuildResult, and BrandingOverrideRequest. Establish the public API surface that downstream consumers will use to obtain light and dark ThemeData.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 0 - 440 tasks
Handles integration between different epics or system components. Requires coordination across multiple development streams.
Implementation Notes
Place all interface and data class definitions in lib/src/theme/accessible_theme_builder.dart. Use Dart's abstract interface class keyword (Dart 3.0+) for AccessibleThemeBuilder to prevent mixin abuse. For immutability, use const constructors throughout — avoid freezed unless it is already a project dependency, to minimize new dependencies. Define OrgIdentifier as an enum with a name property and optional defaultConfig() factory for convenience.
Keep ThemeBuildResult simple: two ThemeData fields, no additional logic. The BrandingOverrideRequest should mirror OrgBrandingConfig but with all fields nullable to allow partial overrides via a merge method. Export all types from a single lib/src/theme/theme.dart barrel file.
Testing Requirements
Unit tests for data class construction: verify that OrgBrandingConfig can be constructed for all four OrgIdentifier values, that copyWith() produces correct partial overrides on BrandingOverrideRequest, and that equality checks work correctly (two configs with same values are equal). Use dart test (not flutter test) since no widget rendering is needed. Verify dart analyze --fatal-infos passes with zero issues. Target 100% coverage of all data class constructors and factory methods.
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.
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.