Skip to main content

Overview

Flowery.Uno uses a palette-based architecture where themes are defined as collections of color resources. This guide covers how to create custom themes, override palette resources, and use lightweight styling patterns.
For basic theme usage, see the Theming Guide. For theme switching patterns, see Advanced Theme Switching.

Palette Architecture

Flowery.Uno’s theming system is built on these principles:
  1. Palette Factory - DaisyPaletteFactory produces per-theme resources
  2. Stable Brush Instances - Brushes are mutated (Color property) when themes change
  3. ThemeResource Bindings - Controls use {ThemeResource} to automatically update
  4. Resource Hierarchy - Application → Page → Control resources

Key Palette Resources

ResourceUsage
DaisyBase100BrushPage/window background
DaisyBase200BrushElevated surfaces (cards, sidebar)
DaisyBase300BrushBorders
DaisyBaseContentBrushDefault text/icon color
DaisyPrimaryBrushPrimary accent color
DaisySecondaryBrushSecondary accent
DaisyAccentBrushTertiary accent
DaisyInfoBrushInfo status color
DaisySuccessBrushSuccess status color
DaisyWarningBrushWarning status color
DaisyErrorBrushError status color

Lightweight Styling (Per-Control Customization)

WinUI/Uno supports lightweight styling - overriding theme resources for individual controls without creating full custom styles.

Override a Single Control’s Colors

Place a ResourceDictionary with ThemeDictionaries inside the control’s Resources:
<Button Content="Custom Purple Button">
    <Button.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
                    <SolidColorBrush x:Key="ButtonForeground" Color="MediumSlateBlue"/>
                    <SolidColorBrush x:Key="ButtonBorderBrush" Color="MediumSlateBlue"/>
                </ResourceDictionary>
                <ResourceDictionary x:Key="Dark">
                    <SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
                    <SolidColorBrush x:Key="ButtonForeground" Color="Coral"/>
                    <SolidColorBrush x:Key="ButtonBorderBrush" Color="Coral"/>
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </Button.Resources>
</Button>

Handle Pointer States

Override state-specific resources using standard suffixes:
StateSuffix Example
HoverButtonBackgroundPointerOver
PressedButtonForegroundPressed
DisabledButtonBorderBrushDisabled
<CheckBox Content="Purple CheckBox">
    <CheckBox.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="CheckBoxForegroundUnchecked" Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxForegroundChecked" Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxCheckGlyphForegroundChecked" Color="White"/>
                    <SolidColorBrush x:Key="CheckBoxCheckBackgroundFillChecked" Color="Purple"/>
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </CheckBox.Resources>
</CheckBox>

Page-Wide Overrides

Apply lightweight styling to all controls of a type on a page:
<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                <SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
                <SolidColorBrush x:Key="ButtonForeground" Color="MediumSlateBlue"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Page.Resources>

<!-- All buttons on this page get the custom colors -->
<Button Content="Button 1"/>
<Button Content="Button 2"/>

App-Wide Overrides

Place theme overrides in App.xaml to affect all controls globally:
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- Your other resources -->
        </ResourceDictionary.MergedDictionaries>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                <SolidColorBrush x:Key="ButtonBackground" Color="Lavender"/>
            </ResourceDictionary>
            <ResourceDictionary x:Key="Dark">
                <SolidColorBrush x:Key="ButtonBackground" Color="DarkSlateBlue"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Application.Resources>

Daisy Control Styling Resources

Flowery.Uno controls support lightweight styling through control-specific resource keys.

Why Daisy-Specific Resources?

