import 'package:flutter/material.dart'; import '../../../../core/theme/design_tokens.dart'; class AuthPageScaffold extends StatelessWidget { const AuthPageScaffold({ super.key, required this.mainContent, this.footer, this.mainContentKey, this.footerKey, }); final Widget mainContent; final Widget? footer; final Key? mainContentKey; final Key? footerKey; @override Widget build(BuildContext context) { final keyboardInset = MediaQuery.viewInsetsOf(context).bottom; return Scaffold( backgroundColor: AppColors.authBackgroundBottom, body: DecoratedBox( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ AppColors.authBackgroundTop, AppColors.authBackgroundBottom, ], ), ), child: Stack( children: [ const _AuthBackgroundOrbs(), SafeArea( child: LayoutBuilder( builder: (context, constraints) { return SingleChildScrollView( keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, padding: EdgeInsets.fromLTRB( AppSpacing.lg, AppSpacing.md, AppSpacing.lg, keyboardInset + AppSpacing.md, ), child: ConstrainedBox( constraints: BoxConstraints( minHeight: constraints.maxHeight, ), child: Center( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ KeyedSubtree( key: mainContentKey, child: mainContent, ), if (footer != null) ...[ SizedBox(height: AppSpacing.md), KeyedSubtree(key: footerKey, child: footer!), ], ], ), ), ), ); }, ), ), ], ), ), ); } } class AuthHeroHeader extends StatelessWidget { const AuthHeroHeader({ super.key, this.title, this.subtitle, this.showBrand = false, }); final String? title; final String? subtitle; final bool showBrand; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ if (showBrand) ...[ Container( width: 88, height: 88, decoration: BoxDecoration( color: AppColors.appIconRing, borderRadius: BorderRadius.circular(AppRadius.full), border: Border.all(color: AppColors.appIconBorder), boxShadow: [ BoxShadow( color: AppColors.blue300.withValues(alpha: 0.28), blurRadius: 30, offset: const Offset(0, 16), ), ], ), child: Center( child: ClipRRect( borderRadius: BorderRadius.circular(AppRadius.full), child: Image.asset( 'assets/images/logo.png', width: 58, height: 58, fit: BoxFit.cover, ), ), ), ), SizedBox(height: AppSpacing.lg), const Text( 'linksy', style: TextStyle( fontFamily: 'Playfair Display', fontSize: 34, fontWeight: FontWeight.w700, fontStyle: FontStyle.italic, color: AppColors.appTitle, letterSpacing: 0.4, ), ), ], if (title != null) ...[ if (showBrand) SizedBox(height: AppSpacing.lg), Text( title!, textAlign: TextAlign.center, style: const TextStyle( fontSize: 28, fontWeight: FontWeight.w700, color: AppColors.slate900, letterSpacing: -0.2, ), ), ], if (subtitle != null) ...[ SizedBox(height: AppSpacing.sm), Text( subtitle!, textAlign: TextAlign.center, style: const TextStyle( fontSize: 14, height: 1.45, color: AppColors.authLinkMuted, ), ), ], ], ); } } class AuthSurfaceCard extends StatelessWidget { const AuthSurfaceCard({super.key, required this.child}); final Widget child; @override Widget build(BuildContext context) { return Container( width: double.infinity, padding: const EdgeInsets.all(AppSpacing.xl), decoration: BoxDecoration( color: AppColors.authCardBackground, borderRadius: BorderRadius.circular(AppRadius.xxl), border: Border.all(color: AppColors.authCardBorder), boxShadow: [ BoxShadow( color: AppColors.blue200.withValues(alpha: 0.18), blurRadius: 34, offset: const Offset(0, 18), ), BoxShadow( color: AppColors.slate900.withValues(alpha: 0.06), blurRadius: 20, offset: const Offset(0, 10), ), ], ), child: child, ); } } class AuthSection extends StatelessWidget { const AuthSection({ super.key, this.title, this.description, required this.child, }); final String? title; final String? description; final Widget child; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (title != null) ...[ Text( title!, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w700, color: AppColors.slate800, ), ), if (description != null) ...[ SizedBox(height: AppSpacing.xs), Text( description!, style: const TextStyle( fontSize: 13, height: 1.4, color: AppColors.authLinkMuted, ), ), ], SizedBox(height: AppSpacing.md), ], child, ], ); } } class _AuthBackgroundOrbs extends StatelessWidget { const _AuthBackgroundOrbs(); @override Widget build(BuildContext context) { return IgnorePointer( child: Stack( children: [ Positioned( top: -72, left: -38, child: _Orb( size: 168, color: AppColors.authBackgroundOrb.withValues(alpha: 0.42), ), ), Positioned( top: 108, right: -32, child: _Orb( size: 120, color: AppColors.blue100.withValues(alpha: 0.32), ), ), Positioned( bottom: 36, left: 24, child: _Orb( size: 92, color: AppColors.blue50.withValues(alpha: 0.7), ), ), ], ), ); } } class _Orb extends StatelessWidget { const _Orb({required this.size, required this.color}); final double size; final Color color; @override Widget build(BuildContext context) { return Container( width: size, height: size, decoration: BoxDecoration(shape: BoxShape.circle, color: color), ); } }