diff --git a/app/src/AppRoutes.tsx b/app/src/AppRoutes.tsx
index 3e85a8969..ae47e152b 100644
--- a/app/src/AppRoutes.tsx
+++ b/app/src/AppRoutes.tsx
@@ -4,6 +4,7 @@ import AppRoutesIOS from './AppRoutesIOS';
import DefaultRedirect from './components/DefaultRedirect';
import ProtectedRoute from './components/ProtectedRoute';
import PublicRoute from './components/PublicRoute';
+import HumanPage from './features/human/HumanPage';
import { getIsMobile } from './lib/platform';
import Accounts from './pages/Accounts';
import Activity from './pages/Activity';
@@ -64,10 +65,17 @@ const AppRoutes = () => {
}
/>
- {/* Phase 6 — /human merged into /chat (Assistant surface).
- Preserve the route for back-compat (deep links, iOS share sheets, etc.).
- iOS AppRoutesIOS still serves /human natively — only desktop redirects. */}
- } />
+ {/* Human — first-class destination again (restored after the IA Phase 6
+ merge into Assistant). Renders the Human/mascot surface. iOS serves
+ /human via AppRoutesIOS. */}
+
+
+
+ }
+ />
{/* Brain — the centerpiece memory knowledge-graph surface, reached from
the raised center button in the bottom bar. Full-page, graph-only. */}
diff --git a/app/src/components/BottomTabBar.tsx b/app/src/components/BottomTabBar.tsx
index 9c83184cc..27cb67299 100644
--- a/app/src/components/BottomTabBar.tsx
+++ b/app/src/components/BottomTabBar.tsx
@@ -228,17 +228,16 @@ const BottomTabBar = () => {
trackEvent('avatar_menu_item_click', { item_id: itemId });
};
- // One regular pill tab. `iconOnly` renders just the glyph (no label) — used
- // for the pinned Home button so it reads as a fixed icon, like the avatar.
+ // One regular pill tab.
//
// When labels are always visible (theme setting), every labelled tab is given
// the SAME fixed width so the row stays symmetric. In the default hover mode
// the label still expands on hover (no fixed width) — unchanged behaviour.
- const renderTab = (tab: (typeof tabs)[number], iconOnly = false) => {
+ const renderTab = (tab: (typeof tabs)[number]) => {
const active = isActive(tab.path);
const showBadge = tab.id === 'notifications' && unreadCount > 0;
const showCompanionDot = tab.id === 'settings' && companionActive;
- const fixedWidth = !iconOnly && labelsAlwaysVisible;
+ const fixedWidth = labelsAlwaysVisible;
return (
);
};
@@ -289,6 +282,12 @@ const BottomTabBar = () => {
// The Brain — a raised circular button rising out of the center of the bar.
// The bg-colored ring fakes a notch cut into the pill's top edge. `brain-fab`
// is targeted by the reduced-motion gate in index.css to silence the glow.
+ //
+ // `-my-3` collapses the button's 48px (h-12) layout footprint so it no longer
+ // forces the nav row taller than the ~32px pill tabs — the bar height is
+ // driven by the tabs, while `-translate-y-5` still lifts the circle above the
+ // top edge. Without it the lower half of the raised circle left a dead band
+ // of empty bar height beneath the tabs.
const renderBrainButton = () => {
const active = isActive(BRAIN_TAB.path);
const brainTab = { ...BRAIN_TAB, label: t(BRAIN_TAB.labelKey) };
@@ -300,7 +299,7 @@ const BottomTabBar = () => {
onClick={() => handleTabClick(brainTab, active)}
aria-label={brainTab.label}
title={brainTab.label}
- className={`brain-fab group relative mx-1 flex h-12 w-12 -translate-y-5 items-center justify-center rounded-full text-white shadow-soft ring-4 ring-stone-200 transition-all duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] cursor-pointer dark:ring-neutral-900 ${
+ className={`brain-fab group relative mx-1 flex h-12 w-12 -my-3 -translate-y-4 items-center justify-center rounded-full text-white shadow-soft ring-4 ring-stone-200 transition-all duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] cursor-pointer dark:ring-neutral-900 ${
active
? 'bg-primary-600 animate-glow-pulse shadow-[0_0_16px_rgba(74,131,221,0.55)] scale-105'
: 'bg-primary-500 hover:bg-primary-600 hover:scale-105'
@@ -310,12 +309,11 @@ const BottomTabBar = () => {
);
};
- // Home is pinned to the far-left of the pill behind a divider — mirroring the
- // avatar pinned to the far-right behind its own divider. The rest of the row
- // splits evenly around the centered Brain button:
- // [ home ] | assistant · connections ( 🧠 ) activity · settings | [ avatar ]
- const homeTab = tabs[0];
- const leftTabs = tabs.slice(1, 3);
+ // Home is a normal pill tab now (no longer pinned/icon-only). The regular
+ // tabs split evenly around the centered Brain button; only the avatar stays
+ // pinned to the far-right behind a divider:
+ // | home · human · assistant ( 🧠 ) connections · activity · settings | [ avatar ]
+ const leftTabs = tabs.slice(0, 3);
const rightTabs = tabs.slice(3);
return (
@@ -342,9 +340,6 @@ const BottomTabBar = () => {
if (!e.currentTarget.contains(e.relatedTarget as Node)) setRevealed(false);
}}>