import 'package:flutter/material.dart'; /// Animação de entrada (fade + leve deslize para cima) para dar vida a /// cards e listas quando aparecem em ecrã. Suporta [delay] para permitir /// efeito "staggered" (itens surgindo em sequência) em listas/grades. class FadeSlideIn extends StatefulWidget { const FadeSlideIn({ super.key, required this.child, this.delay = Duration.zero, this.duration = const Duration(milliseconds: 420), this.offset = const Offset(0, 0.08), }); final Widget child; final Duration delay; final Duration duration; final Offset offset; @override State createState() => _FadeSlideInState(); } class _FadeSlideInState extends State with SingleTickerProviderStateMixin { late final AnimationController _controller = AnimationController( vsync: this, duration: widget.duration, ); late final Animation _fade = CurvedAnimation( parent: _controller, curve: Curves.easeOut, ); late final Animation _slide = Tween( begin: widget.offset, end: Offset.zero, ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic)); @override void initState() { super.initState(); if (widget.delay == Duration.zero) { _controller.forward(); } else { Future.delayed(widget.delay, () { if (mounted) _controller.forward(); }); } } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return FadeTransition( opacity: _fade, child: SlideTransition(position: _slide, child: widget.child), ); } }