Make the UI usable on mobile - #21
Open
dgruhin-hrizn wants to merge 1 commit into
Open
Conversation
The layout is desktop-only: three fixed flex columns (280px sidebar + 3x320px kanban + 400px detail panel) needing roughly 1740px, no media queries at all, hover-only affordances, 32px touch targets and a lot of 9-11px type. On a 375px phone the sidebar alone takes 75% of the screen and the board is scrolled off-canvas. Adds a desktop-first override block appended before </style>. The existing 1450 lines are all correct at width, so mobile lives in one contiguous place rather than being threaded through the file. Three breakpoints: <=1023px (drawer + sheet), <=767px (tabs, type scale, 44px targets) and (hover: none), which is capability-based so it also covers touch laptops and iPads. - The sidebar becomes an off-canvas drawer. The hamburger lives in .main rather than .view-header, because the empty state has no header at all and would otherwise have no way to reach the sessions list. - The detail panel becomes a full-screen sheet, riding on the existing .visible toggle -- Esc and the close button needed no changes. - The kanban collapses to one column behind a sticky status-tab bar. State is a single <body data-kanban-tab> attribute whose effect is scoped inside the media query, so crossing the breakpoint needs no resize listener and no state reconciliation. - Timeline: --tl-gutter replaces a 160px constant that was hardcoded in both CSS and JS, so bars and axis stay aligned at either size. Hover tooltips become tap-to-open, and the axis drops from 7 ticks to 3 where the labels would otherwise overlap solid. - PWA: manifest, plus a deliberately inert service worker -- it has a fetch handler for Android installability but caches nothing, so the SSE stream can never be served stale. Icons are derived from the existing checkmark logo with qlmanage and sips; no new dependencies. Three bugs surfaced while building this: - Closing the drawer inside fetchTasks/showAllTasks would have slammed it shut on every SSE refresh, since refreshCurrentView() and the event handler also call them. Moved to selectSession()/ selectAllTasks() wrappers on the user-initiated paths. - renderTimeline read --tl-gutter from :root while the override lands on body, misaligning the axis by 34px. - min-height on .task-card acted as a shrink *target*, not a floor: .column-tasks is a flex column, so cards collapsed to 56px and spilled their text. Fixed with flex-shrink: 0. theme-color is set to the accent so iOS tints the status bar and browser controls to match the app rather than painting a plain white band. Desktop is unchanged -- verified identical at 1440px: 280px static sidebar, 320px columns, 400px detail panel, 13px body, 32px icon buttons, 16px/24px header padding, --tl-gutter 160px, and every mobile rule inert. Not verified, needs real hardware beyond what emulation covers: iOS input focus-zoom and env(safe-area-inset-*) on a notched device.
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.
What
Makes the viewer usable on a phone. Today the layout is desktop-only: three fixed flex columns (280px sidebar + 3×320px kanban + 400px detail panel) needing ~1740px, no
@mediaqueries anywhere, hover-only affordances, 32px touch targets and a lot of 9–11px type. On a 375px screen the sidebar alone takes 75% of the viewport and the board is scrolled off-canvas.Approach
Desktop-first overrides, appended as one contiguous block before
</style>. The existing ~1450 lines are all correct at width, so rewriting mobile-first would mean touching everything — this way mobile lives in one place, and is one place to delete if you don't want it.Three breakpoints:
max-width: 1023pxmax-width: 767pxhover: none:hover, adds:activeThat last one is capability-based rather than width-based, so it also fixes touch laptops and iPads.
Notable decisions
.main, not.view-header. The empty state (#no-session) has no header at all, so a header-mounted button would strand you with no way back to the sessions list.<body data-kanban-tab>attribute whose effect is scoped inside the media query, so crossing the breakpoint needs no resize listener and no state reconciliation — desktop simply ignores the attribute..kanban'sdisplayis never overridden, becauseswitchView()writes it as an inline style and inline beats any media query. The mobile single-column view hides columns instead.fetchhandler purely for Android installability but caches nothing, so the SSE stream can never be served stale..logo-markcheckmark viaqlmanage+sips. No new dependencies.Three bugs found while building
fetchTasks/showAllTaskswould have slammed it shut on every SSE refresh, sincerefreshCurrentView()and the event handler also call them. Moved toselectSession()/selectAllTasks()wrappers on the user-initiated paths only.renderTimelineread--tl-gutterfrom:rootwhile the override lands onbody, misaligning the axis by 34px.min-heighton.task-cardacted as a shrink target, not a floor —.column-tasksis a flex column, so cards collapsed to 56px and spilled their text. Fixed withflex-shrink: 0.Verification
Walked drawer → session select → detail sheet → Esc → timeline → tap tooltip → all three status tabs → theme toggle, at 375/768/1440 in both themes, plus a real iPhone.
Desktop is unchanged — measured identical at 1440px: 280px static sidebar, 320px columns, 400px detail panel, 13px body, 32px icon buttons,
16px 24pxheader padding,--tl-gutter: 160px, and every mobile rule inert.Two things emulation can't cover and I could only check by eye on device: iOS input focus-zoom (the 16px input rule is in place) and
env(safe-area-inset-*)on a notched device.Independent of the other PR
I've opened a second PR for dark-mode contrast. They're independent and touch disjoint regions of the file — I verified both merge cleanly onto
mainin either order, and that merging both reproduces exactly the tree I tested. Take either, both, or neither.