refactor(layout): floating sidebar + floating top header

Operator feedback 2026-06-04:
- "pull out the left nav to make it look like it is its own floating
  section versus attached to the top-left"
- "this is also true for the header for the pages"
- "the divider that runs between the right side and the sidebar.
  let's make that divider go away so it all feels like one large
  page"

Changes:

components/Layout.js
- Outer flex shell: `md:p-4 md:gap-4` pulls the sidebar AND the main
  column in from the viewport edges on desktop. Mobile (< 768px) is
  unaffected because the sidebar is `hidden md:flex` already and the
  TopSearchBar / page content still run flush there.
- Desktop sidebar: `md:rounded-3xl md:overflow-hidden` so the rail
  reads as a floating chip. Dropped `var(--rim-light-outer)` from
  its box-shadow stack — that 1px outer ring was literally the
  "vertical divider between the sidebar and the right side" the
  operator wanted gone. Chip edges are now defined by
  `var(--elevation-ambient)` (drop shadow) + the glass-surface-mid
  tint against the body gradient that shows through `md:gap-4`.
- Main column: added `md:gap-4 min-w-0`. The gap separates the
  floating TopSearchBar from the page content vertically so they
  read as two distinct floating chrome elements; min-w-0 prevents
  long card titles / table cells from blowing past the column width.

components/ui/TopSearchBar.js
- `md:rounded-2xl` so the header reads as a floating chip on
  desktop. Mobile stays square (header is edge-to-edge there).
- Box-shadow: `rim-light-inner` + `elevation-ambient`. Deliberately
  no `rim-light-outer` — the prior "remove the divider" feedback
  applies to any visible 1px edge, and a hairline outer ring would
  re-introduce one on mobile where the bar abuts content directly.

Tests:
- npm run test:run: 113/113
- npm run lint: clean
- npm run build: green

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Randall Stillwell 2026-06-04 12:04:36 -05:00
parent 7a01469e5f
commit 3cfdab25c3
2 changed files with 44 additions and 13 deletions

View file

@ -664,7 +664,18 @@ export default function Layout({ children, user = null, showSearch = false }) {
}, []);
return (
<div className="flex h-screen">
// Outer shell — `md:p-4 md:gap-4` pulls both the sidebar and the
// main column in from the viewport edges so the sidebar and the
// top header read as floating chrome chips (operator feedback
// 2026-06-04: "pull out the left nav to make it look like it is
// its own floating section versus attached to the top-left"). The
// `md:gap-4` on this row also creates the visible page-body
// background between the sidebar's right edge and the main
// column, which replaces the previous hard divider — "all feels
// like one large page" is achieved by the hearth gradient
// showing through the gap. Mobile (< 768px) keeps the current
// flush layout because the sidebar is `hidden md:flex` anyway.
<div className="flex h-screen md:p-4 md:gap-4">
{/* Mobile Navigation - Bottom bar for mobile */}
<MobileNavigation
onMenuOpen={() => setIsMobileMenuOpen(true)}
@ -815,14 +826,21 @@ export default function Layout({ children, user = null, showSearch = false }) {
{/* Desktop Sidebar - Hidden on mobile. Liquid Glass mid-tint, ambient
elevation + rim-light edges; the page background visibly cools
through the rail. */}
through the rail. 2026-06-04 floating-chrome pass: rounded-3xl
+ overflow-hidden so the rail reads as its own floating chip;
`var(--rim-light-outer)` dropped from the box-shadow stack
because that 1px outer ring was the "vertical divider between
the sidebar and the right side" the operator wanted gone. The
chip's edge is now defined solely by `var(--elevation-ambient)`
(drop shadow) + the glass-surface-mid tint against the body
gradient that shows through `md:gap-4` on the outer flex. */}
<div
className="hidden md:flex md:static inset-y-0 left-0 w-64"
className="hidden md:flex md:static inset-y-0 left-0 w-64 md:rounded-3xl md:overflow-hidden"
style={{
background: 'var(--glass-surface-mid)',
backdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
WebkitBackdropFilter: 'blur(var(--glass-blur-mid)) saturate(var(--glass-saturate))',
boxShadow: 'var(--rim-light-inner), var(--rim-light-outer), var(--elevation-ambient)',
boxShadow: 'var(--rim-light-inner), var(--elevation-ambient)',
}}
>
<div className="p-4 h-full flex flex-col w-full">
@ -933,8 +951,14 @@ export default function Layout({ children, user = null, showSearch = false }) {
</div>
</div>
{/* Main Content */}
<div className="flex-1 flex flex-col pb-16 md:pb-0">
{/* Main Content. `md:gap-4` adds vertical breathing room between
the floating TopSearchBar header and the page content so they
read as two distinct floating chrome elements over the body
gradient (rather than the header sitting flush against the
content). `min-w-0` prevents flex children from blowing past
the column width when long card titles or table cells refuse
to wrap. */}
<div className="flex-1 flex flex-col pb-16 md:pb-0 md:gap-4 min-w-0">
{/* Global top bar redesign-v2 sub-convoy #3 (2026-06-04).
Rendered for ALL authenticated pages so the search +
notifications + user-menu chrome is consistent everywhere

View file

@ -62,17 +62,24 @@ export default function TopSearchBar({
return (
<header
className="px-4 sm:px-6 py-3 flex items-center gap-3 sm:gap-4"
// Floating-chrome pass 2026-06-04: `md:rounded-2xl` so the bar
// reads as its own floating chip on desktop (Layout's
// `md:p-4 md:gap-4` puts visible body gradient on all four sides
// of it). Mobile keeps square corners since the header runs
// edge-to-edge there. The shadow stack pairs `rim-light-inner`
// (subtle top inset highlight kept from the prior pass) with
// `elevation-ambient` (drop shadow) so it floats over the body
// gradient. We deliberately did NOT add `rim-light-outer` here:
// the operator's "remove the divider" feedback from the prior
// pass applies to any visible 1px edge, and a hairline outer
// ring would re-introduce one on mobile where the bar abuts
// content directly.
className="px-4 sm:px-6 py-3 flex items-center gap-3 sm:gap-4 md:rounded-2xl"
style={{
background: 'var(--glass-surface-mid)',
backdropFilter: 'blur(12px) saturate(180%)',
WebkitBackdropFilter: 'blur(12px) saturate(180%)',
// The hairline border-bottom (`0 1px 0 var(--border)`) was
// removed 2026-06-04 per operator feedback ("almost looks
// seamless between that header and the rest of that page
// content"). The rim-light-inner highlight stays so the bar
// still reads as elevated chrome against the gradient body.
boxShadow: 'var(--rim-light-inner)',
boxShadow: 'var(--rim-light-inner), var(--elevation-ambient)',
}}
>
{/* Search affordance read-only-ish input that opens the