import 'package:flutter/material.dart'; import '../theme/app_surfaces.dart'; enum _M3CardVariant { elevated, filled, outlined } /// Cyber/IT Card variants (Material 3). /// /// Use these factory constructors to build semantically correct cards: /// - [M3Card.elevated] — default panel: tonal fill + hairline outline (flat). /// - [M3Card.filled] — high-emphasis fill (caller passes [color]); no border. /// - [M3Card.outlined] — transparent fill with a hairline outline border. class M3Card extends StatelessWidget { const M3Card._( this._variant, { required this.child, this.color, this.shape, this.margin, this.clipBehavior = Clip.none, this.onTap, }); /// Elevated card — default panel with a tonal fill + hairline outline. /// 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._( _M3CardVariant.elevated, color: color, shape: shape, margin: margin, clipBehavior: clipBehavior, onTap: onTap, child: child, ); } /// Filled card — a high-emphasis fill (caller passes a semantic [color] or a /// surfaceContainer tone). No border. Best for summary/callout panels. factory M3Card.filled({ required Widget child, Color? color, ShapeBorder? shape, EdgeInsetsGeometry? margin, Clip clipBehavior = Clip.none, VoidCallback? onTap, }) { return M3Card._( _M3CardVariant.filled, color: color, shape: shape, margin: margin, clipBehavior: clipBehavior, onTap: onTap, child: child, ); } /// Outlined card — transparent fill with a hairline 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._( _M3CardVariant.outlined, color: color, shape: shape, margin: margin, clipBehavior: clipBehavior, onTap: onTap, child: child, ); } final _M3CardVariant _variant; final Widget child; final Color? color; final ShapeBorder? shape; final EdgeInsetsGeometry? margin; final Clip clipBehavior; final VoidCallback? onTap; @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; final radius = AppSurfaces.of(context).cardRadius; final isDark = cs.brightness == Brightness.dark; final Color resolvedColor; final bool bordered; switch (_variant) { case _M3CardVariant.elevated: resolvedColor = color ?? (isDark ? cs.surfaceContainer : cs.surfaceContainerLowest); bordered = true; case _M3CardVariant.filled: resolvedColor = color ?? cs.surfaceContainerHighest; bordered = false; case _M3CardVariant.outlined: resolvedColor = color ?? Colors.transparent; bordered = true; } final resolvedShape = shape ?? RoundedRectangleBorder( borderRadius: BorderRadius.circular(radius), side: bordered ? BorderSide(color: cs.outlineVariant) : BorderSide.none, ); return Card( color: resolvedColor, elevation: 0, shadowColor: Colors.transparent, surfaceTintColor: Colors.transparent, shape: resolvedShape, margin: margin ?? EdgeInsets.zero, clipBehavior: onTap != null && clipBehavior == Clip.none ? Clip.antiAlias : clipBehavior, child: onTap != null ? InkWell( onTap: onTap, borderRadius: BorderRadius.circular(radius), child: child, ) : child, ); } }