anchor.diff:    final backgroundColor = theme.colorScheme.surface;
     final foregroundColor = theme.colorScheme.onSurface;
     return Container(
  -    color: backgroundColor,
  -    child: Row(
  -      children: [
  -        Padding(
  -          padding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
  -          child: ListThumbnail(song.artwork),
  +      color: backgroundColor,
  +      child: Stack(children: [
  +        _trackDetails(song, foregroundColor),
  +        Positioned(
  +          bottom: 0,
  +          left: 0,
  +          right: 0,
  +          height: 3,
  +          child: _progressBar(),
           ),
  -        Expanded(
  -          child: Column(
  -            crossAxisAlignment: CrossAxisAlignment.start,
  -            mainAxisAlignment: MainAxisAlignment.center,
  -            children: [
  -              Text(
  -                song.title,
  -                style: theme.textTheme.subtitle2.copyWith(color: foregroundColor),
  -                overflow: TextOverflow.ellipsis,
  -                maxLines: 1,
  -              ),
  -              Text(
  -                song.artist,
  -                style: theme.textTheme.caption.copyWith(color: foregroundColor.withOpacity(0.75)),
  -                overflow: TextOverflow.ellipsis,
  -                maxLines: 1,
  -              ),
  -            ],
  -          ),
  -        ),
  -        StreamBuilder<PlaybackState>(
  -          stream: AudioService.playbackStateStream,
  -          builder: (context, snapshot) {
  -            bool playing = false;
  -            if (snapshot.hasData) {
  -              playing = snapshot.data.playing && snapshot.data.processingState != AudioProcessingState.completed;
  -            }
  -            return Row(
  -              mainAxisAlignment: MainAxisAlignment.center,
  -              children: [
  -                // TODO add previous button
  -                if (playing) pauseButton(foregroundColor) else playButton(foregroundColor),
  -                nextButton(foregroundColor), // TODO grey out when cannot skip next
  -              ],
  -            );
  -          },
  -        ),
  -        // TODO Buffering indicator
  -        // TODO Progress bar
  -      ],
  -    ),
  -  );
  +      ]));
   }
   
  -IconButton pauseButton(Color color) => IconButton(
  +Widget _trackDetails(Song song, Color foregroundColor) => LayoutBuilder(
  +      builder: (context, size) {
  +        return Row(
  +          children: [
  +            Padding(
  +              padding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
  +              child: ListThumbnail(song.artwork),
  +            ),
  +            Expanded(
  +              child: Column(
  +                crossAxisAlignment: CrossAxisAlignment.start,
  +                mainAxisAlignment: MainAxisAlignment.center,
  +                children: [
  +                  Text(
  +                    song.title,
  +                    style: Theme.of(context).textTheme.subtitle2.copyWith(color: foregroundColor),
  +                    overflow: TextOverflow.ellipsis,
  +                    maxLines: 1,
  +                  ),
  +                  Text(
  +                    song.artist,
  +                    style: Theme.of(context).textTheme.caption.copyWith(color: foregroundColor.withOpacity(0.75)),
  +                    overflow: TextOverflow.ellipsis,
  +                    maxLines: 1,
  +                  ),
  +                ],
  +              ),
  +            ),
  +            _controls(foregroundColor),
  +            // TODO Buffering indicator
  +          ],
  +        );
  +      },
  +    );
  +
  +Widget _controls(Color foregroundColor) => StreamBuilder<PlaybackState>(
  +      stream: AudioService.playbackStateStream,
  +      builder: (context, snapshot) {
  +        bool playing = false;
  +        if (snapshot.hasData) {
  +          playing = snapshot.data.playing && snapshot.data.processingState != AudioProcessingState.completed;
  +        }
  +        return Row(
  +          mainAxisAlignment: MainAxisAlignment.center,
  +          children: [
  +            // TODO add previous button
  +            if (playing) _pauseButton(foregroundColor) else _playButton(foregroundColor),
  +            _nextButton(foregroundColor), // TODO grey out when cannot skip next
  +          ],
  +        );
  +      },
  +    );
  +
  +IconButton _pauseButton(Color color) => IconButton(
         icon: Icon(Icons.pause),
         onPressed: AudioService.pause,
         iconSize: 24.0,
         color: color,
       );
   
  -IconButton playButton(Color color) => IconButton(
  +IconButton _playButton(Color color) => IconButton(
         icon: Icon(Icons.play_arrow),
         onPressed: AudioService.play,
         iconSize: 24.0,
         color: color,
       );
   
  -IconButton nextButton(Color color) => IconButton(
  +IconButton _nextButton(Color color) => IconButton(
         icon: Icon(Icons.skip_next),
         onPressed: AudioService.skipToNext,
         iconSize: 24.0,
         color: color,
       );
  +
  +Widget _progressBar() => LayoutBuilder(
  +      builder: (context, size) {
  +        final Color backgroundColor = Theme.of(context).colorScheme.primary.withOpacity(0.4);
  +        final Color foregroundColor = Theme.of(context).colorScheme.primary;
  +        return Stack(
  +          children: [
  +            Container(color: backgroundColor),
  +            StreamBuilder<MediaState>(
  +              stream: _mediaStateStream,
  +              builder: (context, snapshot) {
  +                double progress = 0.0;
  +                if (snapshot.hasData) {
  +                  final int position = snapshot.data.position?.inMilliseconds;
  +                  final int duration = snapshot.data.mediaItem?.duration?.inMilliseconds;
  +                  if (position != null && duration != null && duration > 0) {
  +                    progress = (position / duration).clamp(0.0, 1.0);
  +                  }
  +                }
  +                return SizedBox(
  +                  width: progress * size.maxWidth,
  +                  child: Container(color: foregroundColor),
  +                );
  +              },
  +            ),
  +          ],
  +        );
  +      },
  +    );
  
positive.code: import 'package:polaris/foreground/ui/utils/thumbnail.dart';
  import 'package:polaris/shared/dto.dart';
  import 'package:polaris/shared/media_item.dart';
  
  final getIt = GetIt.instance;
  
  class Player extends StatelessWidget {
    @override
  
negative.code:             child: InkWell(
                onTap: () {
                  globalNavigatorKey.currentState.push(
                    // TODO prevent opening multiple instances
                    MaterialPageRoute(builder: (context) => QueuePage()),
                  );
                },
  