Move OfflineSyncIndicator (logo pip) and OfflineSyncBanner from the
[recipeLang] layout/page to (main)/+layout.svelte and (main)/+page.svelte.
Sync is an app-wide concern, not recipe-specific, and surfacing it on the
homepage gives the entry point users actually see when they install the
PWA. Indicator pulls language from languageStore since (main) doesn't
have data.lang from a recipe-scoped load.
Drop the now-unused .banner-wrap CSS and OfflineSyncIndicator/Banner
imports from the recipe routes.
Auto-sync cadence:
- AUTO_SYNC_INTERVAL 30 min -> 1 week. Recipes don't change often enough
to justify a half-hourly background download (the user explicitly
wanted this dialed back).
- Internal poll tick 5 min -> 1 hour. Polling 12x an hour for a weekly
event is wasted work; hourly is fine and still responsive when the
weekly window opens.
Bump 1.65.3 -> 1.66.0.
Add type annotations, JSDoc types, null checks, and proper generics
to eliminate all svelte-check errors. Key changes include:
- Type $state(null) variables to avoid 'never' inference
- Add JSDoc typedefs for plain <script> components
- Fix mongoose model typing with Model<any> to avoid union complexity
- Add App.Error/App.PageState interfaces in app.d.ts
- Fix tuple types to array types in types.ts
- Type catch block errors and API handler params
- Add null safety for DOM queries and optional chaining
- Add standard line-clamp property alongside -webkit- prefix
Add theme cycling (system/light/dark) with localStorage persistence
and FOUC prevention. Restructure CSS color tokens to respond to
data-theme attribute across all components. Redesign header as a
floating glass pill bar with smooth view transitions including
clip-reveal logo animation.
- LanguageSelector: add speech bubble tail, replace green active with
nord8 blue + dark text, remove floating gap
- Header: hide hamburger menu on mobile when no links, show profile
picture directly in top bar instead
- UserHeader: center mobile dropdown, fix tail color/position, add
profile picture overlay to tuck tail behind, add drop shadow
- Main layout: stop passing empty links snippet
- Replace deprecated <slot> syntax with modern {#snippet} and {@render} patterns
- Add TypeScript types for snippet props in Header component
- Convert on:click event handlers to onclick attribute throughout
- Update all layout files to use new snippet-based composition pattern
Extract language switching functionality from UserHeader into a new
LanguageSelector component. In mobile view, the selector appears in
the top bar next to the hamburger menu. In desktop view, it appears
in the navigation bar to the left of the UserHeader.
- Create LanguageSelector component with local element bindings
- Update Header component with language_selector_mobile and
language_selector_desktop slots
- Remove language selector code from UserHeader
- Update recipe and main layouts to use new component
- Hide desktop language selector inside mobile hamburger menu
Replace window.location.reload() with custom event dispatching to avoid
flicker when switching languages on main page. Add bilingual labels for
all content including welcome message and link grid.