Replace the mobile tab bar with a hamburger menu
Six tabs (Queue, On-call, Alerts, Team, Admin, Account) had already
outgrown the bottom bar once: 56b8191 let it auto-size its columns to
fit however many there were, but on a phone that only left each tab
55-65px wide. Squeezing further wasn't an option, so the bar is gone
on mobile and a hamburger button in the topbar opens a menu instead.
The menu reuses the sheet + menu-item pattern already used for the
snooze and assign-to actions in incident.js, rather than a new overlay
component. It lists the same sections the sidebar does, including
hiding Admin for non-admins, and the triggered-incident badge that
used to sit on the Queue tab icon now shows on the hamburger button.
Desktop (>=900px) is untouched: the sidebar is the same markup, CSS
alone hides it below 900px and shows it above, so nothing there
changed behaviourally.
Claude-Session: https://claude.ai/code/session_01RHPj4ggeFdEjKKfm4SHbD7
This commit is contained in:
+16
-21
@@ -48,7 +48,11 @@
|
||||
--mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
|
||||
--topbar-h: 52px;
|
||||
--tabbar-h: 58px;
|
||||
/* No bottom tab bar on any breakpoint any more — mobile uses the hamburger
|
||||
menu in the topbar, desktop the sidebar — so this stays 0. Kept as a
|
||||
variable rather than deleted since .view, .toast and .nav's own height
|
||||
calc still read it. */
|
||||
--tabbar-h: 0px;
|
||||
--safe-top: env(safe-area-inset-top, 0px);
|
||||
--safe-bottom: env(safe-area-inset-bottom, 0px);
|
||||
}
|
||||
@@ -196,7 +200,13 @@ input:focus, textarea:focus { outline: none; border-color: var(--accent); box-sh
|
||||
-webkit-backdrop-filter: saturate(1.4) blur(12px);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.topbar-title { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
|
||||
.topbar-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
||||
.topbar-title {
|
||||
font-size: 18px; font-weight: 700; letter-spacing: -0.01em;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
|
||||
}
|
||||
#menu-btn { position: relative; }
|
||||
.nav-badge.menu-btn-badge { top: 2px; left: auto; right: 2px; }
|
||||
|
||||
.open-pill {
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
@@ -209,15 +219,12 @@ input:focus, textarea:focus { outline: none; border-color: var(--accent); box-sh
|
||||
.open-pill.has-triggered::before { background: var(--crit); }
|
||||
.open-pill.all-acked::before { background: var(--warn); }
|
||||
|
||||
/* Bottom tab bar on phones. */
|
||||
/* Hidden on phones — mobile navigates through the hamburger menu in the
|
||||
topbar instead (see #menu-btn / openNavMenu in app.js). Reappears as the
|
||||
left sidebar from 900px, where the desktop block below redeclares display. */
|
||||
.nav {
|
||||
display: none;
|
||||
position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
|
||||
/* One column per link, however many there are. This was repeat(4, 1fr) when
|
||||
there were four tabs; Team and Admin arriving pushed six items into four
|
||||
columns, which on a phone is how they stopped fitting. Auto columns mean
|
||||
the next tab cannot break the row either — and Admin is only rendered for
|
||||
an administrator, so the count genuinely varies between viewers. */
|
||||
display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
|
||||
height: calc(var(--tabbar-h) + var(--safe-bottom));
|
||||
padding-bottom: var(--safe-bottom);
|
||||
background: color-mix(in srgb, var(--surface) 92%, transparent);
|
||||
@@ -239,16 +246,6 @@ input:focus, textarea:focus { outline: none; border-color: var(--accent); box-sh
|
||||
}
|
||||
.nav-link svg { width: 24px; height: 24px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
||||
|
||||
/* Narrow phones, where six tabs each get about 55-65px. Tightening is enough:
|
||||
the widest label, "On-call", is about 38px at this size, so nothing has to
|
||||
be hidden. The ellipsis above is the backstop if a future tab is named
|
||||
something longer. */
|
||||
@media (max-width: 420px) {
|
||||
.nav-link { font-size: 10px; gap: 1px; }
|
||||
.nav-link svg { width: 21px; height: 21px; }
|
||||
.nav-badge { left: calc(50% + 4px); min-width: 16px; height: 16px; font-size: 10px; line-height: 16px; }
|
||||
}
|
||||
|
||||
.nav-link[aria-current="page"] { color: var(--accent); }
|
||||
.nav-badge {
|
||||
position: absolute; top: 6px; left: calc(50% + 6px);
|
||||
@@ -601,8 +598,6 @@ kbd {
|
||||
/* ---------- desktop ---------- */
|
||||
|
||||
@media (min-width: 900px) {
|
||||
:root { --tabbar-h: 0px; }
|
||||
|
||||
.app { display: grid; grid-template-columns: 220px 1fr; height: 100dvh; }
|
||||
|
||||
.nav {
|
||||
|
||||
Reference in New Issue
Block a user