diff --git a/src/lib/assets/brand/favicon-32x32.png b/src/lib/assets/brand/favicon-32x32.png new file mode 100755 index 0000000..81e7d1f Binary files /dev/null and b/src/lib/assets/brand/favicon-32x32.png differ diff --git a/src/lib/chrome.test.ts b/src/lib/chrome.test.ts new file mode 100644 index 0000000..c952aff --- /dev/null +++ b/src/lib/chrome.test.ts @@ -0,0 +1,13 @@ +import { describe, expect, it } from 'vitest'; +import { isImmersive } from './chrome'; + +describe('immersive pages', () => { + 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')}