Skip to content

feat: Improve mobile responsiveness with enhanced navigation and layout fixes#8

Merged
nabobery merged 6 commits into
mainfrom
3-improve-mobile-responsiveness-ensure-central-alignment
Oct 4, 2025
Merged

feat: Improve mobile responsiveness with enhanced navigation and layout fixes#8
nabobery merged 6 commits into
mainfrom
3-improve-mobile-responsiveness-ensure-central-alignment

Conversation

@nabobery

@nabobery nabobery commented Oct 4, 2025

Copy link
Copy Markdown
Owner

Summary

This pull request addresses mobile responsiveness and accessibility improvements, specifically targeting the requirements outlined in issue #3. The changes focus on ensuring proper central alignment and responsive behavior across mobile devices.

Key Changes

Mobile Navigation Enhancement

  • Replaced mobile menu with a proper Sheet component (slide-out drawer) for better UX
  • Added scroll lock functionality when mobile menu is open to prevent background scrolling
  • Implemented keyboard navigation (ESC key support) for better accessibility
  • Improved mobile menu layout with centered content and proper spacing

Layout & Responsive Design

  • Added safe area helpers for iOS notch devices and small screens to prevent content clipping
  • Fixed horizontal scrolling issues by adding overflow-x: hidden and proper width constraints
  • Enhanced container centering through Tailwind config updates for consistent alignment
  • Improved responsive behavior of the particle canvas component

Accessibility Improvements

  • Enhanced theme provider with prefers-reduced-motion support for better accessibility
  • Removed global animations that could cause layout jank or content flashes
  • Added proper ARIA labels and descriptions to mobile navigation components
  • Improved focus management and keyboard navigation support

Technical Enhancements

  • Added scroll lock utility (useLockScroll hook) for modal/drawer components
  • Enhanced Sheet component with proper accessibility attributes
  • Improved CSS architecture with safe area utilities and responsive design patterns

Issue Resolution

This PR successfully addresses issue #3: Improve Mobile Responsiveness: Ensure Central Alignment by implementing:

  • Proper container centering and responsive layout adjustments
  • Mobile-first navigation improvements
  • Safe area handling for various device form factors
  • Enhanced accessibility features for mobile users

The changes ensure that all content and elements are properly centered and accessible across different mobile devices and screen sizes, meeting the core requirements specified in the original issue.

…bile menu improvements, and theme provider updates
@nabobery nabobery linked an issue Oct 4, 2025 that may be closed by this pull request
@vercel

vercel Bot commented Oct 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
project-protico Ready Ready Preview Comment Oct 4, 2025 10:28am

@coderabbitai

coderabbitai Bot commented Oct 4, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Redesigned mobile navigation with a right-side drawer and background scroll lock.
    • Added safe-area padding helpers for devices with notches.
    • Standardized container layout with centered alignment and responsive padding.
  • Bug Fixes

    • Prevented horizontal scrolling and overflow across the app, including canvas elements.
    • Improved mobile touch behavior and vertical panning.
    • Ensured animations respect reduced-motion preferences and removed unnecessary wrapper animations.
  • Accessibility

    • Added hidden titles and descriptions to mobile drawer for better screen reader support.

Walkthrough

Replaces the mobile navbar with a right-anchored Sheet drawer (with ESC-to-close and background scroll lock), adds a useLockScroll hook, honors prefers-reduced-motion, prevents horizontal overflow and adds iOS safe-area helpers, adjusts particle canvas CSS sizing, and configures Tailwind container padding.

Changes

Cohort / File(s) Summary of changes
Mobile navigation (Sheet)
components/layout/navbar.tsx
Replaced AnimatePresence mobile menu with a Radix Sheet-based flow (SheetTrigger, SheetContent), added Sheet-driven mobile nav with links, Get in Touch action and ThemeToggle, integrated reduced-motion guards, and applied safe-area/overflow adjustments.
Sheet accessibility
components/ui/sheet.tsx
Inserted visually-hidden SheetTitle and SheetDescription inside SheetContent to provide accessible title/description for screen readers without changing visible UI.
Scroll locking hook
lib/use-lock-scroll.ts
Added export function useLockScroll(lock: boolean) that saves scroll position, applies fixed positioning and hides overflow when locked, and restores styles and scroll position on unlock.
Reduced-motion / Theme provider
components/theme/theme-provider.tsx
Removed framer-motion wrapper; added client-side effect to detect prefers-reduced-motion and toggle a reduce-motion class on document.documentElement; ensure disableTransitionOnChange defaults to true.
Global CSS / safe-area / overflow
app/globals.css
Enforced width: 100% and overflow-x: hidden on root elements, enabled -webkit-overflow-scrolling: touch and touch-action: pan-y, added .safe-area helpers and inset classes to handle iOS notches and prevent horizontal scroll.
Canvas sizing adjustments
components/ui/particle-canvas.tsx
Changed canvas CSS sizing to width: 100%, height: 100%, and display: block while keeping DPR-backed buffer sizing to avoid horizontal overflow from pixel rounding.
Tailwind container config
tailwind.config.ts
Added theme.container with center: true and padding map: DEFAULT: '1rem', sm: '1.5rem', lg: '2rem'.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant Nav as Navbar
  participant Sheet as Sheet/Dialog
  participant Hook as useLockScroll
  participant Doc as document/body

  U->>Nav: tap menu button
  Nav->>Sheet: open()
  Sheet->>Hook: enable lock (true)
  Hook->>Doc: store scrollY, apply fixed position + hide overflow
  U->>Sheet: interact / press ESC / tap close
  Sheet->>Nav: onOpenChange(false)
  Sheet->>Hook: enable lock (false)
  Hook->>Doc: restore styles and scroll position
