Scanning ${escapeHtml(RELAYS_ROOT)}…
`; if (listing.kind === "unavailable") return renderErrorState("Could not scan workspace relays.", listing.detail); @@ -255,6 +311,13 @@ class PiWebRelaysPanel extends HTMLElement { } } +/** Shell regions come from a literal template; absence means the template broke. */ +function requiredRegion(root: ShadowRoot, selector: string): HTMLElement { + const element = root.querySelector(selector); + if (!(element instanceof HTMLElement)) throw new Error(`relays panel shell is missing ${selector}`); + return element; +} + /** Reload glyph matching the app's own refresh control (AppRefreshControl). */ function refreshIconSvg(): string { return ` @@ -297,6 +360,7 @@ function relaysStyles(): string { the viewer's huge content basis starves them down to a sliver once a tall document renders). The viewer absorbs all shrinking instead. */ .toolbar { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--pi-border-muted); } + .toolbar[hidden], .document-tabs[hidden] { display: none; } .toolbar-actions { display: inline-flex; align-items: center; flex-wrap: nowrap; justify-content: flex-end; gap: 8px; min-width: 0; } .relay-name { min-width: 0; color: var(--pi-text-secondary); overflow-wrap: anywhere; } /* Bottom padding (not viewer margin) so the gap below the tabs persists