Skip to content

fix: improve mobile navigation and layouts on docs site#3

Closed
michaelmcnees wants to merge 2 commits into
mainfrom
fix/mobile-navigation
Closed

fix: improve mobile navigation and layouts on docs site#3
michaelmcnees wants to merge 2 commits into
mainfrom
fix/mobile-navigation

Conversation

@michaelmcnees

Copy link
Copy Markdown
Collaborator

Changes

  • Replaced dual hamburger menu buttons with a single bottom navigation bar on mobile
  • Fixed mobile docs navigation — bottom bar with home, menu, and search actions
  • Added proper bottom padding to content so nothing hides behind the bottom bar
  • Responsive heading sizes (smaller on mobile)
  • Smaller code block fonts on touch devices
  • Various mobile overflow and spacing fixes

Why bottom nav?

Mobile bottom navigation follows standard thumb-zone conventions for easier one-handed use, which matters for a developer docs site where users often reference docs while working.

michaelmcnees and others added 2 commits March 23, 2026 10:10
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…achability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the docs site’s mobile UX by introducing a fixed bottom navigation bar, adjusting docs sidebar behavior for mobile, and applying mobile-specific typography/spacing tweaks to prevent layout overflow and improve readability.

Changes:

  • Replaced the previous mobile hamburger/menu approach with a fixed bottom navigation bar (with docs-specific menu toggle).
  • Updated docs layout/sidebar to accommodate the bottom bar (extra bottom spacing and mobile drawer sizing).
  • Added mobile prose CSS adjustments (heading sizes, code block sizing) and attempted small-screen table overflow handling.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
site/src/styles/global.css Adds mobile typography tweaks and new table-wrapper styling intended for small-screen table overflow.
site/src/pages/index.astro Adds bottom padding to prevent home page content being obscured by the fixed bottom nav on mobile.
site/src/layouts/Docs.astro Adds bottom padding (mobile) and overflow-x-hidden to mitigate mobile overflow issues in docs layout.
site/src/components/Nav.astro Implements the fixed mobile bottom navigation and JS toggle for the docs mobile sidebar.
site/src/components/DocsSidebar.astro Adjusts the mobile sidebar drawer height and updates overlay/link close behavior.
Comments suppressed due to low confidence (1)

site/src/components/DocsSidebar.astro:201

  • initSidebar() replaces #sidebar-overlay with a cloned node, but closeSidebar() still references the original overlay constant. As a result, clicking the new overlay will call closeSidebar() and attempt to hide the old (detached) overlay, leaving the visible overlay in place. Either avoid cloning/replacing the overlay, or update the reference used by closeSidebar() to the newly inserted node before attaching listeners.