Loading
sequenceDiagram
  autonumber
  participant Theme as ThemeProvider
  participant MQ as matchMedia
  participant Doc as document.documentElement

  Theme->>MQ: query("(prefers-reduced-motion)")
  MQ-->>Theme: matches (true/false)
  Theme->>Doc: add/remove "reduce-motion" class
  Theme->>MQ: add change listener
  MQ-->>Theme: change event
  Theme->>Doc: update "reduce-motion" class
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I hopped through sheets that slide with care,
Locked the scroll so breezes spare,
Motion softened at the moon's request,
Safe-area pockets keep things blessed,
Canvas snug — no overflow, hooray! 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely summarizes the primary improvements in mobile responsiveness, navigation experience, and layout fixes, reflecting the main focus of the changeset without extraneous details.
Description Check ✅ Passed The description directly outlines the key changes made to mobile navigation, layout responsiveness, safe area handling, and accessibility enhancements, all of which correspond closely to the modified files and stated objectives.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 3-improve-mobile-responsiveness-ensure-central-alignment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 6a829fd and b2051e4.

📒 Files selected for processing (1)
  • components/layout/navbar.tsx (7 hunks)
🔇 Additional comments (5)
components/layout/navbar.tsx (5)

1-17: Imports look good!

The new imports for Sheet components, useReducedMotion, and useLockScroll are all appropriate for the mobile navigation refactor and accessibility improvements.


29-77: Excellent reduced motion implementation!

The reduced motion setup is thorough and correct:

  • State is synchronized with the hook immediately (line 42) before any early returns, ensuring preference changes are reflected promptly
  • The matchMedia fallback provides defensive coverage for environments where the hook might not work
  • Cleanup is handled properly for both modern and legacy browsers

This addresses all the previous concerns about reduced motion synchronization.


103-104: LGTM!

The useLockScroll hook is called correctly to prevent background scrolling when the mobile menu is open.


122-206: Desktop navigation motion guards are well implemented!

All motion components properly respect the reduced motion preference:

  • Logo, text, and navigation items conditionally apply motion props only when !prefersReducedMotion
  • The active section underline (lines 180-185) uses a clever pattern: layout: false when reduced motion is requested, and layoutId when not, effectively disabling the shared layout animation for users who need reduced motion

This resolves the previous concern about the shared layout animation persisting when reduced motion was requested.


210-320: Excellent Sheet-based mobile navigation with strong accessibility!

The mobile menu implementation addresses all previous accessibility concerns:

  • SheetTitle and SheetDescription (lines 229-234) are properly included with sr-only class for screen reader support
  • The <nav> element (line 235) now correctly maintains its navigation role without the improper role="dialog" override
  • ARIA labels are present on the trigger button (lines 215-218)
  • All motion animations respect the reduced motion preference throughout (lines 242-258, 279-294)
  • Menu automatically closes when links are clicked (lines 272, 301) for smooth UX
  • Scroll locking is active when the menu is open

The Sheet pattern with ESC-to-close and background click-to-close provides a polished, accessible mobile navigation experience.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nabobery nabobery changed the title feat: Enhance layout and accessibility with new safe area helpers, mo… feat: Improve mobile responsiveness with enhanced navigation and layout fixes Oct 4, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between a45f378 and a269ee6.

📒 Files selected for processing (7)
  • app/globals.css (2 hunks)
  • components/layout/navbar.tsx (4 hunks)
  • components/theme/theme-provider.tsx (1 hunks)
  • components/ui/particle-canvas.tsx (1 hunks)
  • components/ui/sheet.tsx (1 hunks)
  • lib/use-lock-scroll.ts (1 hunks)
  • tailwind.config.ts (1 hunks)

