// FaiEmptyState — gracious empty / loading / error placeholder. // Replaces "(no data)" strings with one tone, one icon, one tip. import 'package:flutter/material.dart'; import '../theme/tokens.dart'; class FaiEmptyState extends StatelessWidget { final IconData icon; final String title; final String? hint; final Widget? action; /// Icon tone. Defaults to muted; set to [Theme.colorScheme.error] /// for connection-failure variants. final Color? iconColor; const FaiEmptyState({ super.key, required this.icon, required this.title, this.hint, this.action, this.iconColor, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final color = iconColor ?? theme.colorScheme.onSurfaceVariant; return Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), child: Padding( padding: const EdgeInsets.all(FaiSpace.xxl), child: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Container( width: 56, height: 56, decoration: BoxDecoration( color: color.withValues(alpha: 0.1), shape: BoxShape.circle, ), child: Icon(icon, size: 24, color: color), ), const SizedBox(height: FaiSpace.lg), Text( title, textAlign: TextAlign.center, style: theme.textTheme.titleMedium, ), if (hint != null) ...[ const SizedBox(height: FaiSpace.sm), Text( hint!, textAlign: TextAlign.center, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), ), ], if (action != null) ...[ const SizedBox(height: FaiSpace.lg), action!, ], ], ), ), ), ); } }