import 'package:flutter/material.dart'; class StatCard extends StatefulWidget { final String title; final String value; final IconData icon; final Color color; final int delayMs; const StatCard({ super.key, required this.title, required this.value, required this.icon, required this.color, this.delayMs = 0, }); @override State createState() => _StatCardState(); } class _StatCardState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _fadeAnim; late Animation _slideAnim; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 400), vsync: this, ); _fadeAnim = Tween(begin: 0, end: 1).animate( CurvedAnimation(parent: _controller, curve: Curves.easeOut), ); _slideAnim = Tween( begin: const Offset(0, 0.15), end: Offset.zero, ).animate( CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic), ); if (widget.delayMs > 0) { Future.delayed(Duration(milliseconds: widget.delayMs), () { if (mounted) _controller.forward(); }); } else { _controller.forward(); } } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final theme = Theme.of(context); return FadeTransition( opacity: _fadeAnim, child: SlideTransition( position: _slideAnim, child: Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(widget.icon, color: widget.color, size: 20), const SizedBox(width: 8), Text(widget.title, style: theme.textTheme.bodySmall), ], ), const SizedBox(height: 8), Text( widget.value, style: theme.textTheme.headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), ], ), ), ), ), ); } }