Per-server customer app. index.astro = server list; [id]/ = one server with tabs: index
(dashboard), console/, history/, backups/, friends/, settings/, files/. Each tab is a
thin .astro shell rendering a Solid island from its _components/. [id]/_perms_readme.md
documents the full permission model — read it before touching gating.
ScreenLayout.astro. Nav rendered by [id]/_components/ServerWrapper.astro, gated
server-side via getServerPermissionsById (src/client/api.ts).createResource(getServerPermissionsById) and redirect to
/server/[id]/ when the required flag is missing — console/history/files/settings need
manage; friends is always viewable; start/stop buttons need start/stop; admin-only
settings need admin._ServerDashboard.tsx polls getServerState; backups polls run-state (~3s).
Islands re-derive serverId from window.location.pathname.split('/')[2]._perms_readme.md.styles/server.css drives this shell and its row layout is min-width:641px-gated on
purpose (see styles/AGENTS.md).