Merge "Added changes for a custom banner" into main
diff --git a/res/drawable/ic_font_size_filled_24px.xml b/res/drawable/ic_font_size_filled_24px.xml
new file mode 100644
index 0000000..b37e8e6
--- /dev/null
+++ b/res/drawable/ic_font_size_filled_24px.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M560,800L560,280L360,280L360,160L880,160L880,280L680,280L680,800L560,800ZM200,800L200,480L80,480L80,360L440,360L440,480L320,480L320,800L200,800Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/layout/clock_style_option.xml b/res/layout/clock_style_option.xml
index fa20706..c59a9d4 100644
--- a/res/layout/clock_style_option.xml
+++ b/res/layout/clock_style_option.xml
@@ -14,57 +14,25 @@
      limitations under the License.
 -->
 <!-- Content description is set programmatically on the parent FrameLayout -->
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/floating_sheet_clock_style_option_width"
-    android:layout_height="@dimen/floating_sheet_clock_style_option_height"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+    android:layout_height="@dimen/floating_sheet_clock_style_option_size"
     android:clipToPadding="false"
     android:clipChildren="false">
 
     <com.android.wallpaper.picker.option.ui.view.OptionItemBackground
         android:id="@id/background"
-        android:layout_width="@dimen/floating_sheet_clock_style_option_background_size"
-        android:layout_height="@dimen/floating_sheet_clock_style_option_background_size"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
-        android:importantForAccessibility="no"
-        android:layout_gravity="bottom" />
+        android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+        android:layout_height="@dimen/floating_sheet_clock_style_option_size"
+        android:layout_gravity="center"
+        android:importantForAccessibility="no" />
 
 
     <ImageView
         android:id="@+id/foreground"
         android:layout_width="@dimen/floating_sheet_clock_style_option_thumbnail_size"
         android:layout_height="@dimen/floating_sheet_clock_style_option_thumbnail_size"
-        android:layout_marginBottom="@dimen/floating_sheet_clock_style_thumbnail_margin_bottom"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintBottom_toBottomOf="parent"
+        android:layout_gravity="center"
         android:src="@drawable/ic_clock_24px" />
-
-    <FrameLayout
-        android:id="@+id/edit_icon"
-        android:layout_width="@dimen/floating_sheet_clock_edit_icon_size"
-        android:layout_height="@dimen/floating_sheet_clock_edit_icon_size"
-        android:layout_marginTop="@dimen/floating_sheet_clock_edit_icon_margin"
-        android:layout_marginEnd="@dimen/floating_sheet_clock_edit_icon_margin"
-        app:layout_constraintEnd_toEndOf="@+id/background"
-        app:layout_constraintTop_toTopOf="@+id/background" >
-        <ImageView
-            android:id="@+id/edit_icon_background"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:src="@drawable/edit_icon_background"
-            android:importantForAccessibility="no" />
-
-        <ImageView
-            android:id="@+id/edit_icon_foreground"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:src="@drawable/edit_icon_foreground"
-            android:importantForAccessibility="no" />
-    </FrameLayout>
-
-
-</androidx.constraintlayout.widget.ConstraintLayout>
+</FrameLayout>
 
diff --git a/res/layout/floating_sheet_clock.xml b/res/layout/floating_sheet_clock.xml
index 6b757be..2e98b4f 100644
--- a/res/layout/floating_sheet_clock.xml
+++ b/res/layout/floating_sheet_clock.xml
@@ -41,8 +41,8 @@
             android:layout_height="wrap_content" />
 
         <include
-            layout="@layout/floating_sheet_clock_font_content"
-            android:id="@+id/clock_floating_sheet_font_content"
+            layout="@layout/floating_sheet_clock_size_content"
+            android:id="@+id/clock_floating_sheet_size_content"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
     </FrameLayout>
@@ -66,28 +66,5 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center" />
-
-        <LinearLayout
-            android:id="@+id/clock_font_toolbar"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_gravity="center_horizontal">
-
-            <ImageView
-                android:id="@+id/clock_font_revert"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:src="@drawable/clock_font_revert"
-                android:contentDescription="@string/clock_font_editor_revert" />
-
-            <ImageView
-                android:id="@+id/clock_font_apply"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:paddingStart="@dimen/clock_font_apply_padding_start"
-                android:src="@drawable/clock_font_apply"
-                android:contentDescription="@string/clock_font_editor_apply" />
-        </LinearLayout>
     </FrameLayout>
 </LinearLayout>
diff --git a/res/layout/floating_sheet_clock_font_content.xml b/res/layout/floating_sheet_clock_font_content.xml
deleted file mode 100644
index ba6c70c..0000000
--- a/res/layout/floating_sheet_clock_font_content.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright (C) 2024 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/clock_floating_sheet_font_content"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
-    android:paddingHorizontal="@dimen/floating_sheet_content_horizontal_padding"
-    android:clipChildren="false"
-    android:clipToPadding="false">
-
-    <TextView
-        android:id="@+id/clock_axis_slider_name1"
-        android:layout_width="@dimen/clock_font_axis_name_width"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@+id/barrier1"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/clock_axis_slider1"
-        android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
-        android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
-        android:lines="1"
-        android:ellipsize="end"
-        style="@style/CustomizationOptionEntryTitleTextStyle"
-        android:text="@string/tab_placeholder_text" />
-
-    <com.google.android.material.slider.Slider
-        android:id="@+id/clock_axis_slider1"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:minHeight="@dimen/accessibility_min_height"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@+id/barrier1"
-        app:layout_constraintStart_toEndOf="@+id/clock_axis_slider_name1"
-        app:layout_constraintEnd_toEndOf="parent"
-        android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
-        app:trackHeight="@dimen/slider_track_height"
-        app:thumbHeight="@dimen/slider_thumb_height"
-        android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/barrier1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:barrierDirection="bottom"
-        app:constraint_referenced_ids="clock_axis_slider1,clock_axis_slider_name1" />
-
-    <TextView
-        android:id="@+id/clock_axis_slider_name2"
-        android:layout_width="@dimen/clock_font_axis_name_width"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toBottomOf="@+id/barrier1"
-        app:layout_constraintBottom_toTopOf="@+id/barrier2"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/clock_axis_slider2"
-        android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
-        android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
-        android:lines="1"
-        android:ellipsize="end"
-        style="@style/CustomizationOptionEntryTitleTextStyle"
-        android:text="@string/tab_placeholder_text" />
-
-    <com.google.android.material.slider.Slider
-        android:id="@+id/clock_axis_slider2"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:minHeight="@dimen/accessibility_min_height"
-        app:layout_constraintTop_toBottomOf="@+id/barrier1"
-        app:layout_constraintBottom_toTopOf="@+id/barrier2"
-        app:layout_constraintStart_toEndOf="@+id/clock_axis_slider_name2"
-        app:layout_constraintEnd_toEndOf="parent"
-        android:layout_marginVertical="@dimen/clock_axis_control_slider_row_margin_vertical"
-        app:trackHeight="@dimen/slider_track_height"
-        app:thumbHeight="@dimen/slider_thumb_height"
-        android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/barrier2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:barrierDirection="bottom"
-        app:constraint_referenced_ids="clock_axis_slider2,clock_axis_slider_name2" />
-
-    <TextView
-        android:id="@+id/clock_axis_switch_name1"
-        android:layout_width="@dimen/clock_font_axis_name_width"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toBottomOf="@+id/barrier2"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
-        android:lines="1"
-        android:ellipsize="end"
-        style="@style/CustomizationOptionEntryTitleTextStyle"
-        android:text="@string/tab_placeholder_text" />
-
-    <com.google.android.material.materialswitch.MaterialSwitch
-        android:id="@+id/clock_axis_switch1"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toBottomOf="@+id/barrier2"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toEndOf="@+id/clock_axis_switch_name1"
-        android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
-        android:layout_marginStart="@dimen/clock_axis_control_text_margin_end"
-        android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-
-    <ImageView
-        android:id="@+id/divider"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toBottomOf="@+id/barrier2"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintHorizontal_bias="0.5"
-        android:src="@drawable/clock_font_switch_divider"
-        android:importantForAccessibility="no" />
-
-    <TextView
-        android:id="@+id/clock_axis_switch_name2"
-        android:layout_width="@dimen/clock_font_axis_name_width"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toBottomOf="@+id/barrier2"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/clock_axis_switch2"
-        android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
-        android:layout_marginEnd="@dimen/clock_axis_control_text_margin_end"
-        android:lines="1"
-        android:ellipsize="end"
-        style="@style/CustomizationOptionEntryTitleTextStyle"
-        android:text="@string/tab_placeholder_text" />
-
-    <com.google.android.material.materialswitch.MaterialSwitch
-        android:id="@+id/clock_axis_switch2"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:layout_constraintTop_toBottomOf="@+id/barrier2"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        android:layout_marginVertical="@dimen/clock_axis_control_switch_row_margin_vertical"
-        android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/layout/floating_sheet_clock_size_content.xml b/res/layout/floating_sheet_clock_size_content.xml
new file mode 100644
index 0000000..e6c41f2
--- /dev/null
+++ b/res/layout/floating_sheet_clock_size_content.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
+    android:clipToPadding="false"
+    android:clipChildren="false">
+
+    <TextView
+        android:id="@+id/clock_style_clock_size_title"
+        style="@style/CustomizationOptionEntryTitleTextStyle"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:text="@string/clock_size_large"
+        android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
+        android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
+        app:layout_constraintTop_toBottomOf="parent"
+        app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_description" />
+
+    <TextView
+        android:id="@+id/clock_style_clock_size_description"
+        style="@style/CustomizationOptionEntrySubtitleTextStyle"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
+        android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
+        android:text="@string/clock_size_large_description"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
+        app:layout_constraintTop_toBottomOf="@+id/clock_style_clock_size_title"
+        app:layout_constraintBottom_toBottomOf="parent" />
+
+    <com.google.android.material.materialswitch.MaterialSwitch
+        android:id="@+id/clock_style_clock_size_switch"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="@dimen/floating_sheet_content_horizontal_padding"
+        app:layout_constraintTop_toTopOf="@+id/clock_style_clock_size_title"
+        app:layout_constraintBottom_toBottomOf="@+id/clock_style_clock_size_description"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/floating_sheet_clock_style_content.xml b/res/layout/floating_sheet_clock_style_content.xml
index 0339e26..259f376 100644
--- a/res/layout/floating_sheet_clock_style_content.xml
+++ b/res/layout/floating_sheet_clock_style_content.xml
@@ -13,26 +13,18 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<androidx.constraintlayout.widget.ConstraintLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingTop="@dimen/floating_sheet_clock_style_content_top_padding"
-    android:paddingBottom="@dimen/floating_sheet_clock_style_content_bottom_padding"
+    android:orientation="vertical"
+    android:paddingVertical="@dimen/floating_sheet_content_vertical_padding"
     android:clipToPadding="false"
     android:clipChildren="false">
 
     <FrameLayout
-        android:id="@+id/clock_style_list_container"
-        android:layout_width="0dp"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_title"
-        android:layout_marginBottom="@dimen/floating_sheet_clock_style_option_list_margin_bottom"
         android:clipToPadding="false"
         android:clipChildren="false">
 
@@ -47,8 +39,8 @@
         -->
         <include
             layout="@layout/clock_style_option"
-            android:layout_width="@dimen/floating_sheet_clock_style_option_width"
-            android:layout_height="@dimen/floating_sheet_clock_style_option_height"
+            android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+            android:layout_height="@dimen/floating_sheet_clock_style_option_size"
             android:visibility="invisible" />
 
         <androidx.recyclerview.widget.RecyclerView
@@ -59,40 +51,18 @@
             android:clipToPadding="false"/>
     </FrameLayout>
 
