| name | xaml-theme-generator |
| description | Generate XAML ResourceDictionary theme files (WinUI, UWP, MAUI) from a single accent color. Trigger when the user provides an accent color for a XAML app, says "generate a XAML theme", "create WinUI theme resources", "update MAUI colors", "generate App.xaml theme", or asks to theme their WinUI/UWP/MAUI application. Handles both hsl(H, S%, L%) and |
XAML Theme Generator
Generates XAML ResourceDictionary theme files for WinUI 3, UWP, and MAUI from a single accent color. Uses the same HSL color scale and desaturated surface algorithms as css-theme-generator and blazor-theme-generator.
Inputs
| Input | Required | Notes |
|---|
| Accent color | Yes | HSL string like hsl(149, 100%, 42%) or hex like #00D766 |
| Platform | No | maui, winui, or all (default: all) |
Step 1: Parse accent color
Same as css-theme-generator. Extract H (0โ360), S (0โ100), and R/G/B.
If hex โ convert to HSL:
r' = R/255, g' = G/255, b' = B/255
max = max(r', g', b'), min = min(r', g', b'), ฮ = max - min
L = (max + min) / 2
S = ฮ / (1 - |2L - 1|) (0 if ฮ=0)
H = 60 * ((g'-b')/ฮ mod 6) if max=r'
60 * ((b'-r')/ฮ + 2) if max=g'
60 * ((r'-g')/ฮ + 4) if max=b'
H = round(H) mod 360, S = round(S * 100)
Step 2: Generate the saturated primary scale
Same 11-step HSL scale with perceptual adjustments:
| Step | L% | H adj | S adj |
|---|
| 50 | 97 | +2 | -2 |
| 100 | 93 | -1 | +1 |
| 200 | 87 | 0 | -1 |
| 300 | 79 | 0 | -1 |
| 400 | 69 | 0 | 0 |
| 500 | 58 | 0 | 0 |
| 600 | 49 | 0 | 0 |
| 700 | 41 | 0 | 0 |
| 800 | 33 | 0 | 0 |
| 900 | 26 | 0 | 0 |
| 950 | 20 | 0 | 0 |
Convert each step to hex. This is the saturated brand scale โ used for accents, buttons, links, focus visuals.
Step 3: Compute desaturated surface colors
Same formulas as blazor-theme-generator. Convert to hex.
Dark mode surfaces
| Resource key | H | S formula | L |
|---|
| SurfaceDarkest | H - 6 | max(4, round(S * 0.13)) | 8% |
| BackgroundDark | H - 11 | max(4, round(S * 0.11)) | 11% |
| SurfaceDark | H - 21 | max(4, round(S * 0.10)) | 14% |
| SurfaceDarkVariant | H - 18 | max(4, round(S * 0.08)) | 18% |
| SurfaceDarkAlt | H - 9 | max(4, round(S * 0.07)) | 22% |
Light mode surfaces
| Resource key | H | S formula | L |
|---|
| SurfaceLight | H - 3 | max(3, round(S * 0.08)) | 88% |
| BackgroundLight | H - 3 | max(3, round(S * 0.10)) | 90% |
| SurfaceLightVariant | H - 3 | max(3, round(S * 0.08)) | 92% |
| SurfaceLightAlt | H - 2 | max(5, round(S * 0.12)) | 84% |
| SurfaceCard | โ | 0% | 100% (#FFFFFF) |
Step 4: Compute text colors
Same formulas. Convert to hex.
Dark theme text:
| Resource key | H | S | L |
|---|
| TextDark | 0 | 0% | 96% |
| TextDarkSecondary | accent_H | 4% | 65% |
| TextDarkTertiary | accent_H | 4% | 38% |
Light theme text:
| Resource key | H | S | L |
|---|
| TextLight | accent_H | 10% | 9% |
| TextLightSecondary | accent_H | 6% | 32% |
| TextLightTertiary | accent_H | 4% | 50% |
Step 5: Compute accent RGB (for opacity variants)
Accent = scale-500: Hโ
โโ, Sโ
โโ, L=58%. Convert to R,G,B.
AccentDark = scale-700: Hโโโ, Sโโโ, L=41%. Convert to R,G,B.
Also generate low-opacity accent variants as hex with alpha:
AccentDimDark = #1A{R_dark:X2}{G_dark:X2}{B_dark:X2} (10% opacity)
AccentGlowDark = #38{R_dark:X2}{G_dark:X2}{B_dark:X2} (22% opacity)
AccentDimLight = #24{R_light:X2}{G_light:X2}{B_light:X2} (14% opacity)
AccentGlowLight = #42{R_light:X2}{G_light:X2}{B_light:X2} (26% opacity)
Where the alpha byte = round(opacity * 255). 0.10โ26=0x1A, 0.22โ56=0x38, 0.14โ36=0x24, 0.26โ66=0x42.
Step 6: Platform-specific key mappings
MAUI convention
Primary โ Primary500 (scale-500)
PrimaryDark โ Primary700 (scale-700)
PrimaryLight โ Primary300 (scale-300)
Secondary โ Primary400
Tertiary โ Primary300
Surface โ theme: SurfaceCard (light) / SurfaceDark (dark)
SurfaceVariant โ theme: SurfaceLightVariant / SurfaceDarkVariant
Background โ theme: BackgroundLight / BackgroundDark
Error โ static #FF4757
OnPrimary โ #FFFFFF (always white โ accent is dark enough)
OnSurface โ theme: TextLight / TextDark
OnBackground โ theme: TextLight / TextDark
Outline โ theme: border-light / border-dark
WinUI / UWP convention
SystemAccentColor โ Primary500
SystemAccentColorLight1 โ Primary300
SystemAccentColorLight2 โ Primary200
SystemAccentColorLight3 โ Primary100
SystemAccentColorDark1 โ Primary700
SystemAccentColorDark2 โ Primary800
SystemAccentColorDark3 โ Primary900
SystemAccentColorComplementary โ (H+180 mod 360, same S/L as Primary500)
Step 7: Assemble output
Universal color scale (all platforms)
<ResourceDictionary>
<Color x:Key="Primary50">#FF{hex50}</Color>
<Color x:Key="Primary100">#FF{hex100}</Color>
<Color x:Key="Primary200">#FF{hex200}</Color>
<Color x:Key="Primary300">#FF{hex300}</Color>
<Color x:Key="Primary400">#FF{hex400}</Color>
<Color x:Key="Primary500">#FF{hex500}</Color>
<Color x:Key="Primary600">#FF{hex600}</Color>
<Color x:Key="Primary700">#FF{hex700}</Color>
<Color x:Key="Primary800">#FF{hex800}</Color>
<Color x:Key="Primary900">#FF{hex900}</Color>
<Color x:Key="Primary950">#FF{hex950}</Color>
<Color x:Key="Error">#FFFF4757</Color>
<Color x:Key="Success">#FF4ADE80</Color>
<Color x:Key="Warning">#FFFBBF24</Color>
</ResourceDictionary>
Light theme dictionary
<ResourceDictionary x:Key="Light">
<Color x:Key="Surface">{hex_SurfaceCard}</Color>
<Color x:Key="SurfaceVariant">{hex_SurfaceLightVariant}</Color>
<Color x:Key="SurfaceAlt">{hex_SurfaceLightAlt}</Color>
<Color x:Key="Background">{hex_BackgroundLight}</Color>
<Color x:Key="SidebarBackground">{hex_SurfaceLight}</Color>
<Color x:Key="Accent">{hex_Primary700}</Color>
<Color x:Key="AccentDim">{hex_AccentDimLight}</Color>
<Color x:Key="AccentGlow">{hex_AccentGlowLight}</Color>
<Color x:Key="Text">{hex_TextLight}</Color>
<Color x:Key="TextSecondary">{hex_TextLightSecondary}</Color>
<Color x:Key="TextTertiary">{hex_TextLightTertiary}</Color>
<Color x:Key="Border">#1F000000</Color>
</ResourceDictionary>
Dark theme dictionary
<ResourceDictionary x:Key="Dark">
<Color x:Key="Surface">{hex_SurfaceDark}</Color>
<Color x:Key="SurfaceVariant">{hex_SurfaceDarkVariant}</Color>
<Color x:Key="SurfaceAlt">{hex_SurfaceDarkAlt}</Color>
<Color x:Key="Background">{hex_BackgroundDark}</Color>
<Color x:Key="SidebarBackground">{hex_SurfaceDarkest}</Color>
<Color x:Key="Accent">{hex_Primary500}</Color>
<Color x:Key="AccentDim">{hex_AccentDimDark}</Color>
<Color x:Key="AccentGlow">{hex_AccentGlowDark}</Color>
<Color x:Key="Text">{hex_TextDark}</Color>
<Color x:Key="TextSecondary">{hex_TextDarkSecondary}</Color>
<Color x:Key="TextTertiary">{hex_TextDarkTertiary}</Color>
<Color x:Key="Border">#14FFFFFF</Color>
</ResourceDictionary>
Platform integration instructions
MAUI โ Resources/Styles/Colors.xaml
Merge all three dictionaries into one file. Reference with {AppThemeBinding Light={StaticResource Surface}, Dark={StaticResource Surface}} in styles, or use separate light/dark style dictionaries.
WinUI 3 / UWP โ App.xaml
Wrap light and dark dictionaries in <ResourceDictionary.ThemeDictionaries>:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>
Summary format
Print before the XAML output:
Source: {input} โ H={H} S={S}%
Scale:
Light end: Primary50 = {hex50}
Mid: Primary500 = {hex500}
Dark end: Primary950 = {hex950}
Dark theme:
Surfaces: {darkest} โ {lightest} (S=7โ13%, L=8โ22%)
Accent: Primary500 ({hex500})
Text: {TextDark} / {TextDarkSecondary} / {TextDarkTertiary}
Light theme:
Surfaces: {lightest} โ {darkest} (S=8โ12%, L=84โ100%)
Accent: Primary700 ({hex700})
Text: {TextLight} / {TextLightSecondary} / {TextLightTertiary}