feat(layout): migrate to full-width topbar with mobile drawer navigation

Move topbar outside the grid container as a standalone sticky header
(Shopify/Stripe pattern). Sidebar and icon bar use position:sticky
relative to topbar height. Mobile uses drawer pattern with backdrop,
focus trap, ESC close, and scroll lock. Tenant branding moved from
sidebar header into the topbar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 22:21:39 +02:00
parent fe88e748a3
commit a3f270408b
13 changed files with 543 additions and 340 deletions

View File

@@ -19,12 +19,14 @@
display: none;
}
.app-container.is-sidebar-hidden .app-sidebar {
display: none;
}
@media (min-width: 768px) {
.app-container.is-sidebar-hidden .app-sidebar {
display: none;
}
.sidebar-hidden .app-sidebar {
display: none;
.sidebar-hidden .app-sidebar {
display: none;
}
}
h1,
@@ -381,42 +383,43 @@
}
.app-container.is-sidebar-hidden:has(.aside-icon-bar):has(.app-sidebar) {
display: grid;
min-height: 100dvh;
align-items: flex-start;
grid-template-columns: minmax(0, 60px) minmax(0, 1fr);
min-height: calc(100dvh - var(--app-topbar-height));
align-items: stretch;
grid-template-columns: minmax(0, 52px) minmax(0, 1fr);
}
.sidebar-hidden .app-container:has(.aside-icon-bar):has(.app-sidebar) {
grid-template-columns: minmax(0, 60px) minmax(0, 1fr);
grid-template-columns: minmax(0, 52px) minmax(0, 1fr);
}
.app-container:has(.aside-icon-bar):has(.app-sidebar) {
display: grid;
min-height: 100dvh;
align-items: flex-start;
grid-template-columns: minmax(0, 60px) minmax(0, 220px) minmax(0, 1fr);
min-height: calc(100dvh - var(--app-topbar-height));
align-items: stretch;
grid-template-columns: minmax(0, 52px) minmax(0, 220px) minmax(0, 1fr);
}
.app-container.is-sidebar-collapsed:has(.aside-icon-bar):has(.app-sidebar) {
display: grid;
min-height: 100dvh;
align-items: flex-start;
grid-template-columns: minmax(0, 60px) minmax(0, 220px) minmax(0, 1fr);
min-height: calc(100dvh - var(--app-topbar-height));
align-items: stretch;
grid-template-columns: minmax(0, 52px) minmax(0, 220px) minmax(0, 1fr);
}
.app-container.is-sidebar-collapsed {
grid-template-columns: minmax(0, 60px) minmax(0, 220px) minmax(0, 1fr);
grid-template-columns: minmax(0, 52px) minmax(0, 220px) minmax(0, 1fr);
}
.sidebar-collapsed .app-container {
grid-template-columns: minmax(0, 60px) minmax(0, 220px) minmax(0, 1fr);
grid-template-columns: minmax(0, 52px) minmax(0, 220px) minmax(0, 1fr);
}
.app-main {
border-left: 1px solid var(--app-border);
min-height: 100dvh;
min-height: calc(100dvh - var(--app-topbar-height));
background: var(--app-background-color);
}
.app-main-content {
padding-inline: calc(var(--app-spacing) * 2);
padding-block-start: var(--app-spacing);
margin-bottom: calc(var(--app-spacing) * 2);
}
.app-main-content:has(.app-details-container) {
@@ -3016,4 +3019,18 @@
body.is-loading textarea {
pointer-events: none;
}
/* ── Print: hide all navigation chrome ── */
@media print {
.app-header,
aside.aside-icon-bar,
aside.app-sidebar,
.app-drawer-backdrop {
display: none !important;
}
.app-container {
display: block !important;
}
}
}