Fix role fit-and-finish: Desktop-only router note, narrow-viewport layout

Systems Operational on roles with no enabled domain services (a
fresh Desktop-only install, or everything turned off) rendered no
Router card but still showed a "Who uses these ports" note listing
services the machine does not have. Any role with no enabled domain
service now gets the calm "No router setup needed yet" card with
role-appropriate wording, and the who-uses note only appears when
a domain service is actually enabled.

Narrow viewports (phones, half-screen RDP) had no layout at all:
the sidebar and topbar forced ~900px of horizontal scroll on every
role. The sidebar now collapses to a 76px icon rail below 920px,
the topbar wraps its search onto a second row below 640px, and the
welcome column reflows to one card per row. Legacy pre-redesign
media rules in onboarding.css (which targeted the old DOM and set
.sidebar{width:100%}) are removed — they silently overrode the new
layout, and one shrank the Zeus QR to 200px; QR codes keep their
repo-original 240px at every width.
This commit is contained in:
2026-09-08 19:38:34 -05:00
parent 4476a5e0e2
commit bbf53d089a
4 changed files with 60 additions and 61 deletions
@@ -100,4 +100,8 @@
padding: 5px 10px;
font-size: 0.72rem;
}
.btn-logout {
padding: 5px 10px;
font-size: 0.72rem;
}
}
@@ -634,3 +634,42 @@
font-size: 0.85rem;
margin-bottom: 24px;
}
/* ── Narrow viewports (phone / half-screen RDP) ──────────────────── */
/* The sidebar becomes an icon rail so the content keeps room, and the
topbar wraps its search onto a second row instead of overflowing. */
@media (max-width: 920px) {
.sidebar {
width: 76px;
padding: 16px 8px 12px;
}
.brand { justify-content: center; padding: 2px 0 18px; gap: 0; }
.brand-text,
.nav-label,
.nav-text,
.nav-count,
.sidebar-support-text,
.sidebar-divider,
#sidebar-features { display: none; }
.nav-item { justify-content: center; gap: 0; padding: 10px 0; }
.sidebar-support-btn { justify-content: center; gap: 0; padding: 10px 0; }
.content { padding: 18px 18px 40px; }
/* keep the welcome background full-bleed against the new padding */
.welcome {
margin: -18px -18px -40px;
padding: 48px 20px 40px;
min-height: calc(100% + 58px);
}
}
@media (max-width: 640px) {
.topbar { flex-wrap: wrap; row-gap: 10px; padding: 12px 16px; }
.search-box { order: 5; flex-basis: 100%; }
.welcome { padding: 40px 16px 36px; }
.welcome-cards { grid-template-columns: 1fr; }
}
@@ -823,57 +823,8 @@
/* ── Responsive ─────────────────────────────────────────────────── */
@media (max-width: 768px) {
body {
overflow: auto;
}
.main-content {
flex-direction: column;
overflow: visible;
}
.sidebar {
width: 100%;
height: auto;
border-right: none;
border-bottom: 1px solid var(--border-color);
padding: 14px 12px;
}
#tiles-area {
height: auto;
overflow-y: visible;
padding: 16px 12px 40px;
}
}
@media (max-width: 600px) {
.header-bar {
padding: 10px 14px;
gap: 10px;
}
.header-bar .title {
font-size: 0.95rem;
}
.ip-bar {
gap: 16px;
flex-wrap: wrap;
padding: 8px 14px;
}
.tiles-grid {
justify-content: center;
}
.service-tile {
width: 140px;
min-height: 130px;
}
.reboot-card {
padding: 36px 28px;
margin: 0 16px;
}
.creds-dialog {
margin: 0 12px;
}
.creds-qr-img {
width: 200px;
height: 200px;
}
}
/* Legacy pre-redesign narrow-screen rules removed: they targeted the old
DOM (.main-content, .header-bar, .ip-bar) and their .sidebar /
#tiles-area / .service-tile / .creds-qr-img overrides fought the new
responsive layout in layout.css (sidebar icon rail, wrapping topbar).
Narrow-viewport behavior now lives in layout.css + header.css. */
@@ -345,13 +345,18 @@
/* Router — a simple open / not-open verdict. How to open the ports is
covered during onboarding, so the modal does not repeat instructions.
Node-only role: ports only matter once BTCPay Server or Lightning
Wallet Connections (LNURL) is turned on. */
if (isNodeRole() && !hasEnabledDomainService(c.services)) {
When no domain service is enabled (a fresh Desktop-only install, a
Node with BTCPay/LNURL off, or everything turned off), there is
nothing to check on the router — say so instead of listing services
this machine does not have. */
if (!hasEnabledDomainService(c.services)) {
var noRouterDesc = isNodeRole()
? 'Ports 80 and 443 only need to be forwarded on your router if you turn on <strong>BTCPay Server</strong> or <strong>Lightning Wallet Connections (LNURL)</strong>. If you enable one of them, come back here to check your ports.'
: 'None of your services need ports forwarded from your router right now. If you turn on a service that uses a domain, come back here to check your ports.';
html += '<div class="sysmodal-card">' +
'<div class="sysmodal-card-title">' + icon("g-wifi") + 'Router</div>' +
'<div class="sysnote"><div class="sysnote-title">' + icon("g-check") + 'No router setup needed yet</div>' +
'<div class="sysnote-desc">Ports 80 and 443 only need to be forwarded on your router if you turn on <strong>BTCPay Server</strong> or <strong>Lightning Wallet Connections (LNURL)</strong>. If you enable one of them, come back here to check your ports.</div></div>' +
'<div class="sysnote-desc">' + noRouterDesc + '</div></div>' +
'</div>';
} else {
html += '<div class="sysmodal-card" id="sys-ports-card" style="display:none">' +
@@ -360,9 +365,9 @@
'</div>';
}
/* Who uses these ports (redundant on a Node install with no domain
services on — the router note above already covers it) */
if (!isNodeRole() || hasEnabledDomainService(c.services)) {
/* Who uses these ports (only meaningful when a domain service is
actually enabled — otherwise the router note above covers it) */
if (hasEnabledDomainService(c.services)) {
html += '<div class="sysnote" style="margin-top:14px">' +
'<div class="sysnote-title">' + icon("g-antenna") + 'Who uses these ports</div>' +
'<div class="sysnote-desc">' + whoUsesPorts() + '</div></div>';