<script is:inline>
function initSidebar() {
  const mobileSidebar = document.getElementById('docs-sidebar-mobile');
  const overlay = document.getElementById('sidebar-overlay');
  if (!mobileSidebar || !overlay) return;

  function closeSidebar() {
    mobileSidebar.classList.add('-translate-x-full');
    overlay.classList.add('hidden');
  }

  const newOverlay = overlay.cloneNode(true);
  overlay.parentNode?.replaceChild(newOverlay, overlay);
  newOverlay.addEventListener('click', closeSidebar);

  mobileSidebar.querySelectorAll('a').forEach((a) => {
    a.addEventListener('click', closeSidebar);
  });

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +79 to +96
const btn = document.getElementById('bottom-nav-docs-btn');
const docsSidebar = document.getElementById('docs-sidebar-mobile');
const overlay = document.getElementById('sidebar-overlay');
if (!btn || !docsSidebar || !overlay) return;

// Remove old listeners by cloning
const newBtn = btn.cloneNode(true);
btn.parentNode?.replaceChild(newBtn, btn);
newBtn.addEventListener('click', () => menu.classList.toggle('hidden'));

newBtn.addEventListener('click', () => {
const isOpen = !docsSidebar.classList.contains('-translate-x-full');
if (isOpen) {
docsSidebar.classList.add('-translate-x-full');
overlay.classList.add('hidden');
} else {
docsSidebar.classList.remove('-translate-x-full');
overlay.classList.remove('hidden');
}

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

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

initNav() captures a reference to #sidebar-overlay, but DocsSidebar.astro replaces that element via cloneNode/replaceChild. That leaves this handler toggling classes on a detached node, so the overlay (and menu close behavior) can break. Prefer not replacing #sidebar-overlay at all, or re-query the current overlay element inside the click handler (or ensure only one component owns overlay event binding).

Copilot uses AI. Check for mistakes.
<Base title="Mantle — Headless AI Workflow Automation">
<Nav isHome={true} />
<main id="main-content">
<main id="main-content" class="pb-16 md:pb-0">

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

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

The new bottom padding (pb-16) doesn’t account for env(safe-area-inset-bottom). On devices with a home indicator, the bottom nav height becomes h-14 + safe-area, so 4rem padding may still allow content to be obscured. Consider using a calc that includes the safe-area inset (e.g., pb-[calc(4rem+env(safe-area-inset-bottom))]) or a shared CSS variable derived from the bottom-nav height.

Suggested change
<main id="main-content" class="pb-16 md:pb-0">
<main id="main-content" class="pb-[calc(4rem+env(safe-area-inset-bottom))] md:pb-0">

Copilot uses AI. Check for mistakes.
</button>

<div class="mx-auto max-w-[1280px] px-4 sm:px-6 overflow-x-hidden">
<div class="flex min-h-screen pt-16 pb-16 md:pb-0">

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

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

The pb-16 added for the mobile bottom nav doesn’t include env(safe-area-inset-bottom), so on iOS the last content can still sit under the nav (nav adds safe-area padding in Nav.astro). Consider using padding that includes the safe-area inset (or a shared CSS var) so the docs content always clears the bottom bar.

Suggested change
<div class="flex min-h-screen pt-16 pb-16 md:pb-0">
<div class="flex min-h-screen pt-16 pb-[calc(4rem+env(safe-area-inset-bottom))] md:pb-0">

Copilot uses AI. Check for mistakes.

<!-- Mobile sidebar drawer -->
<aside id="docs-sidebar-mobile" class="fixed top-16 left-0 bottom-0 z-50 w-72 bg-surface-container-lowest border-r border-outline-variant transform -translate-x-full transition-transform duration-200 lg:hidden overflow-y-auto">
<aside id="docs-sidebar-mobile" class="fixed top-16 left-0 bottom-14 md:bottom-0 z-50 w-72 bg-surface-container-lowest border-r border-outline-variant transform -translate-x-full transition-transform duration-200 lg:hidden overflow-y-auto">

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

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

bottom-14 reserves space for a 56px bottom nav, but the nav also adds padding-bottom: env(safe-area-inset-bottom). On devices with a bottom safe-area inset, the sidebar can overlap the bottom nav/home-indicator region. Consider including the safe-area inset in the sidebar’s bottom offset (or add equivalent padding to the sidebar) to prevent content from being hidden.

Suggested change
<aside id="docs-sidebar-mobile" class="fixed top-16 left-0 bottom-14 md:bottom-0 z-50 w-72 bg-surface-container-lowest border-r border-outline-variant transform -translate-x-full transition-transform duration-200 lg:hidden overflow-y-auto">
<aside id="docs-sidebar-mobile" class="fixed top-16 left-0 bottom-[calc(3.5rem+env(safe-area-inset-bottom))] md:bottom-0 z-50 w-72 bg-surface-container-lowest border-r border-outline-variant transform -translate-x-full transition-transform duration-200 lg:hidden overflow-y-auto">

Copilot uses AI. Check for mistakes.
Comment on lines +320 to +329
/* Tables — horizontally scrollable on small screens */
.prose .table-wrapper {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
margin-top: 1.5em;
}

.prose .table-wrapper table {
margin-top: 0;
}

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

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

The new .prose .table-wrapper styles won’t have any effect unless tables are actually wrapped in an element with class="table-wrapper" (search in site/src shows no usage). If the goal is to make markdown tables scroll on mobile, consider applying overflow-x: auto/display: block directly to .prose table under a small-screen media query or adding a markdown/rehype transform that wraps generated tables.

Copilot uses AI. Check for mistakes.
Menu
</button>

<div class="mx-auto max-w-[1280px] px-4 sm:px-6 overflow-x-hidden">

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

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

overflow-x-hidden on the docs container can clip any horizontally overflowing content (notably wide markdown tables). Since the new table-scrolling styles currently target a .table-wrapper that isn’t present, this may result in table content being cut off with no way to scroll. Consider removing overflow-x-hidden or ensuring tables/code blocks have an internal horizontal scroll container before hiding overflow on the page wrapper.

Suggested change
<div class="mx-auto max-w-[1280px] px-4 sm:px-6 overflow-x-hidden">
<div class="mx-auto max-w-[1280px] px-4 sm:px-6">

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +57
<!-- Mobile bottom navigation bar -->
<nav id="mobile-bottom-nav" class="fixed bottom-0 left-0 right-0 z-50 md:hidden border-t border-outline-variant bg-surface/95 backdrop-blur-md">
<div class="flex items-center justify-around h-14 px-2">
<a href="/" class:list={["bottom-nav-item flex flex-col items-center gap-0.5 px-3 py-1 text-[11px] transition-colors", isHome ? "text-primary" : "text-on-surface-variant hover:text-on-surface"]}>
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955a1.126 1.126 0 011.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"/></svg>
<span>Home</span>
</a>
{isDocs && (
<button id="bottom-nav-docs-btn" class="bottom-nav-item flex flex-col items-center gap-0.5 px-3 py-1 text-[11px] text-on-surface-variant hover:text-on-surface transition-colors" aria-label="Documentation menu">
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/></svg>
<span>Menu</span>
</button>
)}
<a href="/docs/getting-started" class:list={["bottom-nav-item flex flex-col items-center gap-0.5 px-3 py-1 text-[11px] transition-colors", isDocs ? "text-primary" : "text-on-surface-variant hover:text-on-surface"]}>
<svg class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25"/></svg>
<span>Docs</span>
</a>
<a href="https://github.com/dvflw/mantle" class="bottom-nav-item flex flex-col items-center gap-0.5 px-3 py-1 text-[11px] text-on-surface-variant hover:text-on-surface transition-colors" aria-label="GitHub">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/></svg>
<span>GitHub</span>
</a>

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

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

PR description mentions the mobile bottom bar includes “home, menu, and search” actions, but the implemented bottom nav has Home, Menu (docs only), Docs, and GitHub — no search action/link. Either update the PR description to match what shipped, or add the intended search affordance to the bottom nav.

Copilot uses AI. Check for mistakes.
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.

2 participants