Skip to main content

orbital_shell/tokens/
motion.rs

1//! Motion duration, easing, and named presets.
2
3/// Durations aligned with the Orbital motion scale.
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
5pub enum MotionDuration {
6    Ultrafast,
7    Faster,
8    Fast,
9    Normal,
10    Slow,
11    Slower,
12}
13
14impl MotionDuration {
15    pub const fn as_class(self) -> &'static str {
16        match self {
17            Self::Ultrafast => "orbital-token-motion-ultrafast",
18            Self::Faster => "orbital-token-motion-faster",
19            Self::Fast => "orbital-token-motion-fast",
20            Self::Normal => "orbital-token-motion-normal",
21            Self::Slow => "orbital-token-motion-slow",
22            Self::Slower => "orbital-token-motion-slower",
23        }
24    }
25
26    pub const fn as_token(self) -> &'static str {
27        match self {
28            Self::Ultrafast => "50ms",
29            Self::Faster => "100ms",
30            Self::Fast => "200ms",
31            Self::Normal => "250ms",
32            Self::Slow => "400ms",
33            Self::Slower => "600ms",
34        }
35    }
36}
37
38/// Easing curves.
39#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
40pub enum MotionEasing {
41    Linear,
42    EaseIn,
43    EaseOut,
44    EaseInOut,
45    Decelerate,
46    Accelerate,
47}
48
49impl MotionEasing {
50    pub const fn as_class(self) -> &'static str {
51        match self {
52            Self::Linear => "orbital-token-ease-linear",
53            Self::EaseIn => "orbital-token-ease-in",
54            Self::EaseOut => "orbital-token-ease-out",
55            Self::EaseInOut => "orbital-token-ease-in-out",
56            Self::Decelerate => "orbital-token-ease-decelerate",
57            Self::Accelerate => "orbital-token-ease-accelerate",
58        }
59    }
60
61    pub const fn as_token(self) -> &'static str {
62        match self {
63            Self::Linear => "linear",
64            Self::EaseIn => "ease-in",
65            Self::EaseOut => "ease-out",
66            Self::EaseInOut => "ease-in-out",
67            Self::Decelerate => "cubic-bezier(0, 0, 0, 1)",
68            Self::Accelerate => "cubic-bezier(1, 0, 1, 1)",
69        }
70    }
71}
72
73/// Named motion recipes (duration + easing) for marketing surfaces.
74#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
75pub enum MotionPreset {
76    /// Coachmarks, info-label popovers.
77    EnterPopover,
78    ExitPopover,
79    /// Family card on intersection enter.
80    RevealCard,
81    /// Card hover lift (`translateY(-1px)`).
82    HoverLift,
83    /// Route transitions between marketing pages.
84    TopLevelPageFade,
85    /// Capability tab underline slide.
86    TabIndicatorSlide,
87    /// Sponsor progress bar fill on mount.
88    ProgressFill,
89}
90
91impl MotionPreset {
92    pub const fn as_class(self) -> &'static str {
93        match self {
94            Self::EnterPopover => "orbital-token-motion-enter-popover",
95            Self::ExitPopover => "orbital-token-motion-exit-popover",
96            Self::RevealCard => "orbital-token-motion-reveal-card",
97            Self::HoverLift => "orbital-token-motion-hover-lift",
98            Self::TopLevelPageFade => "orbital-token-motion-page-fade",
99            Self::TabIndicatorSlide => "orbital-token-motion-tab-slide",
100            Self::ProgressFill => "orbital-token-motion-progress-fill",
101        }
102    }
103
104    /// CSS `transition` shorthand fragment (property left to caller).
105    pub const fn transition_timing(self) -> &'static str {
106        match self {
107            Self::EnterPopover => "100ms ease-out",
108            Self::ExitPopover => "100ms ease-in",
109            Self::RevealCard => "250ms ease-out",
110            Self::HoverLift => "50ms ease-out",
111            Self::TopLevelPageFade => "200ms ease-in-out",
112            Self::TabIndicatorSlide => "200ms ease-in-out",
113            Self::ProgressFill => "400ms ease-in-out",
114        }
115    }
116}