Since Daisy controls are code-driven (they build their visual tree programmatically in C#), standard WinUI template-based lightweight styling doesn’t apply. Instead, Daisy controls check for resource overrides using a consistent naming pattern.

Resource Naming Convention

All Daisy styling resources follow this pattern:
Daisy{ControlName}{Part?}{State?}{Property}
Examples:
  • DaisyButtonBackground – Button background
  • DaisyToggleKnobBrush – Toggle switch knob color
  • DaisyTableRowHoverBackground – Table row hover state
  • DaisyInputPrimaryBorderBrush – Primary variant border

Lookup Priority

Resources are resolved in this order:
  1. Control.Resources – Instance-level override (highest priority)
  2. Application.Current.Resources – App-wide override
  3. Fallback – Control’s internal palette logic

Application-Level Styling

Override in App.xaml to affect all instances of a control:
<Application.Resources>
    <ResourceDictionary>
        <SolidColorBrush x:Key="DaisyButtonBackground" Color="MediumSlateBlue"/>
        <SolidColorBrush x:Key="DaisyCardBackground" Color="#2A2A3A"/>
    </ResourceDictionary>
</Application.Resources>

Instance-Level Styling

Override on a single control instance:
<daisy:DaisyButton Content="Custom Button">
    <daisy:DaisyButton.Resources>
        <SolidColorBrush x:Key="DaisyButtonBackground" Color="Coral"/>
        <SolidColorBrush x:Key="DaisyButtonForeground" Color="White"/>
    </daisy:DaisyButton.Resources>
</daisy:DaisyButton>

Common Controls (Quick Reference)

ControlResources
DaisyButtonBackground, Foreground, BorderBrush + variant-specific
DaisyInputBackground, Foreground, BorderBrush + variant-specific
DaisyCardBackground, Foreground
DaisyBadgeBackground, Foreground + variant-specific
DaisyToggleKnobBrush, TrackBackground + variant-specific
DaisyProgressFillBrush, TrackBrush + variant-specific
DaisyModalBackdropBrush, Background

Variant-Specific Resources

Many controls support variant-specific overrides. The pattern is:
Daisy{Control}{Variant}{Property}
Example for DaisyButton with Primary variant:
  • DaisyButtonPrimaryBackground
  • DaisyButtonPrimaryForeground
  • DaisyButtonPrimaryBorderBrush
<Application.Resources>
    <ResourceDictionary>
        <!-- Override all Primary buttons -->
        <SolidColorBrush x:Key="DaisyButtonPrimaryBackground" Color="DeepPink"/>
        <SolidColorBrush x:Key="DaisyButtonPrimaryForeground" Color="White"/>
    </ResourceDictionary>
</Application.Resources>

<!-- This button now has DeepPink background -->
<daisy:DaisyButton Content="Primary" Variant="Primary" />

Creating Custom Themes

Method 1: Override Palette Resources

The simplest approach is to override the core palette brushes in App.xaml:
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- Include Flowery.Uno resources -->
            <ResourceDictionary Source="ms-appx:///Flowery.Uno/Themes/Generic.xaml" />
        </ResourceDictionary.MergedDictionaries>
        
        <!-- Override palette for custom theme -->
        <SolidColorBrush x:Key="DaisyBase100Brush" Color="#1E1E2E"/>
        <SolidColorBrush x:Key="DaisyBase200Brush" Color="#2A2A3A"/>
        <SolidColorBrush x:Key="DaisyBase300Brush" Color="#3E3E4E"/>
        <SolidColorBrush x:Key="DaisyBaseContentBrush" Color="#E0E0E0"/>
        
        <SolidColorBrush x:Key="DaisyPrimaryBrush" Color="#FF6B9D"/>
        <SolidColorBrush x:Key="DaisySecondaryBrush" Color="#C678DD"/>
        <SolidColorBrush x:Key="DaisyAccentBrush" Color="#61AFEF"/>
        
        <SolidColorBrush x:Key="DaisyInfoBrush" Color="#61AFEF"/>
        <SolidColorBrush x:Key="DaisySuccessBrush" Color="#98C379"/>
        <SolidColorBrush x:Key="DaisyWarningBrush" Color="#E5C07B"/>
        <SolidColorBrush x:Key="DaisyErrorBrush" Color="#E06C75"/>
    </ResourceDictionary>
</Application.Resources>

Method 2: Custom Theme Dictionary

Create a separate ResourceDictionary for your theme: Themes/MyCustomTheme.xaml:
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <!-- Base colors -->
    <SolidColorBrush x:Key="DaisyBase100Brush" Color="#0F0F1E"/>
    <SolidColorBrush x:Key="DaisyBase200Brush" Color="#1A1A2E"/>
    <SolidColorBrush x:Key="DaisyBase300Brush" Color="#25253E"/>
    <SolidColorBrush x:Key="DaisyBaseContentBrush" Color="#EAEAEA"/>
    
    <!-- Accent colors -->
    <SolidColorBrush x:Key="DaisyPrimaryBrush" Color="#FF5370"/>
    <SolidColorBrush x:Key="DaisySecondaryBrush" Color="#C792EA"/>
    <SolidColorBrush x:Key="DaisyAccentBrush" Color="#82AAFF"/>
    
    <!-- Status colors -->
    <SolidColorBrush x:Key="DaisyInfoBrush" Color="#82AAFF"/>
    <SolidColorBrush x:Key="DaisySuccessBrush" Color="#C3E88D"/>
    <SolidColorBrush x:Key="DaisyWarningBrush" Color="#FFCB6B"/>
    <SolidColorBrush x:Key="DaisyErrorBrush" Color="#FF5370"/>
</ResourceDictionary>
App.xaml:
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ms-appx:///Flowery.Uno/Themes/Generic.xaml" />
            <ResourceDictionary Source="Themes/MyCustomTheme.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Method 3: Programmatic Theme Creation

Create themes dynamically in code:
public static class CustomThemeManager
{
    public static void ApplyCustomTheme(string themeName)
    {
        var palette = themeName switch
        {
            "Midnight" => CreateMidnightPalette(),
            "Ocean" => CreateOceanPalette(),
            "Forest" => CreateForestPalette(),
            _ => CreateDefaultPalette()
        };
        
        ApplyPalette(palette);
    }
    
    private static Dictionary<string, Color> CreateMidnightPalette()
    {
        return new Dictionary<string, Color>
        {
            ["DaisyBase100"] = Color.FromArgb(255, 15, 15, 30),
            ["DaisyBase200"] = Color.FromArgb(255, 26, 26, 46),
            ["DaisyBase300"] = Color.FromArgb(255, 37, 37, 62),
            ["DaisyBaseContent"] = Color.FromArgb(255, 234, 234, 234),
            ["DaisyPrimary"] = Color.FromArgb(255, 255, 83, 112),
            ["DaisySecondary"] = Color.FromArgb(255, 199, 146, 234),
            ["DaisyAccent"] = Color.FromArgb(255, 130, 170, 255),
            // ... other colors
        };
    }
    
    private static void ApplyPalette(Dictionary<string, Color> palette)
    {
        foreach (var (key, color) in palette)
        {
            var brushKey = key + "Brush";
            if (Application.Current.Resources.TryGetValue(brushKey, out var resource) &&
                resource is SolidColorBrush brush)
            {
                brush.Color = color;
            }
            else
            {
                Application.Current.Resources[brushKey] = new SolidColorBrush(color);
            }
        }
    }
}

Theme Color Calculation

Deriving Shades

Generate lighter/darker variants from a base color:
public static Color Lighten(Color color, double amount)
{
    var hsl = new HslColor(color);
    hsl.L = Math.Min(1.0, hsl.L + amount);
    return hsl.ToRgbColor();
}

public static Color Darken(Color color, double amount)
{
    var hsl = new HslColor(color);
    hsl.L = Math.Max(0.0, hsl.L - amount);
    return hsl.ToRgbColor();
}

// Usage
var baseColor = Color.FromArgb(255, 100, 150, 200);
var base100 = Darken(baseColor, 0.3);
var base200 = Darken(baseColor, 0.2);
var base300 = Darken(baseColor, 0.1);

Complementary Colors

Generate accent colors from primary:
public static Color GetComplementary(Color color)
{
    var hsl = new HslColor(color);
    hsl.H = (hsl.H + 180) % 360;
    return hsl.ToRgbColor();
}

public static Color GetTriadic(Color color, int offset)
{
    var hsl = new HslColor(color);
    hsl.H = (hsl.H + offset) % 360;
    return hsl.ToRgbColor();
}

// Usage
var primary = Colors.Blue;
var secondary = GetTriadic(primary, 120);
var accent = GetTriadic(primary, 240);

Style Inheritance with BasedOn

Create style hierarchies using BasedOn:
<Page.Resources>
    <Style x:Key="BaseButtonStyle" TargetType="Button">
        <Setter Property="Height" Value="40" />
        <Setter Property="CornerRadius" Value="8" />
    </Style>

    <Style x:Key="PrimaryButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
        <Setter Property="Background" Value="{ThemeResource DaisyPrimaryBrush}" />
    </Style>

    <Style x:Key="SecondaryButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
        <Setter Property="Background" Value="{ThemeResource DaisySecondaryBrush}" />
    </Style>
</Page.Resources>
For system controls, base on the default style:
<Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextBoxStyle}">
    <Setter Property="BorderBrush" Value="{ThemeResource DaisyPrimaryBrush}"/>
