Initial commit: Svrnty Console Flutter application with GetWidget integration

- Implemented responsive dashboard UI with Material Design 3
- Integrated GetWidget 7.0.0 for modern UI components (GFAvatar, custom badges)
- Created collapsible navigation sidebar with smooth animations
- Built status cards grid with uniform badge sizing
- Added activity timeline with recent events
- Configured custom Svrnty branding (Crimson Red #F3574E, Slate Blue #5A6F7D)
- Set up development server on http://localhost:54952/
- Included Montserrat and IBM Plex Mono custom fonts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-25 13:47:58 -04:00
commit e20ea43a85
198 changed files with 10220 additions and 0 deletions
+322
View File
@@ -0,0 +1,322 @@
import 'package:flutter/material.dart';
import 'package:animate_do/animate_do.dart';
import 'package:iconsax/iconsax.dart';
import 'package:getwidget/getwidget.dart';
class NavigationSidebar extends StatefulWidget {
final bool isExpanded;
final Function(String) onNavigate;
final String currentPage;
const NavigationSidebar({
Key? key,
required this.isExpanded,
required this.onNavigate,
required this.currentPage,
}) : super(key: key);
@override
State<NavigationSidebar> createState() => _NavigationSidebarState();
}
class _NavigationSidebarState extends State<NavigationSidebar> {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final width = widget.isExpanded ? 250.0 : 70.0;
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: width,
decoration: BoxDecoration(
color: colorScheme.surfaceContainerLow,
border: Border(
right: BorderSide(
color: colorScheme.outline.withOpacity(0.2),
width: 1,
),
),
),
child: Column(
children: [
// Svrnty Logo Section
_buildLogoSection(colorScheme),
const SizedBox(height: 20),
// Navigation Menu Items
Expanded(
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 8),
children: [
_buildMenuItem(
icon: Iconsax.home,
title: 'Dashboard',
pageId: 'dashboard',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.hierarchy_square,
title: 'The Architect',
pageId: 'architect',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.cpu,
title: 'Agents',
pageId: 'agents',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.chart_square,
title: 'Analytics',
pageId: 'analytics',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.box,
title: 'Tools',
pageId: 'tools',
colorScheme: colorScheme,
),
const SizedBox(height: 8),
_buildMenuItem(
icon: Iconsax.setting_2,
title: 'Settings',
pageId: 'settings',
colorScheme: colorScheme,
),
],
),
),
// User Profile Section (bottom)
_buildUserSection(colorScheme),
],
),
);
}
Widget _buildLogoSection(ColorScheme colorScheme) {
return Container(
padding: EdgeInsets.symmetric(
vertical: 20,
horizontal: widget.isExpanded ? 20 : 12,
),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: colorScheme.outline.withOpacity(0.2),
width: 1,
),
),
),
child: widget.isExpanded
? FadeIn(
duration: const Duration(milliseconds: 200),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: colorScheme.primary,
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'S',
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Svrnty',
style: TextStyle(
fontSize: 20.7,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
Text(
'Console',
style: TextStyle(
fontSize: 12.65,
color: colorScheme.onSurfaceVariant,
),
),
],
),
),
],
),
)
: Center(
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: colorScheme.primary,
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'S',
style: TextStyle(
color: Colors.white,
fontSize: 23,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
Widget _buildMenuItem({
required IconData icon,
required String title,
required String pageId,
required ColorScheme colorScheme,
}) {
final isActive = widget.currentPage == pageId;
return FadeInLeft(
duration: const Duration(milliseconds: 300),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () => widget.onNavigate(pageId),
borderRadius: BorderRadius.circular(12),
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
padding: EdgeInsets.symmetric(
vertical: 14,
horizontal: widget.isExpanded ? 16 : 12,
),
decoration: BoxDecoration(
color: isActive
? colorScheme.primary.withOpacity(0.25)
: Colors.transparent,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: isActive
? colorScheme.primary.withOpacity(0.7)
: Colors.transparent,
width: 2,
),
),
child: Row(
children: [
Icon(
icon,
color: isActive
? Colors.white
: colorScheme.onSurfaceVariant,
size: 24,
),
if (widget.isExpanded) ...[
const SizedBox(width: 16),
Expanded(
child: FadeIn(
duration: const Duration(milliseconds: 200),
child: Text(
title,
style: TextStyle(
fontSize: 17.25,
fontWeight:
isActive ? FontWeight.w600 : FontWeight.w400,
color: isActive
? Colors.white
: colorScheme.onSurface,
),
),
),
),
],
],
),
),
),
),
);
}
Widget _buildUserSection(ColorScheme colorScheme) {
return Container(
padding: EdgeInsets.all(widget.isExpanded ? 16 : 12),
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: colorScheme.outline.withOpacity(0.2),
width: 1,
),
),
),
child: widget.isExpanded
? FadeIn(
duration: const Duration(milliseconds: 200),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
GFAvatar(
radius: 18,
backgroundColor: colorScheme.primary.withOpacity(0.3),
child: Icon(
Iconsax.user,
color: colorScheme.primary,
size: 18,
),
shape: GFAvatarShape.circle,
),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Admin',
style: TextStyle(
fontSize: 14.95,
fontWeight: FontWeight.w600,
color: colorScheme.onSurface,
),
),
Text(
'admin@svrnty.ai',
style: TextStyle(
fontSize: 11.5,
color: colorScheme.onSurfaceVariant,
),
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
)
: Center(
child: GFAvatar(
radius: 20,
backgroundColor: colorScheme.primary.withOpacity(0.2),
child: Icon(
Iconsax.user,
color: colorScheme.primary,
size: 20,
),
shape: GFAvatarShape.circle,
),
),
);
}
}
+478
View File
@@ -0,0 +1,478 @@
import 'package:flutter/material.dart';
import 'package:animate_do/animate_do.dart';
/// Svrnty Design System Components
/// Reusable, branded components for the Svrnty Console application
///
/// Brand Colors:
/// - Primary (Crimson): #C44D58
/// - Secondary (Slate Blue): #475C6C
// ============================================================================
// SVRNTY BUTTONS
// ============================================================================
enum SvrntyButtonVariant { primary, secondary, ghost, danger }
class SvrntyButton extends StatelessWidget {
final String text;
final VoidCallback? onPressed;
final SvrntyButtonVariant variant;
final IconData? icon;
final bool isLoading;
final bool fullWidth;
const SvrntyButton({
Key? key,
required this.text,
this.onPressed,
this.variant = SvrntyButtonVariant.primary,
this.icon,
this.isLoading = false,
this.fullWidth = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
Color backgroundColor;
Color textColor;
Color? borderColor;
switch (variant) {
case SvrntyButtonVariant.primary:
backgroundColor = colorScheme.primary;
textColor = Colors.white;
borderColor = null;
break;
case SvrntyButtonVariant.secondary:
backgroundColor = colorScheme.secondary;
textColor = Colors.white;
borderColor = null;
break;
case SvrntyButtonVariant.ghost:
backgroundColor = Colors.transparent;
textColor = colorScheme.primary;
borderColor = colorScheme.primary;
break;
case SvrntyButtonVariant.danger:
backgroundColor = colorScheme.error;
textColor = Colors.white;
borderColor = null;
break;
}
return FadeInUp(
duration: const Duration(milliseconds: 300),
child: SizedBox(
width: fullWidth ? double.infinity : null,
child: ElevatedButton(
onPressed: isLoading ? null : onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor,
foregroundColor: textColor,
elevation: variant == SvrntyButtonVariant.ghost ? 0 : 2,
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: borderColor != null
? BorderSide(color: borderColor, width: 2)
: BorderSide.none,
),
),
child: isLoading
? SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(textColor),
),
)
: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null) ...[
Icon(icon, size: 20),
const SizedBox(width: 8),
],
Text(
text,
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16,
),
),
],
),
),
),
);
}
}
// ============================================================================
// SVRNTY CARDS
// ============================================================================
class SvrntyCard extends StatelessWidget {
final Widget child;
final Color? accentColor;
final VoidCallback? onTap;
final bool showBorder;
final EdgeInsetsGeometry? padding;
const SvrntyCard({
Key? key,
required this.child,
this.accentColor,
this.onTap,
this.showBorder = true,
this.padding,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
final effectiveAccentColor = accentColor ?? colorScheme.primary;
return FadeInUp(
duration: const Duration(milliseconds: 400),
child: Container(
decoration: showBorder
? BoxDecoration(
borderRadius: BorderRadius.circular(16),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
effectiveAccentColor.withOpacity(0.15),
effectiveAccentColor.withOpacity(0.05),
],
),
border: Border.all(
color: effectiveAccentColor.withOpacity(0.3),
width: 1,
),
)
: null,
child: Card(
elevation: 2,
color: showBorder ? Colors.transparent : null,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(16),
child: Container(
decoration: showBorder
? BoxDecoration(
border: Border(
left: BorderSide(
color: effectiveAccentColor,
width: 4,
),
),
)
: null,
child: Padding(
padding: padding ?? const EdgeInsets.all(20),
child: child,
),
),
),
),
),
);
}
}
// ============================================================================
// SVRNTY BADGES
// ============================================================================
enum SvrntyBadgeStatus { success, warning, error, info, neutral }
class SvrntyBadge extends StatelessWidget {
final String text;
final SvrntyBadgeStatus status;
final IconData? icon;
const SvrntyBadge({
Key? key,
required this.text,
this.status = SvrntyBadgeStatus.neutral,
this.icon,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
Color backgroundColor;
Color textColor;
switch (status) {
case SvrntyBadgeStatus.success:
backgroundColor = Colors.green;
textColor = Colors.white;
break;
case SvrntyBadgeStatus.warning:
backgroundColor = Colors.orange;
textColor = Colors.white;
break;
case SvrntyBadgeStatus.error:
backgroundColor = colorScheme.error;
textColor = Colors.white;
break;
case SvrntyBadgeStatus.info:
backgroundColor = colorScheme.primary;
textColor = Colors.white;
break;
case SvrntyBadgeStatus.neutral:
backgroundColor = colorScheme.secondary;
textColor = Colors.white;
break;
}
return Pulse(
duration: const Duration(milliseconds: 1000),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: backgroundColor.withOpacity(0.3),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null) ...[
Icon(icon, color: textColor, size: 16),
const SizedBox(width: 6),
],
Text(
text,
style: TextStyle(
color: textColor,
fontSize: 12,
fontWeight: FontWeight.bold,
fontFamily: 'Montserrat',
),
),
],
),
),
);
}
}
// ============================================================================
// SVRNTY ICON BUTTONS
// ============================================================================
class SvrntyIconButton extends StatelessWidget {
final IconData icon;
final VoidCallback? onPressed;
final Color? backgroundColor;
final Color? iconColor;
final double size;
const SvrntyIconButton({
Key? key,
required this.icon,
this.onPressed,
this.backgroundColor,
this.iconColor,
this.size = 40,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return FadeIn(
child: Container(
width: size,
height: size,
decoration: BoxDecoration(
color: backgroundColor ?? colorScheme.primary.withOpacity(0.1),
shape: BoxShape.circle,
),
child: IconButton(
icon: Icon(icon),
color: iconColor ?? colorScheme.primary,
iconSize: size * 0.5,
onPressed: onPressed,
),
),
);
}
}
// ============================================================================
// SVRNTY SECTION HEADER
// ============================================================================
class SvrntySectionHeader extends StatelessWidget {
final String title;
final String? subtitle;
final Widget? action;
const SvrntySectionHeader({
Key? key,
required this.title,
this.subtitle,
this.action,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return FadeInLeft(
duration: const Duration(milliseconds: 400),
child: Row(
children: [
Container(
width: 4,
height: 28,
decoration: BoxDecoration(
color: colorScheme.primary,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
fontFamily: 'Montserrat',
),
),
if (subtitle != null) ...[
const SizedBox(height: 4),
Text(
subtitle!,
style: TextStyle(
fontSize: 14,
color: colorScheme.onSurfaceVariant,
fontFamily: 'Montserrat',
),
),
],
],
),
),
if (action != null) action!,
],
),
);
}
}
// ============================================================================
// SVRNTY INPUT FIELD
// ============================================================================
class SvrntyTextField extends StatelessWidget {
final String label;
final String? hint;
final TextEditingController? controller;
final IconData? prefixIcon;
final bool obscureText;
final TextInputType? keyboardType;
final String? Function(String?)? validator;
const SvrntyTextField({
Key? key,
required this.label,
this.hint,
this.controller,
this.prefixIcon,
this.obscureText = false,
this.keyboardType,
this.validator,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return FadeInUp(
duration: const Duration(milliseconds: 350),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
color: colorScheme.onSurface,
fontFamily: 'Montserrat',
),
),
const SizedBox(height: 8),
TextFormField(
controller: controller,
obscureText: obscureText,
keyboardType: keyboardType,
validator: validator,
style: const TextStyle(fontFamily: 'Montserrat'),
decoration: InputDecoration(
hintText: hint,
prefixIcon: prefixIcon != null ? Icon(prefixIcon) : null,
filled: true,
fillColor: colorScheme.surfaceContainerHighest,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: colorScheme.outline.withOpacity(0.3),
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: colorScheme.outline.withOpacity(0.2),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: colorScheme.primary,
width: 2,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: colorScheme.error,
width: 2,
),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 16,
),
),
),
],
),
);
}
}
+597
View File
@@ -0,0 +1,597 @@
import 'package:flutter/material.dart';
import 'package:iconsax/iconsax.dart';
import 'package:animate_do/animate_do.dart';
import 'package:getwidget/getwidget.dart';
import 'components/navigation_sidebar.dart';
class ConsoleLandingPage extends StatefulWidget {
const ConsoleLandingPage({Key? key}) : super(key: key);
@override
State<ConsoleLandingPage> createState() => _ConsoleLandingPageState();
}
class _ConsoleLandingPageState extends State<ConsoleLandingPage> {
bool _isSidebarExpanded = true;
String _currentPage = 'dashboard';
void _toggleSidebar() {
setState(() {
_isSidebarExpanded = !_isSidebarExpanded;
});
}
void _navigateToPage(String pageId) {
setState(() {
_currentPage = pageId;
});
// Handle page navigation here
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Navigating to: $pageId')),
);
}
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Scaffold(
backgroundColor: colorScheme.surface,
body: Row(
children: [
// Navigation Sidebar
NavigationSidebar(
isExpanded: _isSidebarExpanded,
onNavigate: _navigateToPage,
currentPage: _currentPage,
),
// Main Content Area
Expanded(
child: Column(
children: [
// AppBar
_buildAppBar(colorScheme),
// Main Content
Expanded(
child: _buildMainContent(colorScheme),
),
],
),
),
],
),
);
}
Widget _buildAppBar(ColorScheme colorScheme) {
return Container(
height: 70,
decoration: BoxDecoration(
color: colorScheme.surfaceContainerLow,
border: Border(
bottom: BorderSide(
color: colorScheme.outline.withOpacity(0.2),
width: 1,
),
),
),
child: Row(
children: [
// Toggle Sidebar Button
IconButton(
icon: Icon(
_isSidebarExpanded ? Iconsax.arrow_left_2 : Iconsax.arrow_right_3,
color: colorScheme.onSurface,
),
onPressed: _toggleSidebar,
tooltip: _isSidebarExpanded ? 'Collapse sidebar' : 'Expand sidebar',
),
const SizedBox(width: 12),
// Page Title
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
_getPageTitle(),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
Text(
'sovereign AI solutions',
style: TextStyle(
fontSize: 11,
color: colorScheme.onSurfaceVariant,
),
),
],
),
),
// Action Buttons
Container(
margin: const EdgeInsets.only(right: 8),
child: IconButton(
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: colorScheme.primary.withOpacity(0.1),
shape: BoxShape.circle,
),
child: Icon(Iconsax.notification, color: colorScheme.primary),
),
onPressed: () {},
),
),
Container(
margin: const EdgeInsets.only(right: 12),
child: IconButton(
icon: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: colorScheme.secondary.withOpacity(0.1),
shape: BoxShape.circle,
),
child: Icon(Iconsax.setting_2, color: colorScheme.secondary),
),
onPressed: () {},
),
),
],
),
);
}
String _getPageTitle() {
switch (_currentPage) {
case 'dashboard':
return 'Dashboard';
case 'architect':
return 'The Architect';
case 'agents':
return 'AI Agents';
case 'analytics':
return 'Analytics';
case 'tools':
return 'Tools';
case 'settings':
return 'Settings';
default:
return 'Svrnty Console';
}
}
Widget _buildMainContent(ColorScheme colorScheme) {
return LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
padding: EdgeInsets.all(_getPagePadding(constraints.maxWidth)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Page Title
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
colorScheme.primary.withOpacity(0.2),
colorScheme.secondary.withOpacity(0.15),
],
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: colorScheme.primary.withOpacity(0.5),
width: 1,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
color: colorScheme.primary,
borderRadius: BorderRadius.circular(6),
),
child: const Text(
'S',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
const SizedBox(width: 10),
Text(
'Svrnty Console',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
],
),
const SizedBox(height: 8),
Text(
'sovereign AI solutions • 30 October 2025',
style: TextStyle(
fontSize: 14,
color: colorScheme.onSurfaceVariant,
fontFamily: 'Montserrat',
),
),
],
),
),
const SizedBox(height: 28),
// Status Cards Grid
_buildResponsiveGrid(
constraints.maxWidth,
[
_buildStatusCard(
'Backend',
'Access Swagger',
colorScheme.primary,
Icons.api,
'Active',
),
_buildStatusCard(
'Frontend',
'UI Status',
colorScheme.primary,
Icons.web,
'Online',
),
_buildStatusCard(
'To-Do',
'Analytics Dashboard',
colorScheme.primary,
Icons.analytics_outlined,
'Running',
),
_buildStatusCard(
'Pull requests',
'Connection Pool',
colorScheme.secondary,
Icons.storage_outlined,
'Connected',
),
_buildStatusCard(
'Work Logs',
'View Recent Activity',
colorScheme.secondary,
Icons.receipt_long_outlined,
'Active',
),
_buildStatusCard(
'Mindbox',
'Metrics & Monitoring',
colorScheme.secondary,
Icons.speed_outlined,
'Normal',
),
],
),
const SizedBox(height: 32),
// Recent Activity Section
_buildSectionHeader('Recent Activity'),
const SizedBox(height: 16),
_buildActivityCard(
'PR request',
'Authentification_module.config is updated',
'2 minutes ago',
Icons.check_circle_outline,
colorScheme.primary,
),
const SizedBox(height: 12),
_buildActivityCard(
'Database Sync',
'Completed backup operation',
'3 hours 11 minutes ago',
Icons.cloud_done_outlined,
colorScheme.secondary,
),
const SizedBox(height: 12),
_buildActivityCard(
'The Archivist agent created',
'Modele configured and operational',
'3 days ago',
Icons.security_outlined,
colorScheme.secondary,
),
],
),
);
},
);
}
// Helper method: Get responsive padding based on screen width
double _getPagePadding(double width) {
if (width < 600) {
return 16.0; // Mobile
} else if (width < 1024) {
return 24.0; // Tablet
} else {
return 32.0; // Desktop
}
}
// Helper method: Build responsive grid
Widget _buildResponsiveGrid(double width, List<Widget> children) {
int crossAxisCount;
double childAspectRatio;
double spacing;
if (width < 600) {
// Mobile: 1 column
crossAxisCount = 1;
childAspectRatio = 1.8;
spacing = 12.0;
} else if (width < 900) {
// Tablet: 2 columns
crossAxisCount = 2;
childAspectRatio = 1.3;
spacing = 16.0;
} else if (width < 1200) {
// Small desktop: 3 columns
crossAxisCount = 3;
childAspectRatio = 1.1;
spacing = 20.0;
} else {
// Large desktop: 3 columns with more space
crossAxisCount = 3;
childAspectRatio = 1.3;
spacing = 24.0;
}
return GridView.count(
crossAxisCount: crossAxisCount,
childAspectRatio: childAspectRatio,
crossAxisSpacing: spacing,
mainAxisSpacing: spacing,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: children,
);
}
// Helper method: Build GetWidget-powered status card
Widget _buildStatusCard(
String title,
String subtitle,
Color color,
IconData icon,
String status,
) {
final colorScheme = Theme.of(context).colorScheme;
return FadeInUp(
duration: const Duration(milliseconds: 400),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
color.withOpacity(0.25),
color.withOpacity(0.12),
],
),
border: Border.all(
color: color.withOpacity(0.5),
width: 1.5,
),
),
child: Card(
elevation: 4,
color: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: InkWell(
onTap: () {
GFToast.showToast(
'$title tapped',
context,
toastPosition: GFToastPosition.BOTTOM,
textStyle: const TextStyle(fontSize: 14, color: Colors.white),
backgroundColor: color.withOpacity(0.9),
toastDuration: 2,
);
},
borderRadius: BorderRadius.circular(16),
child: Container(
decoration: BoxDecoration(
border: Border(
left: BorderSide(
color: color,
width: 4,
),
),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GFAvatar(
backgroundColor: color.withOpacity(0.3),
child: Icon(icon, size: 28, color: color),
radius: 26,
shape: GFAvatarShape.standard,
),
Container(
constraints: const BoxConstraints(minWidth: 100),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(20),
),
child: Center(
child: Text(
status,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
letterSpacing: 0.5,
),
),
),
),
],
),
const SizedBox(height: 16),
Text(
title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
letterSpacing: 0.3,
),
),
const SizedBox(height: 6),
Text(
subtitle,
style: TextStyle(
fontSize: 14,
color: colorScheme.onSurfaceVariant,
),
),
],
),
),
),
),
),
),
);
}
// Helper method: Build section header
Widget _buildSectionHeader(String title) {
final colorScheme = Theme.of(context).colorScheme;
return Row(
children: [
Container(
width: 4,
height: 24,
decoration: BoxDecoration(
color: colorScheme.primary,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(width: 12),
Text(
title,
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: colorScheme.onSurface,
),
),
],
);
}
// Helper method: Build GetWidget-powered activity card
Widget _buildActivityCard(
String title,
String description,
String time,
IconData icon,
Color color,
) {
final colorScheme = Theme.of(context).colorScheme;
return FadeInLeft(
duration: const Duration(milliseconds: 400),
child: Container(
margin: const EdgeInsets.only(bottom: 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: color.withOpacity(0.4),
width: 1.5,
),
),
child: Card(
elevation: 2,
child: ListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
leading: GFAvatar(
backgroundColor: color.withOpacity(0.25),
child: Icon(icon, color: color, size: 22),
radius: 22,
shape: GFAvatarShape.circle,
),
title: Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: colorScheme.onSurface,
letterSpacing: 0.2,
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
description,
style: TextStyle(
fontSize: 13,
color: colorScheme.onSurfaceVariant,
),
),
),
Container(
margin: const EdgeInsets.only(top: 8),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
decoration: BoxDecoration(
color: colorScheme.surfaceContainerHighest,
borderRadius: BorderRadius.circular(8),
),
child: Text(
time,
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.w500,
color: colorScheme.onSurfaceVariant,
),
),
),
],
),
),
),
),
);
}
}
+110
View File
@@ -0,0 +1,110 @@
import 'package:flutter/material.dart';
import 'console_landing_page.dart';
import 'theme.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return MaterialApp(
title: 'Svrnty Console - Sovereign AI Solutions',
theme: MaterialTheme(textTheme).light(),
darkTheme: MaterialTheme(textTheme).dark(),
themeMode: ThemeMode.dark,
home: const ConsoleLandingPage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// TRY THIS: Try changing the color here to a specific color (to
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
// change color while the other colors stay the same.
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
//
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
// action in the IDE, or press "p" in the console), to see the
// wireframe for each widget.
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
+408
View File
@@ -0,0 +1,408 @@
import "package:flutter/material.dart";
class MaterialTheme {
final TextTheme textTheme;
const MaterialTheme(this.textTheme);
// Svrnty Brand Colors - Light Theme
static ColorScheme lightScheme() {
return const ColorScheme(
brightness: Brightness.light,
primary: Color(0xffC44D58), // Svrnty Crimson Red
surfaceTint: Color(0xffC44D58),
onPrimary: Color(0xffffffff),
primaryContainer: Color(0xffffd8db),
onPrimaryContainer: Color(0xff8b3238),
secondary: Color(0xff475C6C), // Svrnty Slate Blue
onSecondary: Color(0xffffffff),
secondaryContainer: Color(0xffd1dce7),
onSecondaryContainer: Color(0xff2e3d4a),
tertiary: Color(0xff5a4a6c),
onTertiary: Color(0xffffffff),
tertiaryContainer: Color(0xffe0d3f2),
onTertiaryContainer: Color(0xff3d2f4d),
error: Color(0xffba1a1a),
onError: Color(0xffffffff),
errorContainer: Color(0xffffdad6),
onErrorContainer: Color(0xff93000a),
surface: Color(0xfffafafa),
onSurface: Color(0xff1a1c1e),
onSurfaceVariant: Color(0xff43474e),
outline: Color(0xff74777f),
outlineVariant: Color(0xffc4c6cf),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xff2f3033),
inversePrimary: Color(0xffffb3b9),
primaryFixed: Color(0xffffd8db),
onPrimaryFixed: Color(0xff410008),
primaryFixedDim: Color(0xffffb3b9),
onPrimaryFixedVariant: Color(0xff8b3238),
secondaryFixed: Color(0xffd1dce7),
onSecondaryFixed: Color(0xff0f1a24),
secondaryFixedDim: Color(0xffb5c0cb),
onSecondaryFixedVariant: Color(0xff2e3d4a),
tertiaryFixed: Color(0xffe0d3f2),
onTertiaryFixed: Color(0xff1f122f),
tertiaryFixedDim: Color(0xffc4b7d6),
onTertiaryFixedVariant: Color(0xff3d2f4d),
surfaceDim: Color(0xffdadcde),
surfaceBright: Color(0xfffafafa),
surfaceContainerLowest: Color(0xffffffff),
surfaceContainerLow: Color(0xfff4f5f7),
surfaceContainer: Color(0xffeef0f2),
surfaceContainerHigh: Color(0xffe8eaec),
surfaceContainerHighest: Color(0xffe2e4e7),
);
}
ThemeData light() {
return theme(lightScheme());
}
static ColorScheme lightMediumContrastScheme() {
return const ColorScheme(
brightness: Brightness.light,
primary: Color(0xff0d3665),
surfaceTint: Color(0xff3d5f90),
onPrimary: Color(0xffffffff),
primaryContainer: Color(0xff4d6ea0),
onPrimaryContainer: Color(0xffffffff),
secondary: Color(0xff2d3747),
onSecondary: Color(0xffffffff),
secondaryContainer: Color(0xff636d80),
onSecondaryContainer: Color(0xffffffff),
tertiary: Color(0xff442e4c),
onTertiary: Color(0xffffffff),
tertiaryContainer: Color(0xff7d6485),
onTertiaryContainer: Color(0xffffffff),
error: Color(0xff740006),
onError: Color(0xffffffff),
errorContainer: Color(0xffcf2c27),
onErrorContainer: Color(0xffffffff),
surface: Color(0xfff9f9ff),
onSurface: Color(0xff0f1116),
onSurfaceVariant: Color(0xff33363d),
outline: Color(0xff4f525a),
outlineVariant: Color(0xff6a6d75),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xff2e3035),
inversePrimary: Color(0xffa6c8ff),
primaryFixed: Color(0xff4d6ea0),
onPrimaryFixed: Color(0xffffffff),
primaryFixedDim: Color(0xff335686),
onPrimaryFixedVariant: Color(0xffffffff),
secondaryFixed: Color(0xff636d80),
onSecondaryFixed: Color(0xffffffff),
secondaryFixedDim: Color(0xff4b5567),
onSecondaryFixedVariant: Color(0xffffffff),
tertiaryFixed: Color(0xff7d6485),
onTertiaryFixed: Color(0xffffffff),
tertiaryFixedDim: Color(0xff644c6c),
onTertiaryFixedVariant: Color(0xffffffff),
surfaceDim: Color(0xffc5c6cd),
surfaceBright: Color(0xfff9f9ff),
surfaceContainerLowest: Color(0xffffffff),
surfaceContainerLow: Color(0xfff3f3fa),
surfaceContainer: Color(0xffe7e8ee),
surfaceContainerHigh: Color(0xffdcdce3),
surfaceContainerHighest: Color(0xffd0d1d8),
);
}
ThemeData lightMediumContrast() {
return theme(lightMediumContrastScheme());
}
static ColorScheme lightHighContrastScheme() {
return const ColorScheme(
brightness: Brightness.light,
primary: Color(0xff002c58),
surfaceTint: Color(0xff3d5f90),
onPrimary: Color(0xffffffff),
primaryContainer: Color(0xff264a79),
onPrimaryContainer: Color(0xffffffff),
secondary: Color(0xff232d3d),
onSecondary: Color(0xffffffff),
secondaryContainer: Color(0xff404a5b),
onSecondaryContainer: Color(0xffffffff),
tertiary: Color(0xff392441),
onTertiary: Color(0xffffffff),
tertiaryContainer: Color(0xff584160),
onTertiaryContainer: Color(0xffffffff),
error: Color(0xff600004),
onError: Color(0xffffffff),
errorContainer: Color(0xff98000a),
onErrorContainer: Color(0xffffffff),
surface: Color(0xfff9f9ff),
onSurface: Color(0xff000000),
onSurfaceVariant: Color(0xff000000),
outline: Color(0xff292c33),
outlineVariant: Color(0xff464951),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xff2e3035),
inversePrimary: Color(0xffa6c8ff),
primaryFixed: Color(0xff264a79),
onPrimaryFixed: Color(0xffffffff),
primaryFixedDim: Color(0xff063361),
onPrimaryFixedVariant: Color(0xffffffff),
secondaryFixed: Color(0xff404a5b),
onSecondaryFixed: Color(0xffffffff),
secondaryFixedDim: Color(0xff293343),
onSecondaryFixedVariant: Color(0xffffffff),
tertiaryFixed: Color(0xff584160),
onTertiaryFixed: Color(0xffffffff),
tertiaryFixedDim: Color(0xff402b48),
onTertiaryFixedVariant: Color(0xffffffff),
surfaceDim: Color(0xffb7b8bf),
surfaceBright: Color(0xfff9f9ff),
surfaceContainerLowest: Color(0xffffffff),
surfaceContainerLow: Color(0xfff0f0f7),
surfaceContainer: Color(0xffe1e2e9),
surfaceContainerHigh: Color(0xffd3d4da),
surfaceContainerHighest: Color(0xffc5c6cd),
);
}
ThemeData lightHighContrast() {
return theme(lightHighContrastScheme());
}
// Svrnty Brand Colors - Dark Theme (Bold & Saturated)
static ColorScheme darkScheme() {
return const ColorScheme(
brightness: Brightness.dark,
primary: Color(0xffF3574E), // Bold Svrnty Crimson Red (slightly desaturated)
surfaceTint: Color(0xffF3574E),
onPrimary: Color(0xffffffff),
primaryContainer: Color(0xffC44D58), // True brand crimson
onPrimaryContainer: Color(0xffffffff),
secondary: Color(0xff5A6F7D), // Rich Svrnty Slate Blue
onSecondary: Color(0xffffffff),
secondaryContainer: Color(0xff475C6C), // True brand slate
onSecondaryContainer: Color(0xffffffff),
tertiary: Color(0xffA78BBF), // Richer purple
onTertiary: Color(0xffffffff),
tertiaryContainer: Color(0xff8B6FA3),
onTertiaryContainer: Color(0xffffffff),
error: Color(0xffFF5449),
onError: Color(0xffffffff),
errorContainer: Color(0xffD32F2F),
onErrorContainer: Color(0xffffffff),
surface: Color(0xff1a1c1e), // Svrnty Dark Background
onSurface: Color(0xfff0f0f0),
onSurfaceVariant: Color(0xffc8cad0),
outline: Color(0xff8d9199),
outlineVariant: Color(0xff43474e),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xffe2e4e7),
inversePrimary: Color(0xffC44D58),
primaryFixed: Color(0xffFFD8DB),
onPrimaryFixed: Color(0xff2d0008),
primaryFixedDim: Color(0xffF3574E),
onPrimaryFixedVariant: Color(0xffffffff),
secondaryFixed: Color(0xffD1DCE7),
onSecondaryFixed: Color(0xff0f1a24),
secondaryFixedDim: Color(0xff5A6F7D),
onSecondaryFixedVariant: Color(0xffffffff),
tertiaryFixed: Color(0xffE0D3F2),
onTertiaryFixed: Color(0xff1f122f),
tertiaryFixedDim: Color(0xffA78BBF),
onTertiaryFixedVariant: Color(0xffffffff),
surfaceDim: Color(0xff1a1c1e),
surfaceBright: Color(0xff404244),
surfaceContainerLowest: Color(0xff0f1113),
surfaceContainerLow: Color(0xff1f2123),
surfaceContainer: Color(0xff23252a),
surfaceContainerHigh: Color(0xff2d2f35),
surfaceContainerHighest: Color(0xff383940),
);
}
ThemeData dark() {
return theme(darkScheme());
}
static ColorScheme darkMediumContrastScheme() {
return const ColorScheme(
brightness: Brightness.dark,
primary: Color(0xffcbddff),
surfaceTint: Color(0xffa6c8ff),
onPrimary: Color(0xff00264d),
primaryContainer: Color(0xff7192c6),
onPrimaryContainer: Color(0xff000000),
secondary: Color(0xffd3ddf2),
onSecondary: Color(0xff1c2636),
secondaryContainer: Color(0xff8791a5),
onSecondaryContainer: Color(0xff000000),
tertiary: Color(0xfff1d2f8),
onTertiary: Color(0xff321e3a),
tertiaryContainer: Color(0xffa387aa),
onTertiaryContainer: Color(0xff000000),
error: Color(0xffffd2cc),
onError: Color(0xff540003),
errorContainer: Color(0xffff5449),
onErrorContainer: Color(0xff000000),
surface: Color(0xff111318),
onSurface: Color(0xffffffff),
onSurfaceVariant: Color(0xffdadce5),
outline: Color(0xffafb2bb),
outlineVariant: Color(0xff8d9099),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xffe1e2e9),
inversePrimary: Color(0xff254978),
primaryFixed: Color(0xffd5e3ff),
onPrimaryFixed: Color(0xff001129),
primaryFixedDim: Color(0xffa6c8ff),
onPrimaryFixedVariant: Color(0xff0d3665),
secondaryFixed: Color(0xffd9e3f8),
onSecondaryFixed: Color(0xff071120),
secondaryFixedDim: Color(0xffbdc7dc),
onSecondaryFixedVariant: Color(0xff2d3747),
tertiaryFixed: Color(0xfff8d8ff),
onTertiaryFixed: Color(0xff1c0924),
tertiaryFixedDim: Color(0xffdbbde2),
onTertiaryFixedVariant: Color(0xff442e4c),
surfaceDim: Color(0xff111318),
surfaceBright: Color(0xff42444a),
surfaceContainerLowest: Color(0xff05070c),
surfaceContainerLow: Color(0xff1b1e22),
surfaceContainer: Color(0xff26282d),
surfaceContainerHigh: Color(0xff303338),
surfaceContainerHighest: Color(0xff3b3e43),
);
}
ThemeData darkMediumContrast() {
return theme(darkMediumContrastScheme());
}
static ColorScheme darkHighContrastScheme() {
return const ColorScheme(
brightness: Brightness.dark,
primary: Color(0xffeaf0ff),
surfaceTint: Color(0xffa6c8ff),
onPrimary: Color(0xff000000),
primaryContainer: Color(0xffa3c4fb),
onPrimaryContainer: Color(0xff000b1e),
secondary: Color(0xffeaf0ff),
onSecondary: Color(0xff000000),
secondaryContainer: Color(0xffb9c3d8),
onSecondaryContainer: Color(0xff030b1a),
tertiary: Color(0xfffeeaff),
onTertiary: Color(0xff000000),
tertiaryContainer: Color(0xffd7b9de),
onTertiaryContainer: Color(0xff16041e),
error: Color(0xffffece9),
onError: Color(0xff000000),
errorContainer: Color(0xffffaea4),
onErrorContainer: Color(0xff220001),
surface: Color(0xff111318),
onSurface: Color(0xffffffff),
onSurfaceVariant: Color(0xffffffff),
outline: Color(0xffedf0f9),
outlineVariant: Color(0xffc0c2cb),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xffe1e2e9),
inversePrimary: Color(0xff254978),
primaryFixed: Color(0xffd5e3ff),
onPrimaryFixed: Color(0xff000000),
primaryFixedDim: Color(0xffa6c8ff),
onPrimaryFixedVariant: Color(0xff001129),
secondaryFixed: Color(0xffd9e3f8),
onSecondaryFixed: Color(0xff000000),
secondaryFixedDim: Color(0xffbdc7dc),
onSecondaryFixedVariant: Color(0xff071120),
tertiaryFixed: Color(0xfff8d8ff),
onTertiaryFixed: Color(0xff000000),
tertiaryFixedDim: Color(0xffdbbde2),
onTertiaryFixedVariant: Color(0xff1c0924),
surfaceDim: Color(0xff111318),
surfaceBright: Color(0xff4e5055),
surfaceContainerLowest: Color(0xff000000),
surfaceContainerLow: Color(0xff1d2024),
surfaceContainer: Color(0xff2e3035),
surfaceContainerHigh: Color(0xff393b41),
surfaceContainerHighest: Color(0xff45474c),
);
}
ThemeData darkHighContrast() {
return theme(darkHighContrastScheme());
}
ThemeData theme(ColorScheme colorScheme) => ThemeData(
useMaterial3: true,
brightness: colorScheme.brightness,
colorScheme: colorScheme,
textTheme: const TextTheme(
displayLarge: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.bold),
displayMedium: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.bold),
displaySmall: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.bold),
headlineLarge: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w600),
headlineMedium: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w600),
headlineSmall: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w600),
titleLarge: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w600),
titleMedium: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w500),
titleSmall: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w500),
bodyLarge: TextStyle(fontFamily: 'Montserrat'),
bodyMedium: TextStyle(fontFamily: 'Montserrat'),
bodySmall: TextStyle(fontFamily: 'Montserrat'),
labelLarge: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w500),
labelMedium: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w500),
labelSmall: TextStyle(fontFamily: 'Montserrat', fontWeight: FontWeight.w500),
).apply(
bodyColor: colorScheme.onSurface,
displayColor: colorScheme.onSurface,
),
fontFamily: 'Montserrat',
scaffoldBackgroundColor: colorScheme.surface,
canvasColor: colorScheme.surface,
);
List<ExtendedColor> get extendedColors => [
];
}
class ExtendedColor {
final Color seed, value;
final ColorFamily light;
final ColorFamily lightHighContrast;
final ColorFamily lightMediumContrast;
final ColorFamily dark;
final ColorFamily darkHighContrast;
final ColorFamily darkMediumContrast;
const ExtendedColor({
required this.seed,
required this.value,
required this.light,
required this.lightHighContrast,
required this.lightMediumContrast,
required this.dark,
required this.darkHighContrast,
required this.darkMediumContrast,
});
}
class ColorFamily {
const ColorFamily({
required this.color,
required this.onColor,
required this.colorContainer,
required this.onColorContainer,
});
final Color color;
final Color onColor;
final Color colorContainer;
final Color onColorContainer;
}