diff --git a/calm-hub-ui/src/components/navbar/Navbar.test.tsx b/calm-hub-ui/src/components/navbar/Navbar.test.tsx index bb468e971a..403c2e9a19 100644 --- a/calm-hub-ui/src/components/navbar/Navbar.test.tsx +++ b/calm-hub-ui/src/components/navbar/Navbar.test.tsx @@ -173,3 +173,24 @@ describe('Navbar UI config', () => { expect(screen.getByRole('link', { name: 'Support' })).toHaveAttribute('href', 'https://support.example.com'); }); }); + +// jsdom does no layout, so these guard the classes that set it (#3505). +describe('Navbar layout', () => { + it('keeps the logo in the flex flow below lg, so page actions cannot cover it', () => { + renderNavbar(makeState({})); + const center = screen.getByRole('link', { name: 'CALM Hub home' }).parentElement; + + expect(center).not.toHaveClass('absolute'); + expect(center).toHaveClass('lg:absolute', 'max-lg:shrink', 'min-w-0'); + expect(screen.getByAltText('CALM Logo')).toHaveClass('object-contain'); + }); + + it('stops the side groups shrinking under their content below lg', () => { + const { container } = renderNavbar(makeState({})); + + for (const side of [container.querySelector('.navbar-start'), container.querySelector('.navbar-end')]) { + expect(side).toHaveClass('max-lg:w-auto', 'max-lg:flex-1', 'lg:min-w-0'); + expect(side).not.toHaveClass('min-w-0'); + } + }); +}); diff --git a/calm-hub-ui/src/components/navbar/Navbar.tsx b/calm-hub-ui/src/components/navbar/Navbar.tsx index b08b827e23..77bbcaa8ae 100644 --- a/calm-hub-ui/src/components/navbar/Navbar.tsx +++ b/calm-hub-ui/src/components/navbar/Navbar.tsx @@ -42,7 +42,10 @@ export function Navbar({ storage }: NavbarProps = {}) { return (
-
+ {/* Below lg the logo stays in the flex flow: equal flex-1 sides keep it + centred, but neither side can shrink under its content, so page + actions in #navbar-actions push the logo aside instead of covering it. */} +
-
- - CALM Logo +
+ + CALM Logo
-
+
{/* Portal target for page-level actions (e.g. the diagram's view-options menu), always visible across breakpoints. */}