/// First route shown after launch. Hands off to the practice flow. library; import 'package:flutter/material.dart'; import '../utils/constants.dart'; import 'practice_flow_screen.dart'; /// Soft branded splash before the welcome screen. class SplashScreen extends StatefulWidget { const SplashScreen({super.key}); @override State createState() => _SplashScreenState(); } class _SplashScreenState extends State with SingleTickerProviderStateMixin { late final AnimationController _controller; late final Animation _fade; late final Animation _scale; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 700), ); _fade = CurvedAnimation(parent: _controller, curve: Curves.easeOut); _scale = Tween(begin: 0.92, end: 1).animate( CurvedAnimation(parent: _controller, curve: Curves.easeOutBack), ); _controller.forward(); _goToPractice(); } Future _goToPractice() async { await Future.delayed(kSplashDuration); if (!mounted) return; Navigator.of(context).pushReplacement( PageRouteBuilder( pageBuilder: (_, animation, _) => FadeTransition( opacity: animation, child: const PracticeFlowScreen(), ), transitionDuration: const Duration(milliseconds: 400), ), ); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final textTheme = Theme.of(context).textTheme; final colors = Theme.of(context).colorScheme; final isDark = colors.brightness == Brightness.dark; return Scaffold( body: DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: isDark ? [ colors.surface, colors.surfaceContainerLow, colors.surfaceContainer, ] : [ colors.surface, colors.surfaceContainerLow, const Color(0xFFE8DFD2), ], ), ), child: SafeArea( child: FadeTransition( opacity: _fade, child: ScaleTransition( scale: _scale, child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ ClipOval( child: Image.asset( 'assets/images/emblem.png', width: 88, height: 88, fit: BoxFit.cover, errorBuilder: (_, _, _) => Container( width: 88, height: 88, color: colors.primaryContainer, child: const Icon( Icons.spa, size: 44, color: Colors.white, ), ), ), ), const SizedBox(height: 24), Text( kAppName, style: textTheme.displaySmall?.copyWith( color: colors.onSurface, ), ), const SizedBox(height: 8), Text( 'Clarify what guides you', style: textTheme.bodyLarge?.copyWith( color: colors.onSurfaceVariant, ), ), const SizedBox(height: 40), SizedBox( width: 28, height: 28, child: CircularProgressIndicator( strokeWidth: 3, color: colors.primary, ), ), ], ), ), ), ), ), ), ); } }