import 'package:flutter/material.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/widgets/surface_card.dart'; /// Compact live car data shown only while the ELM327 adapter is delivering /// fresh speed/throttle values. class ObdCard extends StatelessWidget { const ObdCard({ super.key, required this.speedKmh, required this.throttlePercent, required this.economyL100, this.compact = false, }); final double? speedKmh; final double? throttlePercent; final double? economyL100; final bool compact; @override Widget build(BuildContext context) { final colors = context.colors; final theme = Theme.of(context); final throttle = (throttlePercent ?? 0).clamp(0.0, 100.0); return SurfaceCard( padding: EdgeInsets.fromLTRB( compact ? 16 : 20, compact ? 13 : 16, compact ? 16 : 20, compact ? 13 : 16, ), radius: 24, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 7, height: 7, decoration: BoxDecoration( color: colors.accent, shape: BoxShape.circle, ), ), const SizedBox(width: 8), Text( 'OBD-II', style: theme.textTheme.labelMedium?.copyWith( color: colors.inkMuted, letterSpacing: 0.8, ), ), const Spacer(), Text( 'LIVE', style: theme.textTheme.labelSmall?.copyWith( color: colors.accent, fontWeight: FontWeight.w700, letterSpacing: 0.8, ), ), ], ), SizedBox(height: compact ? 6 : 8), Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( speedKmh == null ? '—' : speedKmh!.round().toString(), style: theme.textTheme.displaySmall?.copyWith( fontSize: compact ? 38 : 46, height: 0.95, fontFeatures: const [FontFeature.tabularFigures()], ), ), const SizedBox(width: 7), Padding( padding: const EdgeInsets.only(bottom: 5), child: Text( 'km/h', style: theme.textTheme.bodySmall?.copyWith( color: colors.inkMuted, ), ), ), ], ), SizedBox(height: compact ? 7 : 9), Row( children: [ Text( 'Throttle', style: theme.textTheme.bodySmall?.copyWith( color: colors.inkMuted, ), ), const Spacer(), Text( '${throttle.round()}%', style: theme.textTheme.labelMedium?.copyWith( color: colors.ink, fontFeatures: const [FontFeature.tabularFigures()], ), ), ], ), const SizedBox(height: 5), ClipRRect( borderRadius: BorderRadius.circular(999), child: TweenAnimationBuilder( tween: Tween(begin: 0, end: throttle / 100), duration: const Duration(milliseconds: 180), curve: Curves.easeOut, builder: (context, value, _) { return LinearProgressIndicator( value: value, minHeight: compact ? 5 : 6, backgroundColor: colors.border, valueColor: AlwaysStoppedAnimation(colors.accent), ); }, ), ), SizedBox(height: compact ? 7 : 9), Row( children: [ Text( 'Rolling economy', style: theme.textTheme.bodySmall?.copyWith( color: colors.inkMuted, ), ), const Spacer(), Text( economyL100 == null ? '—' : '${economyL100!.toStringAsFixed(1)} L/100 km', style: theme.textTheme.labelMedium?.copyWith( color: colors.ink, fontFeatures: const [FontFeature.tabularFigures()], ), ), ], ), ], ), ); } }