Use SvelteKit param matchers for bilingual URL routing (e.g. /fitness/stats
and /fitness/statistik). Add centralized i18n module with translation
dictionary, language detection from URL, and path conversion utilities.
Translate all UI text across pages, components, and navigation.
LanguageSelector and language store previously only dispatched
languagechange events on '/'. Now any page that isn't a recipe or
faith route gets inline language switching via the custom event.
Rework UserHeader and LanguageSelector dropdowns to use wrapper +
triangle pattern with theme-aware backgrounds. Use solid grey for
inactive nav text instead of semi-transparent. Reduce instruction
info box shadow. Add emoji font to CompactCard favorites.
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
Add Guardian Angel, Apostles' Creed, Tantum Ergo, Angelus, and Regina
Caeli to the prayers collection. Move standalone Angelus route into the
prayers system with a 301 redirect from the old path. Extract Easter
computation into shared utility ($lib/js/easter.svelte.ts) and use it
for liturgical season awareness: during Eastertide the rosary defaults
to Glorious mysteries and swaps Salve Regina for Regina Caeli; during
Lent it defaults to Sorrowful mysteries. Seasonal badges shown on both
the mystery selector and prayer sections.
- Rosary: mystery selection, luminous toggle, and latin toggle fall back
to URL params (?mystery=, ?luminous=, ?latin=) for no-JS navigation
- Prayers/Angelus: latin toggle uses URL param fallback
- Search on prayers page hidden without JS (requires DOM queries)
- Toggle component supports href prop for link-based no-JS self-submit
- LanguageSelector uses <a> links with computed paths and :focus-within
dropdown for no-JS; displays correct language via server-provided prop
- Recipe language links use translated slugs from $page.data
- URL params cleaned via replaceState after hydration to avoid clutter
Add language toggle support for faith pages similar to recipes.
Routes now work in both German and English:
- /glaube ↔ /faith
- /glaube/gebete ↔ /faith/prayers
- /glaube/rosenkranz ↔ /faith/rosary
- /glaube/angelus ↔ /faith/angelus
Replace non-reactive window.location.pathname with SvelteKit's reactive $page store to ensure language selector updates when navigating via browser back/forward buttons.
When switching languages on specific category or tag pages, redirect to
the selection page instead of trying to maintain the same category/tag,
since category and tag names differ between languages. Icon pages continue
to swap directly since icons are consistent across languages.
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