<%# App shell: sidebar (brand + nav slot + footer) · topbar · content slot. 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`, `brand` ({ name, logo?, sub? } — logo image else the default mark), `theme` (default for the theme-switch), `user`, `breadcrumbs`, `csrfToken` (the Sign-out POST form's hidden field). Branding comes from config/menu.ts; `user`/`csrfToken` from §4 auth. %><% const title = locals.title || "Plainpages"; const brand = locals.brand || { name: "Plainpages" }; 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) %> <%= title %> <% styles.forEach((href) => { %> <% }) %> <%- include("icons") %>

<%= title %>

<% if (breadcrumbs.length) { %> <% } %>
<%- actions %>
<%- body %>