impulse_thaw/theme/
color.rs

1use std::collections::HashMap;
2
3use thaw_macro::WriteCSSVars;
4
5#[derive(Clone, WriteCSSVars)]
6pub struct ColorTheme {
7    pub color_scheme: String,
8
9    pub color_neutral_background_static: String,
10    pub color_neutral_background_inverted: String,
11    pub color_neutral_background_disabled: String,
12    pub color_neutral_background_1: String,
13    pub color_neutral_background_1_hover: String,
14    pub color_neutral_background_1_pressed: String,
15    pub color_neutral_background_3: String,
16    pub color_neutral_background_3_hover: String,
17    pub color_neutral_background_3_pressed: String,
18    pub color_neutral_background_4: String,
19    pub color_neutral_background_4_hover: String,
20    pub color_neutral_background_4_pressed: String,
21    pub color_neutral_background_5: String,
22    pub color_neutral_background_6: String,
23
24    pub color_neutral_foreground_static_inverted: String,
25    pub color_neutral_foreground_disabled: String,
26    pub color_neutral_foreground_1: String,
27    pub color_neutral_foreground_1_hover: String,
28    pub color_neutral_foreground_1_pressed: String,
29    pub color_neutral_foreground_2: String,
30    pub color_neutral_foreground_2_hover: String,
31    pub color_neutral_foreground_2_pressed: String,
32    pub color_neutral_foreground_2_brand_hover: String,
33    pub color_neutral_foreground_2_brand_pressed: String,
34    pub color_neutral_foreground_2_brand_selected: String,
35    pub color_neutral_foreground_3: String,
36    pub color_neutral_foreground_4: String,
37    pub color_neutral_foreground_on_brand: String,
38    pub color_neutral_foreground_inverted: String,
39
40    pub color_neutral_stroke_disabled: String,
41    pub color_neutral_stroke_1: String,
42    pub color_neutral_stroke_1_hover: String,
43    pub color_neutral_stroke_1_pressed: String,
44    pub color_neutral_stroke_2: String,
45    pub color_neutral_stroke_accessible: String,
46    pub color_neutral_stroke_accessible_hover: String,
47    pub color_neutral_stroke_accessible_pressed: String,
48
49    pub color_neutral_shadow_ambient: String,
50    pub color_neutral_shadow_key: String,
51
52    pub color_neutral_stencil_1: String,
53    pub color_neutral_stencil_2: String,
54
55    pub color_compound_brand_foreground_1: String,
56    pub color_compound_brand_foreground_1_hover: String,
57    pub color_compound_brand_foreground_1_pressed: String,
58    pub color_compound_brand_background: String,
59    pub color_compound_brand_background_hover: String,
60    pub color_compound_brand_background_pressed: String,
61    pub color_compound_brand_stroke: String,
62    pub color_compound_brand_stroke_pressed: String,
63
64    pub color_brand_background: String,
65    pub color_brand_background_hover: String,
66    pub color_brand_background_pressed: String,
67    pub color_brand_background_2: String,
68    pub color_brand_foreground_1: String,
69    pub color_brand_foreground_2: String,
70    pub color_brand_stroke_1: String,
71    pub color_brand_stroke_2: String,
72    pub color_brand_stroke_2_contrast: String,
73    pub color_brand_foreground_link: String,
74    pub color_brand_foreground_link_hover: String,
75    pub color_brand_foreground_link_pressed: String,
76
77    pub color_stroke_focus_2: String,
78
79    pub color_palette_red_background_1: String,
80    pub color_palette_red_background_3: String,
81    pub color_palette_red_foreground_1: String,
82    pub color_palette_red_foreground_3: String,
83    pub color_palette_red_border_1: String,
84    pub color_palette_red_border_2: String,
85    pub color_palette_green_background_1: String,
86    pub color_palette_green_background_3: String,
87    pub color_palette_green_foreground_1: String,
88    pub color_palette_green_foreground_3: String,
89    pub color_palette_green_border_1: String,
90    pub color_palette_green_border_2: String,
91    pub color_palette_yellow_background_1: String,
92    pub color_palette_yellow_background_3: String,
93    pub color_palette_yellow_foreground_1: String,
94    pub color_palette_yellow_foreground_2: String,
95    pub color_palette_yellow_border_1: String,
96
97    pub color_palette_dark_orange_background_1: String,
98    pub color_palette_dark_orange_background_3: String,
99    pub color_palette_dark_orange_foreground_1: String,
100    pub color_palette_dark_orange_foreground_3: String,
101    pub color_palette_dark_orange_border_1: String,
102
103    pub color_status_success_background_1: String,
104    pub color_status_success_foreground_1: String,
105    pub color_status_success_border_1: String,
106    pub color_status_warning_background_1: String,
107    pub color_status_warning_foreground_3: String,
108    pub color_status_warning_border_1: String,
109    pub color_status_danger_background_1: String,
110    pub color_status_danger_foreground_1: String,
111    pub color_status_danger_border_1: String,
112
113    pub color_subtle_background: String,
114    pub color_subtle_background_hover: String,
115    pub color_subtle_background_pressed: String,
116    pub color_transparent_background: String,
117    pub color_transparent_background_hover: String,
118    pub color_transparent_background_pressed: String,
119    pub color_transparent_stroke: String,
120
121    pub shadow4: String,
122    pub shadow8: String,
123    pub shadow16: String,
124    pub shadow64: String,
125}
126
127impl ColorTheme {
128
129    fn validate_palette(brand_colors: &HashMap<i32, &str>) { 
130        for v in 1..=16 {
131            let variant = v*10; 
132            brand_colors.get(&variant).unwrap_or_else(|| panic!("Missing variant {} in brand color palette", variant));
133        }
134    }
135    pub fn custom_light(brand_colors: &HashMap<i32, &str>) -> Self {
136        Self::validate_palette(brand_colors);
137        let mut theme = Self::light();
138        theme.color_brand_background = brand_colors.get(&80).unwrap().to_string();
139        theme.color_brand_background_2 = brand_colors.get(&160).unwrap().to_string();
140        theme.color_brand_background_hover = brand_colors.get(&70).unwrap().to_string();
141        theme.color_brand_background_pressed = brand_colors.get(&40).unwrap().to_string();
142        theme.color_brand_foreground_1 = brand_colors.get(&80).unwrap().to_string();
143        theme.color_brand_foreground_2 = brand_colors.get(&70).unwrap().to_string();
144        theme.color_brand_foreground_link = brand_colors.get(&70).unwrap().to_string();
145        theme.color_brand_foreground_link_hover = brand_colors.get(&60).unwrap().to_string();
146        theme.color_brand_foreground_link_pressed = brand_colors.get(&40).unwrap().to_string();
147        theme.color_brand_stroke_1 = brand_colors.get(&80).unwrap().to_string();
148        theme.color_brand_stroke_2 = brand_colors.get(&140).unwrap().to_string();
149        theme.color_brand_stroke_2_contrast = brand_colors.get(&140).unwrap().to_string();
150        theme.color_compound_brand_background = brand_colors.get(&80).unwrap().to_string();
151        theme.color_compound_brand_background_hover = brand_colors.get(&70).unwrap().to_string();
152        theme.color_compound_brand_background_pressed = brand_colors.get(&60).unwrap().to_string();
153        theme.color_compound_brand_foreground_1 = brand_colors.get(&80).unwrap().to_string();
154        theme.color_compound_brand_foreground_1_hover = brand_colors.get(&70).unwrap().to_string();
155        theme.color_compound_brand_foreground_1_pressed = brand_colors.get(&60).unwrap().to_string();
156        theme.color_compound_brand_stroke = brand_colors.get(&80).unwrap().to_string();
157        theme.color_compound_brand_stroke_pressed = brand_colors.get(&60).unwrap().to_string();
158        theme.color_neutral_foreground_2_brand_hover = brand_colors.get(&80).unwrap().to_string();
159        theme.color_neutral_foreground_2_brand_pressed = brand_colors.get(&70).unwrap().to_string();
160        theme.color_neutral_foreground_2_brand_selected = brand_colors.get(&80).unwrap().to_string();
161        theme
162    }
163
164    pub fn custom_dark(brand_colors: &HashMap<i32, &str>) -> Self {
165        Self::validate_palette(brand_colors);
166        let mut theme = Self::dark();
167        theme.color_brand_background = brand_colors.get(&70).unwrap().to_string();
168        theme.color_brand_background_2 = brand_colors.get(&20).unwrap().to_string();
169        theme.color_brand_background_hover = brand_colors.get(&80).unwrap().to_string();
170        theme.color_brand_background_pressed = brand_colors.get(&40).unwrap().to_string();
171        theme.color_brand_foreground_1 = brand_colors.get(&110).unwrap().to_string();
172        theme.color_brand_foreground_2 = brand_colors.get(&120).unwrap().to_string();
173        theme.color_brand_foreground_link = brand_colors.get(&100).unwrap().to_string();
174        theme.color_brand_foreground_link_hover = brand_colors.get(&110).unwrap().to_string();
175        theme.color_brand_foreground_link_pressed = brand_colors.get(&90).unwrap().to_string();
176        theme.color_brand_stroke_1 = brand_colors.get(&100).unwrap().to_string();
177        theme.color_brand_stroke_2 = brand_colors.get(&50).unwrap().to_string();
178        theme.color_brand_stroke_2_contrast = brand_colors.get(&50).unwrap().to_string();
179        theme.color_compound_brand_background = brand_colors.get(&100).unwrap().to_string();
180        theme.color_compound_brand_background_hover = brand_colors.get(&110).unwrap().to_string();
181        theme.color_compound_brand_background_pressed = brand_colors.get(&90).unwrap().to_string();
182        theme.color_compound_brand_foreground_1 = brand_colors.get(&100).unwrap().to_string();
183        theme.color_compound_brand_foreground_1_hover = brand_colors.get(&110).unwrap().to_string();
184        theme.color_compound_brand_foreground_1_pressed = brand_colors.get(&90).unwrap().to_string();
185        theme.color_compound_brand_stroke = brand_colors.get(&100).unwrap().to_string();
186        theme.color_compound_brand_stroke_pressed = brand_colors.get(&90).unwrap().to_string();
187        theme.color_neutral_foreground_2_brand_hover = brand_colors.get(&100).unwrap().to_string();
188        theme.color_neutral_foreground_2_brand_pressed = brand_colors.get(&90).unwrap().to_string();
189        theme.color_neutral_foreground_2_brand_selected = brand_colors.get(&100).unwrap().to_string();
190        theme
191    }
192
193    pub fn light() -> Self {
194        Self {
195            color_scheme: "light".into(),
196
197            color_neutral_background_static: "#333333".into(),
198            color_neutral_background_inverted: "#292929".into(),
199            color_neutral_background_disabled: "#f0f0f0".into(),
200            color_neutral_background_1: "#ffffff".into(),
201            color_neutral_background_1_hover: "#f5f5f5".into(),
202            color_neutral_background_1_pressed: "#e0e0e0".into(),
203            color_neutral_background_3: "#f5f5f5".into(),
204            color_neutral_background_3_hover: "#ebebeb".into(),
205            color_neutral_background_3_pressed: "#d6d6d6".into(),
206            color_neutral_background_4: "#f0f0f0".into(),
207            color_neutral_background_4_hover: "#fafafa".into(),
208            color_neutral_background_4_pressed: "#f5f5f5".into(),
209            color_neutral_background_5: "#ebebeb".into(),
210            color_neutral_background_6: "#e6e6e6".into(),
211
212            color_neutral_foreground_static_inverted: "#ffffff".into(),
213            color_neutral_foreground_disabled: "#bdbdbd".into(),
214            color_neutral_foreground_1: "#242424".into(),
215            color_neutral_foreground_1_hover: "#242424".into(),
216            color_neutral_foreground_1_pressed: "#242424".into(),
217            color_neutral_foreground_2: "#424242".into(),
218            color_neutral_foreground_2_hover: "#242424".into(),
219            color_neutral_foreground_2_pressed: "#242424".into(),
220            color_neutral_foreground_2_brand_hover: "#0f6cbd".into(),
221            color_neutral_foreground_2_brand_pressed: "#115ea3".into(),
222            color_neutral_foreground_2_brand_selected: "#0f6cbd".into(),
223            color_neutral_foreground_3: "#616161".into(),
224            color_neutral_foreground_4: "#707070".into(),
225            color_neutral_foreground_on_brand: "#fff".into(),
226            color_neutral_foreground_inverted: "#fff".into(),
227
228            color_neutral_stroke_disabled: "#e0e0e0".into(),
229            color_neutral_stroke_1: "#d1d1d1".into(),
230            color_neutral_stroke_1_hover: "#c7c7c7".into(),
231            color_neutral_stroke_1_pressed: "#b3b3b3".into(),
232            color_neutral_stroke_2: "#e0e0e0".into(),
233            color_neutral_stroke_accessible: "#616161".into(),
234            color_neutral_stroke_accessible_hover: "#575757".into(),
235            color_neutral_stroke_accessible_pressed: "#4d4d4d".into(),
236
237            color_neutral_shadow_ambient: "rgba(0,0,0,0.12)".into(),
238            color_neutral_shadow_key: "rgba(0,0,0,0.14)".into(),
239
240            color_neutral_stencil_1: "#e6e6e6".into(),
241            color_neutral_stencil_2: "#fafafa".into(),
242
243            color_compound_brand_foreground_1: "#0f6cbd".into(),
244            color_compound_brand_foreground_1_hover: "#115ea3".into(),
245            color_compound_brand_foreground_1_pressed: "#0f548c".into(),
246
247            color_compound_brand_background: "#0f6cbd".into(),
248            color_compound_brand_background_hover: "#115ea3".into(),
249            color_compound_brand_background_pressed: "#0f548c".into(),
250            color_compound_brand_stroke: "#0f6cbd".into(),
251            color_compound_brand_stroke_pressed: "#0f548c".into(),
252
253            color_brand_background: "#0f6cbd".into(),
254            color_brand_background_hover: "#115ea3".into(),
255            color_brand_background_pressed: "#0c3b5e".into(),
256            color_brand_background_2: "#ebf3fc".into(),
257            color_brand_foreground_1: "#0f6cbd".into(),
258            color_brand_foreground_2: "#115ea3".into(),
259            color_brand_stroke_1: "#0f6cbd".into(),
260            color_brand_stroke_2: "#b4d6fa".into(),
261            color_brand_stroke_2_contrast: "#b4d6fa".into(),
262            color_brand_foreground_link: "#115ea3".into(),
263            color_brand_foreground_link_hover: "#0f548c".into(),
264            color_brand_foreground_link_pressed: "#0c3b5e".into(),
265
266            color_stroke_focus_2: "#000000".into(),
267
268            color_palette_red_background_1: "#fdf6f6".into(),
269            color_palette_red_background_3: "#d13438".into(),
270            color_palette_red_foreground_1: "#bc2f32".into(),
271            color_palette_red_foreground_3: "#d13438".into(),
272            color_palette_red_border_1: "#f1bbbc".into(),
273            color_palette_red_border_2: "#d13438".into(),
274            color_palette_green_background_1: "#f1faf1".into(),
275            color_palette_green_background_3: "#107c10".into(),
276            color_palette_green_foreground_1: "#0e700e".into(),
277            color_palette_green_foreground_3: "#107c10".into(),
278            color_palette_green_border_1: "#9fd89f".into(),
279            color_palette_green_border_2: "#107c10".into(),
280            color_palette_yellow_background_1: "#fffef5".into(),
281            color_palette_yellow_background_3: "#fde300".into(),
282            color_palette_yellow_foreground_1: "#817400".into(),
283            color_palette_yellow_foreground_2: "#817400".into(),
284            color_palette_yellow_border_1: "#fef7b2".into(),
285
286            color_palette_dark_orange_background_1: "#fdf6f3".into(),
287            color_palette_dark_orange_background_3: "#da3b01".into(),
288            color_palette_dark_orange_foreground_1: "#c43501".into(),
289            color_palette_dark_orange_foreground_3: "#da3b01".into(),
290            color_palette_dark_orange_border_1: "#f4bfab".into(),
291
292            color_status_success_background_1: "#f1faf1".into(),
293            color_status_success_foreground_1: "#0e700e".into(),
294            color_status_success_border_1: "#9fd89f".into(),
295            color_status_warning_background_1: "#fff9f5".into(),
296            color_status_warning_foreground_3: "#bc4b09".into(),
297            color_status_warning_border_1: "#fdcfb4".into(),
298            color_status_danger_background_1: "#fdf3f4".into(),
299            color_status_danger_foreground_1: "#b10e1c".into(),
300            color_status_danger_border_1: "#eeacb2".into(),
301
302            color_subtle_background: "transparent".into(),
303            color_subtle_background_hover: "#f5f5f5".into(),
304            color_subtle_background_pressed: "#e0e0e0".into(),
305            color_transparent_background: "transparent".into(),
306            color_transparent_background_hover: "transparent".into(),
307            color_transparent_background_pressed: "transparent".into(),
308            color_transparent_stroke: "transparent".into(),
309
310            shadow4: "0 0 2px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.14)".into(),
311            shadow8: "0 0 2px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.14)".into(),
312            shadow16: "0 0 2px rgba(0,0,0,0.12), 0 8px 16px rgba(0,0,0,0.14)".into(),
313            shadow64: "0 0 8px rgba(0,0,0,0.12), 0 32px 64px rgba(0,0,0,0.14)".into(),
314        }
315    }
316
317    pub fn dark() -> Self {
318        Self {
319            color_scheme: "dark".into(),
320
321            color_neutral_background_static: "#3d3d3d".into(),
322            color_neutral_background_inverted: "#ffffff".into(),
323            color_neutral_background_disabled: "#141414".into(),
324            color_neutral_background_1: "#292929".into(),
325            color_neutral_background_1_hover: "#3d3d3d".into(),
326            color_neutral_background_1_pressed: "#1f1f1f".into(),
327            color_neutral_background_3: "#141414".into(),
328            color_neutral_background_3_hover: "#292929".into(),
329            color_neutral_background_3_pressed: "#0a0a0a".into(),
330            color_neutral_background_4: "#0a0a0a".into(),
331            color_neutral_background_4_hover: "#1f1f1f".into(),
332            color_neutral_background_4_pressed: "#000000".into(),
333            color_neutral_background_5: "#000000".into(),
334            color_neutral_background_6: "#333333".into(),
335
336            color_neutral_foreground_static_inverted: "#ffffff".into(),
337            color_neutral_foreground_disabled: "#5c5c5c".into(),
338            color_neutral_foreground_1: "#fff".into(),
339            color_neutral_foreground_1_hover: "#fff".into(),
340            color_neutral_foreground_1_pressed: "#fff".into(),
341            color_neutral_foreground_2: "#d6d6d6".into(),
342            color_neutral_foreground_2_hover: "#fff".into(),
343            color_neutral_foreground_2_pressed: "#fff".into(),
344            color_neutral_foreground_2_brand_hover: "#479ef5".into(),
345            color_neutral_foreground_2_brand_pressed: "#2886de".into(),
346            color_neutral_foreground_2_brand_selected: "#479ef5".into(),
347            color_neutral_foreground_3: "#adadad".into(),
348            color_neutral_foreground_4: "#999999".into(),
349            color_neutral_foreground_on_brand: "#fff".into(),
350            color_neutral_foreground_inverted: "#242424".into(),
351
352            color_neutral_stroke_disabled: "#424242".into(),
353            color_neutral_stroke_1: "#666666".into(),
354            color_neutral_stroke_1_hover: "#757575".into(),
355            color_neutral_stroke_1_pressed: "#6b6b6b".into(),
356            color_neutral_stroke_2: "#525252".into(),
357            color_neutral_stroke_accessible: "#adadad".into(),
358            color_neutral_stroke_accessible_hover: "#bdbdbd".into(),
359            color_neutral_stroke_accessible_pressed: "#b3b3b3".into(),
360
361            color_neutral_shadow_ambient: "rgba(0,0,0,0.24)".into(),
362            color_neutral_shadow_key: "rgba(0,0,0,0.28)".into(),
363
364            color_neutral_stencil_1: "#575757".into(),
365            color_neutral_stencil_2: "#333333".into(),
366
367            color_compound_brand_foreground_1: "#479ef5".into(),
368            color_compound_brand_foreground_1_hover: "#62abf5".into(),
369            color_compound_brand_foreground_1_pressed: "#2886de".into(),
370
371            color_compound_brand_background: "#479ef5".into(),
372            color_compound_brand_background_hover: "#62abf5".into(),
373            color_compound_brand_background_pressed: "#2886de".into(),
374            color_compound_brand_stroke: "#479ef5".into(),
375            color_compound_brand_stroke_pressed: "#2886de".into(),
376
377            color_brand_background: "#115ea3".into(),
378            color_brand_background_hover: "#0f6cbd".into(),
379            color_brand_background_pressed: "#0c3b5e".into(),
380            color_brand_background_2: "#082338".into(),
381            color_brand_foreground_1: "#479ef5".into(),
382            color_brand_foreground_2: "#62abf5".into(),
383            color_brand_stroke_1: "#479ef5".into(),
384            color_brand_stroke_2: "#0e4775".into(),
385            color_brand_stroke_2_contrast: "#0e4775".into(),
386            color_brand_foreground_link: "#479ef5".into(),
387            color_brand_foreground_link_hover: "#62abf5".into(),
388            color_brand_foreground_link_pressed: "#2886de".into(),
389
390            color_stroke_focus_2: "#ffffff".into(),
391
392            color_palette_red_background_1: "#3f1011".into(),
393            color_palette_red_background_3: "#d13438".into(),
394            color_palette_red_foreground_1: "#e37d80".into(),
395            color_palette_red_foreground_3: "#e37d80".into(),
396            color_palette_red_border_1: "#d13438".into(),
397            color_palette_red_border_2: "#e37d80".into(),
398            color_palette_green_background_1: "#052505".into(),
399            color_palette_green_background_3: "#107c10".into(),
400            color_palette_green_foreground_1: "#54b054".into(),
401            color_palette_green_foreground_3: "#9fd89f".into(),
402            color_palette_green_border_1: "#107c10".into(),
403            color_palette_green_border_2: "#9fd89f".into(),
404            color_palette_yellow_background_1: "#4c4400".into(),
405            color_palette_yellow_background_3: "#fde300".into(),
406            color_palette_yellow_foreground_1: "#feee66".into(),
407            color_palette_yellow_foreground_2: "#fef7b2".into(),
408            color_palette_yellow_border_1: "#fde300".into(),
409
410            color_palette_dark_orange_background_1: "#411200".into(),
411            color_palette_dark_orange_background_3: "#da3b01".into(),
412            color_palette_dark_orange_foreground_1: "#e9835e".into(),
413            color_palette_dark_orange_foreground_3: "#e9835e".into(),
414            color_palette_dark_orange_border_1: "#da3b01".into(),
415
416            color_status_success_background_1: "#052505".into(),
417            color_status_success_foreground_1: "#54b054".into(),
418            color_status_success_border_1: "#107c10".into(),
419            color_status_warning_background_1: "#4a1e04".into(),
420            color_status_warning_foreground_3: "#f98845".into(),
421            color_status_warning_border_1: "#f7630c".into(),
422            color_status_danger_background_1: "#3b0509".into(),
423            color_status_danger_foreground_1: "#dc626d".into(),
424            color_status_danger_border_1: "#c50f1f".into(),
425
426            color_subtle_background: "transparent".into(),
427            color_subtle_background_hover: "#383838".into(),
428            color_subtle_background_pressed: "#2e2e2e".into(),
429            color_transparent_background: "transparent".into(),
430            color_transparent_background_hover: "transparent".into(),
431            color_transparent_background_pressed: "transparent".into(),
432            color_transparent_stroke: "transparent".into(),
433
434            shadow4: "0 0 2px rgba(0,0,0,0.24), 0 2px 4px rgba(0,0,0,0.28)".into(),
435            shadow8: "0 0 2px rgba(0,0,0,0.24), 0 4px 8px rgba(0,0,0,0.28)".into(),
436            shadow16: "0 0 2px rgba(0,0,0,0.24), 0 8px 16px rgba(0,0,0,0.28)".into(),
437            shadow64: "0 0 8px rgba(0,0,0,0.24), 0 32px 64px rgba(0,0,0,0.28)".into(),
438        }
439    }
440}