| name | avalonia-pro-max/design-system |
| description | Use when establishing or refactoring an Avalonia app's design system — semantic color tokens, theme-variant dictionaries (light/dark), typography scale, spacing rhythm, radius and elevation tokens. Produces production-ready Resources/Tokens.axaml. |
Design System for Avalonia
Goal
A design system in Avalonia is a set of named resources (colors, brushes, fonts, doubles, thicknesses) that:
- Live in
ResourceDictionary files merged into App.axaml.
- Are referenced via
{DynamicResource Name} in views — never hard-coded hex/numbers.
- Are split by theme variant (Light/Dark) so the entire UI re-themes instantly.
- Follow a 3-layer naming model: primitive → semantic → component.
3-Layer Token Model
Layer 1 — Primitives (raw values, never used in views)
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Color x:Key="Slate50">#F8FAFC</Color>
<Color x:Key="Slate100">#F1F5F9</Color>
<Color x:Key="Slate200">#E2E8F0</Color>
<Color x:Key="Slate500">#64748B</Color>
<Color x:Key="Slate700">#334155</Color>
<Color x:Key="Slate900">#0F172A</Color>
<Color x:Key="Slate950">#020617</Color>
<Color x:Key="Blue500">#3B82F6</Color>
<Color x:Key="Blue600">#2563EB</Color>
<Color x:Key="Blue700">#1D4ED8</Color>
<Color x:Key="Red500">#EF4444</Color>
<Color x:Key="Green500">#22C55E</Color>
<Color x:Key="Amber500">#F59E0B</Color>
</ResourceDictionary>
Layer 2 — Semantic tokens (theme-variant aware)
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="avares://MyApp/Resources/Primitives.axaml"/>
</ResourceDictionary.MergedDictionaries>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="SurfaceBackgroundBrush" Color="{StaticResource Slate50}"/>
<SolidColorBrush x:Key="SurfaceBrush" Color="#FFFFFF"/>
<SolidColorBrush x:Key="SurfaceElevatedBrush" Color="#FFFFFF"/>
<SolidColorBrush x:Key="SurfaceMutedBrush" Color="{StaticResource Slate100}"/>
<SolidColorBrush x:Key="TextPrimaryBrush" Color="{StaticResource Slate900}"/>
<SolidColorBrush x:Key="TextSecondaryBrush" Color="{StaticResource Slate700}"/>
<SolidColorBrush x:Key="TextMutedBrush" Color="{StaticResource Slate500}"/>
<SolidColorBrush x:Key="TextOnAccentBrush" Color="#FFFFFF"/>
<SolidColorBrush x:Key="BorderBrush" Color="{StaticResource Slate200}"/>
<SolidColorBrush x:Key="BorderStrongBrush" Color="{StaticResource Slate500}"/>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource Blue600}"/>
<SolidColorBrush x:Key="DangerBrush" Color="{StaticResource Red500}"/>
<SolidColorBrush x:Key="SuccessBrush" Color="{StaticResource Green500}"/>
<SolidColorBrush x:Key="WarningBrush" Color="{StaticResource Amber500}"/>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="SurfaceBackgroundBrush" Color="{StaticResource Slate950}"/>
<SolidColorBrush x:Key="SurfaceBrush" Color="{StaticResource Slate900}"/>
<SolidColorBrush x:Key="SurfaceElevatedBrush" Color="#1E293B"/>
<SolidColorBrush x:Key="SurfaceMutedBrush" Color="#1E293B"/>
<SolidColorBrush x:Key="TextPrimaryBrush" Color="{StaticResource Slate50}"/>
<SolidColorBrush x:Key="TextSecondaryBrush" Color="{StaticResource Slate200}"/>
<SolidColorBrush x:Key="TextMutedBrush" Color="{StaticResource Slate500}"/>
<SolidColorBrush x:Key="TextOnAccentBrush" Color="#FFFFFF"/>
<SolidColorBrush x:Key="BorderBrush" Color="#1E293B"/>
<SolidColorBrush x:Key="BorderStrongBrush" Color="{StaticResource Slate700}"/>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource Blue500}"/>
<SolidColorBrush x:Key="DangerBrush" Color="#F87171"/>
<SolidColorBrush x:Key="SuccessBrush" Color="#4ADE80"/>
<SolidColorBrush x:Key="WarningBrush" Color="#FBBF24"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
Layer 3 — Component-specific (optional)
<SolidColorBrush x:Key="ButtonPrimaryBackgroundBrush" Color="{DynamicResource AccentBrush}"/>
<SolidColorBrush x:Key="CardBackgroundBrush" Color="{DynamicResource SurfaceElevatedBrush}"/>
Rule: Views use Layer 2/3 only. Never reference Slate900 directly from a view.
Typography Scale
Choose ONE scale and stick to it. Modular scale 1.25 (Major Third) is a safe default.
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="using:System">
<FontFamily x:Key="FontSans">avares://MyApp/Assets/Fonts/Inter-Variable.ttf#Inter</FontFamily>
<FontFamily x:Key="FontMono">avares://MyApp/Assets/Fonts/JetBrainsMono-Variable.ttf#JetBrains Mono</FontFamily>
<sys:Double x:Key="FontSizeXs">12</sys:Double>
<sys:Double x:Key="FontSizeSm">13</sys:Double>
<sys:Double x:Key="FontSizeBase">14</sys:Double>
<sys:Double x:Key="FontSizeMd">16</sys:Double>
<sys:Double x:Key="FontSizeLg">18</sys:Double>
<sys:Double x:Key="FontSizeXl">22</sys:Double>
<sys:Double x:Key="FontSize2xl">28</sys:Double>
<sys:Double x:Key="FontSize3xl">36</sys:Double>
<sys:Double x:Key="FontSize4xl">48</sys:Double>
<sys:Double x:Key="LineHeightTight">1.2</sys:Double>
<sys:Double x:Key="LineHeightNormal">1.5</sys:Double>
<sys:Double x:Key="LineHeightRelaxed">1.65</sys:Double>
</ResourceDictionary>
Type ramp Styles:
<Style Selector="TextBlock.h1">
<Setter Property="FontFamily" Value="{StaticResource FontSans}"/>
<Setter Property="FontSize" Value="{StaticResource FontSize3xl}"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="LineHeight" Value="44"/>
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}"/>
</Style>
<Style Selector="TextBlock.body">
<Setter Property="FontSize" Value="{StaticResource FontSizeBase}"/>
<Setter Property="LineHeight" Value="21"/>
<Setter Property="Foreground" Value="{DynamicResource TextPrimaryBrush}"/>
</Style>
<Style Selector="TextBlock.muted">
<Setter Property="Foreground" Value="{DynamicResource TextMutedBrush}"/>
</Style>
Usage: <TextBlock Classes="h1">Dashboard</TextBlock>
Variable fonts
Avalonia 11+ supports variable fonts (.ttf/.otf with axes). Inter and JetBrains Mono variable versions cover most needs at one file each.
Spacing Scale (4 / 8 rhythm)
<sys:Double x:Key="Space0">0</sys:Double>
<sys:Double x:Key="Space1">4</sys:Double>
<sys:Double x:Key="Space2">8</sys:Double>
<sys:Double x:Key="Space3">12</sys:Double>
<sys:Double x:Key="Space4">16</sys:Double>
<sys:Double x:Key="Space5">20</sys:Double>
<sys:Double x:Key="Space6">24</sys:Double>
<sys:Double x:Key="Space8">32</sys:Double>
<sys:Double x:Key="Space10">40</sys:Double>
<sys:Double x:Key="Space12">48</sys:Double>
<sys:Double x:Key="Space16">64</sys:Double>
For Margin/Padding use Thickness:
<Thickness x:Key="PaddingCard">20</Thickness>
<Thickness x:Key="PaddingCardCompact">12</Thickness>
<Thickness x:Key="PaddingPage">24,16</Thickness>
Padding="{StaticResource PaddingCard}".
Radius & Elevation
<CornerRadius x:Key="RadiusSm">4</CornerRadius>
<CornerRadius x:Key="RadiusMd">8</CornerRadius>
<CornerRadius x:Key="RadiusLg">12</CornerRadius>
<CornerRadius x:Key="RadiusXl">16</CornerRadius>
<CornerRadius x:Key="RadiusFull">9999</CornerRadius>
<BoxShadows x:Key="ShadowSm">0 1 2 0 #19000000</BoxShadows>
<BoxShadows x:Key="ShadowMd">0 4 8 -2 #26000000, 0 2 4 -2 #1A000000</BoxShadows>
<BoxShadows x:Key="ShadowLg">0 12 24 -8 #33000000, 0 4 8 -4 #1F000000</BoxShadows>
Apply to Border:
<Border Background="{DynamicResource SurfaceBrush}"
CornerRadius="{StaticResource RadiusLg}"
BoxShadow="{StaticResource ShadowMd}"
Padding="{StaticResource PaddingCard}">
</Border>
For dark mode, halve shadow opacity in the dark theme dictionary (or use a subtle 1px border instead).
Wire Everything Up
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.App"
RequestedThemeVariant="Default">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="avares://MyApp/Resources/Primitives.axaml"/>
<ResourceInclude Source="avares://MyApp/Resources/Semantic.axaml"/>
<ResourceInclude Source="avares://MyApp/Resources/Typography.axaml"/>
<ResourceInclude Source="avares://MyApp/Resources/Spacing.axaml"/>
<ResourceInclude Source="avares://MyApp/Resources/Radius.axaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
<Application.Styles>
<FluentTheme/>
<StyleInclude Source="avares://MyApp/Styles/Typography.axaml"/>
<StyleInclude Source="avares://MyApp/Styles/Components.axaml"/>
</Application.Styles>
</Application>
Theme Switching at Runtime
Application.Current!.RequestedThemeVariant =
Application.Current.ActualThemeVariant == ThemeVariant.Dark
? ThemeVariant.Light
: ThemeVariant.Dark;
Persist to settings; restore on launch in OnFrameworkInitializationCompleted.
Palette Selection by Product Type
| Product type | Accent suggestion | Tone |
|---|
| Productivity / SaaS dashboard | Blue 600 / Indigo 600 | Cool, professional |
| Developer tool / IDE | Slate + accent (Cyan 500 or Violet 500) | Neutral, dark-mode first |
| Finance / banking | Green 600 or Navy 800 | Trust, conservative |
| Health / wellness | Teal 500 / Emerald 500 | Calm, fresh |
| Creative / media | Bold gradient or Magenta 500 | Vibrant |
| Gaming / entertainment | Purple 600 + Neon accent | Energetic |
| Enterprise B2B | Slate + Brand color from logo | Restrained |
| Education / kids | Saturated multi-color (Amber/Sky/Pink) | Friendly |
Always validate accent on white and the dark surface for ≥4.5:1 contrast on text overlays.
Common Mistakes
- Hex literals in views — kills theming. Always
DynamicResource.
- Missing dark-mode variant — app looks broken if user's OS is dark.
- Using
StaticResource for theme-variant brushes — won't switch at runtime.
- More than ~3 accent colors — visual noise; pick one accent + one optional secondary.
- Inventing one-off spacing values (
Margin="13,7") — breaks rhythm.
- Body text below 13px on desktop — readability suffers.
- Pure black
#000 text on pure white — too harsh; use Slate 900 / Slate 50.
- Same shadow opacity in dark mode — looks muddy. Reduce or replace with a 1px border.