+{/if}
diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts
new file mode 100644
index 0000000..10c4e3b
--- /dev/null
+++ b/src/routes/+layout.ts
@@ -0,0 +1,12 @@
+import { isImmersive } from '#lib/chrome.js';
+import type { LayoutLoad } from './$types';
+
+// The site header/footer (icon libraries, dropdowns, the bits-ui Sheet) live in SiteChrome,
+// imported only for pages that show them. Immersive pages such as the /start new-tab
+// dashboard never download that code. Universal loads may return components.
+export const load: LayoutLoad = async ({ data, url }) => ({
+ ...data,
+ Chrome: isImmersive(url.pathname)
+ ? null
+ : (await import('#lib/components/SiteChrome.svelte')).default
+});
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 8d51e6a..c7df489 100755
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -9,6 +9,7 @@
import Mail from 'lucide-svelte/icons/mail';
import BriefcaseBusiness from 'lucide-svelte/icons/briefcase-business';
import GraduationCap from 'lucide-svelte/icons/graduation-cap';
+ import LayoutDashboard from 'lucide-svelte/icons/layout-dashboard';
import type { PageProps } from './$types';
let { data }: PageProps = $props();
@@ -49,6 +50,22 @@
+ {#if data.isOwner}
+
+
+
+ dashboardtasks, server, backups, notifications and links ยท g then d from any page
+
+
+ {/if}
diff --git a/vite.config.ts b/vite.config.ts
index 9a42542..81ed5a1 100755
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -20,6 +20,10 @@ export default defineConfig({
// https, which is right for both staging and production from one image.
adapter: adapter(),
+ // Inline tiny stylesheets (component/page CSS) into the HTML: one request fewer per
+ // page. The big shared app.css stays a cached /_app/immutable file.
+ inlineStyleThreshold: 4096,
+
csrf: {
// Allow form posts from the dev site, which Caddy also serves over https.
trustedOrigins: ['https://dev.stanrunge.dev']