-    <TextView
-        android:id="@+id/clock_style_clock_size_title"
-        style="@style/CustomizationOptionEntryTitleTextStyle"
-        android:layout_width="0dp"
+    <com.google.android.material.slider.Slider
+        android:id="@+id/clock_axis_preset_slider"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="@string/clock_size_large"
-        android:layout_marginTop="8dp"
-        android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
-        android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
-        app:layout_constraintTop_toBottomOf="@+id/clock_style_list_container"
-        app:layout_constraintBottom_toTopOf="@+id/clock_style_clock_size_description" />
-
-    <TextView
-        android:id="@+id/clock_style_clock_size_description"
-        style="@style/CustomizationOptionEntrySubtitleTextStyle"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/floating_sheet_content_horizontal_padding"
-        android:layout_marginEnd="@dimen/floating_sheet_clock_style_clock_size_text_margin_end"
-        android:text="@string/clock_size_large_description"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/clock_style_clock_size_switch"
-        app:layout_constraintTop_toBottomOf="@+id/clock_style_clock_size_title"
-        app:layout_constraintBottom_toBottomOf="parent" />
-
-    <com.google.android.material.materialswitch.MaterialSwitch
-        android:id="@+id/clock_style_clock_size_switch"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="@dimen/floating_sheet_content_horizontal_padding"
-        app:layout_constraintTop_toTopOf="@+id/clock_style_clock_size_title"
-        app:layout_constraintBottom_toBottomOf="@+id/clock_style_clock_size_description"
-        app:layout_constraintEnd_toEndOf="parent"
+        android:minHeight="@dimen/accessibility_min_height"
+        android:layout_marginTop="@dimen/clock_axis_control_slider_row_margin_vertical"
+        android:valueFrom="0.0"
+        android:valueTo="100.0"
+        android:stepSize="10.0"
+        app:trackHeight="@dimen/slider_track_height"
+        app:thumbHeight="@dimen/slider_thumb_height"
+        app:labelBehavior="gone"
         android:theme="@style/Theme.Material3.DynamicColors.DayNight" />
-</androidx.constraintlayout.widget.ConstraintLayout>
+</LinearLayout>
+
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d335636..531523b 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -182,8 +182,6 @@
     <!-- Floating sheet dimensions -->
     <dimen name="floating_sheet_content_vertical_padding">20dp</dimen>
     <dimen name="floating_sheet_content_horizontal_padding">20dp</dimen>
-    <dimen name="floating_sheet_clock_style_content_top_padding">2dp</dimen>
-    <dimen name="floating_sheet_clock_style_content_bottom_padding">20dp</dimen>
     <dimen name="floating_sheet_horizontal_padding">16dp</dimen>
     <dimen name="floating_sheet_tab_toolbar_vertical_margin">8dp</dimen>
     <dimen name="floating_sheet_tab_clock_font_toolbar_top_margin">16dp</dimen>
@@ -191,14 +189,10 @@
     <dimen name="floating_sheet_list_item_horizontal_space">4dp</dimen>
     <dimen name="floating_sheet_grid_list_item_horizontal_space">10dp</dimen>
     <dimen name="floating_sheet_list_item_vertical_space">4dp</dimen>
-    <dimen name="floating_sheet_clock_style_option_list_margin_bottom">8dp</dimen>
-    <dimen name="floating_sheet_clock_style_option_width">80dp</dimen>
-    <dimen name="floating_sheet_clock_style_option_height">98dp</dimen>
-    <dimen name="floating_sheet_clock_style_option_background_size">80dp</dimen>
+    <dimen name="floating_sheet_clock_style_option_size">80dp</dimen>
     <dimen name="floating_sheet_clock_style_option_thumbnail_size">56dp</dimen>
     <dimen name="floating_sheet_clock_edit_icon_size">48dp</dimen>
     <dimen name="floating_sheet_clock_edit_icon_margin">-18dp</dimen>
-    <dimen name="floating_sheet_clock_style_thumbnail_margin_bottom">12dp</dimen>
     <dimen name="floating_sheet_clock_style_clock_size_text_margin_end">16dp</dimen>
     <dimen name="floating_sheet_color_option_size">54dp</dimen>
     <dimen name="floating_sheet_color_option_stroke_width">3dp</dimen>
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
index fa71fc2..feebf43 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
@@ -52,7 +52,7 @@
 
     suspend fun setClockSize(size: ClockSize)
 
-    suspend fun setClockFontAxes(axisSettings: ClockAxisStyle)
+    suspend fun setClockAxisStyle(axisStyle: ClockAxisStyle)
 
     fun isReactiveToTone(clockId: ClockId): Boolean?
 }
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
index 9342ab5..fd0cd11 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -22,8 +22,8 @@
 import androidx.annotation.IntRange
 import com.android.customization.picker.clock.shared.ClockSize
 import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.systemui.plugins.clocks.AxisPresetConfig
 import com.android.systemui.plugins.clocks.ClockAxisStyle
-import com.android.systemui.plugins.clocks.ClockFontAxis
 import com.android.systemui.plugins.clocks.ClockId
 import com.android.systemui.plugins.clocks.ClockMetadata
 import com.android.systemui.shared.clocks.ClockRegistry
@@ -73,7 +73,7 @@
                                     description = clockConfig.description,
                                     thumbnail = clockConfig.thumbnail,
                                     isReactiveToTone = clockConfig.isReactiveToTone,
-                                    fontAxes = clockConfig.axes,
+                                    axisPresetConfig = clockConfig.presetConfig,
                                 )
                             } else {
                                 null
@@ -85,6 +85,10 @@
 
                 val listener =
                     object : ClockRegistry.ClockChangeListener {
+                        override fun onCurrentClockChanged() {
+                            send()
+                        }
+
                         override fun onAvailableClocksChanged() {
                             send()
                         }
@@ -119,7 +123,7 @@
                                     description = it.description,
                                     thumbnail = it.thumbnail,
                                     isReactiveToTone = it.isReactiveToTone,
-                                    fontAxes = it.axes,
+                                    axisPresetConfig = it.presetConfig,
                                     selectedColorId = metadata?.getSelectedColorId(),
                                     colorTone =
                                         metadata?.getColorTone()
@@ -191,9 +195,9 @@
         )
     }
 
-    override suspend fun setClockFontAxes(axisSettings: ClockAxisStyle) {
+    override suspend fun setClockAxisStyle(axisStyle: ClockAxisStyle) {
         registry.mutateSetting { oldSettings ->
-            val newSettings = oldSettings.copy(axes = axisSettings)
+            val newSettings = oldSettings.copy(axes = axisStyle)
             newSettings.metadata = oldSettings.metadata
             newSettings
         }
@@ -224,7 +228,7 @@
         description: String,
         thumbnail: Drawable,
         isReactiveToTone: Boolean,
-        fontAxes: List<ClockFontAxis>,
+        axisPresetConfig: AxisPresetConfig?,
         selectedColorId: String? = null,
         @IntRange(from = 0, to = 100) colorTone: Int = 0,
         @ColorInt seedColor: Int? = null,
@@ -235,7 +239,7 @@
             description = description,
             thumbnail = thumbnail,
             isReactiveToTone = isReactiveToTone,
-            fontAxes = fontAxes,
+            axisPresetConfig = axisPresetConfig,
             selectedColorId = selectedColorId,
             colorToneProgress = colorTone,
             seedColor = seedColor,
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
index acff6e8..b962652 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
@@ -61,9 +61,7 @@
     val seedColor: Flow<Int?> = repository.selectedClock.map { clock -> clock.seedColor }
 
     val axisSettings: Flow<ClockAxisStyle?> =
-        repository.selectedClock.map { clock ->
-            if (clock.fontAxes.isEmpty()) null else ClockAxisStyle(clock.fontAxes)
-        }
+        repository.selectedClock.map { it.axisPresetConfig?.current?.style }
 
     val selectedClockSize: Flow<ClockSize> = repository.selectedClockSize
 
@@ -136,7 +134,7 @@
             )
         }
         clockSnapshotModel.clockId?.let { repository.setSelectedClock(it) }
-        clockSnapshotModel.axisSettings?.let { repository.setClockFontAxes(it) }
+        clockSnapshotModel.axisSettings?.let { repository.setClockAxisStyle(it) }
     }
 
     private suspend fun storeCurrentClockOption(clockSnapshotModel: ClockSnapshotModel) {
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt
index 41e82eb..62e6d16 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerSnapshotRestorer.kt
@@ -60,7 +60,7 @@
                 seedColor = repository.selectedClock.map { clock -> clock.seedColor }.firstOrNull(),
                 axisSettings =
                     repository.selectedClock
-                        .map { clock -> ClockAxisStyle(clock.fontAxes) }
+                        .map { clock -> clock.axisPresetConfig?.current?.style ?: ClockAxisStyle() }
                         .firstOrNull(),
             )
         return snapshot(originalOption)
@@ -97,7 +97,7 @@
                 )
             }
             optionToRestore.clockId?.let { repository.setSelectedClock(it) }
-            optionToRestore.axisSettings?.let { repository.setClockFontAxes(it) }
+            optionToRestore.axisSettings?.let { repository.setClockAxisStyle(it) }
         }
     }
 
diff --git a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
index 8414960..c2274a7 100644
--- a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
+++ b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
@@ -20,7 +20,7 @@
 import android.graphics.drawable.Drawable
 import androidx.annotation.ColorInt
 import androidx.annotation.IntRange
