From dfef26bad55ac53b9d92be546a8676a7892f2a58 Mon Sep 17 00:00:00 2001 From: shahondin1624 Date: Thu, 12 Mar 2026 13:17:02 +0100 Subject: [PATCH] feat: add responsive layout and mobile support (#19) Add collapsible sidebars with slide-in drawers on mobile, hamburger menu for session sidebar, stacked layouts for screens under 768px, 44px touch targets, and overflow prevention across all pages. Co-Authored-By: Claude Opus 4.6 --- implementation-plans/_index.md | 1 + implementation-plans/issue-019.md | 80 ++++++++++++++++++++++++ src/lib/components/ConfigSidebar.svelte | 53 +++++++++++++--- src/lib/components/MessageBubble.svelte | 2 +- src/lib/components/MessageInput.svelte | 6 +- src/lib/components/SessionSidebar.svelte | 60 +++++++++++++++--- src/routes/+page.svelte | 14 ++--- src/routes/audit/+page.svelte | 22 +++---- src/routes/chat/+page.svelte | 52 ++++++++++++--- src/routes/lineage/+page.svelte | 30 ++++++--- src/routes/memory/+page.svelte | 16 ++--- 11 files changed, 268 insertions(+), 68 deletions(-) create mode 100644 implementation-plans/issue-019.md diff --git a/implementation-plans/_index.md b/implementation-plans/_index.md index 7345620..8c648e0 100644 --- a/implementation-plans/_index.md +++ b/implementation-plans/_index.md @@ -20,3 +20,4 @@ | #16 | Memory candidates viewer | COMPLETED | [issue-016.md](issue-016.md) | | #17 | Audit/activity log view | COMPLETED | [issue-017.md](issue-017.md) | | #18 | Dark/light theme toggle | COMPLETED | [issue-018.md](issue-018.md) | +| #19 | Responsive layout and mobile support | COMPLETED | [issue-019.md](issue-019.md) | diff --git a/implementation-plans/issue-019.md b/implementation-plans/issue-019.md new file mode 100644 index 0000000..3a8d172 --- /dev/null +++ b/implementation-plans/issue-019.md @@ -0,0 +1,80 @@ +# Issue #19: Responsive layout and mobile support + +**Status: COMPLETED** + +## Summary + +Make the dashboard fully usable on mobile with collapsible sidebars, stacked layouts for small screens, touch-friendly tap targets, and no horizontal scrolling. + +## Changes + +### Chat Page (`src/routes/chat/+page.svelte`) +- Added hamburger menu button visible only on mobile (`md:hidden`) to toggle the session sidebar +- SessionSidebar rendered twice: always-visible wrapper for desktop (`hidden md:flex`) and a mobile drawer controlled by `showSessionSidebar` state +- Config sidebar now passes `onClose` callback to enable closing on mobile +- Nav links (Lineage, Memory, Audit) hidden on small screens (`hidden sm:inline-flex`) +- Config button shows gear icon on small screens, text label on larger screens +- Added `overflow-hidden` to root container to prevent horizontal scrolling +- All header padding reduced on mobile (`px-3` vs `md:px-4`) + +### SessionSidebar (`src/lib/components/SessionSidebar.svelte`) +- Accepts new `open` and `onClose` props for mobile drawer control +- On mobile: renders as fixed overlay (`fixed inset-y-0 left-0 z-50`) with slide-in transition +- On desktop: renders as relative-positioned sidebar with no transition (`md:relative md:translate-x-0`) +- Backdrop overlay (`bg-black/50`) shown on mobile when sidebar is open +- Close button visible only on mobile (`md:hidden`) +- Session selection and new chat actions auto-close the sidebar on mobile + +### ConfigSidebar (`src/lib/components/ConfigSidebar.svelte`) +- Accepts new optional `onClose` prop +- On mobile: renders as fixed overlay from the right (`fixed inset-y-0 right-0 z-50`) +- On desktop: renders as relative-positioned sidebar (`md:relative md:z-auto`) +- Backdrop overlay shown when `onClose` is provided (mobile only) +- Close button visible only on mobile + +### MessageInput (`src/lib/components/MessageInput.svelte`) +- Send button has `min-h-[44px] min-w-[44px]` for touch-friendly 44px tap target +- Textarea uses `text-base` on mobile (prevents iOS zoom) and `md:text-sm` on desktop +- Reduced padding on mobile (`p-3` vs `md:p-4`) + +### MessageBubble (`src/lib/components/MessageBubble.svelte`) +- Increased max-width on mobile from 75% to 85% (`max-w-[85%] md:max-w-[75%]`) +- Slightly reduced padding on mobile + +### Home Page (`src/routes/+page.svelte`) +- Nav cards stack vertically on mobile (`flex-col sm:flex-row`) +- Full-width centered layout with `max-w-md` constraint on mobile +- Larger touch targets for nav links (`py-3 sm:py-2`) +- Added horizontal padding to prevent edge clipping + +### Lineage Page (`src/routes/lineage/+page.svelte`) +- Content area stacks vertically on mobile (`flex-col md:flex-row`) +- Detail panel renders as fixed overlay on mobile with backdrop +- Reduced padding on mobile +- "Sample Data" badge hidden on very small screens + +### Memory Page (`src/routes/memory/+page.svelte`) +- Filters stack vertically on mobile (`flex-col sm:flex-row`) +- Reduced padding on mobile +- "Sample Data" badge hidden on very small screens + +### Audit Page (`src/routes/audit/+page.svelte`) +- Filters stack vertically on mobile (`flex-col sm:flex-row`) +- Session select constrained to prevent horizontal overflow (`min-w-0 max-w-full truncate`) +- Reduced padding on mobile +- "Sample Data" badge hidden on very small screens + +## Acceptance Criteria Met + +- [x] Sidebars collapsible on mobile (hamburger menu for sessions, tap to close) +- [x] Stacked layout for screens < 768px (md breakpoint = 768px) +- [x] Chat input remains accessible and usable on mobile (always at bottom, full width) +- [x] Touch-friendly tap targets (min 44px on send button, hamburger, config toggle) +- [x] No horizontal scrolling on any viewport (overflow-hidden on containers) +- [x] Works on common mobile breakpoints (320px, 375px, 414px) via responsive Tailwind classes + +## Quality Gates + +- `npm run build` - PASSED +- `npm run lint` - PASSED (0 errors) +- `npm run check` - PASSED (0 errors, 0 warnings) diff --git a/src/lib/components/ConfigSidebar.svelte b/src/lib/components/ConfigSidebar.svelte index 6b1db0f..1bfd3cb 100644 --- a/src/lib/components/ConfigSidebar.svelte +++ b/src/lib/components/ConfigSidebar.svelte @@ -7,8 +7,13 @@ let { config, - onConfigChange - }: { config: SessionConfig; onConfigChange: (config: SessionConfig) => void } = $props(); + onConfigChange, + onClose + }: { + config: SessionConfig; + onConfigChange: (config: SessionConfig) => void; + onClose?: () => void; + } = $props(); let newPermission = $state(''); let newPresetName = $state(''); @@ -115,7 +120,23 @@ } -