FlutterArtist Theme Design Tokens Architecture
When building a scalable UI system, managing styles through hard-coded values (colors, spacing, radius, etc.) quickly becomes difficult to maintain. To address this, FlutterArtist Theme adopts the Design Tokens approach — an abstraction layer that organizes all design values into structured and reusable entities.
Instead of accessing ThemeData directly or defining styles ad hoc within widgets, the system is standardized through FaXxxTokens classes. Each token group represents a specific aspect of the UI, including colors, typography, spacing, layout, components, and motion.

In this document, we will go through each FaXxxTokens class to understand its role, structure, and practical usage.
No ADS
1. FaTheme
To create a custom theme, you need to extend the FaTheme class and implement its core components. Here is the basic skeleton:
CustomFaTheme
class CustomFaTheme extends FaTheme {
@override
String get name => "Artist Midnight";
@override
IconData get icon => Icons.dark_mode_outlined;
@override
Color get seedColor => const Color(0xFF1A237E);
@override
Brightness get brightness => Brightness.dark;
@override
String? get fontFamily => 'Inter';
@override
FaThemeTokens createThemeTokens() {
// ....
}
} name
The unique identifier for the Theme. Avoid duplicates; if a conflict occurs, the newly registered Theme will overwrite the existing one in FaThemeHub.
icon
The visual icon representing the Theme, making it easy for users to identify and select within the selection Dialog.
fontFamily
The primary font family applied consistently across the entire system.
seedColor
The "seed" that allows FlutterArtist (via Material 3 algorithms) to automatically generate a harmonious ColorScheme. Instead of manually defining dozens of colors, the system handles the rest, ensuring standard contrast and aesthetic appeal.
brightness
brightness - is more than just swapping background colors. It acts as a "suggestion" for FlutterArtist to handle contrast. When set to Brightness.dark, the system understands that surfaces will have dark tones and automatically calculates foreground colors (onSurface, onPrimary) to lighter shades, ensuring content remains crisp and legible.
createThemeTokens()
The createThemeTokens() method is where you define the "DNA" of your UI. The beauty of this system is that you don't have to redefine everything from scratch. You can leverage the rulebook automatically generated from the seedColor and simply override specific details that don't meet your needs. These targeted changes apply only to those elements, without disrupting the overall consistency of the system.
tokens
Provides access to the design tokens you've defined via the createThemeTokens() method.
2. FaThemeTokens
If FaTheme is the master plan, then FaThemeTokens is the detailed technical specification. This class extends ThemeExtension, a powerful Flutter feature that allows us to extend the standard ThemeData without breaking the framework's core structure.
FaThemeTokens acts as a massive "container," unifying all aspects of the design language — from colors and spacing to motion effects — into a single entity. This ensures UI management remains centralized, consistent, and incredibly easy when passing theme data down the widget tree via BuildContext.
FaThemeTokens
class FaThemeTokens extends ThemeExtension<FaThemeTokens> {
final FaColorTokens colors;
final FaSpacingTokens spacing;
final FaRadiusTokens radius;
final FaElevationTokens elevation;
final FaTypographyTokens typography;
final FaComponentTokens components;
final FaLayoutTokens layout;
final FaMotionTokens motion;
FaThemeTokens({
required this.colors,
required this.spacing,
required this.radius,
required this.elevation,
required this.typography,
required this.components,
required this.layout,
required this.motion,
});
// ...
} 
No ADS
colors (FaColorTokens):
Manages the color system. Use FaColorTokens.fromSeed(seedColor) for auto-generation, then use .copyWith() to override only specific colors like primary or error.
spacing (FaSpacingTokens):
Defines standard spacing (padding, margin), ensuring a consistent whitespace "rhythm" throughout the UI.
radius (FaRadiusTokens):
Governs corner radius. Change it once, and the entire app becomes "soft" or "sharp" instantly.
elevation (FaElevationTokens):
Manages shadows and widget layering, creating a sense of spatial depth.
typography (FaTypographyTokens):
A collection of TextStyle(s) for title, body, and caption.
components (FaComponentTokens):
Specific tweaks for individual widgets like Button(s) or Card(s).
layout (FaLayoutTokens):
Defines layout parameters like Sidebar width or Max Content Width.
motion (FaMotionTokens):
Defines the duration and curves of motion effects.
3. FaColorTokens
If FaThemeTokens is the brain, then FaColorTokens is the eyes of the application. It is the central hub for all color definitions, ranging from vibrant primary hues to the subtle shades of surfaces and borders.
The key feature is that the properties in this class are fully compatible with and designed to override standard Flutter Theme properties. We preserve the original meaning and intent of each color to keep things familiar, while providing much more powerful customization capabilities.
FaColorTokens
class FaColorTokens {
final Brightness brightness;
final Color? divider;
final Color primary;
final Color onPrimary;
final Color secondary;
final Color onSecondary;
final Color error;
final Color onError;
final Color background;
final Color surface;
final Color onSurface;
final Color onSurfaceVariant;
final Color surfaceContainerLowest;
final Color surfaceContainerLow;
final Color surfaceContainer;
final Color surfaceContainerHigh;
final Color surfaceContainerHighest;
final Color textPrimary;
final Color textSecondary;
final Color border;
final Color outlineVariant;
final Color tertiary;
final Color onTertiary;
final Color outline;
final Color shadow;
final Color scrim;
final Color inverseSurface;
final Color onInverseSurface;
final Color inversePrimary;
const FaColorTokens({
required this.brightness,
required this.primary,
required this.onPrimary,
// ...
});
factory FaColorTokens.fromSeed(Color seed) {
final scheme = ColorScheme.fromSeed(seedColor: seed);
return FaColorTokens(
brightness: scheme.brightness,
primary: scheme.primary,
onPrimary: scheme.onPrimary,
// ...
);
}
}Understanding primary & onPrimary
To help you get started, let's look at the two "main characters" that appear most frequently:
primary:
The main brand color. It is used for key components like primary action buttons, selected states, or prominent toolbars.
onPrimary:
The color for content (text or icons) displayed on top of the primary color. For example, if your button is blue (primary), the text inside should be white (onPrimary) to ensure perfect contrast.
No ADS
Don't Worry!
The great thing is, no matter how much you customize within FaColorTokens, you can still access these colors using the standard Flutter Theme.of(context) call. The FlutterArtist system ensures all your changes are perfectly synced with the standard ColorScheme.
// Standard way to access colors
final Color primaryColor = Theme.of(context).colorScheme.primary;
final Color textColorOnPrimary = Theme.of(context).colorScheme.onPrimary;
// Everything works perfectly with your custom overrides! 4. FaTypographyTokens
FaTypographyTokens acts as a powerful override filter for the typography system. The beauty of this class is its "optional" nature: you don't need to redefine all 15 Material Design styles. If you want to change a specific style, simply provide that property with a non-null value. Anything left null will be automatically filled by FlutterArtist using Material 3 default standards.
FaTypographyTokens
class FaTypographyTokens {
// --- DISPLAY ---
final TextStyle? displayLarge;
final TextStyle? displayMedium;
final TextStyle? displaySmall;
// --- HEADLINE ---
final TextStyle? headlineLarge;
final TextStyle? headlineMedium;
final TextStyle? headlineSmall;
// --- TITLE
final TextStyle? titleLarge;
final TextStyle? titleMedium;
final TextStyle? titleSmall;
// --- BODY
final TextStyle? bodyLarge;
final TextStyle? bodyMedium;
final TextStyle? bodySmall;
// --- LABEL ---
final TextStyle? labelLarge;
final TextStyle? labelMedium;
final TextStyle? labelSmall;
} Traditional Access
The great thing is that all your customizations in FaTypographyTokens are directly synced into Flutter's TextTheme via FaThemeFactory. This means you can still use the familiar Theme.of(context) call without changing your coding habits
// Standard Flutter way to access your custom styles
Text(
"Hello FlutterArtist",
style: Theme.of(context).textTheme.titleLarge,
);No ADS
Typography Reference Table
Below are the attribute groups you can override in FaTypographyTokens:
display(Large/Medium/Small) | Ultra-large text or numbers, used to create a strong visual impact on the screen. |
headline(Large/Medium/Small) | Main titles for pages or critical content sections. |
title(Large/Medium/Small) | Titles for Widgets, Dialogs, or list items. |
body(Large/Medium/Small) | The core of the content, used for all detailed informational text. |
label(Large/Medium/Small) | Labels for buttons, captions, or input field labels. |
In Flutter, although there are up to 15 predefined text styles (TextStyle), in practice only a few are used most frequently.
titleMedium:
Commonly used for Card titles, Dialog headers, or list items. It’s not as large as a headline, but still prominent enough for users to recognize it as a title.
bodyMedium:
Suitable for descriptions, article content, or user data. It is optimized for long reading sessions without causing eye strain.
labelLarge:
Typically used for buttons or short labels that need clarity. It often has a stronger font weight to draw attention to actions.
5. FaButtonTokens
While colors and typography create the look, FaButtonTokens defines the feel and consistency of buttons across the entire system. Instead of having inconsistent styles, you can set a common "standard" for height and border radius for all buttons in your app.
FaButtonTokens
class FaButtonTokens {
final double height;
final double radius;
const FaButtonTokens({this.height = 40, this.radius = 8});
}A crucial point to note: Unlike FaColorTokens or FaTypographyTokens, which are mapped to ThemeData to override default Flutter values, FaButtonTokens is a completely independent Extension.
This means you cannot access these parameters via the traditional Theme.of(context). Instead, you will use FlutterArtist's "specialty": context.faTokens.
Why do we do this? Because we want to keep Flutter's ThemeData as clean as possible, while providing you with a shorter, more intuitive path to fetch custom parameters that are not available in standard Flutter.
ElevatedButton
// The FlutterArtist way
ElevatedButton(
style: ElevatedButton.styleFrom(
minimumSize: Size(0, context.faTokens.components.button.height),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(context.faTokens.components.button.radius),
),
),
onPressed: () {},
child: const Text("Click Me"),
)6. FaCardTokens
While Buttons emphasize actions, Card is the "home" for content. FaCardTokens defines how information blocks are wrapped and presented. Instead of manually calculating padding or border radius for every frame, you simply set a common standard to create a visual rhythm across your entire UI.
FaCardTokens
class FaCardTokens {
final double radius;
final double padding;
const FaCardTokens({this.radius = 12, this.padding = 16});
}Similar to its sibling FaButtonTokens, FaCardTokens is also an independent Extension. It doesn't blindly override Flutter's default CardTheme.
// Implementing a perfectly standardized Card
Container(
padding: EdgeInsets.all(context.faTokens.components.card.padding),
decoration: BoxDecoration(
color: context.faTokens.colors.surface,
borderRadius: BorderRadius.circular(context.faTokens.components.card.radius),
boxShadow: context.faTokens.shortcut.cardShadows,
),
child: const Text("Artist Content"),
)7. FaComponentTokens
FaComponentTokens is an aggregate class used to manage design tokens at the component level within a UI system.
FaComponentTokens
class FaComponentTokens {
final FaButtonTokens button;
final FaCardTokens card;
const FaComponentTokens({
this.button = const FaButtonTokens(),
this.card = const FaCardTokens(),
});
}The structure of FaComponentTokens includes sub-token groups such as FaButtonTokens and FaCardTokens, each representing the visual configuration of a specific component type.
8. FaLayoutTokens
FaLayoutTokens defines all design tokens related to layout within the UI system.
This class is designed to group layout-related values into two main parts: metrics and colors, ensuring a clear separation between structural layout and visual styling.
FaLayoutTokens
class FaLayoutTokens {
final FaLayoutMetricsTokens metrics;
final FaLayoutColorTokens colors;
const FaLayoutTokens({
this.metrics = const FaLayoutMetricsTokens(),
required this.colors,
});
}9. FaLayoutColorTokens
FaLayoutColorTokens defines color tokens specifically for layout regions such as sidebar and topbar.
FaLayoutColorTokens
class FaLayoutColorTokens {
final Color sidebarSurface;
final Color onSidebarSurface;
final Color topbarSurface;
final Color onTopbarSurface;
const FaLayoutColorTokens({
required this.sidebarSurface,
required this.onSidebarSurface,
required this.topbarSurface,
required this.onTopbarSurface,
});
factory FaLayoutColorTokens.fromColorTokens(FaColorTokens colors) {
return FaLayoutColorTokens(
sidebarSurface: colors.surfaceContainerLow,
onSidebarSurface: colors.onSurface,
topbarSurface: colors.surface,
onTopbarSurface: colors.onSurface,
);
}
}Unlike a global color palette, this class is semantic, mapping colors to specific UI regions to ensure design consistency.
Example
// Applying to a custom Sidebar
Container(
color: context.faTokens.layout.colors.sidebarSurface,
child: Icon(
Icons.menu,
color: context.faTokens.layout.colors.onSidebarSurface,
),
)No ADS
sidebarSurface | Background color of the sidebar. Usually uses a darker or contrasting tone to create depth. |
onSidebarSurface | Color for text and icons on the Sidebar, ensuring they are always legible. |
topbarSurface | Background color for the top toolbar. FlutterArtist uses this to configure the AppBarTheme. |
onTopbarSurface | The color for titles and action buttons on the Topbar. |
10. FaLayoutMetricsTokens
FaLayoutMetricsTokens defines dimensional and constraint-related layout values. These values directly affect how layout is arranged on the screen.
// Setting Sidebar width dynamically from Tokens
SizedBox(
width: context.faTokens.layout.metrics.sidebarWidth,
child: const AppSidebar(),
)
// Applying max width for web layouts
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: context.faTokens.layout.metrics.contentMaxWidth ?? double.infinity,
),
child: const MainFeed(),
)sidebarWidth | Governs the width of the side navigation bar. Ensures the Sidebar maintains a precise size across all screens. |
contentMaxWidth | Limits the width of the primary content (typically for large screens). Prevents overly long lines of text that hinder readability. |
11. FaMotionTokens
A static interface often feels rigid. FaMotionTokens exists to manage animations, defining the speed and rhythm of visual feedback. Instead of using random numbers for durations or scattered animation curves, this class helps you organize them into a single standard.
FaMotionTokens
class FaMotionTokens {
final Duration fast;
final Duration normal;
final Duration slow;
final Curve standard;
final Curve emphasized;
const FaMotionTokens({
this.fast = const Duration(milliseconds: 120),
this.normal = const Duration(milliseconds: 220),
this.slow = const Duration(milliseconds: 360),
this.standard = Curves.easeOut,
this.emphasized = Curves.easeInOut,
});
}Please note that FaMotionTokens is a completely supplementary Extension. In standard Flutter, there is no specific place within ThemeData to centrally store shared Duration(s) or Curve(s) for the entire app.
Example
// Implementing a smooth animated container
AnimatedContainer(
duration: context.faTokens.motion.normal,
curve: context.faTokens.motion.standard,
color: isSelected
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.surface,
child: const MyWidget(),
)No ADS
12. FaSpacingTokens
FaSpacingTokens defines the standard spacing system used throughout the UI. This class provides a set of standardized spacing values to ensure consistency in layout and visual rhythm across components.
FaSpacingTokens
class FaSpacingTokens {
final double xs; // Extra S
final double sm;
final double md;
final double lg;
final double xl;
const FaSpacingTokens({
this.xs = 4,
this.sm = 8,
this.md = 16,
this.lg = 24,
this.xl = 32,
});
}xs (Extra Small) | Tiny gaps, used for close details like an icon with small text. |
sm (Small) | Small gaps, typically used between elements within the same content group. |
md (Medium) | The standard gap, used for Card padding or spacing between major content blocks. |
lg (Large) | Large gaps, used to separate major page sections or create "breathing room." |
xl (Extra Large) | Very large gaps, used for outer margins or layouts requiring extreme minimalism. |
Example
// Using spacing tokens for a consistent layout
Column(
children: [
Text("Title", style: context.faTokens.shortcut.titleMedium),
SizedBox(height: context.faTokens.spacing.sm), // Gap of 8px
Text("Content text...", style: context.faTokens.shortcut.bodyMedium),
Padding(
padding: EdgeInsets.all(context.faTokens.spacing.md), // Padding 16px
child: const MyActionCard(),
),
],
)13. FaRadiusTokens
Corner radius is a key factor in determining a UI's "personality". FaRadiusTokens provides standardized rounding levels, ensuring all components—from Button(s) and Card(s) to Input Fields (TextField)—maintain aesthetic consistency.
FaRadiusTokens
class FaRadiusTokens {
final double sm; // Small (e.g., 4px)
final double md; // Medium (e.g., 8px)
final double lg; // Large (e.g., 12px)
final double xl; // Extra Large (e.g., 16px)
const FaRadiusTokens({this.sm = 4, this.md = 8, this.lg = 12, this.xl = 16});
// Default value used for general components
double get borderRadius => md;
}The borderRadius getter provides a default value (md) for cases where a specific level is not required. This helps reduce repetition when most components share the same radius value.
Example
// Applying radius tokens for a customized container
Container(
decoration: BoxDecoration(
color: context.faTokens.colors.surface,
// Using the 'large' radius for a softer look
borderRadius: BorderRadius.circular(context.faTokens.radius.lg),
),
child: const MyWidget(),
)No ADS
sm (Small) | Slight rounding, typically used for Checkboxes or small, delicate elements. |
md (Medium) | The default standard, used for Buttons and Input Fields. Creates a balanced feel. |
lg (Large) | Large rounding, ideal for Cards or primary content containers. |
xl (Extra Large) | Extra large rounding, used for Modal Bottom Sheets or ultra-modern designs. |
14. FaElevationTokens
FaElevationTokens defines the elevation system used in the UI to create depth and hierarchy between components. By standardizing elevation levels, this class defines how components “rise” above the surface and interact with light (shadows).
FaElevationTokens
class FaElevationTokens {
final double level1;
final double level2;
final double level3;
const FaElevationTokens({this.level1 = 1, this.level2 = 3, this.level3 = 6});
double get buttonElevation => level2;
double get defaultValue => level2;
}Example
// Using elevation tokens for a floating effect
Material(
elevation: context.faTokens.elevation.level3, // High elevation for a dialog
borderRadius: BorderRadius.circular(context.faTokens.radius.lg),
child: const MyDialogContent(),
)level1 | The lowest elevation, creating a subtle shadow border to delicately separate objects from the background. |
level2 | The standard level, used for interactive components like Button(s) or selected Card(s). |
level3 | High elevation, used for components requiring absolute focus, such as FloatingActionButton(s) or Dialog(s). |
No ADS
FlutterArtist
- Basic concepts in Flutter Artist
- FlutterArtist Block ex1
- FlutterArtist Filter Example
- FlutterArtist FilterModel MultiOptFilterCriterion ex1
- FlutterArtist FilterInput Example 1
- FlutterArtist Form ex1
- The idea of designing filter models in FlutterArtist
- FlutterArtist FormModel.patchFormFields() Ex1
- FlutterArtist BlockQuickItemUpdateAction Example
- FlutterArtist BlockNumberPagination Ex1
- FlutterArtist GridView Infinite Scroll Example
- FlutterArtist BlockQuickMultiItemCreationAction Example
- FlutterArtist ListView Infinite Scroll Pagination Example
- FlutterArtist Pagination
- FlutterArtist Sort DropdownSortPanel Example
- FlutterArtist Dio
- FlutterArtist BlockBackendAction Example
- FlutterArtist BackgroundWebDownloadAction Example
- FlutterArtist StorageBackendAction ex1
- FlutterArtist Block External Shelf Event Example
- FlutterArtist Filter FormBuilderMultiDropDown Ex1
- FlutterArtist Master-detail Blocks ex1
- FlutterArtist Scalar ex1
- FlutterArtist Pagination Davi table Infinite Scroll Ex1
- FlutterArtist Filter Tree FormBuilderField ex1
- FlutterArtist Filter FormBuilderRadioGroup ex1
- FlutterArtist Form Parent-child MultiOptFormProp ex1
- FlutterArtist Manual Sorting ReorderableGridView Example
- FlutterArtist Manual Sorting ReorderableListView
- FlutterArtist Scalar External Shelf Event Example
- FlutterArtist Code Flow Viewer
- FlutterArtist Log Viewer
- FlutterArtist config
- FlutterArtist StorageStructure
- FlutterArtist Debug Storage Viewer
- FlutterArtist DebugMenu
- FlutterArtist Debug UI Components Viewer
- FlutterArtist Debug Shelf Structure Viewer
- FlutterArtist Context Provider Views
- FlutterArtist FilterModelStructure ex1
- FlutterArtist FilterModelStructure ex2
- FlutterArtist FilterModelStructure ex3
- FlutterArtist Internal Shelf Event ex1
- FlutterArtist Deferring External Shelf Events Example
- FlutterArtist DropdownSortPanel
- Overview of FlutterArtist Theme
- FlutterArtist Theme Design Tokens Architecture
- FlutterArtist Themes FaColorUtils
Show More