diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index a9d57e9265dad..199b5577ad7e5 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -312,6 +312,8 @@ if (_is_default_toolchain) {
 
   android_library("chrome_java") {
     deps = [
+      "//third_party/androidx:androidx_compose_ui_ui_android_java",
+      "//mica:ui_java",
       ":base_module_java",
       ":chrome_app_java_resources",
       ":chrome_public_apk_template_resources",
@@ -1803,6 +1805,10 @@ if (_is_default_toolchain) {
   android_resources("chrome_public_apk_base_module_resources") {
     resource_overlay = true
     sources = [
+      "java/res_chromium_base/drawable/ic_launcher.xml",
+      "java/res_chromium_base/drawable/ic_launcher_round.xml",
+      "java/res_chromium_base/drawable/mica_launcher_foreground.xml",
+      "java/res_chromium_base/drawable/mica_launcher_foreground_monochrome.xml",
       "java/res_chromium_base/drawable/themed_app_icon.xml",
       "java/res_chromium_base/mipmap-hdpi/app_icon.png",
       "java/res_chromium_base/mipmap-hdpi/layered_app_icon.png",
@@ -2109,6 +2115,7 @@ if (_is_default_toolchain) {
   }
 
   chrome_public_apk_or_module_tmpl("chrome_public_apk") {
+    loadable_modules = [ "//mica/libandroidx.graphics.path.so" ]
     target_type = "android_apk"
     apk_name = "ChromePublic"
     if (defined(android_app_secondary_abi)) {
diff --git a/chrome/android/java/res_chromium_base/values/channel_constants.xml b/chrome/android/java/res_chromium_base/values/channel_constants.xml
index cc1f2a30cb3c5..68f69136657d0 100644
--- a/chrome/android/java/res_chromium_base/values/channel_constants.xml
+++ b/chrome/android/java/res_chromium_base/values/channel_constants.xml
@@ -7,8 +7,8 @@ found in the LICENSE file.
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- The application name displayed to the user. -->
-    <string name="app_name" translatable="false">Chromium</string>
-    <string name="bookmark_widget_title" translatable="false">Chromium bookmarks</string>
-    <string name="search_widget_title" translatable="false">Chromium search</string>
-    <string name="quick_action_search_widget_title" translatable="false">Chromium quick action search</string>
+    <string name="app_name" translatable="false">Mica</string>
+    <string name="bookmark_widget_title" translatable="false">Mica bookmarks</string>
+    <string name="search_widget_title" translatable="false">Mica search</string>
+    <string name="quick_action_search_widget_title" translatable="false">Mica quick action search</string>
 </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 411d05fc91a5e..eb388d4f1830c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1669,6 +1669,13 @@ public class ChromeTabbedActivity extends ChromeActivity implements PreAttachInt
             }
 
             super.finishNativeInitialization();
+            // Force Chrome's own toolbar hidden via the real browser-controls state machine
+            // (not a one-off View.setVisibility hack) so it can never be re-shown by
+            // ToolbarManager on tab switch, navigation, or scroll. See installMicaUi() below,
+            // which embeds Chrome's content view (with its now-permanently-hidden toolbar)
+            // inside Mica's own Compose chrome.
+            getBrowserControlsManager().getBrowserVisibilityDelegate().setForceHidden(true);
+            getWindow().getDecorView().post(this::installMicaUi);
 
             TabbedStartupWindowPolicyDelegate.getInstance().initializeWithNative(profile);
 
@@ -6105,4 +6112,129 @@ public class ChromeTabbedActivity extends ChromeActivity implements PreAttachInt
         // future.
         return VerticalTabUtils.isVerticalTabsEnabled(this);
     }
+    private boolean mMicaInstalled;
+    private kotlin.jvm.functions.Function2<? super Float, ? super Boolean, kotlin.Unit> mMicaScrollCallback;
+    private org.chromium.content_public.browser.WebContents mMicaScrollWebContents;
+
+    /**
+     * Bridges real Chromium page-scroll gesture updates into Mica's ContentScrollListener. Uses
+     * the default (NONE) update frequency, which piggybacks on RenderFrameMetadata updates Chrome
+     * already sends during an active scroll rather than requesting extra IPC -- deliberately not a
+     * fake timer or Compose-only scroll simulation.
+     */
+    private final org.chromium.content_public.browser.GestureStateListener mMicaScrollGestureListener =
+            new org.chromium.content_public.browser.GestureStateListener() {
+                private int mLastOffsetY = -1;
+
+                @Override
+                public void onScrollOffsetOrExtentChanged(int scrollOffsetY, int scrollExtentY) {
+                    if (mMicaScrollCallback == null) return;
+                    if (mLastOffsetY < 0) {
+                        mLastOffsetY = scrollOffsetY;
+                        return;
+                    }
+                    // Positive when the page scrolls toward the top, matching
+                    // ContentScrollListener's "finger moves down" sign convention.
+                    float deltaY = mLastOffsetY - scrollOffsetY;
+                    mLastOffsetY = scrollOffsetY;
+                    if (deltaY != 0f) mMicaScrollCallback.invoke(deltaY, scrollOffsetY <= 0);
+                }
+
+                @Override
+                public void onScrollEnded(int scrollOffsetY, int scrollExtentY) {
+                    mLastOffsetY = scrollOffsetY;
+                }
+            };
+
+    private void updateMicaScrollBridge() {
+        Tab tab = getActivityTab();
+        org.chromium.content_public.browser.WebContents webContents =
+                tab == null ? null : tab.getWebContents();
+        if (webContents == mMicaScrollWebContents) return;
+        if (mMicaScrollWebContents != null) {
+            org.chromium.content_public.browser.GestureListenerManager oldManager =
+                    org.chromium.content_public.browser.GestureListenerManager.fromWebContents(
+                            mMicaScrollWebContents);
+            if (oldManager != null) oldManager.removeListener(mMicaScrollGestureListener);
+        }
+        mMicaScrollWebContents = webContents;
+        if (mMicaScrollWebContents != null) {
+            org.chromium.content_public.browser.GestureListenerManager newManager =
+                    org.chromium.content_public.browser.GestureListenerManager.fromWebContents(
+                            mMicaScrollWebContents);
+            if (newManager != null) newManager.addListener(mMicaScrollGestureListener);
+        }
+    }
+
+    private void installMicaUi() {
+        if (mMicaInstalled || isFinishing() || isDestroyed()) return;
+        if (getActivityTab() == null) {
+            getWindow().getDecorView().postDelayed(this::installMicaUi, 100);
+            return;
+        }
+        mMicaInstalled = true;
+        getActivityTab().addObserver(new TabObserver() {
+            @Override
+            public void onContentChanged(Tab tab) {
+                updateMicaScrollBridge();
+            }
+        });
+        // Keep Chrome's native initialization, tab ownership, compositor, and sandbox intact.
+        android.view.ViewGroup container = findViewById(android.R.id.content);
+        android.view.View content = container.getChildAt(0);
+        // Chrome's own control_container view is left inflated and owned by ToolbarManager
+        // (removing it entirely would require gutting ToolbarManager's non-null assumptions
+        // across RootUiCoordinator). It is kept genuinely invisible via
+        // BrowserControlsState.HIDDEN, forced above, which Chrome's existing hide-on-scroll
+        // machinery implements as a full off-screen translate of the toolbar view, robust
+        // against ToolbarManager re-asserting VISIBLE later.
+        getBrowserControlsManager().setTopControlsHeight(0, 0);
+        getBrowserControlsManager().setBottomControlsHeight(0, 0);
+        com.mica.browser.ChromiumMicaHost.attach(this, content,
+                new com.mica.browser.browser.ChromiumPort() {
+                    @Override public String url() {
+                        Tab tab = getActivityTab();
+                        return tab == null ? "" : tab.getUrl().getSpec();
+                    }
+                    @Override public String title() {
+                        Tab tab = getActivityTab();
+                        return tab == null ? "Mica" : tab.getTitle();
+                    }
+                    @Override public boolean loading() {
+                        Tab tab = getActivityTab();
+                        return tab != null && tab.isLoading();
+                    }
+                    @Override public boolean canGoBack() {
+                        Tab tab = getActivityTab();
+                        return tab != null && tab.canGoBack();
+                    }
+                    @Override public void navigate(String url) {
+                        Tab tab = getActivityTab();
+                        if (tab != null) tab.loadUrl(new org.chromium.content_public.browser.LoadUrlParams(url));
+                    }
+                    @Override public void back() {
+                        Tab tab = getActivityTab();
+                        if (tab != null && tab.canGoBack()) tab.goBack();
+                    }
+                    @Override public void reload() {
+                        Tab tab = getActivityTab();
+                        if (tab != null) tab.reload();
+                    }
+                    @Override public void stop() {
+                        Tab tab = getActivityTab();
+                        if (tab != null && tab.getWebContents() != null) tab.getWebContents().stop();
+                    }
+                    @Override
+                    public void setScrollListener(
+                            kotlin.jvm.functions.Function2<? super Float, ? super Boolean, kotlin.Unit> listener) {
+                        mMicaScrollCallback = listener;
+                        updateMicaScrollBridge();
+                    }
+                });
+        // Start on an engine-rendered page instead of Chrome's native new-tab UI.
+        if (getActivityTab().getUrl().getSpec().startsWith("chrome://newtab")) {
+            getActivityTab().loadUrl(new org.chromium.content_public.browser.LoadUrlParams("about:blank"));
+        }
+    }
+
 }
diff --git a/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java b/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java
index df0b45aef0334..1d95996dad142 100644
--- a/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java
+++ b/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java
@@ -39,6 +39,16 @@ public class BrowserStateBrowserControlsVisibilityDelegate extends BrowserContro
     /** Predicate that tells if we're in persistent fullscreen mode. */
     private final NonNullObservableSupplier<Boolean> mPersistentFullscreenMode;
 
+    /**
+     * Embedder-level override (e.g. Mica replacing Chrome's own browser chrome) that forces the
+     * controls hidden unconditionally, taking precedence over any showControlsPersistent()
+     * token. Unlike a one-off View.setVisibility(GONE) call on the control container, this is
+     * consulted every time {@link #calculateVisibilityConstraints()} recomputes (tab switch,
+     * navigation, load state changes, scroll), so it cannot be silently reverted by ToolbarManager
+     * or any other component that shares ownership of the control container view.
+     */
+    private boolean mForceHidden;
+
     private long mCurrentShowingStartTime;
 
     /**
@@ -111,8 +121,24 @@ public class BrowserStateBrowserControlsVisibilityDelegate extends BrowserContro
         mTokenHolder.releaseToken(token);
     }
 
+    /**
+     * Forces the browser controls (top and bottom toolbars) to remain hidden regardless of any
+     * showControlsPersistent() token, scroll state, or tab/navigation changes. Intended for an
+     * embedder (Mica) that replaces Chrome's browser chrome entirely and must guarantee Chrome's
+     * own toolbar never becomes visible again, on any tab or navigation.
+     *
+     * @param forceHidden Whether to force the controls hidden.
+     */
+    public void setForceHidden(boolean forceHidden) {
+        if (mForceHidden == forceHidden) return;
+        mForceHidden = forceHidden;
+        updateVisibilityConstraints();
+    }
+
     private @BrowserControlsState int calculateVisibilityConstraints() {
-        if (mPersistentFullscreenMode.get()) {
+        if (mForceHidden) {
+            return BrowserControlsState.HIDDEN;
+        } else if (mPersistentFullscreenMode.get()) {
             return BrowserControlsState.HIDDEN;
         } else if (ChromeFeatureList.sToolbarScrollAblation.isEnabled()
                 || (mTokenHolder.hasTokens() && !sDisableOverridesForTesting)) {
diff --git a/third_party/androidx/customizations.gni b/third_party/androidx/customizations.gni
index 722779334cc5c..27c9a4fc22905 100644
--- a/third_party/androidx/customizations.gni
+++ b/third_party/androidx/customizations.gni
@@ -21,6 +21,13 @@ template("_androidx_prebuilt") {
       forward_variables_from(invoker, "*", [ "target_type" ])
     }
 
+    if (defined(visibility)) {
+      # //mica:* wraps a handful of these as prebuilt AARs for the Mica browser shell.
+      # //chrome/android:* is chrome_java itself, which depends directly on the compose
+      # UI android resources target (androidx_compose_ui_ui_android_java) alongside //mica:ui_java.
+      visibility += [ "//mica:*", "//chrome/android:*" ]
+    }
+
     if (target_name == "androidx_annotation_annotation_java") {
       # Ensure this dep is the suggested one when targets are missing it.
       preferred_dep = true
