import 'package:flutter/material.dart'; /// M3 Expressive Card variants. /// /// Use these factory constructors to build semantically correct cards: /// - [M3Card.elevated] — default, uses tonal surface tint (no hard shadow). /// - [M3Card.filled] — uses surfaceContainerHighest for emphasis. /// - [M3Card.outlined] — transparent fill with a subtle outline border. class M3Card extends StatelessWidget { const M3Card._({ required this.child, this.color, this.elevation, this.shadowColor, this.surfaceTintColor, this.shape, this.margin, this.clipBehavior = Clip.none, this.onTap, }); /// Elevated card — tonal surface tint, minimal shadow. /// Best for primary content surfaces (metric cards, detail panels). factory M3Card.elevated({ required Widget child, Color? color, ShapeBorder? shape, EdgeInsetsGeometry? margin, Clip clipBehavior = Clip.none, VoidCallback? onTap, }) { return M3Card._( color: color, elevation: 1, shadowColor: Colors.transparent, shape: shape, margin: margin, clipBehavior: clipBehavior, onTap: onTap, child: child, ); } /// Filled card — uses surfaceContainerHighest for high emphasis. /// Best for summary cards, status counts, callout panels. factory M3Card.filled({ required Widget child, Color? color, ShapeBorder? shape, EdgeInsetsGeometry? margin, Clip clipBehavior = Clip.none, VoidCallback? onTap, }) { return M3Card._( color: color, // caller passes surfaceContainerHighest or semantic color elevation: 0, shadowColor: Colors.transparent, surfaceTintColor: Colors.transparent, shape: shape, margin: margin, clipBehavior: clipBehavior, onTap: onTap, child: child, ); } /// Outlined card — transparent fill with outline border. /// Best for list items, form sections, grouped content. factory M3Card.outlined({ required Widget child, Color? color, ShapeBorder? shape, EdgeInsetsGeometry? margin, Clip clipBehavior = Clip.none, VoidCallback? onTap, }) { return M3Card._( color: color, elevation: 0, shadowColor: Colors.transparent, surfaceTintColor: Colors.transparent, shape: shape, margin: margin, clipBehavior: clipBehavior, onTap: onTap, child: child, ); } final Widget child; final Color? color; final double? elevation; final Color? shadowColor; final Color? surfaceTintColor; final ShapeBorder? shape; final EdgeInsetsGeometry? margin; final Clip clipBehavior; final VoidCallback? onTap; @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; // For outlined, we need the border side final resolvedShape = shape ?? (elevation == 0 && surfaceTintColor == Colors.transparent ? RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: (shadowColor == Colors.transparent && color == null) ? BorderSide(color: cs.outlineVariant) : BorderSide.none, ) : null); final card = Card( color: color, elevation: elevation, shadowColor: shadowColor, surfaceTintColor: surfaceTintColor, shape: resolvedShape, margin: margin ?? EdgeInsets.zero, clipBehavior: clipBehavior, child: onTap != null ? InkWell( onTap: onTap, borderRadius: BorderRadius.circular(16), child: child, ) : child, ); return card; } }