rustyle_css/tokens/
typography.rs

1//! Typography token system
2//!
3//! Provides consistent typography definitions including font families, sizes, weights, and line heights.
4
5use crate::css::Length;
6
7/// Font family definitions
8#[derive(Clone, Debug)]
9pub struct FontFamily {
10    /// Primary font family
11    pub primary: String,
12    /// Secondary font family
13    pub secondary: String,
14    /// Monospace font family
15    pub mono: String,
16}
17
18impl FontFamily {
19    /// Create new font family
20    pub fn new(primary: &str, secondary: &str, mono: &str) -> Self {
21        Self {
22            primary: primary.to_string(),
23            secondary: secondary.to_string(),
24            mono: mono.to_string(),
25        }
26    }
27
28    /// Default system font stack
29    pub fn default() -> Self {
30        Self {
31            primary: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif".to_string(),
32            secondary: "Georgia, \"Times New Roman\", serif".to_string(),
33            mono: "\"SF Mono\", Monaco, \"Cascadia Code\", \"Roboto Mono\", Consolas, \"Courier New\", monospace".to_string(),
34        }
35    }
36}
37
38/// Font size scale
39#[derive(Clone, Debug)]
40pub struct FontSizeScale {
41    pub xs: Length,
42    pub sm: Length,
43    pub base: Length,
44    pub lg: Length,
45    pub xl: Length,
46    pub xl2: Length,
47    pub xl3: Length,
48    pub xl4: Length,
49    pub xl5: Length,
50    pub xl6: Length,
51}
52
53impl FontSizeScale {
54    /// Create new font size scale
55    pub fn new(
56        xs: Length,
57        sm: Length,
58        base: Length,
59        lg: Length,
60        xl: Length,
61        xl2: Length,
62        xl3: Length,
63        xl4: Length,
64        xl5: Length,
65        xl6: Length,
66    ) -> Self {
67        Self {
68            xs,
69            sm,
70            base,
71            lg,
72            xl,
73            xl2,
74            xl3,
75            xl4,
76            xl5,
77            xl6,
78        }
79    }
80
81    /// Get font size by name
82    pub fn get(&self, name: &str) -> &Length {
83        match name {
84            "xs" => &self.xs,
85            "sm" => &self.sm,
86            "base" => &self.base,
87            "lg" => &self.lg,
88            "xl" => &self.xl,
89            "2xl" | "xl2" => &self.xl2,
90            "3xl" | "xl3" => &self.xl3,
91            "4xl" | "xl4" => &self.xl4,
92            "5xl" | "xl5" => &self.xl5,
93            "6xl" | "xl6" => &self.xl6,
94            _ => &self.base,
95        }
96    }
97}
98
99/// Font weight scale
100#[derive(Clone, Debug)]
101pub struct FontWeightScale {
102    pub thin: u16,
103    pub light: u16,
104    pub normal: u16,
105    pub medium: u16,
106    pub semibold: u16,
107    pub bold: u16,
108    pub extrabold: u16,
109    pub black: u16,
110}
111
112impl FontWeightScale {
113    /// Create new font weight scale
114    pub fn new(
115        thin: u16,
116        light: u16,
117        normal: u16,
118        medium: u16,
119        semibold: u16,
120        bold: u16,
121        extrabold: u16,
122        black: u16,
123    ) -> Self {
124        Self {
125            thin,
126            light,
127            normal,
128            medium,
129            semibold,
130            bold,
131            extrabold,
132            black,
133        }
134    }
135}
136
137/// Line height scale
138#[derive(Clone, Debug)]
139pub struct LineHeightScale {
140    pub tight: f32,
141    pub snug: f32,
142    pub normal: f32,
143    pub relaxed: f32,
144    pub loose: f32,
145}
146
147impl LineHeightScale {
148    /// Create new line height scale
149    pub fn new(tight: f32, snug: f32, normal: f32, relaxed: f32, loose: f32) -> Self {
150        Self {
151            tight,
152            snug,
153            normal,
154            relaxed,
155            loose,
156        }
157    }
158}
159
160/// Comprehensive typography token system
161#[derive(Clone, Debug)]
162pub struct TypographyTokens {
163    pub font_family: FontFamily,
164    pub font_size: FontSizeScale,
165    pub font_weight: FontWeightScale,
166    pub line_height: LineHeightScale,
167}
168
169impl TypographyTokens {
170    /// Create new typography tokens
171    pub fn new(
172        font_family: FontFamily,
173        font_size: FontSizeScale,
174        font_weight: FontWeightScale,
175        line_height: LineHeightScale,
176    ) -> Self {
177        Self {
178            font_family,
179            font_size,
180            font_weight,
181            line_height,
182        }
183    }
184
185    /// Convert typography tokens to CSS custom properties
186    pub fn to_css_vars(&self) -> String {
187        format!(
188            "  --font-family-primary: {};\n  --font-family-secondary: {};\n  --font-family-mono: {};\n  --font-size-xs: {};\n  --font-size-sm: {};\n  --font-size-base: {};\n  --font-size-lg: {};\n  --font-size-xl: {};\n  --font-size-2xl: {};\n  --font-size-3xl: {};\n  --font-size-4xl: {};\n  --font-size-5xl: {};\n  --font-size-6xl: {};\n  --font-weight-thin: {};\n  --font-weight-light: {};\n  --font-weight-normal: {};\n  --font-weight-medium: {};\n  --font-weight-semibold: {};\n  --font-weight-bold: {};\n  --font-weight-extrabold: {};\n  --font-weight-black: {};\n  --line-height-tight: {};\n  --line-height-snug: {};\n  --line-height-normal: {};\n  --line-height-relaxed: {};\n  --line-height-loose: {};\n",
189            self.font_family.primary,
190            self.font_family.secondary,
191            self.font_family.mono,
192            self.font_size.xs.to_css(),
193            self.font_size.sm.to_css(),
194            self.font_size.base.to_css(),
195            self.font_size.lg.to_css(),
196            self.font_size.xl.to_css(),
197            self.font_size.xl2.to_css(),
198            self.font_size.xl3.to_css(),
199            self.font_size.xl4.to_css(),
200            self.font_size.xl5.to_css(),
201            self.font_size.xl6.to_css(),
202            self.font_weight.thin,
203            self.font_weight.light,
204            self.font_weight.normal,
205            self.font_weight.medium,
206            self.font_weight.semibold,
207            self.font_weight.bold,
208            self.font_weight.extrabold,
209            self.font_weight.black,
210            self.line_height.tight,
211            self.line_height.snug,
212            self.line_height.normal,
213            self.line_height.relaxed,
214            self.line_height.loose,
215        )
216    }
217}
218
219impl Default for TypographyTokens {
220    fn default() -> Self {
221        Self {
222            font_family: FontFamily::default(),
223            font_size: FontSizeScale::new(
224                Length::rem(0.75),  // 12px
225                Length::rem(0.875), // 14px
226                Length::rem(1.0),   // 16px
227                Length::rem(1.125), // 18px
228                Length::rem(1.25),  // 20px
229                Length::rem(1.5),   // 24px
230                Length::rem(1.875), // 30px
231                Length::rem(2.25),  // 36px
232                Length::rem(3.0),   // 48px
233                Length::rem(3.75),  // 60px
234            ),
235            font_weight: FontWeightScale::new(100, 300, 400, 500, 600, 700, 800, 900),
236            line_height: LineHeightScale::new(1.25, 1.375, 1.5, 1.625, 2.0),
237        }
238    }
239}