</Style>

Implicit vs Explicit Styles

Implicit Styles

Implicit styles (no x:Key) apply automatically to all matching controls:
<Page.Resources>
    <!-- Applies to ALL Buttons on this page -->
    <Style TargetType="Button">
        <Setter Property="CornerRadius" Value="12" />
    </Style>
</Page.Resources>

<Button Content="Gets rounded corners automatically" />

Explicit Styles

Explicit styles (with x:Key) must be referenced:
<Page.Resources>
    <Style x:Key="RoundedButton" TargetType="Button">
        <Setter Property="CornerRadius" Value="12" />
    </Style>
</Page.Resources>

<Button Content="Default corners" />
<Button Content="Rounded" Style="{StaticResource RoundedButton}" />

Best Practices

Use BasedOn and resource overrides instead of creating custom control templates. Templates break when WinUI updates.
Generate theme variants using HslColor for consistent lightness/saturation adjustments.
Override only the core palette resources. Let controls derive their colors from the palette.
Define both Light and Dark resource dictionaries for system theme support.
Ensure sufficient contrast ratios (WCAG AA: 4.5:1 for normal text, 3:1 for large text).
Include comments in your theme dictionary explaining color choices and intended usage.

Complete Example: Custom Theme

Themes/SunsetTheme.xaml:
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <!-- Sunset Theme: Warm, vibrant colors inspired by twilight -->
    
    <!-- Base colors: Deep purples and blues -->
    <SolidColorBrush x:Key="DaisyBase100Brush" Color="#1A1625"/>
    <SolidColorBrush x:Key="DaisyBase200Brush" Color="#2A2435"/>
    <SolidColorBrush x:Key="DaisyBase300Brush" Color="#3A3245"/>
    <SolidColorBrush x:Key="DaisyBaseContentBrush" Color="#F0E6FF"/>
    
    <!-- Accent colors: Sunset hues -->
    <SolidColorBrush x:Key="DaisyPrimaryBrush" Color="#FF6B6B"/>     <!-- Coral -->
    <SolidColorBrush x:Key="DaisySecondaryBrush" Color="#FFB347"/>   <!-- Orange -->
    <SolidColorBrush x:Key="DaisyAccentBrush" Color="#FFD93D"/>      <!-- Yellow -->
    
    <!-- Status colors: Matching the sunset palette -->
    <SolidColorBrush x:Key="DaisyInfoBrush" Color="#A29BFE"/>        <!-- Lavender -->
    <SolidColorBrush x:Key="DaisySuccessBrush" Color="#6BCF7F"/>     <!-- Mint -->
    <SolidColorBrush x:Key="DaisyWarningBrush" Color="#FFB347"/>     <!-- Orange -->
    <SolidColorBrush x:Key="DaisyErrorBrush" Color="#FF6B6B"/>       <!-- Coral -->
</ResourceDictionary>
App.xaml:
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ms-appx:///Flowery.Uno/Themes/Generic.xaml" />
            <ResourceDictionary Source="Themes/SunsetTheme.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
Your entire app now uses the Sunset theme!

Build docs developers (and LLMs) love