-import com.android.systemui.plugins.clocks.ClockFontAxis
+import com.android.systemui.plugins.clocks.AxisPresetConfig
 
 /** Model for clock metadata. */
 data class ClockMetadataModel(
@@ -29,7 +29,7 @@
     val description: String,
     val thumbnail: Drawable,
     val isReactiveToTone: Boolean,
-    val fontAxes: List<ClockFontAxis>,
+    val axisPresetConfig: AxisPresetConfig?, // Null indicates the preset list should be disabled.
     val selectedColorId: String?,
     @IntRange(from = 0, to = 100) val colorToneProgress: Int,
     @ColorInt val seedColor: Int?,
diff --git a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
index 09a55e9..275b25a 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
@@ -25,7 +25,6 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.ViewTreeObserver.OnGlobalLayoutListener
-import android.widget.FrameLayout
 import android.widget.ImageView
 import android.widget.TextView
 import androidx.core.graphics.drawable.DrawableCompat
@@ -42,13 +41,9 @@
 import com.android.customization.picker.color.ui.view.ColorOptionIconView2
 import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
 import com.android.customization.picker.common.ui.view.SingleRowListItemSpacing
-import com.android.systemui.plugins.clocks.AxisType
 import com.android.themepicker.R
 import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK
-import com.android.wallpaper.customization.ui.view.ClockFontSliderViewHolder
-import com.android.wallpaper.customization.ui.view.ClockFontSwitchViewHolder
 import com.android.wallpaper.customization.ui.viewmodel.ClockFloatingSheetHeightsViewModel
-import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel
 import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel.ClockStyleModel
 import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel.Tab
 import com.android.wallpaper.customization.ui.viewmodel.ThemePickerCustomizationOptionsViewModel
@@ -60,6 +55,7 @@
 import com.google.android.material.materialswitch.MaterialSwitch
 import com.google.android.material.slider.LabelFormatter
 import com.google.android.material.slider.Slider
+import com.google.android.material.slider.Slider.OnSliderTouchListener
 import java.lang.ref.WeakReference
 import kotlin.math.roundToInt
 import kotlinx.coroutines.DisposableHandle
@@ -90,7 +86,7 @@
         val appContext = view.context.applicationContext
         val isFloatingSheetActive = { optionsViewModel.selectedOption.value == CLOCK }
 
-        val tabs = view.requireViewById<FloatingToolbar>(R.id.floating_toolbar)
+        val tabs: FloatingToolbar = view.requireViewById(R.id.floating_toolbar)
         val tabContainer =
             tabs.findViewById<ViewGroup>(com.android.wallpaper.R.id.floating_toolbar_tab_container)
         ColorUpdateBinder.bind(
@@ -108,8 +104,8 @@
                 )
                 .also { tabs.setAdapter(it) }
 
-        val floatingSheetContainer =
-            view.requireViewById<ViewGroup>(R.id.floating_sheet_content_container)
+        val floatingSheetContainer: ViewGroup =
+            view.requireViewById(R.id.floating_sheet_content_container)
         ColorUpdateBinder.bind(
             setColor = { color ->
                 DrawableCompat.setTint(
@@ -123,9 +119,7 @@
         )
 
         // Clock style
-        val clockStyleContent = view.requireViewById<View>(R.id.clock_floating_sheet_style_content)
-        val clockSizeSwitch =
-            clockStyleContent.requireViewById<MaterialSwitch>(R.id.clock_style_clock_size_switch)
+        val clockStyleContent: View = view.requireViewById(R.id.clock_floating_sheet_style_content)
         val isClockStyleActive = {
             isFloatingSheetActive() && viewModel.selectedTab.value == Tab.STYLE
         }
@@ -135,66 +129,14 @@
                 shouldAnimateColor = isClockStyleActive,
                 lifecycleOwner = lifecycleOwner,
             )
-        val clockStyleList =
-            view.requireViewById<RecyclerView>(R.id.clock_style_list).apply {
-                initStyleList(appContext, clockStyleAdapter)
-            }
-        ColorUpdateBinder.bind(
-            setColor = { color ->
-                clockStyleContent
-                    .requireViewById<TextView>(R.id.clock_style_clock_size_title)
-                    .setTextColor(color)
-            },
-            color = colorUpdateViewModel.colorOnSurface,
-            shouldAnimate = isClockStyleActive,
-            lifecycleOwner = lifecycleOwner,
-        )
-        ColorUpdateBinder.bind(
-            setColor = { color ->
-                clockStyleContent
-                    .requireViewById<TextView>(R.id.clock_style_clock_size_description)
-                    .setTextColor(color)
-            },
-            color = colorUpdateViewModel.colorOnSurfaceVariant,
-            shouldAnimate = isClockStyleActive,
-            lifecycleOwner = lifecycleOwner,
-        )
-
-        // Clock font editor
-        val clockFontContent =
-            view.requireViewById<ViewGroup>(R.id.clock_floating_sheet_font_content)
-        val clockFontToolbar = view.requireViewById<ViewGroup>(R.id.clock_font_toolbar)
-        clockFontToolbar.requireViewById<View>(R.id.clock_font_revert).setOnClickListener {
-            viewModel.cancelFontAxes()
-        }
-        clockFontToolbar.requireViewById<View>(R.id.clock_font_apply).setOnClickListener {
-            viewModel.confirmFontAxes()
-        }
-        val isClockFontActive = {
-            isFloatingSheetActive() && viewModel.selectedTab.value == Tab.FONT
-        }
-        ColorUpdateBinder.bind(
-            setColor = { color ->
-                clockFontContent
-                    .requireViewById<TextView>(R.id.clock_axis_slider_name1)
-                    .setTextColor(color)
-                clockFontContent
-                    .requireViewById<TextView>(R.id.clock_axis_slider_name2)
-                    .setTextColor(color)
-                clockFontContent
-                    .requireViewById<TextView>(R.id.clock_axis_switch_name1)
-                    .setTextColor(color)
-                clockFontContent
-                    .requireViewById<TextView>(R.id.clock_axis_switch_name2)
-                    .setTextColor(color)
-            },
-            color = colorUpdateViewModel.colorOnSurface,
-            shouldAnimate = isClockFontActive,
-            lifecycleOwner = lifecycleOwner,
-        )
+        val clockStyleList: RecyclerView = view.requireViewById(R.id.clock_style_list)
+        clockStyleList.initStyleList(appContext, clockStyleAdapter)
+        val axisPresetSlider: Slider =
+            clockStyleContent.requireViewById(R.id.clock_axis_preset_slider)
 
         // Clock color
-        val clockColorContent = view.requireViewById<View>(R.id.clock_floating_sheet_color_content)
+        val clockColorContent: View = view.requireViewById(R.id.clock_floating_sheet_color_content)
+
         val clockColorAdapter =
             createClockColorOptionItemAdapter(
                 uiMode = view.resources.configuration.uiMode,
@@ -202,21 +144,19 @@
                 shouldAnimateColor = isFloatingSheetActive,
                 lifecycleOwner = lifecycleOwner,
             )
-        val clockColorList =
-            view.requireViewById<RecyclerView>(R.id.clock_color_list).apply {
-                adapter = clockColorAdapter
-                layoutManager =
-                    LinearLayoutManager(appContext, LinearLayoutManager.HORIZONTAL, false)
-            }
-        val clockColorSlider: Slider =
-            view.requireViewById<Slider>(R.id.clock_color_slider).also {
-                SliderColorBinder.bind(
-                    slider = it,
-                    colorUpdateViewModel = colorUpdateViewModel,
-                    shouldAnimateColor = isFloatingSheetActive,
-                    lifecycleOwner = lifecycleOwner,
-                )
-            }
+        val clockColorList: RecyclerView = view.requireViewById(R.id.clock_color_list)
+        clockColorList.adapter = clockColorAdapter
+        clockColorList.layoutManager =
+            LinearLayoutManager(appContext, LinearLayoutManager.HORIZONTAL, false)
+
+        val clockColorSlider: Slider = view.requireViewById(R.id.clock_color_slider)
+        SliderColorBinder.bind(
+            slider = clockColorSlider,
+            colorUpdateViewModel = colorUpdateViewModel,
+            shouldAnimateColor = isFloatingSheetActive,
+            lifecycleOwner = lifecycleOwner,
+        )
+
         clockColorSlider.apply {
             valueFrom = ClockMetadataModel.MIN_COLOR_TONE_PROGRESS.toFloat()
             valueTo = ClockMetadataModel.MAX_COLOR_TONE_PROGRESS.toFloat()
@@ -251,16 +191,44 @@
             lifecycleOwner = lifecycleOwner,
         )
 
+        // Clock size
+        val clockSizeContent: View = view.requireViewById(R.id.clock_floating_sheet_size_content)
+        val clockSizeSwitch: MaterialSwitch =
+            clockSizeContent.requireViewById(R.id.clock_style_clock_size_switch)
+        ColorUpdateBinder.bind(
+            setColor = { color ->
+                clockSizeContent
+                    .requireViewById<TextView>(R.id.clock_style_clock_size_title)
+                    .setTextColor(color)
+            },
+            color = colorUpdateViewModel.colorOnSurface,
+            shouldAnimate = isClockStyleActive,
+            lifecycleOwner = lifecycleOwner,
+        )
+        ColorUpdateBinder.bind(
+            setColor = { color ->
+                clockSizeContent
+                    .requireViewById<TextView>(R.id.clock_style_clock_size_description)
+                    .setTextColor(color)
+            },
+            color = colorUpdateViewModel.colorOnSurfaceVariant,
+            shouldAnimate = isClockStyleActive,
+            lifecycleOwner = lifecycleOwner,
+        )
+
         clockStyleContent.viewTreeObserver.addOnGlobalLayoutListener(
             object : OnGlobalLayoutListener {
                 override fun onGlobalLayout() {
                     if (
                         clockStyleContent.height != 0 &&
+                            axisPresetSlider.height != 0 &&
+                            _clockFloatingSheetHeights.value.axisPresetSliderHeight == null &&
                             _clockFloatingSheetHeights.value.clockStyleContentHeight == null
                     ) {
                         _clockFloatingSheetHeights.value =
                             _clockFloatingSheetHeights.value.copy(
-                                clockStyleContentHeight = clockStyleContent.height
+                                clockStyleContentHeight = clockStyleContent.height,
+                                axisPresetSliderHeight = axisPresetSlider.height,
                             )
                         clockStyleContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
                     }
@@ -285,82 +253,100 @@
             }
         )
 
-        clockFontContent.viewTreeObserver.addOnGlobalLayoutListener(
+        clockSizeContent.viewTreeObserver.addOnGlobalLayoutListener(
             object : OnGlobalLayoutListener {
                 override fun onGlobalLayout() {
                     if (
-                        clockFontContent.height != 0 &&
-                            _clockFloatingSheetHeights.value.clockFontContentHeight == null
+                        clockSizeContent.height != 0 &&
+                            _clockFloatingSheetHeights.value.clockSizeContentHeight == null
                     ) {
                         _clockFloatingSheetHeights.value =
                             _clockFloatingSheetHeights.value.copy(
-                                clockFontContentHeight = clockFontContent.height
+                                clockSizeContentHeight = clockSizeContent.height
                             )
-                        clockColorContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
+                        clockSizeContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
                     }
                 }
             }
         )
 
         lifecycleOwner.lifecycleScope.launch {
-            var currentContent: View = clockStyleContent
+            var currentTab: Tab = Tab.STYLE
             lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                 launch { viewModel.tabs.collect { tabAdapter.submitList(it) } }
 
                 launch {
-                    combine(clockFloatingSheetHeights, viewModel.selectedTab, ::Pair).collect {
-                        (heights, selectedTab) ->
-                        val (
-                            clockStyleContentHeight,
-                            clockColorContentHeight,
-                            clockFontContentHeight) =
-                            heights
-                        clockStyleContentHeight ?: return@collect
-                        clockColorContentHeight ?: return@collect
-                        clockFontContentHeight ?: return@collect
+                    combine(
+                            clockFloatingSheetHeights,
+                            viewModel.selectedTab,
+                            viewModel.shouldShowPresetSlider,
+                            ::Triple,
+                        )
+                        .collect { (heights, selectedTab, shouldShowPresetSlider) ->
+                            val (
+                                clockStyleContentHeight,
+                                clockColorContentHeight,
+                                clockSizeContentHeight,
+                                axisPresetSliderHeight) =
+                                heights
+                            clockStyleContentHeight ?: return@collect
+                            clockColorContentHeight ?: return@collect
+                            clockSizeContentHeight ?: return@collect
+                            axisPresetSliderHeight ?: return@collect
 
-                        val fromHeight = floatingSheetContainer.height
-                        val toHeight =
-                            when (selectedTab) {
-                                Tab.STYLE -> clockStyleContentHeight
-                                Tab.COLOR -> clockColorContentHeight
-                                Tab.FONT -> clockFontContentHeight
-                            }
-                        // Start to animate the content height
-                        ValueAnimator.ofInt(fromHeight, toHeight)
-                            .apply {
-                                addUpdateListener { valueAnimator ->
-                                    val value = valueAnimator.animatedValue as Int
-                                    floatingSheetContainer.layoutParams =
-                                        floatingSheetContainer.layoutParams.apply { height = value }
-                                    currentContent.alpha = getAlpha(fromHeight, toHeight, value)
+                            val fromHeight = floatingSheetContainer.height
+                            val toHeight =
+                                when (selectedTab) {
+                                    Tab.STYLE ->
+                                        if (shouldShowPresetSlider) clockStyleContentHeight
+                                        else clockStyleContentHeight - axisPresetSliderHeight
+                                    Tab.COLOR -> clockColorContentHeight
+                                    Tab.SIZE -> clockSizeContentHeight
                                 }
-                                duration = ANIMATION_DURATION
-                                addListener(
-                                    object : AnimatorListenerAdapter() {
-                                        override fun onAnimationEnd(animation: Animator) {
-                                            clockStyleContent.isVisible = selectedTab == Tab.STYLE
-                                            clockStyleContent.alpha = 1f
-                                            clockColorContent.isVisible = selectedTab == Tab.COLOR
-                                            clockColorContent.alpha = 1f
-                                            clockFontContent.isVisible = selectedTab == Tab.FONT
-                                            clockFontContent.alpha = 1f
-                                            currentContent =
-                                                when (selectedTab) {
-                                                    Tab.STYLE -> clockStyleContent
-                                                    Tab.COLOR -> clockColorContent
-                                                    Tab.FONT -> clockFontContent
-                                                }
-                                            // Also update the floating toolbar when the height
-                                            // animation ends.
-                                            tabs.isVisible = selectedTab != Tab.FONT
-                                            clockFontToolbar.isVisible = selectedTab == Tab.FONT
+                            val currentContent: View =
+                                when (currentTab) {
+                                    Tab.STYLE -> clockStyleContent
+                                    Tab.COLOR -> clockColorContent
+                                    Tab.SIZE -> clockSizeContent
+                                }
+                            val shouldCurrentContentFadeOut = currentTab != selectedTab
+                            // Start to animate the content height
+                            ValueAnimator.ofInt(fromHeight, toHeight)
+                                .apply {
+                                    addUpdateListener { valueAnimator ->
+                                        val value = valueAnimator.animatedValue as Int
+                                        floatingSheetContainer.layoutParams =
+                                            floatingSheetContainer.layoutParams.apply {
+                                                height = value
+                                            }
+                                        if (shouldCurrentContentFadeOut) {
+                                            currentContent.alpha =
+                                                getAlpha(fromHeight, toHeight, value)
                                         }
                                     }
-                                )
-                            }
-                            .start()
-                    }
+                                    duration = ANIMATION_DURATION
+                                    addListener(
+                                        object : AnimatorListenerAdapter() {
+                                            override fun onAnimationEnd(animation: Animator) {
+                                                clockStyleContent.isVisible =
+                                                    selectedTab == Tab.STYLE
+                                                clockStyleContent.alpha = 1f
+                                                clockColorContent.isVisible =
+                                                    selectedTab == Tab.COLOR
+                                                clockColorContent.alpha = 1f
+                                                clockSizeContent.isVisible = selectedTab == Tab.SIZE
+                                                clockSizeContent.alpha = 1f
+                                            }
+                                        }
+                                    )
+                                }
+                                .start()
+                            currentTab = selectedTab
+                        }
+                }
+
+                launch {
+                    viewModel.shouldShowPresetSlider.collect { axisPresetSlider.isVisible = it }
                 }
 
                 launch {
@@ -429,120 +415,30 @@
                         }
                     }
                 }
-            }
-        }
 
-        bindClockFontContent(
-            clockFontContent = clockFontContent,
-            viewModel = viewModel,
-            colorUpdateViewModel = colorUpdateViewModel,
-            shouldAnimateColor = isClockFontActive,
-            lifecycleOwner = lifecycleOwner,
-        )
-    }
-
-    private fun bindClockFontContent(
-        clockFontContent: View,
-        viewModel: ClockPickerViewModel,
-        colorUpdateViewModel: ColorUpdateViewModel,
-        shouldAnimateColor: () -> Boolean,
-        lifecycleOwner: LifecycleOwner,
-    ) {
-        val slider1 =
-            clockFontContent.requireViewById<Slider>(R.id.clock_axis_slider1).also {
-                SliderColorBinder.bind(
-                    slider = it,
-                    colorUpdateViewModel = colorUpdateViewModel,
-                    shouldAnimateColor = shouldAnimateColor,
-                    lifecycleOwner = lifecycleOwner,
-                )
-            }
-        val slider2 =
-            clockFontContent.requireViewById<Slider>(R.id.clock_axis_slider2).also {
-                SliderColorBinder.bind(
-                    slider = it,
-                    colorUpdateViewModel = colorUpdateViewModel,
-                    shouldAnimateColor = shouldAnimateColor,
-                    lifecycleOwner = lifecycleOwner,
-                )
-            }
-        val sliderViewList =
-            listOf(
-                ClockFontSliderViewHolder(
-                    name = clockFontContent.requireViewById(R.id.clock_axis_slider_name1),
-                    slider = slider1,
-                ),
-                ClockFontSliderViewHolder(
-                    name = clockFontContent.requireViewById(R.id.clock_axis_slider_name2),
-                    slider = slider2,
-                ),
-            )
-        val switchViewList =
-            listOf(
-                ClockFontSwitchViewHolder(
-                    name = clockFontContent.requireViewById(R.id.clock_axis_switch_name1),
-                    switch = clockFontContent.requireViewById(R.id.clock_axis_switch1),
-                ),
-                ClockFontSwitchViewHolder(
-                    name = clockFontContent.requireViewById(R.id.clock_axis_switch_name2),
-                    switch = clockFontContent.requireViewById(R.id.clock_axis_switch2),
-                ),
-            )
-        val sliderViewMap: MutableMap<String, ClockFontSliderViewHolder> = mutableMapOf()
-        val switchViewMap: MutableMap<String, ClockFontSwitchViewHolder> = mutableMapOf()
-
-        lifecycleOwner.lifecycleScope.launch {
-            lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                 launch {
-                    viewModel.previewingClockFontAxes.filterNotNull().collect { fontAxes ->
-                        // This data flow updates only when a new clock style is selected. We
-                        // initiate the clock font content with regard to that clock style.
-                        sliderViewMap.clear()
-                        switchViewMap.clear()
+                    viewModel.axisPresetsSliderViewModel.collect {
+                        val axisPresetsSliderViewModel = it ?: return@collect
+                        axisPresetSlider.valueFrom = axisPresetsSliderViewModel.valueFrom
+                        axisPresetSlider.valueTo = axisPresetsSliderViewModel.valueTo
+                        axisPresetSlider.stepSize = axisPresetsSliderViewModel.stepSize
+                        axisPresetSlider.clearOnSliderTouchListeners()
+                        axisPresetSlider.addOnSliderTouchListener(
+                            object : OnSliderTouchListener {
+                                override fun onStartTrackingTouch(slider: Slider) {}
 
-                        // Initiate the slider views
-                        val floatAxisList = fontAxes.filter { it.type == AxisType.Float }
-                        sliderViewList.forEachIndexed { i, viewHolder ->
-                            val floatAxis = floatAxisList.getOrNull(i)
-                            viewHolder.setIsVisible(floatAxis != null)
-                            floatAxis?.let {
-                                sliderViewMap[floatAxis.key] = viewHolder
-                                viewHolder.initView(it) { value ->
-                                    viewModel.updatePreviewFontAxis(floatAxis.key, value)
+                                override fun onStopTrackingTouch(slider: Slider) {
+                                    axisPresetsSliderViewModel.onSliderStopTrackingTouch(
+                                        slider.value
+                                    )
                                 }
                             }
-                        }
-
-                        // Initiate the switch views
-                        val booleanAxisList = fontAxes.filter { it.type == AxisType.Boolean }
-                        switchViewList.forEachIndexed { i, viewHolder ->
-                            val booleanAxis = booleanAxisList.getOrNull(i)
-                            viewHolder.setIsVisible(booleanAxis != null)
-                            booleanAxis?.let {
-                                switchViewMap[it.key] = viewHolder
-                                viewHolder.initView(
-                                    clockFontAxis = booleanAxis,
-                                    onFontAxisValueUpdated = { value ->
-                                        viewModel.updatePreviewFontAxis(booleanAxis.key, value)
-                                    },
-                                    colorUpdateViewModel = colorUpdateViewModel,
-                                    shouldAnimateColor = shouldAnimateColor,
-                                    lifecycleOwner = lifecycleOwner,
-                                )
-                            }
-                        }
+                        )
                     }
                 }
 
                 launch {
-                    viewModel.previewingClockFontAxisMap.collect { axisMap ->
-                        // This data flow updates when user configures the sliders and switches
-                        // in the clock font content.
-                        axisMap.forEach { (key, value) ->
-                            sliderViewMap[key]?.setValue(value)
-                            switchViewMap[key]?.setValue(value)
-                        }
-                    }
+                    viewModel.axisPresetsSliderSelectedValue.collect { axisPresetSlider.value = it }
                 }
             }
         }
@@ -560,29 +456,7 @@
                 view
                     .findViewById<ImageView>(R.id.foreground)
                     ?.setImageDrawable(styleModel.thumbnail)
-                val job =
-                    lifecycleOwner.lifecycleScope.launch {
-                        lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
-                            styleModel.showEditButton.collect {
-                                view.findViewById<FrameLayout>(R.id.edit_icon)?.isVisible = it
-                            }
-                        }
-                    }
-                val binding =
-                    ColorUpdateBinder.bind(
-                        setColor = { color ->
-                            view.findViewById<ImageView>(R.id.edit_icon_background)?.drawable?.let {
-                                DrawableCompat.setTint(DrawableCompat.wrap(it), color)
-                            }
-                        },
-                        color = colorUpdateViewModel.colorOnPrimaryFixedVariant,
-                        shouldAnimate = shouldAnimateColor,
-                        lifecycleOwner = lifecycleOwner,
-                    )
-                return@OptionItemAdapter2 DisposableHandle {
-                    job.cancel()
-                    binding.destroy()
-                }
+                return@OptionItemAdapter2 null
             },
             colorUpdateViewModel = WeakReference(colorUpdateViewModel),
             shouldAnimateColor = shouldAnimateColor,
@@ -616,10 +490,8 @@
             layoutResourceId = R.layout.color_option2,
             lifecycleOwner = lifecycleOwner,
             bindPayload = { itemView: View, colorIcon: ColorOptionIconViewModel ->
-                val colorOptionIconView =
-                    itemView.requireViewById<ColorOptionIconView2>(
-                        com.android.wallpaper.R.id.background
-                    )
+                val colorOptionIconView: ColorOptionIconView2 =
+                    itemView.requireViewById(com.android.wallpaper.R.id.background)
                 val night = uiMode and UI_MODE_NIGHT_MASK == UI_MODE_NIGHT_YES
                 val binding =
                     ColorOptionIconBinder2.bind(
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
index 5736e0e..09bb692 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
@@ -81,6 +81,7 @@
         navigateToMoreLockScreenSettingsActivity: () -> Unit,
         navigateToColorContrastSettingsActivity: () -> Unit,
         navigateToLockScreenNotificationsSettingsActivity: () -> Unit,
+        navigateToPackThemeActivity: () -> Unit,
     ) {
         defaultCustomizationOptionsBinder.bind(
             view,
@@ -93,6 +94,7 @@
             navigateToMoreLockScreenSettingsActivity,
             navigateToColorContrastSettingsActivity,
             navigateToLockScreenNotificationsSettingsActivity,
+            navigateToPackThemeActivity,
         )
 
         val isComposeRefactorEnabled = BaseFlags.get().isComposeRefactorEnabled()
@@ -179,15 +181,18 @@
         var optionPackThemeIconLock: ImageView? = null
 
         if (BaseFlags.get().isPackThemeEnabled()) {
-            val optionPackThemeHome: View =
+            val optionPackThemeHome =
                 homeScreenCustomizationOptionEntries
                     .first { it.first == ThemePickerHomeCustomizationOption.PACK_THEME }
                     .second
+            optionPackThemeHome.setOnClickListener { navigateToPackThemeActivity.invoke() }
             optionPackThemeIconHome = optionPackThemeHome.requireViewById(R.id.option_entry_icon)
-            val optionPackThemeLock: View =
-                homeScreenCustomizationOptionEntries
+
+            val optionPackThemeLock =
+                lockScreenCustomizationOptionEntries
                     .first { it.first == ThemePickerHomeCustomizationOption.PACK_THEME }
                     .second
+            optionPackThemeLock.setOnClickListener { navigateToPackThemeActivity.invoke() }
             optionPackThemeIconLock = optionPackThemeLock.requireViewById(R.id.option_entry_icon)
         }
 
@@ -416,6 +421,7 @@
     override fun bindClockPreview(
         context: Context,
         clockHostView: View,
+        clockFaceClickDelegateView: View,
         viewModel: CustomizationPickerViewModel2,
         colorUpdateViewModel: ColorUpdateViewModel,
         lifecycleOwner: LifecycleOwner,
@@ -486,20 +492,38 @@
                     combine(
                             clockPickerViewModel.previewingSeedColor,
                             clockPickerViewModel.previewingClock,
-                            clockPickerViewModel.previewingClockFontAxisMap,
+                            clockPickerViewModel.previewingClockPresetIndexedStyle,
                             colorUpdateViewModel.systemColorsUpdated,
                             ::Quadruple,
                         )
                         .collect { quadruple ->
-                            val (color, clock, axisMap, _) = quadruple
+                            val (color, clock, clockPresetIndexedStyle, _) = quadruple
                             clockViewFactory.updateColor(clock.clockId, color)
-                            clockViewFactory.updateFontAxes(clock.clockId, ClockAxisStyle(axisMap))
+                            clockViewFactory.updateFontAxes(
+                                clock.clockId,
+                                clockPresetIndexedStyle?.style ?: ClockAxisStyle(),
+                            )
                         }
                 }
 
                 launch {
                     viewModel.lockPreviewAnimateToAlpha.collect { clockHostView.animateToAlpha(it) }
                 }
+
+                launch {
+                    combine(
+                            viewModel.customizationOptionsViewModel.selectedOption,
+                            clockPickerViewModel.onClockFaceClicked,
+                            ::Pair,
+                        )
+                        .collect { (selectedOption, onClockFaceClicked) ->
+                            clockFaceClickDelegateView.isVisible =
+                                selectedOption == ThemePickerLockCustomizationOption.CLOCK
+                            clockFaceClickDelegateView.setOnClickListener {
+                                onClockFaceClicked.invoke()
+                            }
+                        }
+                }
             }
         }
     }
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
index cb4ab57..f818ff8 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerToolbarBinder.kt
@@ -16,8 +16,6 @@
 
 package com.android.wallpaper.customization.ui.binder
 
-import android.animation.ValueAnimator
-import android.view.ViewTreeObserver.OnGlobalLayoutListener
 import android.widget.Button
 import android.widget.FrameLayout
 import android.widget.Toolbar
@@ -35,7 +33,6 @@
 import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK
 import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.SHORTCUTS
 import com.android.wallpaper.customization.ui.viewmodel.ThemePickerCustomizationOptionsViewModel
-import com.android.wallpaper.customization.ui.viewmodel.ToolbarHeightsViewModel
 import com.android.wallpaper.picker.customization.ui.binder.ColorUpdateBinder
 import com.android.wallpaper.picker.customization.ui.binder.DefaultToolbarBinder
 import com.android.wallpaper.picker.customization.ui.binder.ToolbarBinder
@@ -43,7 +40,6 @@
 import com.android.wallpaper.picker.customization.ui.viewmodel.CustomizationOptionsViewModel
 import javax.inject.Inject
 import javax.inject.Singleton
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.launch
 
@@ -61,8 +57,6 @@
         lifecycleOwner: LifecycleOwner,
         onNavBack: () -> Unit,
     ) {
-        val toolbarHeights: MutableStateFlow<ToolbarHeightsViewModel?> = MutableStateFlow(null)
-
         defaultToolbarBinder.bind(
             navButton,
             toolbar,
@@ -79,45 +73,6 @@
             )
         }
 
-        navButton.viewTreeObserver.addOnGlobalLayoutListener(
-            object : OnGlobalLayoutListener {
-                override fun onGlobalLayout() {
-                    if (navButton.height != 0) {
-                        toolbarHeights.value =
-                            toolbarHeights.value?.copy(navButtonHeight = navButton.height)
-                                ?: ToolbarHeightsViewModel(navButtonHeight = navButton.height)
-                    }
-                    navButton.viewTreeObserver.removeOnGlobalLayoutListener(this)
-                }
-            }
-        )
-
-        toolbar.viewTreeObserver.addOnGlobalLayoutListener(
-            object : OnGlobalLayoutListener {
-                override fun onGlobalLayout() {
-                    if (toolbar.height != 0) {
-                        toolbarHeights.value =
-                            toolbarHeights.value?.copy(toolbarHeight = toolbar.height)
-                                ?: ToolbarHeightsViewModel(toolbarHeight = toolbar.height)
-                    }
-                    navButton.viewTreeObserver.removeOnGlobalLayoutListener(this)
-                }
-            }
-        )
-
-        applyButton.viewTreeObserver.addOnGlobalLayoutListener(
-            object : OnGlobalLayoutListener {
-                override fun onGlobalLayout() {
-                    if (applyButton.height != 0) {
-                        toolbarHeights.value =
-                            toolbarHeights.value?.copy(applyButtonHeight = applyButton.height)
-                                ?: ToolbarHeightsViewModel(applyButtonHeight = applyButton.height)
-                    }
-                    applyButton.viewTreeObserver.removeOnGlobalLayoutListener(this)
-                }
-            }
-        )
-
         ColorUpdateBinder.bind(
             setColor = { color ->
                 DrawableCompat.setTint(DrawableCompat.wrap(applyButton.background), color)
@@ -177,53 +132,6 @@
                         toolbar.title = toolbar.resources.getString(stringResId)
                     }
                 }
-
-                launch {
-                    combine(toolbarHeights, viewModel.isToolbarCollapsed, ::Pair).collect {
-                        (toolbarHeights, isToolbarCollapsed) ->
-                        val (navButtonHeight, toolbarHeight, applyButtonHeight) =
-                            toolbarHeights ?: return@collect
-                        navButtonHeight ?: return@collect
-                        toolbarHeight ?: return@collect
-                        applyButtonHeight ?: return@collect
-
-                        val navButtonToHeight = if (isToolbarCollapsed) 0 else navButtonHeight
-                        val toolbarToHeight = if (isToolbarCollapsed) 0 else toolbarHeight
-                        val applyButtonToHeight = if (isToolbarCollapsed) 0 else applyButtonHeight
-                        ValueAnimator.ofInt(navButton.height, navButtonToHeight)
-                            .apply {
-                                addUpdateListener { valueAnimator ->
-                                    val value = valueAnimator.animatedValue as Int
-                                    navButton.layoutParams =
-                                        navButton.layoutParams.apply { height = value }
-                                }
-                                duration = ANIMATION_DURATION
-                            }
-                            .start()
-
-                        ValueAnimator.ofInt(toolbar.height, toolbarToHeight)
-                            .apply {
-                                addUpdateListener { valueAnimator ->
-                                    val value = valueAnimator.animatedValue as Int
-                                    toolbar.layoutParams =
-                                        toolbar.layoutParams.apply { height = value }
-                                }
-                                duration = ANIMATION_DURATION
-                            }
-                            .start()
-
-                        ValueAnimator.ofInt(applyButton.height, applyButtonToHeight)
-                            .apply {
-                                addUpdateListener { valueAnimator ->
-                                    val value = valueAnimator.animatedValue as Int
-                                    applyButton.layoutParams =
-                                        applyButton.layoutParams.apply { height = value }
-                                }
-                                duration = ANIMATION_DURATION
-                            }
-                            .start()
-                    }
-                }
             }
         }
     }
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
deleted file mode 100644
index fb14342..0000000
--- a/src/com/android/wallpaper/customization/ui/view/ClockFontSliderViewHolder.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wallpaper.customization.ui.view
-
-import android.widget.TextView
-import androidx.core.view.isInvisible
-import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.google.android.material.slider.LabelFormatter
-import com.google.android.material.slider.Slider
-
-class ClockFontSliderViewHolder(val name: TextView, val slider: Slider) {
-
-    fun setIsVisible(isVisible: Boolean) {
-        name.isInvisible = !isVisible
-        slider.isInvisible = !isVisible
-    }
-
-    fun initView(clockFontAxis: ClockFontAxis, onFontAxisValueUpdated: (value: Float) -> Unit) {
-        name.text = clockFontAxis.name
-        slider.apply {
-            valueFrom = clockFontAxis.minValue
-            valueTo = clockFontAxis.maxValue
-            value = clockFontAxis.currentValue
-            labelBehavior = LabelFormatter.LABEL_GONE
-            addOnChangeListener { _, value, fromUser ->
-                if (fromUser) {
-                    onFontAxisValueUpdated.invoke(value)
-                }
-            }
-        }
-    }
-
-    fun setValue(value: Float) {
-        slider.value = value
-    }
-}
diff --git a/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt b/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
deleted file mode 100644
index fcf70d3..0000000
--- a/src/com/android/wallpaper/customization/ui/view/ClockFontSwitchViewHolder.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wallpaper.customization.ui.view
-
-import android.widget.TextView
-import androidx.core.view.isVisible
-import androidx.lifecycle.LifecycleOwner
-import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.wallpaper.customization.ui.binder.SwitchColorBinder
-import com.android.wallpaper.picker.customization.ui.viewmodel.ColorUpdateViewModel
-import com.google.android.material.materialswitch.MaterialSwitch
-import kotlin.math.abs
-
-class ClockFontSwitchViewHolder(val name: TextView, val switch: MaterialSwitch) {
-
-    private var switchMaxValue: Float? = null
-
-    fun setIsVisible(isVisible: Boolean) {
-        name.isVisible = isVisible
-        switch.isVisible = isVisible
-    }
-
-    fun initView(
-        clockFontAxis: ClockFontAxis,
-        onFontAxisValueUpdated: (value: Float) -> Unit,
-        colorUpdateViewModel: ColorUpdateViewModel,
-        shouldAnimateColor: () -> Boolean,
-        lifecycleOwner: LifecycleOwner,
-    ) {
-        switchMaxValue = clockFontAxis.maxValue
-        name.text = clockFontAxis.name
-        switch.apply {
-            isChecked = abs(clockFontAxis.currentValue - clockFontAxis.maxValue) < 0.01f
-            var binding: SwitchColorBinder.Binding =
-                SwitchColorBinder.bind(
-                    switch = switch,
-                    isChecked = isChecked,
-                    colorUpdateViewModel = colorUpdateViewModel,
-                    shouldAnimateColor = shouldAnimateColor,
-                    lifecycleOwner = lifecycleOwner,
-                )
-            setOnCheckedChangeListener { v, _ ->
-                binding.destroy()
-                binding =
-                    SwitchColorBinder.bind(
-                        switch = switch,
-                        isChecked = v.isChecked,
-                        colorUpdateViewModel = colorUpdateViewModel,
-                        shouldAnimateColor = shouldAnimateColor,
-                        lifecycleOwner = lifecycleOwner,
-                    )
-                val value = if (v.isChecked) clockFontAxis.maxValue else clockFontAxis.minValue
-                onFontAxisValueUpdated.invoke(value)
-            }
-        }
-    }
-
-    fun setValue(value: Float) {
-        switchMaxValue?.let { switch.isChecked = abs(value - it) < 0.01f }
-    }
-}
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockAxisPresetSliderViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockAxisPresetSliderViewModel.kt
new file mode 100644
index 0000000..d11044a
--- /dev/null
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockAxisPresetSliderViewModel.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wallpaper.customization.ui.viewmodel
+
+/** Data class representing [com.google.android.material.slider]'s configuration. */
+data class ClockAxisPresetSliderViewModel(
+    val valueFrom: Float,
+    val valueTo: Float,
+    val stepSize: Float,
+    val onSliderStopTrackingTouch: (value: Float) -> Unit,
+)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
index 249f862..fcfec5f 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
@@ -19,5 +19,6 @@
 data class ClockFloatingSheetHeightsViewModel(
     val clockStyleContentHeight: Int? = null,
     val clockColorContentHeight: Int? = null,
-    val clockFontContentHeight: Int? = null,
+    val clockSizeContentHeight: Int? = null,
+    val axisPresetSliderHeight: Int? = null,
 )
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
index dca361f..cff9e08 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
@@ -28,6 +28,8 @@
 import com.android.customization.picker.clock.ui.viewmodel.ClockColorViewModel
 import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor2
 import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
