1diff --git a/android/build.gradle b/android/build.gradle
2index 6bd6d5acf6ac3da78232170a6ea8c2b0f6e5504e..a827dad53dcd8c1b2f47fce30ea8bf9140787f38 100644
3--- a/android/build.gradle
4+++ b/android/build.gradle
5@@ -146,6 +146,12 @@ dependencies {
6 implementation "androidx.activity:activity-compose:$activityComposeVersion"
7 implementation "androidx.lifecycle:lifecycle-runtime-compose:$lifecycleVersion"
8 implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleVersion"
9+ // ClerkComposeNativeViewHost imports LocalSavedStateRegistryOwner and
10+ // LocalLifecycleOwner from these artifacts. Earlier SDKs leaked them onto
11+ // the compile classpath through clerk-android-ui's navigation3 runtime
12+ // dependency; AGP 9 resolves the compile classpath on its own.
13+ implementation "androidx.savedstate:savedstate-compose:1.4.0"
14+ implementation "androidx.lifecycle:lifecycle-runtime-compose:2.10.0"
15
16 testImplementation "junit:junit:4.13.2"
17 }
18diff --git a/ios/ClerkAuthNativeView.swift b/ios/ClerkAuthNativeView.swift
19index 5f8d2ba66d5b232890af75c22b173c86d2ef546b..b170304cbf2fbaae8032db8dd6f89b6a59c6e3fe 100644
20--- a/ios/ClerkAuthNativeView.swift
21+++ b/ios/ClerkAuthNativeView.swift
22@@ -111,7 +111,12 @@ public class ClerkAuthNativeView: ClerkNativeViewHost {
23
24 override func makeHostedController() -> UIViewController? {
25 let hostBackAction: (() -> Void)? = currentHostBackButton
26- ? { [weak self] in self?.onHostBack([:]) }
27+ ? { [weak self] in
28+ guard let self else { return }
29+ if !self.popEnclosingNavigationRoute() {
30+ self.onHostBack([:])
31+ }
32+ }
33 : nil
34
35 return ClerkNativeBridge.shared.makeAuthViewController(
36diff --git a/ios/ClerkNativeBridge.swift b/ios/ClerkNativeBridge.swift
37index c90ad2ef1162cc2ac025c8b0b4aa135e8913dc21..ce8cb68764b1a3d3537672fc83e4e3077fceb97a 100644
38--- a/ios/ClerkNativeBridge.swift
39+++ b/ios/ClerkNativeBridge.swift
40@@ -1470,6 +1470,8 @@ private struct ClerkReactEmbeddedUserProfileCustomPage: View {
41 }
42
43 private struct ClerkReactUserProfileCustomPageContent: View {
44+ @Environment(\.clerkTheme) private var theme
45+
46 let path: String
47 let rows: [ClerkUserProfileCustomRowConfig]
48 let state: ClerkUserProfileCustomPageState
49@@ -1483,8 +1485,13 @@ private struct ClerkReactUserProfileCustomPageContent: View {
50 }
51 }
52 .frame(maxWidth: .infinity, maxHeight: .infinity)
53+ // Match Clerk's own profile pages so the navigation bar and page share
54+ // the theme's page background instead of a bare hosting container.
55+ .background(theme.colors.muted)
56 .navigationTitle(userProfileCustomPageLabel(for: path, rows: rows))
57 .navigationBarTitleDisplayMode(.inline)
58+ .preGlassSolidNavBar()
59+ .background(theme.colors.background)
60 }
61 }
62
63diff --git a/ios/ClerkNativeViewHost.swift b/ios/ClerkNativeViewHost.swift
64index 4e6540aceeaaab56ddf327bb3f16e120438f066f..cc16c94ca7a6eb91a97e76d5de02dc586f02a766 100644
65--- a/ios/ClerkNativeViewHost.swift
66+++ b/ios/ClerkNativeViewHost.swift
67@@ -5,6 +5,7 @@ public class ClerkNativeViewHost: ExpoView {
68 private lazy var hostingCoordinator = ClerkNativeHostingCoordinator(containerView: self)
69 private var hasInitialized: Bool = false
70 private var configuredObserver: NSObjectProtocol?
71+ private var isPoppingHostRoute = false
72
73 public required init(appContext: AppContext? = nil) {
74 super.init(appContext: appContext)
75@@ -58,6 +59,30 @@ public class ClerkNativeViewHost: ExpoView {
76
77 func hostedViewDidDetachFromWindow() {}
78
79+ /// Pops the React Navigation route that contains this view without waiting for
80+ /// the JavaScript event loop. React Native Screens reports the native dismissal
81+ /// back to React Navigation so its state remains synchronized.
82+ func popEnclosingNavigationRoute() -> Bool {
83+ guard !isPoppingHostRoute else { return true }
84+
85+ var responder: UIResponder? = self
86+
87+ while let nextResponder = responder?.next {
88+ if let viewController = nextResponder as? UIViewController,
89+ let navigationController = viewController.navigationController,
90+ navigationController.viewControllers.count > 1 {
91+ isPoppingHostRoute = true
92+ if navigationController.popViewController(animated: true) != nil {
93+ return true
94+ }
95+ isPoppingHostRoute = false
96+ }
97+ responder = nextResponder
98+ }
99+
100+ return false
101+ }
102+
103 private func addConfiguredObserver() {
104 guard configuredObserver == nil else { return }
105
106diff --git a/ios/ClerkUserProfileNativeView.swift b/ios/ClerkUserProfileNativeView.swift
107index f2ca604d41f50d05de8ac334879126cdc0414f84..46f406d5361b9a560a7c4ce855e344cbddd1d0b6 100644
108--- a/ios/ClerkUserProfileNativeView.swift
109+++ b/ios/ClerkUserProfileNativeView.swift
110@@ -47,7 +47,12 @@ public class ClerkUserProfileNativeView: ClerkUserProfileCustomPageHost {
111
112 override func makeHostedController() -> UIViewController? {
113 let hostBackAction: (() -> Void)? = currentHostBackButton
114- ? { [weak self] in self?.onHostBack([:]) }
115+ ? { [weak self] in
116+ guard let self else { return }
117+ if !self.popEnclosingNavigationRoute() {
118+ self.onHostBack([:])
119+ }
120+ }
121 : nil
122
123 return ClerkNativeBridge.shared.makeUserProfileViewController(