feat(mobile-nav): hamburger menu + responsive screens (≤640px) - #63
Merged
Conversation
Adds a top-left circular hamburger that opens a left-slide nav drawer (Base UI Dialog) carrying the same six destinations as the desktop SideRail. Hides SideRail on phone-narrow widths via max-[640px]:hidden; shows MobileNav via min-[641px]:hidden on the trigger. Sheet primitive collapses to a single stacked pane on mobile: SheetSidebar becomes full-width with bounded max-h-[40vh] (keeps internal scroll), SheetSidenav becomes a horizontal scroll-tab strip. LettersSheet switches to master/detail (list ↔ detail one at a time) with a 44px back bar; ProfileSheet's 6-tab strip horizontal-scrolls. Shared navigation primitives: - nav-items.ts: SHEET_HREFS + RailItem config - nav-active.ts: pathname → active-key helpers - use-nav-gate.ts: onboarding-hide guard + optimistic pendingPathname - use-is-mobile.ts: SSR-safe matchMedia hook (initializes from window.matchMedia on first client render) Visual chrome matches existing in-world FAB family: - Hamburger style mirrors WorldIconButton (rounded-full, bg-white/82, backdrop-blur-md, warm shadow, lift-on-hover) - +12px inset matches WorldControlsToggle / ZoomHud convention - Drawer primitive grows a `side: 'bottom' | 'left'` prop; bottom retains grabber + close, left renders position-only Mechanical knock-ons: - Engine media-query split: --rail-width zeros at ≤640px (matches Tailwind), --frame-inset/--frame-radius shrink stays at ≤520px - studentSpaceFrameClassName reserves top gutter (4rem) instead of bottom strip - Left-anchored HUDs bump down +68px on mobile to clear hamburger - Drawer auto-closes on viewport flip to desktop (DrawerPortal escapes the trigger wrapper, so the trigger's :hidden alone wouldn't hide it) LettersSheet auto-select is mount-gated via ref so rotation mobile↔desktop doesn't retroactively trigger selection. Plan: docs/plans/2026-05-24-001-feat-mobile-nav-hamburger-screens-plan.md Tests: 669 passing, no new regressions (10 pre-existing failures unchanged). 4 follow-up test files identified as residual: mobile-nav.test.tsx, drawer.test.tsx, nav-active.test.ts, letters-sheet matchMedia coverage.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
# Conflicts: # src/components/student-space/navigation/SideRail.tsx
wondopamine
added a commit
that referenced
this pull request
May 24, 2026
…tab spacing - Kira dialogue: replace the head-anchored speech bubble with a centered chat-card just above the safe-area bottom (≥96px clearance from the Capture FAB / FirstChat chips), with a companion-name eyebrow read from state.profile.displayCompanionName(). Drops the per-frame screen-pos projection from KiraDialogueController; update() is now only the hold-timer + idle-invite checks. Applies to onboarding (FirstChat sayOnboarding), greetings, idle invites, and chat-more beats. Mobile readability gains from PR #61's tighter follow are no longer needed since the card is layout-anchored. - ProfileSheet: move space-y-8 from <SheetBody> onto the <div data-tab-content> wrapper. The motion refactor (35df935) made the wrapper the only direct child of SheetBody, so the original rule had stopped reaching the sibling sections; QC-0 (70cc00b) just made the collapsed gap visible. - Engine View: refresh the kiraDialogue.update() comment to reflect the timer-driven scope (no more screen-position read). Mobile-nav supersession: PR #63 (15b519d) shipped a Drawer-based hamburger + responsive Sheet primitive — same UX intent as the Popover-based mobile nav we prototyped, with a more thorough refactor (nav-items.ts, MobileNav.tsx, use-is-mobile.ts). Adopting PR #63's direction wholesale; our local SideRail changes are not re-applied. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sheetprimitive collapses to a single stacked pane on mobile;LettersSheetswitches to master/detail with a 44px back bar;ProfileSheet's 6-tab strip horizontal-scrolls.WorldIconButton): circular,bg-white/82 backdrop-blur-md, warm shadow, +12px inset matchingWorldControlsToggle/ZoomHud.nav-items.ts,nav-active.ts,use-nav-gate.ts,use-is-mobile.ts.Drawerprimitive gains aside: 'bottom' | 'left'prop.Plan & review
Built via
/ce-plan→/ce-work→/ce-code-reviewpipeline. Plan:docs/plans/2026-05-24-001-feat-mobile-nav-hamburger-screens-plan.md. 7 safe_auto + 6 best-judgment code-review fixes applied (P1 drawer portal-escape on rotation, P2useNavGatehook extraction, P2useIsMobilerelocation, P2LettersSheeteffect mount-gate, P2 hamburger-clearance derivation comments, P2 engine CSS placement annotation).Test plan
pnpm check— zero TypeScript errorspnpm test— 669 passing, 127 skipped, 10 pre-existing failures unchanged (zero new regressions)mobile-nav.test.tsx,drawer.test.tsx(side='left' coverage),nav-active.test.ts,letters-sheet.test.tsxmatchMedia coverage