import 'package:flutter/material.dart'; import '../../../common/painter/wave_painter.dart'; import '../../../common/theme/theme.dart'; class ParticleCard extends StatelessWidget { /// Content yang ditampilkan di atas particle background final Widget child; /// Gradient background card. Default pakai primaryGradient final List? gradientColors; /// Arah gradient. Default topLeft → bottomRight final AlignmentGeometry gradientBegin; final AlignmentGeometry gradientEnd; /// Border radius card. Default 16 final double borderRadius; /// Padding konten. Default 16 semua sisi final EdgeInsetsGeometry? padding; /// Height card. Null = wrap content final double? height; /// Opacity particle & wave. Default 1.0 final double decorationOpacity; const ParticleCard({ super.key, required this.child, this.gradientColors, this.gradientBegin = Alignment.topLeft, this.gradientEnd = Alignment.bottomRight, this.borderRadius = 16, this.padding, this.height, this.decorationOpacity = 1.0, }); @override Widget build(BuildContext context) { final colors = gradientColors ?? AppColor.primaryGradient; return ClipRRect( borderRadius: BorderRadius.circular(borderRadius), child: Container( height: height, decoration: BoxDecoration( borderRadius: BorderRadius.circular(borderRadius), gradient: LinearGradient( colors: colors, begin: gradientBegin, end: gradientEnd, ), boxShadow: [ BoxShadow( color: colors.first.withOpacity(0.35), blurRadius: 16, offset: const Offset(0, 6), ), ], ), child: Stack( children: [ // --- Decorative background --- Opacity( opacity: decorationOpacity, child: Stack( children: [ // Circles kanan atas Positioned( top: -24, right: -24, child: _circle(120, AppColor.white, 0.10), ), Positioned( top: 28, right: 16, child: _circle(60, AppColor.white, 0.06), ), Positioned( top: 70, right: -10, child: _circle(36, AppColor.white, 0.08), ), // Circles kiri bawah Positioned( bottom: -20, left: -20, child: _circle(90, AppColor.white, 0.06), ), Positioned( bottom: 20, left: 40, child: _circle(40, AppColor.white, 0.04), ), // Sparkle icons ..._sparkles(context), // Wave pattern Positioned.fill( child: CustomPaint( painter: WavePainter( animation: 0.0, color: AppColor.white.withOpacity(0.08), ), ), ), // Radial gradient overlay Container( decoration: BoxDecoration( gradient: RadialGradient( center: const Alignment(0.7, -0.5), radius: 1.4, colors: [ Colors.white.withOpacity(0.06), Colors.transparent, ], ), ), ), ], ), ), // --- Content --- Padding( padding: padding ?? const EdgeInsets.all(16), child: child, ), ], ), ), ); } Widget _circle(double size, Color color, double opacity) { return Container( width: size, height: size, decoration: BoxDecoration( shape: BoxShape.circle, color: color.withOpacity(opacity), ), ); } List _sparkles(BuildContext context) { final width = MediaQuery.of(context).size.width; return List.generate(5, (i) { return Positioned( left: (i * 70.0) % (width - 20), top: 10 + (i * 18.0), child: Icon( Icons.auto_awesome, size: 8 + (i % 3) * 3.0, color: AppColor.white.withOpacity(0.18), ), ); }); } }