use crate::theme::{ColorScheme, Theme, ThemeBundle};
use crate::tokens::*;
use blinc_core::Color;
#[derive(Clone, Debug)]
pub struct WindowsTheme {
scheme: ColorScheme,
colors: ColorTokens,
typography: TypographyTokens,
spacing: SpacingTokens,
radii: RadiusTokens,
shadows: ShadowTokens,
animations: AnimationTokens,
}
impl WindowsTheme {
pub fn light() -> Self {
Self {
scheme: ColorScheme::Light,
colors: ColorTokens {
primary: Color::from_hex(0x0078D4),
primary_hover: Color::from_hex(0x106EBE),
primary_active: Color::from_hex(0x005A9E),
secondary: Color::from_hex(0x8A8886),
secondary_hover: Color::from_hex(0x797775),
secondary_active: Color::from_hex(0x605E5C),
success: Color::from_hex(0x107C10), success_bg: Color::from_hex(0x107C10).with_alpha(0.1),
warning: Color::from_hex(0xFFB900), warning_bg: Color::from_hex(0xFFB900).with_alpha(0.1),
error: Color::from_hex(0xD13438), error_bg: Color::from_hex(0xD13438).with_alpha(0.1),
info: Color::from_hex(0x0078D4), info_bg: Color::from_hex(0x0078D4).with_alpha(0.1),
background: Color::from_hex(0xF3F3F3), surface: Color::WHITE, surface_elevated: Color::WHITE,
surface_overlay: Color::from_hex(0xE1DFDD),
text_primary: Color::from_hex(0x1A1A1A), text_secondary: Color::from_hex(0x616161), text_tertiary: Color::from_hex(0x8A8A8A), text_inverse: Color::WHITE,
text_link: Color::from_hex(0x0078D4),
border: Color::rgba(0.0, 0.0, 0.0, 0.08), border_secondary: Color::from_hex(0xBCBCBC), border_hover: Color::rgba(0.0, 0.0, 0.0, 0.12),
border_focus: Color::from_hex(0x0078D4), border_error: Color::from_hex(0xD13438),
input_bg: Color::WHITE,
input_bg_hover: Color::from_hex(0xF9F9F9),
input_bg_focus: Color::WHITE,
input_bg_disabled: Color::from_hex(0xF3F3F3),
selection: Color::from_hex(0x0078D4).with_alpha(0.3),
selection_text: Color::from_hex(0x1A1A1A),
accent: Color::from_hex(0x0078D4),
accent_subtle: Color::from_hex(0x0078D4).with_alpha(0.1),
tooltip_bg: Color::from_hex(0x2D2D2D),
tooltip_text: Color::from_hex(0xF3F3F3),
},
typography: TypographyTokens {
font_sans: FontFamily::new(
"Segoe UI Variable",
vec!["Segoe UI", "system-ui", "sans-serif"],
),
font_serif: FontFamily::new("Cambria", vec!["Georgia", "serif"]),
font_mono: FontFamily::new(
"Cascadia Code",
vec!["Cascadia Mono", "Consolas", "monospace"],
),
text_xs: 12.0, text_sm: 14.0, text_base: 14.0, text_lg: 18.0, text_xl: 20.0, text_2xl: 28.0, text_3xl: 40.0, text_4xl: 48.0,
text_5xl: 68.0, ..Default::default()
},
spacing: SpacingTokens::default(), radii: RadiusTokens {
radius_none: 0.0,
radius_sm: 2.0,
radius_default: 4.0, radius_md: 4.0, radius_lg: 8.0, radius_xl: 8.0, radius_2xl: 8.0,
radius_3xl: 8.0,
radius_full: 9999.0,
},
shadows: Self::light_shadows(),
animations: AnimationTokens::default(),
}
}
pub fn dark() -> Self {
Self {
scheme: ColorScheme::Dark,
colors: ColorTokens {
primary: Color::from_hex(0x60CDFF),
primary_hover: Color::from_hex(0x98D8FF),
primary_active: Color::from_hex(0x4CC2FF),
secondary: Color::from_hex(0x9E9E9E),
secondary_hover: Color::from_hex(0xABABAB),
secondary_active: Color::from_hex(0xBDBDBD),
success: Color::from_hex(0x6CCB5F),
success_bg: Color::from_hex(0x6CCB5F).with_alpha(0.15),
warning: Color::from_hex(0xFCE100),
warning_bg: Color::from_hex(0xFCE100).with_alpha(0.15),
error: Color::from_hex(0xFF99A4),
error_bg: Color::from_hex(0xFF99A4).with_alpha(0.15),
info: Color::from_hex(0x60CDFF),
info_bg: Color::from_hex(0x60CDFF).with_alpha(0.15),
background: Color::from_hex(0x202020), surface: Color::from_hex(0x2D2D2D), surface_elevated: Color::from_hex(0x383838),
surface_overlay: Color::from_hex(0x1F1F1F),
text_primary: Color::WHITE,
text_secondary: Color::from_hex(0xC5C5C5),
text_tertiary: Color::from_hex(0x9A9A9A),
text_inverse: Color::from_hex(0x1A1A1A),
text_link: Color::from_hex(0x60CDFF),
border: Color::rgba(1.0, 1.0, 1.0, 0.08),
border_secondary: Color::from_hex(0x6B6B6B), border_hover: Color::rgba(1.0, 1.0, 1.0, 0.12),
border_focus: Color::from_hex(0x60CDFF),
border_error: Color::from_hex(0xFF99A4),
input_bg: Color::from_hex(0x2D2D2D),
input_bg_hover: Color::from_hex(0x383838),
input_bg_focus: Color::from_hex(0x2D2D2D),
input_bg_disabled: Color::from_hex(0x1F1F1F),
selection: Color::from_hex(0x60CDFF).with_alpha(0.3),
selection_text: Color::WHITE,
accent: Color::from_hex(0x60CDFF),
accent_subtle: Color::from_hex(0x60CDFF).with_alpha(0.15),
tooltip_bg: Color::from_hex(0xF3F3F3),
tooltip_text: Color::from_hex(0x2D2D2D),
},
typography: TypographyTokens {
font_sans: FontFamily::new(
"Segoe UI Variable",
vec!["Segoe UI", "system-ui", "sans-serif"],
),
font_serif: FontFamily::new("Cambria", vec!["Georgia", "serif"]),
font_mono: FontFamily::new(
"Cascadia Code",
vec!["Cascadia Mono", "Consolas", "monospace"],
),
text_xs: 12.0,
text_sm: 14.0,
text_base: 14.0,
text_lg: 18.0,
text_xl: 20.0,
text_2xl: 28.0,
text_3xl: 40.0,
text_4xl: 48.0,
text_5xl: 68.0,
..Default::default()
},
spacing: SpacingTokens::default(),
radii: RadiusTokens {
radius_none: 0.0,
radius_sm: 2.0,
radius_default: 4.0,
radius_md: 4.0,
radius_lg: 8.0,
radius_xl: 8.0,
radius_2xl: 8.0,
radius_3xl: 8.0,
radius_full: 9999.0,
},
shadows: Self::dark_shadows(),
animations: AnimationTokens::default(),
}
}
pub fn bundle() -> ThemeBundle {
ThemeBundle::new("Windows", Self::light(), Self::dark())
}
fn light_shadows() -> ShadowTokens {
let base_color = Color::BLACK;
ShadowTokens {
shadow_sm: Shadow::new(0.0, 1.0, 2.0, 0.0, base_color.with_alpha(0.04)),
shadow_default: Shadow::new(0.0, 2.0, 4.0, 0.0, base_color.with_alpha(0.06)),
shadow_md: Shadow::new(0.0, 4.0, 8.0, 0.0, base_color.with_alpha(0.08)),
shadow_lg: Shadow::new(0.0, 8.0, 16.0, 0.0, base_color.with_alpha(0.1)),
shadow_xl: Shadow::new(0.0, 16.0, 24.0, 0.0, base_color.with_alpha(0.12)),
shadow_2xl: Shadow::new(0.0, 24.0, 48.0, 0.0, base_color.with_alpha(0.16)),
shadow_inner: Shadow::new(0.0, 1.0, 2.0, 0.0, base_color.with_alpha(0.04)),
shadow_none: Shadow::none(),
}
}
fn dark_shadows() -> ShadowTokens {
let base_color = Color::BLACK;
ShadowTokens {
shadow_sm: Shadow::new(0.0, 1.0, 2.0, 0.0, base_color.with_alpha(0.16)),
shadow_default: Shadow::new(0.0, 2.0, 4.0, 0.0, base_color.with_alpha(0.24)),
shadow_md: Shadow::new(0.0, 4.0, 8.0, 0.0, base_color.with_alpha(0.28)),
shadow_lg: Shadow::new(0.0, 8.0, 16.0, 0.0, base_color.with_alpha(0.32)),
shadow_xl: Shadow::new(0.0, 16.0, 24.0, 0.0, base_color.with_alpha(0.36)),
shadow_2xl: Shadow::new(0.0, 24.0, 48.0, 0.0, base_color.with_alpha(0.44)),
shadow_inner: Shadow::new(0.0, 1.0, 2.0, 0.0, base_color.with_alpha(0.12)),
shadow_none: Shadow::none(),
}
}
}
impl Theme for WindowsTheme {
fn name(&self) -> &str {
"Windows"
}
fn color_scheme(&self) -> ColorScheme {
self.scheme
}
fn colors(&self) -> &ColorTokens {
&self.colors
}
fn typography(&self) -> &TypographyTokens {
&self.typography
}
fn spacing(&self) -> &SpacingTokens {
&self.spacing
}
fn radii(&self) -> &RadiusTokens {
&self.radii
}
fn shadows(&self) -> &ShadowTokens {
&self.shadows
}
fn animations(&self) -> &AnimationTokens {
&self.animations
}
}