diff --git a/src/components/onboarding/OnboardingFlow.tsx b/src/components/onboarding/OnboardingFlow.tsx
index cd7b1ba..8382c01 100644
--- a/src/components/onboarding/OnboardingFlow.tsx
+++ b/src/components/onboarding/OnboardingFlow.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useState } from 'react';
+import { useState } from 'react';
import {
ActivityIndicator,
ScrollView,
@@ -11,9 +11,8 @@ import Animated, {
FadeIn,
FadeInDown,
FadeOutUp,
- useAnimatedStyle,
- useSharedValue,
- withTiming,
+ LinearTransition,
+ ReduceMotion,
} from 'react-native-reanimated';
import { Canvas, LinearGradient, Rect, vec } from '@shopify/react-native-skia';
import { Ionicons } from '@expo/vector-icons';
@@ -69,6 +68,10 @@ const WIZARD_THEME_OPTIONS: { id: BaseThemeId; title: string }[] = [
{ id: 'materialYou', title: 'Material You' },
];
+const DOT_TRANSITION = LinearTransition.duration(motion.snap.duration).reduceMotion(
+ ReduceMotion.System
+);
+
/**
* First-run wizard. Rendered by the root layout instead of the app tree while
* `onboarding_complete` is unset. Purely presentational — it drives the existing
@@ -421,15 +424,12 @@ function ScanBanner() {
/** Page indicator dot — widens + brightens when active. Animated View, not an icon. */
function Dot({ active }: { active: boolean }) {
const styles = useStyles();
- const progress = useSharedValue(active ? 1 : 0);
- useEffect(() => {
- progress.value = withTiming(active ? 1 : 0, motion.snap);
- }, [active, progress]);
- const animatedStyle = useAnimatedStyle(() => ({
- width: 8 + progress.value * 14,
- opacity: 0.3 + progress.value * 0.7,
- }));
- return ;
+ return (
+
+ );
}
const useStyles = createThemedStyles((colors) => ({
@@ -568,6 +568,14 @@ const useStyles = createThemedStyles((colors) => ({
borderRadius: 4,
backgroundColor: colors.accent,
},
+ dotActive: {
+ width: 22,
+ opacity: 1,
+ },
+ dotInactive: {
+ width: 8,
+ opacity: 0.3,
+ },
navRow: {
flexDirection: 'row',
alignItems: 'center',