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); }}>