+import com.android.systemui.plugins.clocks.AxisPresetConfig
+import com.android.systemui.plugins.clocks.AxisPresetConfig.IndexedStyle
 import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.themepicker.R
 import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
@@ -40,6 +42,7 @@
 import dagger.assisted.AssistedInject
 import dagger.hilt.android.qualifiers.ApplicationContext
 import dagger.hilt.android.scopes.ViewModelScoped
+import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -74,7 +77,7 @@
     enum class Tab {
         STYLE,
         COLOR,
-        FONT,
+        SIZE,
     }
 
     private val colorMap = ClockColorViewModel.getPresetColorMap(context.resources)
@@ -92,9 +95,9 @@
                             contentDescription = Text.Resource(R.string.clock_style),
                         ),
                     text = context.getString(R.string.clock_style),
-                    isSelected = it == Tab.STYLE || it == Tab.FONT,
+                    isSelected = it == Tab.STYLE,
                     onClick =
-                        if (it == Tab.STYLE || it == Tab.FONT) null
+                        if (it == Tab.STYLE) null
                         else {
                             { _selectedTab.value = Tab.STYLE }
                         },
@@ -113,29 +116,41 @@
                             { _selectedTab.value = Tab.COLOR }
                         },
                 ),
+                FloatingToolbarTabViewModel(
+                    icon =
+                        Icon.Resource(
+                            res = R.drawable.ic_font_size_filled_24px,
+                            contentDescription = Text.Resource(R.string.clock_size),
+                        ),
+                    text = context.getString(R.string.clock_size),
+                    isSelected = it == Tab.SIZE,
+                    onClick =
+                        if (it == Tab.SIZE) null
+                        else {
+                            { _selectedTab.value = Tab.SIZE }
+                        },
+                ),
             )
         }
 
     // Clock style
     private val overridingClock = MutableStateFlow<ClockMetadataModel?>(null)
