Skip to main content

freya_components/theming/
themes.rs

1use std::time::Duration;
2
3use freya_core::prelude::*;
4#[cfg(feature = "titlebar")]
5use torin::prelude::Length;
6use torin::{
7    gaps::Gaps,
8    size::Size,
9};
10
11#[cfg(feature = "calendar")]
12use crate::calendar::CalendarThemePreference;
13#[cfg(feature = "router")]
14use crate::link::LinkThemePreference;
15#[cfg(feature = "titlebar")]
16use crate::titlebar::TitlebarButtonThemePreference;
17use crate::{
18    accordion::AccordionThemePreference,
19    button::{
20        ButtonColorsThemePreference,
21        ButtonLayoutThemePreference,
22    },
23    card::{
24        CardColorsThemePreference,
25        CardLayoutThemePreference,
26    },
27    checkbox::CheckboxThemePreference,
28    chip::ChipThemePreference,
29    color_picker::ColorPickerThemePreference,
30    floating_tab::FloatingTabThemePreference,
31    input::{
32        InputColorsThemePreference,
33        InputLayoutThemePreference,
34    },
35    loader::CircularLoaderThemePreference,
36    menu::{
37        MenuContainerThemePreference,
38        MenuItemThemePreference,
39    },
40    popup::PopupThemePreference,
41    progressbar::ProgressBarThemePreference,
42    radio_item::RadioItemThemePreference,
43    resizable_container::ResizableHandleThemePreference,
44    scrollviews::ScrollBarThemePreference,
45    segmented_button::{
46        ButtonSegmentThemePreference,
47        SegmentedButtonThemePreference,
48    },
49    select::SelectThemePreference,
50    sidebar::SideBarItemThemePreference,
51    skeleton::{
52        SkeletonAnimation,
53        SkeletonThemePreference,
54    },
55    slider::SliderThemePreference,
56    switch::{
57        SwitchColorsThemePreference,
58        SwitchLayoutThemePreference,
59    },
60    table::TableThemePreference,
61    theming::{
62        component_themes::{
63            ColorsSheet,
64            Theme,
65        },
66        macros::Preference,
67    },
68    tooltip::TooltipThemePreference,
69    typography::TypographyThemePreference,
70};
71
72pub const LIGHT_COLORS: ColorsSheet = ColorsSheet {
73    // Brand & Accent
74    primary: Color::from_rgb(103, 80, 164),
75    secondary: Color::from_rgb(202, 193, 227),
76    tertiary: Color::from_rgb(79, 61, 130),
77
78    // Status
79    success: Color::from_rgb(76, 175, 80),
80    warning: Color::from_rgb(255, 193, 7),
81    error: Color::from_rgb(244, 67, 54),
82    info: Color::from_rgb(33, 150, 243),
83
84    // Surfaces
85    background: Color::from_rgb(250, 250, 250),
86    surface_primary: Color::from_rgb(210, 210, 210),
87    surface_secondary: Color::from_rgb(225, 225, 225),
88    surface_tertiary: Color::from_rgb(245, 245, 245),
89    surface_inverse: Color::from_rgb(125, 125, 125),
90    surface_inverse_secondary: Color::from_rgb(110, 110, 110),
91    surface_inverse_tertiary: Color::from_rgb(90, 90, 90),
92
93    // Borders
94    border: Color::from_rgb(210, 210, 210),
95    border_focus: Color::from_rgb(180, 180, 180),
96    border_disabled: Color::from_rgb(210, 210, 210),
97
98    // Text
99    text_primary: Color::from_rgb(10, 10, 10),
100    text_secondary: Color::from_rgb(100, 100, 100),
101    text_placeholder: Color::from_rgb(150, 150, 150),
102    text_inverse: Color::WHITE,
103    text_highlight: Color::from_rgb(38, 89, 170),
104
105    // States
106    focus: Color::from_rgb(225, 225, 255),
107    active: Color::from_rgb(200, 200, 200),
108    disabled: Color::from_rgb(210, 210, 210),
109
110    // Utility
111    overlay: Color::from_af32rgb(0.5, 0, 0, 0),
112    shadow: Color::from_af32rgb(0.2, 0, 0, 0),
113};
114
115pub const DARK_COLORS: ColorsSheet = ColorsSheet {
116    // Brand & Accent
117    primary: Color::from_rgb(103, 80, 164),
118    secondary: Color::from_rgb(202, 193, 227),
119    tertiary: Color::from_rgb(79, 61, 130),
120
121    // Status
122    success: Color::from_rgb(129, 199, 132),
123    warning: Color::from_rgb(255, 213, 79),
124    error: Color::from_rgb(229, 115, 115),
125    info: Color::from_rgb(100, 181, 246),
126
127    // Surfaces
128    background: Color::from_rgb(20, 20, 20),
129    surface_primary: Color::from_rgb(60, 60, 60),
130    surface_secondary: Color::from_rgb(45, 45, 45),
131    surface_tertiary: Color::from_rgb(25, 25, 25),
132    surface_inverse: Color::from_rgb(135, 135, 135),
133    surface_inverse_secondary: Color::from_rgb(150, 150, 150),
134    surface_inverse_tertiary: Color::from_rgb(170, 170, 170),
135
136    // Borders
137    border: Color::from_rgb(60, 60, 60),
138    border_focus: Color::from_rgb(110, 110, 110),
139    border_disabled: Color::from_rgb(80, 80, 80),
140
141    // Text
142    text_primary: Color::from_rgb(250, 250, 250),
143    text_secondary: Color::from_rgb(210, 210, 210),
144    text_placeholder: Color::from_rgb(150, 150, 150),
145    text_inverse: Color::WHITE,
146    text_highlight: Color::from_rgb(96, 145, 224),
147
148    // States
149    focus: Color::from_rgb(100, 100, 120),
150    active: Color::from_rgb(70, 70, 70),
151    disabled: Color::from_rgb(50, 50, 50),
152
153    // Utility
154    overlay: Color::from_af32rgb(0.2, 255, 255, 255),
155    shadow: Color::from_af32rgb(0.6, 0, 0, 0),
156};
157
158fn register_base_component_themes(theme: &mut Theme) {
159    theme.set(
160        "typography",
161        TypographyThemePreference {
162            title: Preference::Specific(24.0),
163            subtitle: Preference::Specific(18.0),
164            body: Preference::Specific(16.0),
165            caption: Preference::Specific(12.0),
166            overline: Preference::Specific(11.0),
167        },
168    );
169    theme.set(
170        "button_layout",
171        ButtonLayoutThemePreference {
172            padding: Preference::Specific(Gaps::new(6., 12., 6., 12.)),
173            margin: Preference::Specific(Gaps::new_all(0.)),
174            corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
175            width: Preference::Specific(Size::Inner),
176            height: Preference::Specific(Size::Inner),
177        },
178    );
179    theme.set(
180        "compact_button_layout",
181        ButtonLayoutThemePreference {
182            padding: Preference::Specific(Gaps::new(3., 6., 3., 6.)),
183            margin: Preference::Specific(Gaps::new_all(0.)),
184            corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
185            width: Preference::Specific(Size::Inner),
186            height: Preference::Specific(Size::Inner),
187        },
188    );
189    theme.set(
190        "expanded_button_layout",
191        ButtonLayoutThemePreference {
192            padding: Preference::Specific(Gaps::new(10., 16., 10., 16.)),
193            margin: Preference::Specific(Gaps::new_all(0.)),
194            corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
195            width: Preference::Specific(Size::Inner),
196            height: Preference::Specific(Size::Inner),
197        },
198    );
199    theme.set(
200        "button",
201        ButtonColorsThemePreference {
202            background: Preference::Reference("surface_tertiary"),
203            hover_background: Preference::Reference("surface_secondary"),
204            border_fill: Preference::Reference("border"),
205            focus_border_fill: Preference::Reference("border_focus"),
206            color: Preference::Reference("text_primary"),
207        },
208    );
209    theme.set(
210        "filled_button",
211        ButtonColorsThemePreference {
212            background: Preference::Reference("primary"),
213            hover_background: Preference::Reference("tertiary"),
214            border_fill: Preference::Specific(Color::TRANSPARENT),
215            focus_border_fill: Preference::Reference("secondary"),
216            color: Preference::Reference("text_inverse"),
217        },
218    );
219    theme.set(
220        "outline_button",
221        ButtonColorsThemePreference {
222            background: Preference::Reference("surface_tertiary"),
223            hover_background: Preference::Reference("surface_secondary"),
224            border_fill: Preference::Reference("border"),
225            focus_border_fill: Preference::Reference("secondary"),
226            color: Preference::Reference("primary"),
227        },
228    );
229    theme.set(
230        "flat_button",
231        ButtonColorsThemePreference {
232            background: Preference::Specific(Color::TRANSPARENT),
233            hover_background: Preference::Reference("surface_tertiary"),
234            border_fill: Preference::Specific(Color::TRANSPARENT),
235            focus_border_fill: Preference::Reference("border"),
236            color: Preference::Reference("text_primary"),
237        },
238    );
239    theme.set(
240        "card_layout",
241        CardLayoutThemePreference {
242            padding: Preference::Specific(Gaps::new(16., 16., 16., 16.)),
243            corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
244        },
245    );
246    theme.set(
247        "compact_card_layout",
248        CardLayoutThemePreference {
249            padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
250            corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
251        },
252    );
253    theme.set(
254        "filled_card",
255        CardColorsThemePreference {
256            background: Preference::Reference("primary"),
257            hover_background: Preference::Reference("tertiary"),
258            border_fill: Preference::Specific(Color::TRANSPARENT),
259            color: Preference::Reference("text_inverse"),
260            shadow: Preference::Reference("shadow"),
261        },
262    );
263    theme.set(
264        "outline_card",
265        CardColorsThemePreference {
266            background: Preference::Reference("surface_tertiary"),
267            hover_background: Preference::Reference("surface_secondary"),
268            border_fill: Preference::Reference("border"),
269            color: Preference::Reference("text_primary"),
270            shadow: Preference::Reference("shadow"),
271        },
272    );
273    theme.set(
274        "accordion",
275        AccordionThemePreference {
276            color: Preference::Reference("text_primary"),
277            background: Preference::Reference("surface_tertiary"),
278            border_fill: Preference::Reference("border"),
279        },
280    );
281    theme.set(
282        "switch",
283        SwitchColorsThemePreference {
284            background: Preference::Reference("surface_secondary"),
285            thumb_background: Preference::Reference("surface_inverse"),
286            toggled_background: Preference::Reference("secondary"),
287            toggled_thumb_background: Preference::Reference("primary"),
288            focus_border_fill: Preference::Reference("border_focus"),
289        },
290    );
291    theme.set(
292        "switch_layout",
293        SwitchLayoutThemePreference {
294            margin: Preference::Specific(Gaps::new_all(0.)),
295            width: Preference::Specific(48.),
296            height: Preference::Specific(28.),
297            padding: Preference::Specific(4.),
298            thumb_size: Preference::Specific(16.),
299            toggled_thumb_size: Preference::Specific(20.),
300            pressed_thumb_size_offset: Preference::Specific(4.),
301            thumb_offset: Preference::Specific(2.),
302            toggled_thumb_offset: Preference::Specific(20.),
303        },
304    );
305    theme.set(
306        "expanded_switch_layout",
307        SwitchLayoutThemePreference {
308            margin: Preference::Specific(Gaps::new_all(0.)),
309            width: Preference::Specific(56.),
310            height: Preference::Specific(32.),
311            padding: Preference::Specific(4.),
312            thumb_size: Preference::Specific(18.),
313            toggled_thumb_size: Preference::Specific(22.),
314            pressed_thumb_size_offset: Preference::Specific(4.),
315            thumb_offset: Preference::Specific(2.),
316            toggled_thumb_offset: Preference::Specific(26.),
317        },
318    );
319    theme.set(
320        "scrollbar",
321        ScrollBarThemePreference {
322            background: Preference::Reference("surface_primary"),
323            thumb_background: Preference::Reference("surface_inverse"),
324            hover_thumb_background: Preference::Reference("surface_inverse_secondary"),
325            active_thumb_background: Preference::Reference("surface_inverse_tertiary"),
326            size: Preference::Specific(15.),
327        },
328    );
329    theme.set(
330        "progressbar",
331        ProgressBarThemePreference {
332            color: Preference::Reference("text_inverse"),
333            background: Preference::Reference("surface_primary"),
334            progress_background: Preference::Reference("primary"),
335            height: Preference::Specific(20.),
336        },
337    );
338    theme.set(
339        "sidebar_item",
340        SideBarItemThemePreference {
341            color: Preference::Reference("text_primary"),
342            background: Preference::Reference("surface_tertiary"),
343            active_background: Preference::Reference("surface_secondary"),
344            hover_background: Preference::Reference("surface_secondary"),
345            focus_border_fill: Preference::Reference("border_focus"),
346            corner_radius: Preference::Specific(CornerRadius::new_all(12.)),
347            margin: Preference::Specific(Gaps::new_all(0.)),
348            padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
349        },
350    );
351    #[cfg(feature = "router")]
352    theme.set(
353        "link",
354        LinkThemePreference {
355            color: Preference::Reference("text_highlight"),
356        },
357    );
358    theme.set(
359        "tooltip",
360        TooltipThemePreference {
361            background: Preference::Reference("surface_tertiary"),
362            color: Preference::Reference("text_primary"),
363            border_fill: Preference::Reference("surface_primary"),
364            font_size: Preference::Specific(14.),
365        },
366    );
367    theme.set(
368        "circular_loader",
369        CircularLoaderThemePreference {
370            primary_color: Preference::Reference("surface_primary"),
371        },
372    );
373    theme.set(
374        "input_layout",
375        InputLayoutThemePreference {
376            corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
377            inner_margin: Preference::Specific(Gaps::new(8., 8., 8., 8.)),
378        },
379    );
380    theme.set(
381        "compact_input_layout",
382        InputLayoutThemePreference {
383            corner_radius: Preference::Specific(CornerRadius::new_all(4.)),
384            inner_margin: Preference::Specific(Gaps::new(4., 6., 4., 6.)),
385        },
386    );
387    theme.set(
388        "expanded_input_layout",
389        InputLayoutThemePreference {
390            corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
391            inner_margin: Preference::Specific(Gaps::new(12., 12., 12., 12.)),
392        },
393    );
394    theme.set(
395        "input",
396        InputColorsThemePreference {
397            background: Preference::Reference("surface_tertiary"),
398            focus_background: Preference::Reference("background"),
399            color: Preference::Reference("text_primary"),
400            placeholder_color: Preference::Reference("text_secondary"),
401            border_fill: Preference::Reference("border"),
402            focus_border_fill: Preference::Reference("border_focus"),
403        },
404    );
405    theme.set(
406        "filled_input",
407        InputColorsThemePreference {
408            background: Preference::Reference("primary"),
409            focus_background: Preference::Reference("tertiary"),
410            color: Preference::Reference("text_inverse"),
411            placeholder_color: Preference::Reference("text_inverse"),
412            border_fill: Preference::Specific(Color::TRANSPARENT),
413            focus_border_fill: Preference::Reference("secondary"),
414        },
415    );
416    theme.set(
417        "flat_input",
418        InputColorsThemePreference {
419            background: Preference::Specific(Color::TRANSPARENT),
420            focus_background: Preference::Reference("surface_tertiary"),
421            color: Preference::Reference("text_primary"),
422            placeholder_color: Preference::Reference("text_secondary"),
423            border_fill: Preference::Specific(Color::TRANSPARENT),
424            focus_border_fill: Preference::Reference("border"),
425        },
426    );
427    theme.set(
428        "radio",
429        RadioItemThemePreference {
430            unselected_fill: Preference::Reference("surface_inverse_tertiary"),
431            selected_fill: Preference::Reference("primary"),
432            border_fill: Preference::Reference("surface_primary"),
433        },
434    );
435    theme.set(
436        "checkbox",
437        CheckboxThemePreference {
438            unselected_fill: Preference::Reference("surface_inverse_tertiary"),
439            selected_fill: Preference::Reference("primary"),
440            selected_icon_fill: Preference::Reference("secondary"),
441            border_fill: Preference::Reference("surface_primary"),
442        },
443    );
444    theme.set(
445        "resizable_handle",
446        ResizableHandleThemePreference {
447            background: Preference::Reference("surface_secondary"),
448            hover_background: Preference::Reference("surface_primary"),
449            corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
450        },
451    );
452    theme.set(
453        "floating_tab",
454        FloatingTabThemePreference {
455            background: Preference::Specific(Color::TRANSPARENT),
456            hover_background: Preference::Reference("surface_secondary"),
457            color: Preference::Reference("text_primary"),
458            padding: Preference::Specific(Gaps::new(6., 12., 6., 12.)),
459            width: Preference::Specific(Size::Inner),
460            height: Preference::Specific(Size::Inner),
461            corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
462        },
463    );
464    theme.set(
465        "slider",
466        SliderThemePreference {
467            background: Preference::Reference("surface_primary"),
468            thumb_background: Preference::Reference("secondary"),
469            thumb_inner_background: Preference::Reference("primary"),
470            border_fill: Preference::Reference("surface_primary"),
471        },
472    );
473    theme.set(
474        "color_picker",
475        ColorPickerThemePreference {
476            background: Preference::Reference("surface_tertiary"),
477            border_fill: Preference::Reference("border"),
478            color: Preference::Reference("text_primary"),
479        },
480    );
481    theme.set(
482        "select",
483        SelectThemePreference {
484            width: Preference::Specific(Size::Inner),
485            margin: Preference::Specific(Gaps::new_all(0.)),
486            select_background: Preference::Reference("background"),
487            background_button: Preference::Reference("surface_tertiary"),
488            hover_background: Preference::Reference("surface_secondary"),
489            color: Preference::Reference("text_primary"),
490            border_fill: Preference::Reference("border"),
491            focus_border_fill: Preference::Reference("border_focus"),
492            arrow_fill: Preference::Reference("text_primary"),
493        },
494    );
495    theme.set(
496        "popup",
497        PopupThemePreference {
498            background: Preference::Reference("background"),
499            color: Preference::Reference("text_primary"),
500            width: Preference::Specific(Size::px(500.)),
501            height: Preference::Specific(Size::auto()),
502            padding: Preference::Specific(Gaps::new_all(8.)),
503            spacing: Preference::Specific(4.),
504        },
505    );
506    theme.set(
507        "table",
508        TableThemePreference {
509            background: Preference::Reference("background"),
510            arrow_fill: Preference::Reference("text_primary"),
511            row_background: Preference::Specific(Color::TRANSPARENT),
512            hover_row_background: Preference::Reference("surface_secondary"),
513            divider_fill: Preference::Reference("surface_primary"),
514            corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
515            color: Preference::Reference("text_primary"),
516        },
517    );
518    theme.set(
519        "chip",
520        ChipThemePreference {
521            background: Preference::Reference("background"),
522            hover_background: Preference::Reference("tertiary"),
523            selected_background: Preference::Reference("primary"),
524            border_fill: Preference::Reference("border"),
525            hover_border_fill: Preference::Reference("tertiary"),
526            selected_border_fill: Preference::Reference("primary"),
527            focus_border_fill: Preference::Reference("secondary"),
528            padding: Preference::Specific(Gaps::new(8., 14., 8., 14.)),
529            margin: Preference::Specific(0.),
530            corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
531            width: Preference::Specific(Size::Inner),
532            height: Preference::Specific(Size::Inner),
533            color: Preference::Reference("text_primary"),
534            hover_color: Preference::Reference("text_inverse"),
535            selected_color: Preference::Reference("text_inverse"),
536            selected_icon_fill: Preference::Reference("secondary"),
537            hover_icon_fill: Preference::Reference("secondary"),
538        },
539    );
540    theme.set(
541        "menu_item",
542        MenuItemThemePreference {
543            background: Preference::Specific(Color::TRANSPARENT),
544            hover_background: Preference::Reference("surface_secondary"),
545            select_background: Preference::Reference("surface_secondary"),
546            border_fill: Preference::Specific(Color::TRANSPARENT),
547            select_border_fill: Preference::Reference("border_focus"),
548            corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
549            color: Preference::Reference("text_primary"),
550        },
551    );
552    theme.set(
553        "menu_container",
554        MenuContainerThemePreference {
555            background: Preference::Reference("background"),
556            padding: Preference::Specific(Gaps::new_all(4.)),
557            shadow: Preference::Reference("shadow"),
558            border_fill: Preference::Reference("surface_primary"),
559            corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
560        },
561    );
562    theme.set(
563        "button_segment",
564        ButtonSegmentThemePreference {
565            background: Preference::Reference("surface_tertiary"),
566            hover_background: Preference::Reference("surface_secondary"),
567            disabled_background: Preference::Reference("disabled"),
568            selected_background: Preference::Reference("surface_secondary"),
569            focus_background: Preference::Reference("surface_secondary"),
570            padding: Preference::Specific(Gaps::new(8., 16., 8., 16.)),
571            selected_padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
572            width: Preference::Specific(Size::Inner),
573            height: Preference::Specific(Size::Inner),
574            color: Preference::Reference("text_primary"),
575            selected_icon_fill: Preference::Reference("primary"),
576        },
577    );
578    theme.set(
579        "segmented_button",
580        SegmentedButtonThemePreference {
581            background: Preference::Reference("surface_tertiary"),
582            border_fill: Preference::Reference("border"),
583            corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
584        },
585    );
586    #[cfg(feature = "calendar")]
587    theme.set(
588        "calendar",
589        CalendarThemePreference {
590            background: Preference::Reference("surface_tertiary"),
591            day_background: Preference::Specific(Color::TRANSPARENT),
592            day_hover_background: Preference::Reference("surface_secondary"),
593            day_selected_background: Preference::Reference("surface_primary"),
594            color: Preference::Reference("text_primary"),
595            day_other_month_color: Preference::Reference("text_placeholder"),
596            header_color: Preference::Reference("text_primary"),
597            corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
598            padding: Preference::Specific(Gaps::new_all(12.)),
599            day_corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
600            nav_button_hover_background: Preference::Reference("surface_secondary"),
601        },
602    );
603    #[cfg(feature = "titlebar")]
604    theme.set(
605        "titlebar_button",
606        TitlebarButtonThemePreference {
607            background: Preference::Specific(Color::TRANSPARENT),
608            hover_background: Preference::Reference("surface_secondary"),
609            corner_radius: Preference::Specific(CornerRadius::new_all(0.0)),
610            width: Preference::Specific(Size::Pixels(Length::new(46.0))),
611            height: Preference::Specific(Size::Fill),
612        },
613    );
614    theme.set(
615        "skeleton",
616        SkeletonThemePreference {
617            background: Preference::Reference("surface_primary"),
618            shimmer_color: Preference::Specific(Color::WHITE.with_a(160)),
619            duration: Preference::Specific(Duration::from_millis(1000)),
620            animation: Preference::Specific(SkeletonAnimation::Pulse),
621            corner_radius: Preference::Specific(CornerRadius::new_all(4.)),
622            shimmer_from: Preference::Specific(-320.),
623            shimmer_to: Preference::Specific(960.),
624            shimmer_width: Preference::Specific(300.),
625        },
626    );
627}
628
629/// Light theme with all built-in component themes registered.
630///
631/// The primary color tracks the OS-level [`AccentColor`] when available; the
632/// secondary and tertiary colors are derived from it (lightened / darkened).
633pub fn light_theme() -> Theme {
634    build_theme("light", LIGHT_COLORS)
635}
636
637/// Dark theme with all built-in component themes registered.
638///
639/// The primary color tracks the OS-level [`AccentColor`] when available; the
640/// secondary and tertiary colors are derived from it (lightened / darkened).
641pub fn dark_theme() -> Theme {
642    build_theme("dark", DARK_COLORS)
643}
644
645fn build_theme(name: &'static str, mut colors: ColorsSheet) -> Theme {
646    if let Some(primary) = current_accent_color() {
647        colors.primary = primary;
648        colors.secondary = Color::lerp(primary, Color::WHITE, 0.65);
649        colors.tertiary = Color::lerp(primary, Color::BLACK, 0.23);
650    }
651    let mut theme = Theme::new(name, colors);
652    register_base_component_themes(&mut theme);
653    theme
654}
655
656fn current_accent_color() -> Option<Color> {
657    let platform: Platform = try_consume_root_context()?;
658    let accent = platform.accent_color.read().0?;
659    let [r, g, b, _] = accent.to_u8_array();
660    Some(Color::from_rgb(r, g, b))
661}