// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.Maui.Graphics;
using SkiaSharp;
namespace Microsoft.Maui.Platform;
///
/// Centralized theme colors for Skia views using MAUI Color types.
/// All colors are defined as MAUI Colors for API compliance and converted to SKColor for rendering.
///
public static class SkiaTheme
{
#region Primary Colors
/// Material Blue - Primary accent color
public static readonly Color Primary = Color.FromRgb(0x21, 0x96, 0xF3);
/// Material Blue Dark - Darker primary variant
public static readonly Color PrimaryDark = Color.FromRgb(0x19, 0x76, 0xD2);
/// Material Blue Light with transparency
public static readonly Color PrimaryLight = Color.FromRgba(0x21, 0x96, 0xF3, 0x60);
/// Material Blue with 35% opacity for selection
public static readonly Color PrimarySelection = Color.FromRgba(0x21, 0x96, 0xF3, 0x59);
/// Material Blue with 50% opacity
public static readonly Color PrimaryHalf = Color.FromRgba(0x21, 0x96, 0xF3, 0x80);
#endregion
#region Text Colors
/// Primary text color - dark gray
public static readonly Color TextPrimary = Color.FromRgb(0x21, 0x21, 0x21);
/// Secondary text color - medium gray
public static readonly Color TextSecondary = Color.FromRgb(0x61, 0x61, 0x61);
/// Tertiary/hint text color
public static readonly Color TextTertiary = Color.FromRgb(0x75, 0x75, 0x75);
/// Disabled text color
public static readonly Color TextDisabled = Color.FromRgb(0x9E, 0x9E, 0x9E);
/// Placeholder text color
public static readonly Color TextPlaceholder = Color.FromRgb(0x80, 0x80, 0x80);
/// Link text color
public static readonly Color TextLink = Color.FromRgb(0x21, 0x96, 0xF3);
/// Visited link text color - Material Purple
public static readonly Color TextLinkVisited = Color.FromRgb(0x9C, 0x27, 0xB0);
#endregion
#region Background Colors
/// White background
public static readonly Color BackgroundWhite = Colors.White;
/// Semi-transparent white (59% opacity)
public static readonly Color WhiteSemiTransparent = Color.FromRgba(255, 255, 255, 150);
/// Light gray background
public static readonly Color BackgroundLight = Color.FromRgb(0xF5, 0xF5, 0xF5);
/// Slightly darker light background
public static readonly Color BackgroundLightAlt = Color.FromRgb(0xFA, 0xFA, 0xFA);
/// Surface background (cards, dialogs)
public static readonly Color BackgroundSurface = Color.FromRgb(0xFF, 0xFF, 0xFF);
/// Disabled background
public static readonly Color BackgroundDisabled = Color.FromRgb(0xEE, 0xEE, 0xEE);
#endregion
#region Gray Scale
/// Gray 50 - lightest
public static readonly Color Gray50 = Color.FromRgb(0xFA, 0xFA, 0xFA);
/// Gray 100
public static readonly Color Gray100 = Color.FromRgb(0xF5, 0xF5, 0xF5);
/// Gray 200
public static readonly Color Gray200 = Color.FromRgb(0xEE, 0xEE, 0xEE);
/// Gray 300
public static readonly Color Gray300 = Color.FromRgb(0xE0, 0xE0, 0xE0);
/// Gray 400
public static readonly Color Gray400 = Color.FromRgb(0xBD, 0xBD, 0xBD);
/// Gray 500
public static readonly Color Gray500 = Color.FromRgb(0x9E, 0x9E, 0x9E);
/// Gray 600
public static readonly Color Gray600 = Color.FromRgb(0x75, 0x75, 0x75);
/// Gray 700
public static readonly Color Gray700 = Color.FromRgb(0x61, 0x61, 0x61);
/// Gray 800
public static readonly Color Gray800 = Color.FromRgb(0x42, 0x42, 0x42);
/// Gray 900 - darkest
public static readonly Color Gray900 = Color.FromRgb(0x21, 0x21, 0x21);
#endregion
#region Border Colors
/// Light border color
public static readonly Color BorderLight = Color.FromRgb(0xE0, 0xE0, 0xE0);
/// Medium border color
public static readonly Color BorderMedium = Color.FromRgb(0xC8, 0xC8, 0xC8);
/// Dark border color
public static readonly Color BorderDark = Color.FromRgb(0xA0, 0xA0, 0xA0);
#endregion
#region Shadow Colors
/// Shadow with 10% opacity
public static readonly Color Shadow10 = Color.FromRgba(0, 0, 0, 0x1A);
/// Shadow with 15% opacity
public static readonly Color Shadow15 = Color.FromRgba(0, 0, 0, 0x26);
/// Shadow with 20% opacity
public static readonly Color Shadow20 = Color.FromRgba(0, 0, 0, 0x33);
/// Shadow with 25% opacity
public static readonly Color Shadow25 = Color.FromRgba(0, 0, 0, 0x40);
/// Shadow with 40% opacity
public static readonly Color Shadow40 = Color.FromRgba(0, 0, 0, 0x64);
/// Shadow with 50% opacity
public static readonly Color Shadow50 = Color.FromRgba(0, 0, 0, 0x80);
#endregion
#region Overlay Colors
/// Scrim/overlay with 40% opacity
public static readonly Color Overlay40 = Color.FromRgba(0, 0, 0, 0x64);
/// Scrim/overlay with 50% opacity
public static readonly Color Overlay50 = Color.FromRgba(0, 0, 0, 0x80);
#endregion
#region Status Colors
/// Error/danger color - Material Red
public static readonly Color Error = Color.FromRgb(0xF4, 0x43, 0x36);
/// Success color - Material Green
public static readonly Color Success = Color.FromRgb(0x4C, 0xAF, 0x50);
/// Warning color - Material Orange
public static readonly Color Warning = Color.FromRgb(0xFF, 0x98, 0x00);
#endregion
#region Button Colors
/// Cancel button background
public static readonly Color ButtonCancel = Color.FromRgb(0x9E, 0x9E, 0x9E);
/// Cancel button hover
public static readonly Color ButtonCancelHover = Color.FromRgb(0x75, 0x75, 0x75);
#endregion
#region Scrollbar Colors
/// Scrollbar thumb color
public static readonly Color ScrollbarThumb = Color.FromRgba(0x80, 0x80, 0x80, 0x80);
/// Scrollbar track color
public static readonly Color ScrollbarTrack = Color.FromRgba(0xC8, 0xC8, 0xC8, 0x40);
#endregion
#region Indicator Colors
/// Unselected indicator color
public static readonly Color IndicatorUnselected = Color.FromRgb(0xB4, 0xB4, 0xB4);
/// Selected indicator color
public static readonly Color IndicatorSelected = Color.FromRgb(0x21, 0x96, 0xF3);
#endregion
#region Menu Colors
/// Menu background
public static readonly Color MenuBackground = Color.FromRgb(0xF0, 0xF0, 0xF0);
/// Menu hover background
public static readonly Color MenuHover = Color.FromRgb(0xDC, 0xDC, 0xDC);
/// Menu active/pressed background
public static readonly Color MenuActive = Color.FromRgb(0xC8, 0xC8, 0xC8);
/// Menu separator color
public static readonly Color MenuSeparator = Color.FromRgb(0xDC, 0xDC, 0xDC);
#endregion
#region Dark Theme Colors
/// Dark theme background
public static readonly Color DarkBackground = Color.FromRgb(0x30, 0x30, 0x30);
/// Dark theme surface
public static readonly Color DarkSurface = Color.FromRgb(0x50, 0x50, 0x50);
/// Dark theme text
public static readonly Color DarkText = Color.FromRgb(0xE0, 0xE0, 0xE0);
/// Dark theme hover
public static readonly Color DarkHover = Color.FromRgb(0x50, 0x50, 0x50);
#endregion
#region SKColor Cached Conversions (for rendering performance)
// Primary
internal static readonly SKColor PrimarySK = Primary.ToSKColor();
internal static readonly SKColor PrimaryDarkSK = PrimaryDark.ToSKColor();
internal static readonly SKColor PrimaryLightSK = PrimaryLight.ToSKColor();
internal static readonly SKColor PrimarySelectionSK = PrimarySelection.ToSKColor();
internal static readonly SKColor PrimaryHalfSK = PrimaryHalf.ToSKColor();
// Text
internal static readonly SKColor TextPrimarySK = TextPrimary.ToSKColor();
internal static readonly SKColor TextSecondarySK = TextSecondary.ToSKColor();
internal static readonly SKColor TextTertiarySK = TextTertiary.ToSKColor();
internal static readonly SKColor TextDisabledSK = TextDisabled.ToSKColor();
internal static readonly SKColor TextPlaceholderSK = TextPlaceholder.ToSKColor();
internal static readonly SKColor TextLinkSK = TextLink.ToSKColor();
internal static readonly SKColor TextLinkVisitedSK = TextLinkVisited.ToSKColor();
// Backgrounds
internal static readonly SKColor BackgroundWhiteSK = SKColors.White;
internal static readonly SKColor WhiteSemiTransparentSK = WhiteSemiTransparent.ToSKColor();
internal static readonly SKColor BackgroundLightSK = BackgroundLight.ToSKColor();
internal static readonly SKColor BackgroundLightAltSK = BackgroundLightAlt.ToSKColor();
internal static readonly SKColor BackgroundSurfaceSK = BackgroundSurface.ToSKColor();
internal static readonly SKColor BackgroundDisabledSK = BackgroundDisabled.ToSKColor();
// Gray scale
internal static readonly SKColor Gray50SK = Gray50.ToSKColor();
internal static readonly SKColor Gray100SK = Gray100.ToSKColor();
internal static readonly SKColor Gray200SK = Gray200.ToSKColor();
internal static readonly SKColor Gray300SK = Gray300.ToSKColor();
internal static readonly SKColor Gray400SK = Gray400.ToSKColor();
internal static readonly SKColor Gray500SK = Gray500.ToSKColor();
internal static readonly SKColor Gray600SK = Gray600.ToSKColor();
internal static readonly SKColor Gray700SK = Gray700.ToSKColor();
internal static readonly SKColor Gray800SK = Gray800.ToSKColor();
internal static readonly SKColor Gray900SK = Gray900.ToSKColor();
// Borders
internal static readonly SKColor BorderLightSK = BorderLight.ToSKColor();
internal static readonly SKColor BorderMediumSK = BorderMedium.ToSKColor();
internal static readonly SKColor BorderDarkSK = BorderDark.ToSKColor();
// Shadows
internal static readonly SKColor Shadow10SK = Shadow10.ToSKColor();
internal static readonly SKColor Shadow15SK = Shadow15.ToSKColor();
internal static readonly SKColor Shadow20SK = Shadow20.ToSKColor();
internal static readonly SKColor Shadow25SK = Shadow25.ToSKColor();
internal static readonly SKColor Shadow40SK = Shadow40.ToSKColor();
internal static readonly SKColor Shadow50SK = Shadow50.ToSKColor();
// Overlays
internal static readonly SKColor Overlay40SK = Overlay40.ToSKColor();
internal static readonly SKColor Overlay50SK = Overlay50.ToSKColor();
// Status
internal static readonly SKColor ErrorSK = Error.ToSKColor();
internal static readonly SKColor SuccessSK = Success.ToSKColor();
internal static readonly SKColor WarningSK = Warning.ToSKColor();
// Buttons
internal static readonly SKColor ButtonCancelSK = ButtonCancel.ToSKColor();
internal static readonly SKColor ButtonCancelHoverSK = ButtonCancelHover.ToSKColor();
// Scrollbars
internal static readonly SKColor ScrollbarThumbSK = ScrollbarThumb.ToSKColor();
internal static readonly SKColor ScrollbarTrackSK = ScrollbarTrack.ToSKColor();
// Indicators
internal static readonly SKColor IndicatorUnselectedSK = IndicatorUnselected.ToSKColor();
internal static readonly SKColor IndicatorSelectedSK = IndicatorSelected.ToSKColor();
// Menu
internal static readonly SKColor MenuBackgroundSK = MenuBackground.ToSKColor();
internal static readonly SKColor MenuHoverSK = MenuHover.ToSKColor();
internal static readonly SKColor MenuActiveSK = MenuActive.ToSKColor();
internal static readonly SKColor MenuSeparatorSK = MenuSeparator.ToSKColor();
// Dark theme
internal static readonly SKColor DarkBackgroundSK = DarkBackground.ToSKColor();
internal static readonly SKColor DarkSurfaceSK = DarkSurface.ToSKColor();
internal static readonly SKColor DarkTextSK = DarkText.ToSKColor();
internal static readonly SKColor DarkHoverSK = DarkHover.ToSKColor();
#endregion
#region Theme-Aware Helpers
///
/// Returns true if dark mode is currently active.
/// Checks UserAppTheme first, falls back to system RequestedTheme.
///
public static bool IsDarkMode
{
get
{
var app = Application.Current;
if (app == null) return false;
// If user explicitly set a theme, use that
if (app.UserAppTheme != AppTheme.Unspecified)
return app.UserAppTheme == AppTheme.Dark;
// Otherwise use system theme
return app.RequestedTheme == AppTheme.Dark;
}
}
///
/// Gets the appropriate button background color for the current theme.
///
public static SKColor ButtonBackgroundSK => IsDarkMode ? DarkSurfaceSK : Gray200SK;
///
/// Gets the appropriate text color for the current theme.
///
public static SKColor CurrentTextSK => IsDarkMode ? DarkTextSK : TextPrimarySK;
///
/// Gets the appropriate background color for input controls in the current theme.
///
public static SKColor InputBackgroundSK => IsDarkMode ? DarkBackgroundSK : BackgroundWhiteSK;
///
/// Gets the appropriate border color for the current theme.
///
public static SKColor CurrentBorderSK => IsDarkMode ? Gray600SK : BorderLightSK;
///
/// Gets the appropriate surface background for the current theme.
///
public static SKColor CurrentSurfaceSK => IsDarkMode ? DarkSurfaceSK : BackgroundWhiteSK;
///
/// Gets the appropriate page background for the current theme.
///
public static SKColor CurrentPageBackgroundSK => IsDarkMode ? DarkBackgroundSK : BackgroundWhiteSK;
#endregion
}