Skip to content

Collapse the sidebar into a hamburger drawer on narrow screens - #44

Merged
MrZoller merged 6 commits into
mainfrom
claude/mobile-layout-responsive-n4w93s
Jun 21, 2026
Merged

MrZoller merged 6 commits into
mainfrom
claude/mobile-layout-responsive-n4w93s

Conversation

@MrZoller

Copy link
Copy Markdown
Owner

The fixed-width nav rail ate the screen on a phone, pushing the actual
content out of view — a first impression of "unfinished" exactly where
some reviewers will land first. Below the lg breakpoint the rail now
collapses to an overlay drawer: a hamburger in a mobile-only top bar
slides it in over a dimming backdrop, and tapping a nav item, the
backdrop, or Escape slides it back out. Navigating always dismisses it,
so the chosen destination is what's on screen. At desktop width the rail
is the same persistent, in-flow column as before — the breakpoint is the
only thing that changed there. The slide honors prefers-reduced-motion.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01WJJ694m44wBKG9acNSdmDS

claude added 3 commits June 21, 2026 12:39
The fixed-width nav rail ate the screen on a phone, pushing the actual
content out of view — a first impression of "unfinished" exactly where
some reviewers will land first. Below the lg breakpoint the rail now
collapses to an overlay drawer: a hamburger in a mobile-only top bar
slides it in over a dimming backdrop, and tapping a nav item, the
backdrop, or Escape slides it back out. Navigating always dismisses it,
so the chosen destination is what's on screen. At desktop width the rail
is the same persistent, in-flow column as before — the breakpoint is the
only thing that changed there. The slide honors prefers-reduced-motion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJJ694m44wBKG9acNSdmDS
Two columns at phone width squeeze both to unreadable. Below lg the
module body becomes one vertical scroll — plots, controls, then the
explanation stacked beneath with a top border instead of a left one —
and the two panes drop their independent scrollers (and the
scroll-internal fade cues) to flow into that single scroll. The
desktop two-pane layout, pinned control rail, and bottom-fade cues are
unchanged at lg and up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJJ694m44wBKG9acNSdmDS
The shared 2rem page gutter is heavy on a phone; ease it to a snugger
padding below the sm breakpoint so the hero, Start Here box, tracks, and
the About/Glossary prose breathe at full width. Desktop spacing
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJJ694m44wBKG9acNSdmDS

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 78113265c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/components/layout/Sidebar.tsx Outdated
Comment thread src/components/layout/Sidebar.tsx
Comment thread src/components/layout/Sidebar.tsx
Three review findings, one root cause: below lg the drawer was a modal
visually but not for keyboard/AT — a CSS transform and pointer-events
don't remove off-canvas buttons from the tab order, nothing made the
dimmed background inert, and the Escape handler was scoped to the nav so
it never fired while focus still sat on the hamburger that opened it.

Treat it as a modal on the compact viewport (a new useIsCompactViewport
media-query hook gates all of it, so desktop is untouched):
- closed drawer is `inert`, so its buttons leave the tab order and the
  a11y tree instead of lurking off-screen ahead of the hamburger;
- opening marks the whole content region `inert` (focus trap) and moves
  focus into the drawer, and closing restores focus to the opener;
- Escape is bound at the document level, so it dismisses from the moment
  the drawer opens regardless of where focus sits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJJ694m44wBKG9acNSdmDS

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 846855a7dc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/hooks/useMediaQuery.ts
claude added 2 commits June 21, 2026 13:07
The drawer's layout switches at the `lg:` utilities — Tailwind's default
`64rem` — but the JS that arms its modal behavior matched a hard-coded
`(max-width: 1023.98px)`. Media-query `rem` resolves against the browser
default font size, so under a non-16px default the px query and the rem
CSS disagree, opening a band where the drawer is shown but its closed-
state `inert` and open-state focus/Escape trap never engage.

Express the band as the exact negation of `(min-width: 64rem)` from one
shared `LG_BREAKPOINT`, so the behavior and the layout cross over at the
identical point regardless of the user's default font size.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJJ694m44wBKG9acNSdmDS
"Hide" sat next to the title block, so it read as if it hid the header
it's beside — and the mobile reflow stacked the explanation to the
bottom, putting the control nowhere near what it controls. Say the
target outright: "Hide explanation" / "Show explanation". The visible
text is the button's accessible name and aria-expanded already conveys
state, so naming the target fixes both the eye and the screen reader at
once. Label-only — no layout, position, or behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJJ694m44wBKG9acNSdmDS
@MrZoller
MrZoller merged commit 470582f into main Jun 21, 2026
2 checks passed
@MrZoller
MrZoller deleted the claude/mobile-layout-responsive-n4w93s branch June 21, 2026 17:16
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