high priority low complexity frontend pending frontend specialist Tier 1

Acceptance Criteria

ReimbursementLineItem widget renders expense type name in the left column and formatted currency amount in the right column
Currency amounts are formatted using Norwegian locale (NOK) with two decimal places (e.g., 'kr 125,00')
Zero amounts display as 'kr 0,00' without hiding or collapsing the row
Each row has a Semantics widget wrapping the entire row with a combined label: '{expense type name}: {formatted amount}'
Widget is stateless and accepts only the expense type name (String) and amount (double) as constructor parameters
Row uses design token spacing and typography values — no hardcoded sizes
Text overflow on the name column is handled with ellipsis, not wrapping, to preserve row height
Widget renders correctly on screen widths from 320px to 428px

Technical Requirements

frameworks
Flutter
flutter_test
data models
ReimbursementLineItemData (expense type name, amount double)
performance requirements
Widget build time under 2ms — no expensive computations in build()
Currency formatting must use a cached NumberFormat instance, not instantiated per build
security requirements
No sensitive financial data logged to console
ui components
Row with MainAxisAlignment.spaceBetween
Text (name) with overflow: TextOverflow.ellipsis
Text (amount) right-aligned using design token typography
Semantics wrapper with combined label

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Use intl package's NumberFormat.currency(locale: 'nb_NO', symbol: 'kr') — instantiate once as a static final to avoid per-build allocation. Keep the widget a pure StatelessWidget with no BLoC dependency; data flows in from the parent panel. Apply design token TextStyle for both name and amount (e.g., AppTypography.bodyMedium and AppTypography.bodyMediumMono or equivalent). The Semantics label must be a single merged string so VoiceOver/TalkBack reads it as one unit rather than two separate elements — use Semantics(label: '$name: $formattedAmount', child: ExcludeSemantics(child: Row(...))).

Testing Requirements

Unit/widget tests using flutter_test. Cover: (1) name renders in left slot, (2) amount renders formatted NOK in right slot, (3) zero amount renders 'kr 0,00' not empty, (4) Semantics label matches '{name}: {formatted amount}' exactly, (5) long names truncate with ellipsis. No golden tests required at this granularity — golden tests are handled at the panel level in task-008.

Component
Expense Calculation Preview
ui low
Epic Risks (2)
medium impact medium prob technical

If the expense calculation preview subscribes to the full BLoC state stream, every unrelated state property change (e.g. a loading flag toggle) triggers a widget rebuild. With complex card animations for the disabled-state transition, this could cause frame drops on low-end Android devices used by some peer mentors.

Mitigation & Contingency

Mitigation: Use select() on the Riverpod provider to subscribe only to the specific state slice each widget needs; write a performance test asserting rebuild count on a rapid sequence of toggle events.

Contingency: If jank is detected in device testing, replace animated disabled-state transitions with instant opacity changes and defer animation polish to a follow-up sprint.

medium impact low prob integration

The disabled card state requires a specific contrast-safe colour combination that communicates unavailability without relying solely on colour (WCAG 1.4.1). If the current design token palette does not include a disabled-state token with sufficient contrast for text on the disabled background, the widget will either fail WCAG AA or require a last-minute design token addition that could break other components.

Mitigation & Contingency

Mitigation: Audit the existing design token manifest for disabled-state tokens at the start of the epic; if missing, raise with the design lead and add a contrast-validated token before widget implementation begins.

Contingency: If no design review is available, use the established --color-text-disabled and --color-surface-disabled tokens with an added strikethrough or lock icon to satisfy WCAG 1.4.1 non-colour requirement, and document the deviation for design review.