<%# App shell: sidebar (brand + nav slot + footer) · topbar · content slot. The one chrome every page renders — dashboard, admin, plugin, login/registration/front — so the menu is identical everywhere, role-filtered to the visitor (anonymous ⇒ public items + Sign in). Slots are pre-rendered HTML locals — `nav` (sidebar tree, see nav-tree partial), `actions` (topbar buttons), `body` (page content); `styles` is an optional array of extra stylesheet hrefs (e.g. a plugin's own /public//x.css). Text locals: `title` (topbar heading; empty ⇒ the page body owns the single

, e.g. login/landing), `docTitle` (the tag; defaults to title or the brand), `brand` ({ name, logo?, sub? }), `theme` (theme-switch default), `user`, `breadcrumbs`, `csrfToken` (the Sign-out form's hidden field), `signInHref` (anonymous "Sign in" target; default /login). `menu` (default true) — set false to drop the sidebar and render a focused single-column page. %><% const brand = locals.brand || { name: "Plainpages" }; const title = locals.title || ""; // topbar heading; empty ⇒ no topbar <h1> (the body owns it) const docTitle = locals.docTitle || title || brand.name; const menu = locals.menu !== false; // sidebar shown by default; a page may opt out const hideSignIn = locals.hideSignIn === true; // the auth pages are already a way in — no footer Sign-in there const user = locals.user || { name: "Guest", initials: "G", email: "" }; const breadcrumbs = locals.breadcrumbs || []; const nav = locals.nav || ""; const actions = locals.actions || ""; const body = locals.body || ""; const styles = locals.styles || []; // extra per-page stylesheet hrefs (e.g. a plugin's own CSS) %><!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title><%= docTitle %> <% styles.forEach((href) => { %> <% }) %> <%- include("icons") %> <% if (menu) { %> <% } %>