-    private val isClockEdited =
-        combine(overridingClock, clockPickerInteractor.selectedClock) {
-            overridingClock,
-            selectedClock ->
-            overridingClock != null && overridingClock.clockId != selectedClock.clockId
-        }
     val selectedClock = clockPickerInteractor.selectedClock
     val previewingClock =
         combine(overridingClock, selectedClock) { overridingClock, selectedClock ->
                 (overridingClock ?: selectedClock)
             }
             .shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
+    private val isClockEdited =
+        combine(overridingClock, selectedClock) { overridingClock, selectedClock ->
+            overridingClock != null && overridingClock.clockId != selectedClock.clockId
+        }
 
     suspend fun getIsShadeLayoutWide() = clockPickerInteractor.getIsShadeLayoutWide()
 
     suspend fun getUdfpsLocation() = clockPickerInteractor.getUdfpsLocation()
 
-    data class ClockStyleModel(val thumbnail: Drawable, val showEditButton: StateFlow<Boolean>)
+    data class ClockStyleModel(val thumbnail: Drawable)
 
     @OptIn(ExperimentalCoroutinesApi::class)
     val clockStyleOptions: StateFlow<List<OptionItemViewModel2<ClockStyleModel>>> =
@@ -143,7 +158,7 @@
             .mapLatest { allClocks ->
                 // Delay to avoid the case that the full list of clocks is not initiated.
                 delay(CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-                val allClockMap = allClocks.groupBy { it.fontAxes.isNotEmpty() }
+                val allClockMap = allClocks.groupBy { it.axisPresetConfig != null }
                 buildList {
                     allClockMap[true]?.map { add(it.toOption(resources)) }
                     allClockMap[false]?.map { add(it.toOption(resources)) }
@@ -155,83 +170,107 @@
             .flowOn(backgroundDispatcher.limitedParallelism(1))
             .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
 
+    // Clock font presets
+    private val overridingClockPresetIndexedStyle: MutableStateFlow<IndexedStyle?> =
+        MutableStateFlow(null)
+    private val selectedClockPresetIndexedStyle: Flow<IndexedStyle?> =
+        previewingClock
+            .map { it.axisPresetConfig?.current }
+            .shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
+    val previewingClockPresetIndexedStyle: Flow<IndexedStyle?> =
+        combine(overridingClockPresetIndexedStyle, selectedClockPresetIndexedStyle) {
+            overridingClockPresetIndexedStyle,
+            selectedClockPresetIndexedStyle ->
+            overridingClockPresetIndexedStyle ?: selectedClockPresetIndexedStyle
+        }
+    private val isClockAxisStyleEdited: Flow<Boolean> =
+        combine(overridingClockPresetIndexedStyle, selectedClockPresetIndexedStyle) {
+            overridingClockPresetIndexedStyle,
+            selectedClockPresetIndexedStyle ->
+            overridingClockPresetIndexedStyle != null &&
+                (overridingClockPresetIndexedStyle.style != selectedClockPresetIndexedStyle?.style)
+        }
+
+    private val groups: Flow<List<AxisPresetConfig.Group>?> =
+        previewingClock.map { it.axisPresetConfig?.groups }
+    private val previewingClockPresetGroupIndex: Flow<Int> =
+        previewingClockPresetIndexedStyle.map { it?.groupIndex ?: 0 }.distinctUntilChanged()
+    val shouldShowPresetSlider: Flow<Boolean> = previewingClock.map { it.axisPresetConfig != null }
+    val axisPresetsSliderViewModel: Flow<ClockAxisPresetSliderViewModel?> =
+        combine(groups, previewingClockPresetGroupIndex) { groups, previewingClockPresetGroupIndex
+            ->
+            if (groups.isNullOrEmpty()) {
+                null
+            } else {
+                val group = groups[previewingClockPresetGroupIndex]
+                ClockAxisPresetSliderViewModel(
+                    valueFrom = 0F,
+                    valueTo = (group.presets.size - 1).toFloat(),
+                    stepSize = 1F,
+                    onSliderStopTrackingTouch = { value ->
+                        val presetIndex = value.roundToInt()
+                        overridingClockPresetIndexedStyle.value =
+                            IndexedStyle(
+                                groupIndex = previewingClockPresetGroupIndex,
+                                presetIndex = presetIndex,
+                                style = group.presets[presetIndex],
+                            )
+                    },
+                )
+            }
+        }
+    val axisPresetsSliderSelectedValue: Flow<Float> =
+        previewingClockPresetIndexedStyle.map { it?.presetIndex?.toFloat() }.filterNotNull()
+    val onClockFaceClicked: Flow<() -> Unit> =
+        combine(groups, previewingClockPresetIndexedStyle) { groups, previewingIndexedStyle ->
+            if (groups.isNullOrEmpty()) {
+                {}
+            } else {
+                val groupCount = groups.size
+                if (groupCount == 1) {
+                    {}
+                } else {
+                    val currentGroupIndex = previewingIndexedStyle?.groupIndex ?: 0
+                    val nextGroupIndex = (currentGroupIndex + 1) % groupCount
+                    val nextPresetIndex = previewingIndexedStyle?.presetIndex ?: (groupCount / 2)
+                    val nextGroup = groups[nextGroupIndex]
+                    {
+                        overridingClockPresetIndexedStyle.value =
+                            IndexedStyle(
+                                groupIndex = nextGroupIndex,
+                                presetIndex = nextPresetIndex,
+                                style = nextGroup.presets[nextPresetIndex],
+                            )
+                    }
+                }
+            }
+        }
+
     private suspend fun ClockMetadataModel.toOption(
         resources: Resources
     ): OptionItemViewModel2<ClockStyleModel> {
         val isSelectedFlow = previewingClock.map { it.clockId == clockId }.stateIn(viewModelScope)
-        val isEditable = fontAxes.isNotEmpty()
-        val showEditButton = isSelectedFlow.map { it && isEditable }.stateIn(viewModelScope)
         val contentDescription =
             resources.getString(R.string.select_clock_action_description, description)
         return OptionItemViewModel2<ClockStyleModel>(
             key = MutableStateFlow(clockId) as StateFlow<String>,
-            payload = ClockStyleModel(thumbnail = thumbnail, showEditButton = showEditButton),
+            payload = ClockStyleModel(thumbnail = thumbnail),
             text = Text.Loaded(contentDescription),
             isTextUserVisible = false,
             isSelected = isSelectedFlow,
             onClicked =
                 isSelectedFlow.map { isSelected ->
-                    if (isSelected && isEditable) {
-                        fun() {
-                            _selectedTab.value = Tab.FONT
-                        }
+                    if (isSelected) {
+                        null
                     } else {
                         fun() {
                             overridingClock.value = this
-                            overrideClockFontAxisMap.value = emptyMap()
                         }
                     }
                 },
         )
     }
 
-    // Clock font axis
-    private val overrideClockFontAxisMap = MutableStateFlow<Map<String, Float>>(emptyMap())
-    val previewingClockFontAxes =
-        previewingClock
-            .map { clock -> clock.fontAxes }
-            .shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
-    private val selectedClockFontAxisMap =
-        selectedClock
-            .map { clock -> clock.fontAxes.associate { it.key to it.currentValue } }
-            .shareIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
-    private val isFontAxisMapEdited =
-        combine(overrideClockFontAxisMap, selectedClockFontAxisMap) {
-            overrideClockFontAxisMap,
-            selectedClockFontAxisMap ->
-            !overrideClockFontAxisMap.all { (key, value) -> selectedClockFontAxisMap[key] == value }
-        }
-    val previewingClockFontAxisMap =
-        combine(overrideClockFontAxisMap, selectedClockFontAxisMap.filterNotNull()) {
-                overrideAxisMap,
-                selectedAxisMap ->
-                if (overrideAxisMap.isEmpty()) {
-                    selectedAxisMap
-                } else {
-                    overrideAxisMap.let {
-                        val mutableMap = selectedAxisMap.toMutableMap()
-                        overrideAxisMap.forEach { (key, value) -> mutableMap[key] = value }
-                        mutableMap.toMap()
-                    }
-                }
-            }
-            .stateIn(viewModelScope, SharingStarted.Eagerly, emptyMap())
-
-    fun updatePreviewFontAxis(key: String, value: Float) {
-        val axisMap = overrideClockFontAxisMap.value.toMutableMap()
-        axisMap[key] = value
-        overrideClockFontAxisMap.value = axisMap.toMap()
-    }
-
-    fun confirmFontAxes() {
-        _selectedTab.value = Tab.STYLE
-    }
-
-    fun cancelFontAxes() {
-        overrideClockFontAxisMap.value = emptyMap()
-        _selectedTab.value = Tab.STYLE
-    }
-
     // Clock size
     private val overridingClockSize = MutableStateFlow<ClockSize?>(null)
     private val isClockSizeEdited =
@@ -415,18 +454,18 @@
     private val isEdited =
         combine(
             isClockEdited,
-            isFontAxisMapEdited,
+            isClockAxisStyleEdited,
             isClockSizeEdited,
             isClockColorIdEdited,
             isSliderProgressEdited,
         ) {
             isClockEdited,
-            isFontAxisMapEdited,
+            isClockAxisStyleEdited,
             isClockSizeEdited,
             isClockColorEdited,
             isSliderProgressEdited ->
             isClockEdited ||
-                isFontAxisMapEdited ||
+                isClockAxisStyleEdited ||
                 isClockSizeEdited ||
                 isClockColorEdited ||
                 isSliderProgressEdited
@@ -440,7 +479,7 @@
             previewingClockSize,
             previewingClockColorId,
             previewingSliderProgress,
-            previewingClockFontAxisMap,
+            previewingClockPresetIndexedStyle,
         ) { array ->
             val onApplyClicked: Boolean = array[0] as Boolean
             val isEdited: Boolean = array[1] as Boolean
@@ -448,7 +487,8 @@
             val size: ClockSize = array[3] as ClockSize
             val previewingColorId: String = array[4] as String
             val previewProgress: Int = array[5] as Int
-            val axisMap: Map<String, Float> = array[6] as Map<String, Float>
+            val clockAxisStyle: ClockAxisStyle =
+                (array[6] as? IndexedStyle)?.style ?: ClockAxisStyle()
             if (isEdited && !onApplyClicked) {
                 {
                     this.onApplyClicked.value = true
@@ -464,7 +504,7 @@
                                     colorTone = it.getColorTone(previewProgress),
                                 )
                             },
-                        axisSettings = ClockAxisStyle(axisMap),
+                        axisSettings = clockAxisStyle,
                     )
                 }
             } else {
@@ -477,7 +517,7 @@
         overridingClockSize.value = null
         overridingClockColorId.value = null
         overridingSliderProgress.value = null
-        overrideClockFontAxisMap.value = emptyMap()
+        overridingClockPresetIndexedStyle.value = null
         _selectedTab.value = Tab.STYLE
         onApplyClicked.value = false
     }
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
index 95f55c0..9414cc7 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ThemePickerCustomizationOptionsViewModel.kt
@@ -32,7 +32,6 @@
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.map
@@ -77,16 +76,6 @@
         defaultCustomizationOptionsViewModel.discardChangesDialogViewModel
 
     override fun handleBackPressed(): Boolean {
-
-        if (
-            defaultCustomizationOptionsViewModel.selectedOption.value ==
-                ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK &&
-                clockPickerViewModel.selectedTab.value == ClockPickerViewModel.Tab.FONT
-        ) {
-            clockPickerViewModel.cancelFontAxes()
-            return true
-        }
-
         if (isApplyButtonEnabled.value) {
             defaultCustomizationOptionsViewModel.showDiscardChangesDialogViewModel()
             return true
@@ -212,14 +201,6 @@
 
     val isApplyButtonVisible: Flow<Boolean> = selectedOption.map { it != null }
 
-    val isToolbarCollapsed: Flow<Boolean> =
-        combine(selectedOption, clockPickerViewModel.selectedTab) { selectedOption, selectedTab ->
-                selectedOption ==
-                    ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption.CLOCK &&
-                    selectedTab == ClockPickerViewModel.Tab.FONT
-            }
-            .distinctUntilChanged()
-
     @ViewModelScoped
     @AssistedFactory
     interface Factory : CustomizationOptionsViewModelFactory {
diff --git a/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt b/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
index fd2c801..7728218 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
@@ -22,16 +22,16 @@
 import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository.Companion.fakeClocks
 import com.android.customization.picker.clock.shared.ClockSize
 import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.systemui.plugins.clocks.AxisPresetConfig
+import com.android.systemui.plugins.clocks.AxisPresetConfig.Group
 import com.android.systemui.plugins.clocks.AxisType
 import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge
 import com.android.systemui.plugins.clocks.ClockId
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.update
 
 /** By default [FakeClockPickerRepository] uses [fakeClocks]. */
 open class FakeClockPickerRepository(clocks: List<ClockMetadataModel> = fakeClocks) :
@@ -43,16 +43,16 @@
     private val colorTone: MutableStateFlow<Int> =
         MutableStateFlow(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS)
     @ColorInt private val seedColor: MutableStateFlow<Int?> = MutableStateFlow(null)
-    private val fontAxes: MutableStateFlow<List<ClockFontAxis>> =
-        MutableStateFlow(listOf(buildFakeAxis(0)))
+    private val clockListFlow: MutableStateFlow<List<ClockMetadataModel>> =
+        MutableStateFlow(fakeClocks)
     override val selectedClock: Flow<ClockMetadataModel> =
-        combine(selectedClockId, selectedColorId, colorTone, seedColor, fontAxes) {
+        combine(clockListFlow, selectedClockId, selectedColorId, colorTone, seedColor) {
+            clockList,
             selectedClockId,
             selectedColor,
             colorTone,
-            seedColor,
-            fontAxes ->
-            val selectedClock = fakeClocks.find { clock -> clock.clockId == selectedClockId }
+            seedColor ->
+            val selectedClock = clockList.find { clock -> clock.clockId == selectedClockId }
             checkNotNull(selectedClock)
             ClockMetadataModel(
                 clockId = selectedClock.clockId,
@@ -60,7 +60,7 @@
                 description = "description",
                 thumbnail = ColorDrawable(0),
                 isReactiveToTone = selectedClock.isReactiveToTone,
-                fontAxes = fontAxes,
+                axisPresetConfig = selectedClock.axisPresetConfig,
                 selectedColorId = selectedColor,
                 colorToneProgress = colorTone,
                 seedColor = seedColor,
@@ -88,16 +88,31 @@
         _selectedClockSize.value = size
     }
 
-    override suspend fun setClockFontAxes(axisSettings: ClockAxisStyle) {
-        fontAxes.update { fontAxes -> fontAxes.merge(axisSettings) }
+    override suspend fun setClockAxisStyle(axisStyle: ClockAxisStyle) {
+        val clockList = clockListFlow.value
+        val newClockList = clockList.toMutableList()
+        for ((index, clock) in clockList.withIndex()) {
+            val presetConfig = clock.axisPresetConfig
+            val style = presetConfig?.findStyle(axisStyle)
+            if (presetConfig != null && style != null) {
+                newClockList[index] =
+                    clock.copy(axisPresetConfig = presetConfig.copy(current = style))
+            }
+        }
+
+        clockListFlow.value = newClockList.toList()
     }
 
     override fun isReactiveToTone(clockId: ClockId): Boolean? = true
 
     companion object {
-        fun buildFakeAxis(i: Int): ClockFontAxis {
+        fun buildFakeClockAxisStyle(i: Int): ClockAxisStyle {
+            return ClockAxisStyle(listOf(buildFakeAxis(i)))
+        }
+
+        private fun buildFakeAxis(i: Int): ClockFontAxis {
             return ClockFontAxis(
-                key = "key",
+                key = "key#$i",
                 type = AxisType.Float,
                 maxValue = 0f,
                 minValue = 1000f,
@@ -107,10 +122,36 @@
             )
         }
 
+        private val fakeClockAxisStyle0 = ClockAxisStyle(listOf(buildFakeAxis(0)))
+        val fakeClockAxisStyle1 = ClockAxisStyle(listOf(buildFakeAxis(1)))
+        private val fakeClockAxisStyle2 = ClockAxisStyle(listOf(buildFakeAxis(2)))
+        private val fakeClockAxisStyle3 = ClockAxisStyle(listOf(buildFakeAxis(3)))
+        private val fakeAxisPresetConfig: AxisPresetConfig =
+            AxisPresetConfig(
+                groups =
+                    listOf(
+                        AxisPresetConfig.Group(
+                            presets = listOf(fakeClockAxisStyle0, fakeClockAxisStyle1),
+                            icon = ColorDrawable(Color.BLUE),
+                        ),
+                        AxisPresetConfig.Group(
+                            presets = listOf(fakeClockAxisStyle2, fakeClockAxisStyle3),
+                            icon = ColorDrawable(Color.YELLOW),
+                        ),
+                    ),
+                current =
+                    AxisPresetConfig.IndexedStyle(
+                        groupIndex = 0,
+                        presetIndex = 0,
+                        style = fakeClockAxisStyle0,
+                    ),
+            )
+
         const val CLOCK_ID_0 = "clock0"
         const val CLOCK_ID_1 = "clock1"
         const val CLOCK_ID_2 = "clock2"
         const val CLOCK_ID_3 = "clock3"
+
         val fakeClocks =
             listOf(
                 ClockMetadataModel(
@@ -119,7 +160,7 @@
                     "description0",
                     ColorDrawable(0),
                     true,
-                    listOf(buildFakeAxis(0)),
+                    fakeAxisPresetConfig,
                     null,
                     50,
                     null,
@@ -130,7 +171,7 @@
                     "description1",
                     ColorDrawable(0),
                     true,
-                    listOf(buildFakeAxis(1)),
+                    null,
                     null,
                     50,
                     null,
@@ -141,7 +182,7 @@
                     "description2",
                     ColorDrawable(0),
                     true,
-                    listOf(buildFakeAxis(2)),
+                    null,
                     null,
                     50,
                     null,
@@ -152,7 +193,7 @@
                     "description3",
                     ColorDrawable(0),
                     false,
-                    listOf(buildFakeAxis(3)),
+                    null,
                     null,
                     50,
                     null,
diff --git a/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt b/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
index 484d810..67c2e46 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
@@ -3,7 +3,6 @@
 import androidx.test.filters.SmallTest
 import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
 import com.android.customization.picker.clock.shared.ClockSize
-import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 import com.android.wallpaper.picker.customization.data.repository.CustomizationRuntimeValuesRepository
 import com.android.wallpaper.testing.FakeSnapshotStore
@@ -89,7 +88,7 @@
     @Test
     fun setFontAxisSettings() = runTest {
         val axisSettings = collectLastValue(underTest.axisSettings)
-        val fakeSettings = ClockAxisStyle(listOf(FakeClockPickerRepository.buildFakeAxis(10)))
+        val fakeSettings = FakeClockPickerRepository.fakeClockAxisStyle1
 
         underTest.setClockFontAxes(fakeSettings)
 
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
index 0386c85..07d7cbf 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -60,7 +60,7 @@
                     description = "description",
                     thumbnail = ColorDrawable(0),
                     isReactiveToTone = true,
-                    fontAxes = listOf(),
+                    axisPresetConfig = null,
                     selectedColorId = null,
                     colorToneProgress = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
                     seedColor = null,
diff --git a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
index 482af7e..132133e 100644
--- a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
+++ b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModelTest.kt
@@ -28,6 +28,7 @@
 import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
 import com.android.customization.picker.color.data.repository.FakeColorPickerRepository2
 import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor2
+import com.android.systemui.plugins.clocks.AxisPresetConfig.IndexedStyle
 import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
 import com.android.themepicker.R
 import com.android.wallpaper.customization.ui.viewmodel.ClockPickerViewModel.Tab
@@ -114,48 +115,13 @@
         Dispatchers.resetMain()
     }
 
-    @Test
-    fun selectedTab_whenClickOnTabStyle() = runTest {
-        val tabs = collectLastValue(underTest.tabs)
-        val selectedTab = collectLastValue(underTest.selectedTab)
-
-        tabs()?.get(0)?.onClick?.invoke()
-
-        assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-    }
-
-    @Test
-    fun selectedTab_whenClickOnTabColor() = runTest {
-        val tabs = collectLastValue(underTest.tabs)
-        val selectedTab = collectLastValue(underTest.selectedTab)
-
-        tabs()?.get(1)?.onClick?.invoke()
-
-        assertThat(selectedTab()).isEqualTo(Tab.COLOR)
-    }
-
-    @Test
-    fun selectedTab_fontEditorWhenClickSelectedClock() = runTest {
-        val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
-        val selectedTab = collectLastValue(underTest.selectedTab)
-        // Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
-        advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-        assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-
-        val firstClock = clockStyleOptions()!![0]
-        val onClicked = collectLastValue(firstClock.onClicked)
-        if (!firstClock.isSelected.value) onClicked()?.invoke()
-        onClicked()?.invoke()
-
-        assertThat(selectedTab()).isEqualTo(Tab.FONT)
-    }
-
+    //// Tabs
     @Test
     fun tabs_whenInitialState() = runTest {
         val tabs = collectLastValue(underTest.tabs)
 
         val resultTabs = checkNotNull(tabs())
-        assertThat(resultTabs).hasSize(2)
+        assertThat(resultTabs).hasSize(3)
         resultTabs.forEachIndexed { index, floatingToolbarTabViewModel ->
             when (index) {
                 0 -> {
@@ -184,6 +150,19 @@
                         isOnClickNull = false,
                     )
                 }
+                2 -> {
+                    assertFloatingToolbarTabViewModel(
+                        viewModel = floatingToolbarTabViewModel,
+                        icon =
+                            Icon.Resource(
+                                res = R.drawable.ic_font_size_filled_24px,
+                                contentDescription = Text.Resource(R.string.clock_size),
+                            ),
+                        text = context.getString(R.string.clock_size),
+                        isSelected = false,
+                        isOnClickNull = false,
+                    )
+                }
             }
         }
     }
@@ -207,6 +186,37 @@
     }
 
     @Test
+    fun selectedTab_whenClickOnTabStyle() = runTest {
+        val tabs = collectLastValue(underTest.tabs)
+        val selectedTab = collectLastValue(underTest.selectedTab)
+
+        tabs()?.get(0)?.onClick?.invoke()
+
+        assertThat(selectedTab()).isEqualTo(Tab.STYLE)
+    }
+
+    @Test
+    fun selectedTab_whenClickOnTabColor() = runTest {
+        val tabs = collectLastValue(underTest.tabs)
+        val selectedTab = collectLastValue(underTest.selectedTab)
+
+        tabs()?.get(1)?.onClick?.invoke()
+
+        assertThat(selectedTab()).isEqualTo(Tab.COLOR)
+    }
+
+    @Test
+    fun selectedTab_whenClickOnTabSize() = runTest {
+        val tabs = collectLastValue(underTest.tabs)
+        val selectedTab = collectLastValue(underTest.selectedTab)
+
+        tabs()?.get(2)?.onClick?.invoke()
+
+        assertThat(selectedTab()).isEqualTo(Tab.SIZE)
+    }
+
+    //// Clock style
+    @Test
     fun selectedClock_whenClickOnStyleOptions() = runTest {
         val selectedClock = collectLastValue(underTest.selectedClock)
 
@@ -241,7 +251,7 @@
         val option1OnClicked = collectLastValue(clockStyleOptions()!![1].onClicked)
 
         assertThat(option0IsSelected()).isTrue()
-        assertThat(option0OnClicked()).isNotNull()
+        assertThat(option0OnClicked()).isNull()
 
         option1OnClicked()?.invoke()
         // Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockColorOptions
@@ -249,9 +259,117 @@
 
         assertThat(option0IsSelected()).isFalse()
         assertThat(option1IsSelected()).isTrue()
-        assertThat(option1OnClicked()).isNotNull()
+        assertThat(option1OnClicked()).isNull()
     }
 
+    //// Clock font
+    @Test
+    fun previewingClockPresetIndexedStyle_whenInitialState() = runTest {
+        val previewingClockPresetIndexedStyle =
+            collectLastValue(underTest.previewingClockPresetIndexedStyle)
+
+        assertThat(previewingClockPresetIndexedStyle())
+            .isEqualTo(FakeClockPickerRepository.fakeClocks[0].axisPresetConfig?.current)
+    }
+
+    @Test
+    fun previewingClockPresetIndexedStyle_whenClickOnSliderStep() = runTest {
+        val previewingClockPresetIndexedStyle =
+            collectLastValue(underTest.previewingClockPresetIndexedStyle)
+        val axisPresetsSliderViewModel = collectLastValue(underTest.axisPresetsSliderViewModel)
+        val onSlierStopTrackingTouch = axisPresetsSliderViewModel()?.onSliderStopTrackingTouch
+        checkNotNull(onSlierStopTrackingTouch)
+
+        onSlierStopTrackingTouch.invoke(1F)
+
+        assertThat(previewingClockPresetIndexedStyle())
+            .isEqualTo(
+                IndexedStyle(
+                    groupIndex = 0,
+                    presetIndex = 1,
+                    style = FakeClockPickerRepository.fakeClockAxisStyle1,
+                )
+            )
+    }
+
+    @Test
+    fun shouldShowPresetSlider_true_whenDefault() = runTest {
+        val shouldShowPresetSlider = collectLastValue(underTest.shouldShowPresetSlider)
+
+        assertThat(shouldShowPresetSlider()).isTrue()
+    }
+
+    @Test
+    fun shouldShowPresetSlider_false_whenSelectClockWithNullAxisPresetConfig() = runTest {
+        val shouldShowPresetSlider = collectLastValue(underTest.shouldShowPresetSlider)
+        val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
+        // Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
+        advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+        val onClockOption1Clicked =
+            clockStyleOptions()?.get(1)?.onClicked?.let { collectLastValue(it) }
+        checkNotNull(onClockOption1Clicked)
+
+        onClockOption1Clicked()?.invoke()
+
+        assertThat(shouldShowPresetSlider()).isFalse()
+    }
+
+    @Test
+    fun axisPresetsSliderViewModel_initialState() = runTest {
+        val axisPresetsSliderViewModel = collectLastValue(underTest.axisPresetsSliderViewModel)
+
+        val expectedPresetSize =
+            FakeClockPickerRepository.fakeClocks[0].axisPresetConfig?.groups?.get(0)?.presets?.size
+        checkNotNull(expectedPresetSize)
+        val resultAxisPresetsSliderViewModel = axisPresetsSliderViewModel()
+        assertThat(resultAxisPresetsSliderViewModel?.valueFrom).isEqualTo(0F)
+        assertThat(resultAxisPresetsSliderViewModel?.valueTo)
+            .isEqualTo((expectedPresetSize - 1).toFloat())
+        assertThat(resultAxisPresetsSliderViewModel?.stepSize).isEqualTo(1F)
+    }
+
+    @Test
+    fun axisPresetsSliderSelectedValue_update_whenClickOnSliderStep() = runTest {
+        val axisPresetsSliderSelectedValue =
+            collectLastValue(underTest.axisPresetsSliderSelectedValue)
+        val axisPresetsSliderViewModel = collectLastValue(underTest.axisPresetsSliderViewModel)
+        val onSlierStopTrackingTouch = axisPresetsSliderViewModel()?.onSliderStopTrackingTouch
+        checkNotNull(onSlierStopTrackingTouch)
+
+        onSlierStopTrackingTouch.invoke(1F)
+
+        val expectedResult =
+            FakeClockPickerRepository.fakeClocks[0]
+                .axisPresetConfig
+                ?.groups
+                ?.get(0)
+                ?.presets
+                ?.get(1)
+        checkNotNull(expectedResult)
+        assertThat(axisPresetsSliderSelectedValue()).isEqualTo(1F)
+    }
+
+    @Test
+    fun previewingClockPresetIndexedStyle_whenOnClockFaceClicked() = runTest {
+        val previewingClockPresetIndexedStyle =
+            collectLastValue(underTest.previewingClockPresetIndexedStyle)
+        val onClockFaceClicked = collectLastValue(underTest.onClockFaceClicked)
+
+        onClockFaceClicked()?.invoke()
+
+        val expectedResult =
+            FakeClockPickerRepository.fakeClocks[0]
+                .axisPresetConfig
+                ?.groups
+                ?.get(1)
+                ?.presets
+                ?.get(0)
+        checkNotNull(expectedResult)
+        assertThat(previewingClockPresetIndexedStyle())
+            .isEqualTo(IndexedStyle(groupIndex = 1, presetIndex = 0, style = expectedResult))
+    }
+
+    //// Clock size
     @Test
     fun previewingClockSize_whenCallingOnClockSizeSwitchChecked() = runTest {
         val previewingClockSize = collectLastValue(underTest.previewingClockSize)
@@ -265,76 +383,7 @@
         assertThat(previewingClockSize()).isEqualTo(ClockSize.SMALL)
     }
 
-    @Test
-    fun previewingFontAxes_defaultWhenNoOverrides() = runTest {
-        val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
-    }
-
-    @Test
-    fun previewingFontAxes_updateAxisChangesSetting() = runTest {
-        val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
-
-        underTest.updatePreviewFontAxis("key", 100f)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
-
-        underTest.updatePreviewFontAxis("extra", 10f)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f, "extra" to 10f))
-    }
-
-    @Test
-    fun previewingFontAxes_applyFontEditorExitsTab_keepsPreviewAxis() = runTest {
-        val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
-        val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
-        val selectedTab = collectLastValue(underTest.selectedTab)
-        // Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
-        advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
-        assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-
-        val firstClock = clockStyleOptions()!![0]
-        val onClicked = collectLastValue(firstClock.onClicked)
-        if (!firstClock.isSelected.value) onClicked()?.invoke()
-        onClicked()?.invoke()
-        underTest.updatePreviewFontAxis("key", 100f)
-
-        assertThat(selectedTab()).isEqualTo(Tab.FONT)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
-
-        underTest.confirmFontAxes()
-
-        assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
-    }
-
-    @Test
-    fun previewingFontAxes_revertFontEditorExitsTab_revertsPreviewAxis() = runTest {
-        val previewingFontAxes = collectLastValue(underTest.previewingClockFontAxisMap)
-        val clockStyleOptions = collectLastValue(underTest.clockStyleOptions)
-        val selectedTab = collectLastValue(underTest.selectedTab)
-        // Advance CLOCKS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from clockStyleOptions
-        advanceTimeBy(ClockPickerViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
-        assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-
-        val firstClock = clockStyleOptions()!![0]
-        val onClicked = collectLastValue(firstClock.onClicked)
-        if (!firstClock.isSelected.value) onClicked()?.invoke()
-        onClicked()?.invoke()
-        underTest.updatePreviewFontAxis("key", 100f)
-
-        assertThat(selectedTab()).isEqualTo(Tab.FONT)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 100f))
-
-        underTest.cancelFontAxes()
-
-        assertThat(selectedTab()).isEqualTo(Tab.STYLE)
-        assertThat(previewingFontAxes()).isEqualTo(mapOf("key" to 50f))
-    }
-
+    //// Clock color
     @Test
     fun sliderProgress_whenOnSliderProgressChanged() = runTest {
         val sliderProgress = collectLastValue(underTest.previewingSliderProgress)
@@ -488,25 +537,6 @@
     }
 
     @Test
-    fun apply_notNullWhenFontAxisChanged() = runTest {
-        val onApply = collectLastValue(underTest.onApply)
-
-        underTest.updatePreviewFontAxis("key", 100f)
-
-        assertThat(onApply()).isNotNull()
-    }
-
-    @Test
-    fun apply_nullAfterApplyingFontAxis() = runTest {
-        val onApply = collectLastValue(underTest.onApply)
-
-        underTest.updatePreviewFontAxis("key", 100f)
-        onApply()?.invoke()
-
-        assertThat(onApply()).isNull()
-    }
-
-    @Test
     fun apply_notNullWhenClockSizeChanged() = runTest {
         val onApply = collectLastValue(underTest.onApply)
         val onClockSizeSwitchCheckedChange =