Comment thread components/layout/navbar.tsx
Comment thread components/theme/theme-provider.tsx
…vigation in Navbar; enhance theme provider for better browser compatibility
@nabobery nabobery marked this pull request as ready for review October 4, 2025 08:31

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
components/layout/navbar.tsx (1)

52-64: Remove redundant ESC key handler.

The Radix UI Sheet component already handles ESC key presses to close the dialog. This custom handler duplicates that built-in functionality and can be safely removed.

Apply this diff to remove the redundant code:

-    // Handle ESC key to close menu
-    useEffect(() => {
-        const handleKeyDown = (event: KeyboardEvent) => {
-            if (event.key === 'Escape' && isMenuOpen) {
-                setIsMenuOpen(false)
-            }
-        }
-
-        if (isMenuOpen) {
-            window.addEventListener('keydown', handleKeyDown)
-            return () => window.removeEventListener('keydown', handleKeyDown)
-        }
-    }, [isMenuOpen])
-
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between a269ee6 and 07ce262.

📒 Files selected for processing (2)
  • components/layout/navbar.tsx (4 hunks)
  • components/theme/theme-provider.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/theme/theme-provider.tsx
🔇 Additional comments (2)
components/layout/navbar.tsx (2)

76-76: Verify that overflow-visible doesn't cause layout issues.

The overflow-visible class on the nav element is unusual. While it's the default overflow behavior, explicitly setting it suggests there's a specific layout requirement. Ensure this doesn't cause unintended content overflow on smaller screens or with larger font sizes.

Test the navbar at various viewport widths and with browser zoom at 200% to confirm the layout remains stable.


206-216: Verify onClick behavior with asChild Button pattern.

When using asChild on a Button, it passes props to its child component (Link). The onClick handler attempting to close the menu might not fire as expected since the Link will handle the click event for navigation. While the Sheet may close automatically on navigation, this pattern could be confusing.

Consider moving the close handler directly to the Link component or verifying that the Sheet closes as expected:

<Button asChild className="w-full">
    <Link 
        href="#contact"
        onClick={() => setIsMenuOpen(false)}
    >
        Get in Touch
    </Link>
</Button>

Comment thread components/layout/navbar.tsx
Comment thread components/layout/navbar.tsx Outdated
…bility; add SheetTitle and SheetDescription for mobile navigation

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 07ce262 and f03259a.

📒 Files selected for processing (1)
  • components/layout/navbar.tsx (7 hunks)

Comment thread components/layout/navbar.tsx
…ize early exit in Navbar useEffect for improved performance

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
components/layout/navbar.tsx (1)

106-118: Optional: Remove redundant ESC key handler.

The Radix UI Sheet component already handles the ESC key natively to close the drawer. Since the Sheet is controlled (open={isMenuOpen} onOpenChange={setIsMenuOpen}), the built-in ESC handler will trigger onOpenChange(false), making this custom handler redundant.

Consider removing this effect to rely on Sheet's built-in keyboard handling:

-    // Handle ESC key to close menu
-    useEffect(() => {
-        const handleKeyDown = (event: KeyboardEvent) => {
-            if (event.key === 'Escape' && isMenuOpen) {
-                setIsMenuOpen(false)
-            }
-        }
-
-        if (isMenuOpen) {
-            window.addEventListener('keydown', handleKeyDown)
-            return () => window.removeEventListener('keydown', handleKeyDown)
-        }
-    }, [isMenuOpen])
-
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between f03259a and 1fca459.

📒 Files selected for processing (1)
  • components/layout/navbar.tsx (7 hunks)
🔇 Additional comments (3)
components/layout/navbar.tsx (3)

29-77: Excellent reduced motion implementation.

The reduced-motion handling properly synchronizes local state with the hook, provides an SSR-safe fallback with matchMedia, and includes defensive compatibility for older browsers. This correctly addresses the previous review concerns about state synchronization when users toggle their OS preference.


219-328: Excellent Sheet implementation with comprehensive accessibility.

The mobile navigation drawer properly implements:

  • Radix UI Sheet with controlled state
  • Required SheetTitle and SheetDescription for screen readers (visually hidden with sr-only)
  • Correct ARIA attributes (aria-label, aria-expanded) without the semantic conflicts from previous reviews
  • Reduced-motion guards on all animations
  • Intuitive UX patterns (menu closes on navigation, theme toggle accessible)

This implementation successfully addresses all previous accessibility and semantic concerns.


129-129: Safe-area utilities are implemented. Confirmed safe-area and safe-area-inset-right classes in app/globals.css; no additional changes needed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 1fca459 and 6a829fd.

📒 Files selected for processing (1)
  • components/layout/navbar.tsx (7 hunks)

Comment thread components/layout/navbar.tsx
@nabobery nabobery merged commit 0b7e4b5 into main Oct 4, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve Mobile Responsiveness: Ensure Central Alignment

1 participant