Reduce all sidebar section outer padding from px-3 to px-2 so hover
backgrounds are wider and items center properly in the 64px collapsed
width. All sections now consistent: px-2 outer + px-2.5 inner.
Sidebar and content header were too transparent — content bled through.
Bump from bg-*/70 to bg-*/90 with backdrop-blur-xl for a subtle glass
effect that's still readable.
Apply the same backdrop-blur-2xl + semi-transparent bg treatment from
the AppLauncher dropdown to the sidebar and content header. Matches
the Ciphera design language: bg-white/70 dark:bg-neutral-900/70 with
supports-[backdrop-filter] progressive enhancement. Soften all borders
to /60 opacity.
Collapsed width 56px→64px to stop clipping site picker badge and icons.
Return null while auth is loading on site pages to prevent brief flash
of the public floating header before the sidebar layout renders.
Root cause: class switching (px-2↔px-3, justify-center↔gap-2.5,
conditional DOM rendering) caused instant layout jumps during the
200ms width transition.
Fix: internal layout is now 100% static — same padding, same gap,
same DOM structure in both states. Only opacity transitions on text
labels (via Label component). The sidebar overflow:hidden + width
transition handles the visual collapse. Collapse icon rotates 180deg
instead of swapping between two icons.
Icons now use justify-center + px-0 when collapsed so they sit
perfectly centered in the 56px rail. Track pending navigation href
optimistically — clicked item shows orange immediately instead of
flashing through the inactive hover state during route transition.
Use framer-motion animated sidebar from 21st.dev — collapses to icons,
expands on hover. Phosphor icons instead of lucide. Remove old manual
collapse/expand and sidebar-context. Top bar has Pulse logo + user
actions, sidebar below with site picker and nav groups.
Restructure layout: top bar spans full width (Pulse logo left, user
actions right) with continuous bottom border. Sidebar sits below with
no vertical border collision. Remove logo from sidebar. Remove all
transition-colors from nav items to prevent white flash on click.
- Fix stretched logo with object-contain
- Remove border below logo
- Add overflow-hidden to prevent scrollbar flash during transition
- Match utility bar height to old header (py-3.5)
- Remove transition-colors from active nav items to prevent white flash
Sidebar takes full viewport height with Pulse logo at top. No Header
on site pages — UtilityBar in content area provides theme toggle, app
launcher, notifications, and user menu. Non-site authenticated pages
keep static Header. No footer on dashboard pages.
Use h-screen overflow-hidden on the root container for authenticated
views. Sidebar and content fill the remaining height below the header.
Remove footer from dashboard pages. Content scrolls inside its own
container, sidebar stays fixed in place.
Replace floating pill header with static variant for authenticated
views. Add collapsible sidebar with site picker, grouped navigation
(Analytics/Infrastructure), and mobile overlay drawer. Remove
horizontal SiteNav tab bar.
Storage/TTL labels used implementation terms (localStorage, sessionStorage, TTL)
that only make sense to developers. Replaced with plain language and added a
description explaining the privacy trade-off.
window.innerWidth is 0 in hidden/minimized tabs, causing the heuristic bot
scorer (added in #40) to drop legitimate custom events with a score of 5.
Use window.screen.width as fallback, matching the existing trackPageview logic.
window.innerWidth is 0 in hidden/minimized tabs, causing the heuristic bot
scorer (added in #40) to drop legitimate custom events with a score of 5.
Use window.screen.width as fallback, matching the existing trackPageview logic.
IsSuspiciousEvent already scores 0x0 screens as +5 (bot threshold).
Keeping the check client-side hides bot traffic from analysis and
is trivially bypassable.
Server-side heuristic scoring already catches these patterns via
IsSuspiciousEvent. Client-side checks are trivially bypassable
(script is public) and add payload weight for all real users.