From cc4b10f239f38e4404cbe6a8e3b1e647b23c8f5b Mon Sep 17 00:00:00 2001 From: Stan Runge Date: Sat, 24 Oct 2026 15:35:38 +0000 Subject: [PATCH] site: owner-only dashboard link in header, mobile menu and homepage (g then d from any page); /start skips the site chrome JS - Header/footer moved to #lib/components/SiteChrome.svelte, returned by a universal +layout.ts load only for non-immersive pages, so /start and the book reader never download icon libraries, dropdowns or the bits-ui Sheet. /start: 36 -> 18 JS files, 133 -> 78 KB gzip. - Header logo is a hashed asset (inlined), so it is cached with the build. - inlineStyleThreshold 4096: tiny page/component CSS is inlined into the HTML. - Umami is not loaded on /start. --- src/lib/assets/brand/favicon-32x32.png | Bin 0 -> 1239 bytes src/lib/chrome.test.ts | 13 + src/lib/chrome.ts | 19 ++ src/lib/components/SiteChrome.svelte | 429 +++++++++++++++++++++++++ src/routes/+layout.svelte | 405 +---------------------- src/routes/+layout.ts | 12 + src/routes/+page.svelte | 17 + vite.config.ts | 4 + 8 files changed, 505 insertions(+), 394 deletions(-) create mode 100755 src/lib/assets/brand/favicon-32x32.png create mode 100644 src/lib/chrome.test.ts create mode 100644 src/lib/chrome.ts create mode 100644 src/lib/components/SiteChrome.svelte create mode 100644 src/routes/+layout.ts diff --git a/src/lib/assets/brand/favicon-32x32.png b/src/lib/assets/brand/favicon-32x32.png new file mode 100755 index 0000000000000000000000000000000000000000..81e7d1f420cf8420d480f79e306882b61fa162bc GIT binary patch literal 1239 zcmV;|1StE7P)Px(kx4{BR9Hvtm+OmEbsWY&=RRjHJF_FZqq{0euHuDyQz4iIf>IHRDF}gJpioGJ z(5t`~^%vC3UIfvN3fd?#BSb?f1ufCGwq4VmG2P4T?##~4nK?7(8t1Sho9@i4mx#b~ zUY_4M-{5*rTji(Mv3O1Oe`M7tkqCtg-W%GrYhl@RH~DXL<-mS z&^47G&z`5h|66?5YYCz?1A@SYjeWeZ<5~W?F-k-a07QuCQEK%%Wy3@gWmHu~mStSm zMbk6{Q6wHq@ZS3$b7d&oQi_%UBw6Orq5b&2OQBc{bx);YB;s*IQDnL>i|2Xhy3W*8 zfx1;kRTWa59q5q+BiU@e=;_UHsn~ITCI+0n&DCA z&Dq|u9c;&D&DuUxIf79&dFSnSDVHljk1i-hQviY}uzB+)4j$ac(C{#ZQN^~ZVeiM| zaq4voMUjce;?!z2EZbtHSj6!xmM>pQvZITNY4PC)pOd|Mt*Hzx0qolK9D8=}Bs-F2 zvM`O~*x-Ai-s#R1nx>;gR1&cSm#_TE)oeC=9#6zr{qPz_N5}a7_$h`5uY^o3lnX5Z z?AZAXdv@<2o6S-zP9q2sRkMmHLU&geF+E0lNgCU6nVl^&@cVDrwuK_gJhXBZmj(wo z|MLLXua4dY1A@Sor#5lmz&^&tMkyQRP`*qGFz_mMgK9%MdR)OEbHy&tvBDmFvBHsLURuUr;Y&YHmv5gS6{}qY?2*`umcc;P?DexgB%Fb zZ)&Pj5w$tdP}EUS)f+t{{) z5Zt0jp-^Nbm*e<}lN9phrtWWq!h#G0x;7{a&jU?i|K8`>x_uk2FHxK44*NY@C@=87t6xUgU=F%wuz* zEM63V`EuOUPMG_nX)%S}(?s--d9THZ-q_`BOXjxL4n*65 { + it('skips the site chrome on /start and the book reader only', () => { + expect(isImmersive('/start')).toBe(true); + expect(isImmersive('/start/')).toBe(true); + expect(isImmersive('/trackers/books/12/read')).toBe(true); + expect(isImmersive('/')).toBe(false); + expect(isImmersive('/starter')).toBe(false); + expect(isImmersive('/trackers/books/12')).toBe(false); + }); +}); diff --git a/src/lib/chrome.ts b/src/lib/chrome.ts new file mode 100644 index 0000000..5861086 --- /dev/null +++ b/src/lib/chrome.ts @@ -0,0 +1,19 @@ +/** + * Full-screen pages that render without the site header and footer: the /start new-tab + * dashboard and the book reader. They also skip loading the header's JS (icons, menus, + * the mobile Sheet): src/routes/+layout.ts only imports SiteChrome for other pages. + */ +export function isImmersive(pathname: string): boolean { + return /^\/start\/?$/.test(pathname) || /^\/trackers\/books\/\d+\/read\/?$/.test(pathname); +} + +/** True when a keyboard shortcut should not fire because the user is typing. */ +export function isTyping(target: EventTarget | null): boolean { + if (!(target instanceof HTMLElement)) return false; + return ( + target.isContentEditable || + target.tagName === 'INPUT' || + target.tagName === 'TEXTAREA' || + target.tagName === 'SELECT' + ); +} diff --git a/src/lib/components/SiteChrome.svelte b/src/lib/components/SiteChrome.svelte new file mode 100644 index 0000000..8d7ec88 --- /dev/null +++ b/src/lib/components/SiteChrome.svelte @@ -0,0 +1,429 @@ + + + + +{#snippet themeIcon()} + +{/snippet} + +
+ skip to content + +
+
+ + + stan runge + + + + + + + stan rungeNavigation + + + + {#if data.user} + +
+ +
+ {:else} + + + {/if} +
+
+ +
+
+
{@render children()}
+
+
+
+ stan runge {data.version.slice(0, 7)} + source +
+ +
+
+
+ + diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 8270fd2..112b8b2 100755 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,153 +1,18 @@ -{#snippet themeIcon()} - -{/snippet} - - {#if !dev} + {#if !dev && !page.url.pathname.startsWith('/start')}