high priority medium complexity frontend pending frontend specialist Tier 2

Acceptance Criteria

Widget accepts: BenefitCalculationResultModel result, BenefitResultsCardMode mode (BenefitResultsCardMode.card | .fullScreen), GlobalKey repaintBoundaryKey
In card mode: compact layout with 2×2 grid of BenefitMetricTile(compact) and a headline; total height ≤ 280dp
In fullScreen mode: expanded layout with 2×2 grid of BenefitMetricTile(expanded), headline, subheadline, and branding footer
RepaintBoundary wraps the entire visual tree and is keyed with the provided repaintBoundaryKey
A single top-level Semantics node with a complete summary label is present, e.g. 'Your benefit summary: 42 volunteer hours, 18 contacts reached, 54 lives touched, 12 600 kroner economic value'
All child BenefitMetricTile nodes have their own merged Semantics — the card Semantics node does NOT merge descendants to avoid double-reading at tile level
Card background uses design token for 'surface elevated' color; dark mode switches automatically
Gradient or decorative background can be applied via a parameter; defaults to flat surface color
No hardcoded pixel values for padding or font sizes — all from design token spacing/typography scales
Widget renders correctly at screen widths from 320dp (iPhone SE) to 428dp (iPhone 14 Pro Max) without overflow
When result values are zero, tiles render '0 hours' etc. — no empty or missing tiles
Widget is purely presentational — no BLoC reference; caller passes the result model directly

Technical Requirements

frameworks
Flutter
performance requirements
RepaintBoundary isolates the card's render layer — mutations outside the card do not repaint card content
Widget tree depth kept minimal to reduce rasterisation time before PNG capture
security requirements
No personal identity information (name, personnummer) rendered inside the card — only aggregate numeric metrics safe for sharing
ui components
BenefitResultsCard (StatelessWidget)
BenefitResultsCardMode (enum: card, fullScreen)
RepaintBoundary (keyed)
BenefitMetricTile (×4 instances)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Key implementation detail: RepaintBoundary must be the outermost widget so the GlobalKey can reference it for RenderRepaintBoundary.toImage() in BenefitShareService. Wrap it with a Material widget (elevation 0 in card mode) to ensure the card background clips correctly and prevents transparent corners in the exported PNG. For the 2×2 grid use a GridView.count or a Wrap with spacing derived from design tokens. The gradient option can be implemented as a BoxDecoration parameter on the outermost Container.

Avoid ClipRRect with borderRadius inside the RepaintBoundary since it can cause alpha channel issues in toImage() — instead clip the outer Container and let RepaintBoundary sit inside. Test the PNG export path manually at least once with a physical device to confirm pixel density is correct (use pixelRatio: window.devicePixelRatio in toImage call).

Testing Requirements

Widget tests: render both modes and verify 4 BenefitMetricTile instances are present. Golden snapshot tests at card and fullScreen modes in light/dark at 1.0x and 2.0x text scale — 8 golden images total. Test that repaintBoundaryKey is attached to the root render object. Test zero-value result renders without exceptions.

Semantics tree test: top-level summary label present and contains all four metric values as substrings. Target coverage ≥ 85%.

Component
Benefit Results Card
ui low
Epic Risks (3)
high impact medium prob technical

The RepaintBoundary PNG capture approach for sharing the results card may produce blurry or oversized images on high-DPI devices, or may silently fail on certain Android OEM configurations that restrict off-screen rendering. A failed share would break one of the core use cases (recruitment tool).

Mitigation & Contingency

Mitigation: Implement the capture using the established screenshot-capture-utility pattern already present in the Wrapped summary feature (component 542-screenshot-capture-utility). Test on a range of iOS and Android devices including Samsung and Huawei OEM builds during development. Set explicit pixel ratio (3.0) when calling toImage() to guarantee resolution.

Contingency: If image capture fails on a platform, the BenefitShareService falls back to sharing the plain-text summary only, with a user-facing message explaining the image could not be generated. This ensures the share flow never fully blocks.

high impact medium prob technical

Implementing full WCAG 2.2 AA compliance for the results card and metric tiles — including live regions, focus management, and semantic labels that read naturally in Norwegian — requires deep familiarity with Flutter semantics APIs. Gaps may only surface during screen reader testing on physical devices, late in the sprint.

Mitigation & Contingency

Mitigation: Use the existing semantics-wrapper-widget (606) and live-region-announcer (608) components from the accessibility feature rather than implementing custom semantics. Assign screen reader testing on a physical iPhone with VoiceOver as a mandatory acceptance gate, not an afterthought. Write widget tests using Flutter's AccessibilityGuideline matchers early in development.

Contingency: If screen reader issues are found late, the pure semantic markup approach (no Canvas numbers, all Semantics wrappers) limits the blast radius to label text corrections. Escalate to the accessibility feature team for a pairing session to resolve complex focus management issues.

medium impact low prob integration

The BenefitResultsCard must match the Wrapped design language used in the annual summary feature. If design tokens or widget patterns are inconsistent between the two features, the results card will look out of place and undermine the intended emotional impact for sharing.

Mitigation & Contingency

Mitigation: Review the existing Wrapped summary screen (529-wrapped-summary-screen) and stat card widget (530-stat-card-widget) implementations before building the results card. Reuse design tokens from the existing design-token-theme (200) system. Involve the designer in a review of the results card mock-up against the Wrapped language before implementation begins.

Contingency: If design parity issues are discovered post-implementation, isolate visual adjustments to the BenefitResultsCard widget. The feature's business logic and accessibility compliance are unaffected by visual polish changes.