diff --git a/src/quo/animated.cljs b/src/quo/animated.cljs
index 751ce656611..6402746575f 100644
--- a/src/quo/animated.cljs
+++ b/src/quo/animated.cljs
@@ -51,7 +51,8 @@
 (def bezier (.-bezier ^js Easing))
 (def linear (.-linear ^js Easing))
 
-(def easings {:ease-in     (bezier 0.42 0 1 1)
+(def easings {:linear      linear
+              :ease-in     (bezier 0.42 0 1 1)
               :ease-out    (bezier 0 0 0.58 1)
               :ease-in-out (bezier 0.42 0 0.58 1)})
 
@@ -182,6 +183,31 @@
 (defn snap-point [value velocity snap-points]
   (.snapPoint ^js redash value velocity (to-array snap-points)))
 
+(defn cancelable-loop
+  [{:keys [clock duration finished on-reach]}]
+  (let [time       (value 0)
+        frame-time (value 0)
+        position   (value 0)
+        to-value   (value 1)
+        state      {:time      time
+                    :frameTime frame-time
+                    :finished  finished
+                    :position  position}
+        config     {:toValue  to-value
+                    :duration duration
+                    :easing   (:linear easings)}]
+    (block
+     [(timing clock state config)
+      (cond* (and* finished
+                   (eq position to-value))
+             (call* [] on-reach))
+      (cond* finished
+             [(set finished 0)
+              (set time 0)
+              (set frame-time 0)
+              (set position 0)])
+      position])))
+
 (defn with-easing
   [{val   :value
     :keys [snap-points velocity offset state easing duration on-snap]
diff --git a/src/quo/react_native.cljs b/src/quo/react_native.cljs
index 669a3815d08..3ec796860ab 100644
--- a/src/quo/react_native.cljs
+++ b/src/quo/react_native.cljs
@@ -8,7 +8,7 @@
 (def platform (.-Platform ^js rn))
 
 (def view (reagent/adapt-react-class (.-View ^js rn)))
-
+(def image (reagent/adapt-react-class (.-Image rn)))
 (def text (reagent/adapt-react-class (.-Text ^js rn)))
 
 (def scroll-view (reagent/adapt-react-class (.-ScrollView ^js rn)))
diff --git a/src/status_im/ui/screens/intro/carousel.cljs b/src/status_im/ui/screens/intro/carousel.cljs
new file mode 100644
index 00000000000..b061cd55daa
--- /dev/null
+++ b/src/status_im/ui/screens/intro/carousel.cljs
@@ -0,0 +1,129 @@
+(ns status-im.ui.screens.intro.carousel
+  (:require [quo.animated :as animated]
+            [quo.react-native :as rn]
+            [quo.core :as quo]
+            [reagent.core :as r]
+            [status-im.i18n :as i18n]
+            [status-im.ui.screens.intro.styles :as styles]))
+
+(defn dot []
+  (let [active            (animated/value 0)
+        active-transition (animated/with-timing-transition active {:duration 100})]
+    (fn [{:keys [selected progress]}]
+      [animated/view {:style (styles/dot-style active-transition)}
+       [animated/code {:exec (animated/set active (if selected 1 0))}]
+       [animated/view {:style (styles/dot-progress active-transition progress)}]])))
+
+(defn dots-selector [{:keys [n selected progress]}]
+  [rn/view {:style (styles/dot-selector)}
+   (for [i (range n)]
+     ^{:key i}
+     [dot {:progress progress
+           :selected (= selected i)}])])
+
+(defn viewer [slides window-height _]
+  (let [scroll-x          (r/atom 0)
+        scroll-view-ref   (atom nil)
+        width             (r/atom 0)
+        height            (r/atom 0)
+        text-height       (r/atom 0)
+        index             (r/atom 0)
+        manual-scroll     (atom false)
+        text-temp-height  (atom 0)
+        text-temp-timer   (atom nil)
+        bottom-margin     (if (> window-height 600) 32 16)
+        progress          (animated/value 1)
+        autoscroll        (animated/value 1)
+        finished          (animated/value 0)
+        clock             (animated/clock)
+        go-next           (fn []
+                            (let [x (if (>= @scroll-x (* (dec (count slides))
+                                                         @width))
+                                      0
+                                      (+ @scroll-x @width))]
+                              (reset! index (Math/round (/ x @width)))
+                              (some-> ^js @scroll-view-ref (.scrollTo #js {:x x :animated true}))))
+        code              (animated/block
+                           [(animated/cond* (animated/and* (animated/not* (animated/clock-running clock))
+                                                           autoscroll)
+                                            (animated/start-clock clock))
+                            (animated/cond* (animated/and* (animated/clock-running clock)
+                                                           (animated/not* autoscroll))
+                                            [(animated/stop-clock clock)
+                                             (animated/set finished 1)])
+                            (animated/set progress (animated/cancelable-loop
+                                                    {:clock    clock
+                                                     :finished finished
+                                                     :duration 4000
+                                                     :on-reach go-next}))])
+        cancel-animation  (fn []
+                            (reset! manual-scroll true)
+                            (animated/set-value autoscroll 0))
+        restart-animation (fn []
+                            (animated/set-value autoscroll 1))]
+    (fn [_ _ view-id]
+      (let [current-screen? (or (nil? view-id) (= view-id :intro))]
+        [rn/view {:style     {:align-items     :center
+                              :flex            1
+                              :margin-bottom   bottom-margin
+                              :justify-content :flex-end}
+                  :on-layout (fn [^js e]
+                               (when current-screen?
+                                 (reset! width (-> e .-nativeEvent .-layout .-width))))}
+         (when current-screen?
+           [animated/code {:exec code}])
+         [rn/scroll-view {:horizontal                        true
+                          :paging-enabled                    true
+                          :ref                               #(reset! scroll-view-ref %)
+                          :shows-vertical-scroll-indicator   false
+                          :shows-horizontal-scroll-indicator false
+                          :pinch-gesture-enabled             false
+                          :scroll-event-throttle             16
+                          :on-scroll                         #(let [x (.-nativeEvent.contentOffset.x ^js %)]
+                                                                (when @manual-scroll
+                                                                  ;; NOTE: Will be not synced if velocity is big
+                                                                  (reset! index (Math/round (/ x @width))))
+                                                                (reset! scroll-x x))
+                          :on-scroll-begin-drag              cancel-animation
+                          :on-scroll-end-drag                restart-animation
+                          :on-momentum-scroll-end            #(reset! manual-scroll false)
+                          :style                             {:margin-bottom bottom-margin}}
+          (doall
+           (for [s slides]
+             ^{:key (:title s)}
+             [rn/view {:style {:flex               1
+                               :width              @width
+                               :justify-content    :flex-end
+                               :align-items        :center
+                               :padding-horizontal 32}}
+              (let [size (min @width @height)]
+                [rn/view {:style     {:flex 1}
+                          :on-layout (fn [^js e]
+                                       (let [new-height (-> e .-nativeEvent .-layout .-height)]
+                                         (when current-screen?
+                                           (swap! height #(if (pos? %) (min % new-height) new-height)))))}
+                 [rn/image {:source      (:image s)
+                            :resize-mode :contain
+                            :style       {:width  size
+                                          :height size}}]])
+              [quo/text {:style  styles/wizard-title
+                         :align  :center
+                         :weight :bold
+                         :size   :x-large}
+               (i18n/label (:title s))]
+              [quo/text {:style (styles/wizard-text-with-height @text-height)
+                         :on-layout
+                         (fn [^js e]
+                           (let [new-height (-> e .-nativeEvent .-layout .-height)]
+                             (when (and current-screen?
+                                        (not= new-height @text-temp-height)
+                                        (not (zero? new-height))
+                                        (< new-height 200))
+                               (swap! text-temp-height #(if (pos? %) (max % new-height) new-height))
+                               (when @text-temp-timer (js/clearTimeout @text-temp-timer))
+                               (reset! text-temp-timer
+                                       (js/setTimeout #(reset! text-height @text-temp-height) 500)))))}
+               (i18n/label (:text s))]]))]
+         [dots-selector {:selected @index
+                         :progress progress
+                         :n        (count slides)}]]))))
diff --git a/src/status_im/ui/screens/intro/styles.cljs b/src/status_im/ui/screens/intro/styles.cljs
index 841d8fb31db..2459087ae6b 100644
--- a/src/status_im/ui/screens/intro/styles.cljs
+++ b/src/status_im/ui/screens/intro/styles.cljs
@@ -1,33 +1,38 @@
 (ns status-im.ui.screens.intro.styles
-  (:require [status-im.ui.components.colors :as colors]))
+  (:require [status-im.ui.components.colors :as colors]
+            [quo.animated :as animated]))
+
+(def dot-size 6)
+(def progress-size 36)
 
 (def intro-view
   {:flex               1
    :justify-content    :flex-end
    :margin-bottom      12})
 
-(defn dot-selector [n]
-  (let [diameter 6
-        interval 10]
-    {:flex-direction  :row
-     :justify-content :space-between
-     :align-items     :center
-     :height          diameter
-     :width           (+ diameter (* (+ diameter interval)
-                                     (dec n)))}))
-
-(defn dot [color selected?]
-  {:background-color (if selected?
-                       color
-                       (colors/alpha color 0.2))
-   :width            6
-   :height           6
-   :border-radius    3})
+(defn dot-selector []
+  {:flex-direction  :row
+   :justify-content :space-between
+   :align-items     :center})
+
+(defn dot-style [active]
+  {:background-color  colors/blue-light
+   :overflow          :hidden
+   :opacity           1
+   :margin-horizontal 2
+   :width             (animated/mix active dot-size progress-size)
+   :height            dot-size
+   :border-radius     3})
+
+(defn dot-progress [active progress]
+  {:background-color colors/blue
+   :height           dot-size
+   :width            progress-size
+   :opacity          (animated/mix active 0 1)
+   :transform        [{:translateX (animated/mix progress (- progress-size) 0)}]})
 
 (def wizard-title
-  {:typography    :header
-   :text-align    :center
-   :margin-bottom 16})
+  {:margin-bottom 16})
 
 (def wizard-text
   {:color      colors/gray
diff --git a/src/status_im/ui/screens/intro/views.cljs b/src/status_im/ui/screens/intro/views.cljs
index 6b3bec859fa..1c97d9833de 100644
--- a/src/status_im/ui/screens/intro/views.cljs
+++ b/src/status_im/ui/screens/intro/views.cljs
@@ -18,93 +18,24 @@
             [status-im.utils.identicon :as identicon]
             [status-im.utils.platform :as platform]
             [status-im.utils.security :as security]
+            [status-im.ui.screens.intro.carousel :as carousel]
             [quo.core :as quo]
             [status-im.utils.utils :as utils])
   (:require-macros [status-im.utils.views :refer [defview letsubs]]))
 
-(defn dots-selector [{:keys [n selected color]}]
-  [react/view {:style (styles/dot-selector n)}
-   (doall
-    (for [i (range n)]
-      ^{:key i}
-      [react/view {:style (styles/dot color (selected i))}]))])
-
-(defn intro-viewer [slides window-height _]
-  (let [scroll-x (r/atom 0)
-        scroll-view-ref (atom nil)
-        width (r/atom 0)
-        height (r/atom 0)
-        text-height (r/atom 0)
-        text-temp-height (atom 0)
-        text-temp-timer (atom nil)
-        bottom-margin (if (> window-height 600) 32 16)]
-    (fn [_ _ view-id]
-      (let [current-screen? (or (nil? view-id) (= view-id :intro))]
-        [react/view {:style {:align-items :center
-                             :flex 1
-                             :margin-bottom bottom-margin
-                             :justify-content :flex-end}
-                     :on-layout (fn [^js e]
-                                  (when current-screen?
-                                    (reset! width (-> e .-nativeEvent .-layout .-width))))}
-         [react/scroll-view {:horizontal true
-                             :paging-enabled true
-                             :ref #(reset! scroll-view-ref %)
-                             :shows-vertical-scroll-indicator false
-                             :shows-horizontal-scroll-indicator false
-                             :pinch-gesture-enabled false
-                             :on-scroll #(let [^js x (.-nativeEvent.contentOffset.x ^js %)]
-                                           (reset! scroll-x x))
-                             :style {:margin-bottom bottom-margin}}
-          (doall
-           (for [s slides]
-             ^{:key (:title s)}
-             [react/view {:style {:flex 1
-                                  :width @width
-                                  :justify-content :flex-end
-                                  :align-items :center
-                                  :padding-horizontal 32}}
-              (let [size (min @width @height)]
-                [react/view {:style {:flex 1}
-                             :on-layout (fn [^js e]
-                                          (let [new-height (-> e .-nativeEvent .-layout .-height)]
-                                            (when current-screen?
-                                              (swap! height #(if (pos? %) (min % new-height) new-height)))))}
-                 [react/image {:source (:image s)
-                               :resize-mode :contain
-                               :style {:width size
-                                       :height size}}]])
-              [react/i18n-text {:style styles/wizard-title :key (:title s)}]
-              [react/text {:style (styles/wizard-text-with-height @text-height)
-                           :on-layout
-                           (fn [^js e]
-                             (let [new-height (-> e .-nativeEvent .-layout .-height)]
-                               (when (and current-screen?
-                                          (not= new-height @text-temp-height)
-                                          (not (zero? new-height))
-                                          (< new-height 200))
-                                 (swap! text-temp-height #(if (pos? %) (max % new-height) new-height))
-                                 (when @text-temp-timer (js/clearTimeout @text-temp-timer))
-                                 (reset! text-temp-timer
-                                         (js/setTimeout #(reset! text-height @text-temp-height) 500)))))}
-               (i18n/label (:text s))]]))]
-         (let [selected (hash-set (quot (int @scroll-x) (int @width)))]
-           [dots-selector {:selected selected :n (count slides)
-                           :color colors/blue}])]))))
-
 (defview intro []
   (letsubs  [{window-height :height} [:dimensions/window]
              view-id [:view-id]]
     [react/view {:style styles/intro-view}
-     [intro-viewer [{:image (resources/get-theme-image :chat)
-                     :title :intro-title1
-                     :text :intro-text1}
-                    {:image (resources/get-theme-image :wallet)
-                     :title :intro-title2
-                     :text :intro-text2}
-                    {:image (resources/get-theme-image :browser)
-                     :title :intro-title3
-                     :text :intro-text3}] window-height view-id]
+     [carousel/viewer [{:image (resources/get-theme-image :chat)
+                        :title :intro-title1
+                        :text :intro-text1}
+                       {:image (resources/get-theme-image :wallet)
+                        :title :intro-title2
+                        :text :intro-text2}
+                       {:image (resources/get-theme-image :browser)
+                        :title :intro-title3
+                        :text :intro-text3}] window-height view-id]
      [react/view styles/buttons-container
       [components.common/button {:button-style (assoc styles/bottom-button :margin-bottom 16)
                                  :on-press     #(re-frame/dispatch [:multiaccounts.create.ui/intro-wizard])