- LanguageSelector: add kalender/calendar/calendarium mappings so swapping
language from /glaube/kalender/... produces /faith/calendar/... instead
of the broken /faith/kalender/... URL.
- HeroCard: move margin-bottom off the anchor so the plain (1969) variant
keeps the same bottom spacing as the linked (1962) variant.
- Calendar overview: omit detail href on 1969 so the hover chevron /
hover elevation don't appear when no detail page exists.
- Detail route: 404 any /detail/... under the 1969 rite — only 1962 has
day-detail pages.
- Auto-fill missing vernacular propers from Allioli (DE) or DRB (EN)
when the 1962 missal bundle lacks a translation, mapped per Latin slot
via romcal's scriptureRef blocks (compound refs split 1-to-1 when
segment count matches slot count).
- Strip Psalm superscriptions and trailing periods so lookups parse and
Bible text aligns with the Latin antiphon.
- Localize the section reference header (Marc → Mk, Vulgate→Hebrew
psalm shift for DE) instead of showing raw Latin.
- Add Latin / Parallel / Vernacular view toggle with localStorage
persistence; hide Allioli/DRB badge in Latin-only view.
- Latin column now takes primary text color; vernacular secondary,
matching the Prayer.svelte convention.
Removes decorative route-label h1s across fitness, recipe and cospend
pages — replaced with sr-only h1s for assistive tech and a shared
.sr-only utility in app.css. On the measure page, the tucked-away
profile chip becomes a dismissible setup banner that only appears
when sex/height/birth year are missing, with a permanent "Edit profile"
link at the foot of the page.
Macro split now always renders (faded rings + hint when no food logged),
and the calorie balance hint distinguishes missing demographics/weight
from missing food-log data with a warning style.
ActionButton now renders as <a> (href) or <button> (onclick), so
SaveFab wraps it to inherit the shake/hover/focus behavior already
used by AddButton/EditButton. Body-parts review replaces its inline
save button with SaveFab for consistency.
Latest measurements render as a 3x3 card grid (vertical mobile,
horizontal on ≥768px) linking to `/fitness/{measure}/{history}/{part}`
with summary stats + chart. Slugs localize (hals, oberschenkel, …)
when on the German route.
Pre-compute romcal year maps on server boot for current + next civil year
across en/de/la in each rite's default diocese, non-blocking so startup is
unaffected.
Also fixes several 1962-rite rendering bugs: commemorations previously
leaked 1969-shape ids (e.g. andrew_apostle) next to proper 1962 sancti;
station church names came through unresolved because RomcalConfig's
internal i18next has no bundle loaded; season names arrived as raw keys
(advent.season) for the same reason. All three now resolve locally via
the shipped 1962 bundle with Latin as fallback. ClassIV ferias get a
small dot on the grid.
The active-workout activity picker updated local state + workout.name
but never synced workout.activityType, so every hiking/walking/cycling
workout was saved with an inner exercise of 'running'. That silently
applied the wrong kcal model — running Minetti for hiking/walking
(~43% overestimate) and running instead of the cycling physics model
(large overestimate for cycling).
Adds an activityType setter on the workout store and invokes it from
selectActivity() so the saved session's exercise matches the picked
activity.
Average calorie balance was comparing logged-day intake against all-day
expenditure, producing a spurious deficit on weeks with untracked days.
Now restrict both sides to days with non-zero logged intake so the
subtraction compares apples to apples.
Past and today return projectedExercise=null, so the estimate no longer
appears on days where the user could have just skipped a workout. Also
skips the WorkoutSchedule lookup when not needed.
- Add `timing` handle in hooks.server.ts emitting Server-Timing headers
and expose `locals.timing.mark/measure` for per-load instrumentation.
- Drop dead `getEnrichedExerciseById` fallback in fitness detail page —
server load already 404s via errorWithVerse, so the client no longer
pulls exercisedb-raw.json (~760KB) into the detail bundle.
- Add `{ createdBy: 1, nextExecutionDate: -1 }` index on RecurringPayment
for user-scoped list queries.
- Narrow populate projections in cospend/debts (title/date/category on
userSplits, _id only on allRelatedSplits) to cut payload + hydration.
- Parallelize today's sessions + WorkoutSchedule lookup in the nutrition
page load via Promise.all; add `.lean()` + `.select('templateId')` to
the lastScheduled query.
Cap shell height to viewport minus header so the bottombar stays visible,
allow the stage to scroll internally, and swap the thigh diagram to a
mask-tinted SVG that tracks the text-primary color across themes.
SvelteKit's handleError hook is skipped for expected `error()` throws,
so verses set there never reached `$page.error` for server-thrown 404s
and auth denials. Introduce `errorWithVerse()` in `$lib/server/errorQuote`
that fetches a random verse first, then throws `error(status, body)`
with `{ message, bibleQuote, lang }`, making the quote available in
every `SectionError`. Convert all page load throws (catchalls, layout
validators, calendar, prayers, recipes, fitness, cospend, admin) and
hooks.server auth gates to the helper. Add `src/error.html` as a
branded last-resort fallback.
Replace the emoji/gradient card with an editorial layout: small lucide
glyph, oversized error code, hairline-divided serif bible quote.
Extract shared ErrorView + SectionError components and a bilingual
string helper. Add +error.svelte at each section root (faith, recipes,
fitness, tasks, cospend) so errors render inside the correct layout and
inherit the section-specific header/nav. Catch-all [...rest]/+page.ts
stubs route unmatched URLs through the section layout so the right
error page catches them.
The raw series has `pending: number | null`, but the rendered series stores
pending as `{ x, y, value }` for SVG placement. Legend labels were calling
`.toFixed(1)` directly on the object, crashing as soon as a pending value
existed (i.e. whenever the user typed a measurement).
romcal's package.json is not listed in its exports map, so
require.resolve('romcal/package.json') throws ERR_PACKAGE_PATH_NOT_EXPORTED
under Node's strict exports enforcement. Resolve the main entry instead
and walk up until we find the package.json belonging to romcal itself.
romcal's 1962 bundle files live outside the package's exports map and were
being loaded via a cwd-relative path. Under systemd the server runs with
cwd /usr/share/webapps/homepage/dist/, so node_modules/romcal/... resolved
against dist/ and hit ERR_MODULE_NOT_FOUND. Switch to createRequire +
require.resolve('romcal/package.json') so the bundle path is anchored to
the actual package root regardless of cwd.
Also track scripts/hooks/pre-push which runs scripts/deploy.sh after a
master push to origin. Git has no native post-push hook; pre-push is the
closest client-side equivalent — if deploy fails the push is aborted.
Install with: ln -sf ../../scripts/hooks/pre-push .git/hooks/pre-push
New /fitness/measure/body-parts route with step-by-step tape-measure
flow, per-step tips, L/R paired inputs, inline history chart, and
review-before-save summary. Measure page replaces the old body-parts
accordion with a launch button. Fitness layout goes full-bleed and
hides the site footer for this route via a :has() attribute selector,
and the desktop 3-column grid now extends rail and side panel up past
the floating nav while the middle column compensates with padding.
Inline italic captions under each single-sided input (neck, shoulders,
chest, waist, hips) and row-spanning captions with a primary accent bar
under each paired row (biceps, forearms, thighs, calves) — one tip per
pair, not per side. EN + DE copy.
Schema uses flat keys (leftBicep, rightBicep, leftForearm, ...), but
create/edit forms built nested objects (biceps: {left, right}), which
Mongoose silently stripped — so paired parts never persisted. The
latest-measurements endpoint also wraps the body-parts doc in
{value, date}; the display path skipped the .value hop, hiding every
body-part field. Switch client to flat keys end-to-end.
- Reserve an angular gap in the ring and render a clickable green triangle
that jumps to Advent I of the following liturgical year; on hover the
center numeral previews the upcoming LY in a muted color.
- Show the liturgical year (not civil) in the ring center so Advent 2025
already reads 2026, and promote the selected arc to the top of the
SVG paint order so its highlighted border is never clipped by neighbors.
- Lift the selected-season glow by mixing the season tint with the
foreground color so purple stays visible on dark backgrounds and white
on light backgrounds.
- On feast-dot hover, pop a colored SVG pill with the short date and feast
name, tracked by ISO so it auto-clears when the dot is unmounted by
navigation.
- Server now derives the liturgical year from the selected date, shifting
yearMap forward when the URL civil date lies past Advent I of that year
so clicks on Dec 25 no longer select the prior post-Pentecost cycle.
- Add data-sveltekit-keepfocus on ring anchors to avoid the focus-scroll
jump after client-side navigation.
Switch the romcal dependency to AlexBocken/romcal (monorepo fork with
collapsed bucket prefixes) and strip the runtime prefix-fallback chain
from liturgicalCalendar.ts — name/propers lookups now use a single
flat id. The 1962 data model shrinks to just what the rendering uses
(commem {id,name}, detail carrying propers as {key, la[], local[]})
and the detail + overview pages drop the rubrics/octave/properSource
fields that never got wired in.
- Rotate the ring smoothly to put the selected day under a static vertical
needle pin; pivot uses a shortest-arc Tween, respects prefers-reduced-motion,
and falls back to today when no selection. Pin + bar cross-fade color in
lockstep (650ms cubicOut) to the selected day's liturgical color (gold when
selected == today).
- Split the overview into an inline hero (selected day) and a dedicated
/detail/{yyyy}/{mm}/{dd} route that opens on hero click; drop the old
inline detail block.
- Restyle the month grid to a minimalist card-grid: taupe feria fills,
rounded cells, gold today-ring + dot, Roman-numeral rank badges, and
equal-width columns via minmax(0, 1fr) so long feast names no longer
stretch a column.
- Default the calendar view to the ring, reorder the view switcher
(ring first), and match hero-card color transition to the ring timing.
- Extract shared calendar types to $lib/calendarTypes.ts and server helpers
to $lib/server/liturgicalCalendar.ts so the overview + detail routes share
one source of truth. Bump romcal dep to the dev branch, alias the Swiss
1969 bundle so its exports resolve.
- Bump version to 1.35.0.
Show propers text for each 1962 celebration with scripture reference pills
grouping each block. When a translated proper is missing, fall back to the
local-language Bible (Douay-Rheims for en, Allioli for de), showing a note
above the translated column. Handles multi-segment refs (e.g. "Ps 118:85;
118:46") with inherited book/chapter, and shifts Vulgate→Hebrew psalm
numbering for Allioli.
Also restructures date navigation as folder-based optional params
(/yyyy/mm/dd) with the rite forced as a required path segment so day/month
navigation stays within the active rite.
Add a small banner on the 1962 rite view noting that day-to-day data is
still being verified and that local proper calendars (diocese, order,
national feasts) are not yet layered on top of the general Roman
calendar. Bump the romcal dep to AlexBocken/romcal1962#e4731a8 for the
Holy Week / Easter Octave name fixes and the Pentecost-season color fix
(ordinary-time Sundays are now Green, not White/Red).
Replace four tastytea-style SVGs (blanket, hammer, teapot, heart_tastytea)
whose 800px viewBox clashed with the 33.866666 viewBox of the rest, and add
the full Tirifto gutkato_ set. Catalog grows from 54 to 113 positive stickers
(new foods/drinks, rose and cat colors, professions, cute expressions, signs).
Adds a calendar tile to the /faith (glaube/fides) LinksGrid linking to the
liturgical calendar. Homepage description and WIP body reference the "older
rite" / "alten Ritus" rather than "Tridentine" to avoid loaded connotations;
subtitle labels keep the neutral Ordinary/Extraordinary Form terminology.
Adds `/faith/calendar`, `/glaube/kalender`, `/fides/calendarium` route backed by
romcal v3 + @romcal/calendar.general-roman with native EN/DE/LA locales. Month
grid, today hero, and day detail panel use liturgical colors from the rubric.
Header gets a segmented 1969/1962 pill toggle; selecting 1962 shows a WIP
placeholder (Tridentine calendar data not yet wired up).
WebKit's hidden <input type="checkbox" switch> haptic trick is gated on
tap-completion, not tap-start. Firing on pointerdown ran the programmatic
click() before iOS committed to "this is a tap" so the switch-toggle
haptic was suppressed. pointerup lands inside iOS's tap-completion
window — still earlier than click (no movement filter, no 300ms wait).
Android native bridge path is unaffected.
Derive recents from current-day entries merged with historical
server data so logging a food updates the quick-log bar instantly.
FoodSearch now emits onfavoritechange so toggling a heart keeps
the quick-log favorites tab in sync without reloading.
Align muscle group and equipment filters in the exercise picker
with the rest of the fitness UI — horizontal pill scrollers, multi-
select, with Lucide icons for each equipment type.
Edit mode now shows a pill row (breakfast/lunch/dinner/snack with their
icons) beneath the grams input so the entry can be moved to another meal.
Food cards are also draggable; dropping onto a different meal section
optimistically moves the entry (rolls back on API error). Desktop/pointer
only — touch devices use the pill row.
Allow users to nest steps inside a repeat group (e.g. "5×: 30s sprint,
60s recovery") when building GPS interval templates. Groups are tagged
{ type: 'group', repeat, steps } alongside flat { type: 'step' } entries
and capped at one nesting level. Entries are expanded into a flat list
before handing off to the native Android TTS/interval service, so the
runtime state machine is unchanged.
Distinguish stretches, strength, cardio, and plyometric exercises
with a curated `exerciseType` field that overrides mislabels in
ExerciseDB for the hand-curated stretch set. Surface the type as
pills on the detail page and as a filter toggle on the list page.
Replace the muscle-group and equipment dropdowns with horizontally
scrolling pill rows; equipment pills carry Lucide icons, and the
type toggle shows a flexed-bicep / person / layers glyph. Selected
muscle groups hoist to the front of the scroller.
Viewer: cake-form adjust now collapses into a summary trigger with live
factor badge; shape picker replaced with icon-only tiles that flex to
fill the row; numeric inputs gain inline cm suffix; restore-default link
appears when user deviates from the default. Editor: default-Backform
config mirrors the same card + tile pattern (adds "none" tile), plus
inline cm suffixes. Baking info row in instruction editor becomes a
click-to-reveal card with summary chips, mode presets, and editable
fields behind the chevron.
Replace CardAdd with EditTitleImgParallax so /rezepte/edit/[name]
mirrors the hero-parallax layout of /rezepte/[name]. Add Lucide icons
and a width-constrained info-card grid to CreateStepList's additional
info section. Refactor the English translation view to use semantic
theme vars, side-by-side German/English field comparison, and a card
aesthetic matching the rest of the site.
Fix portions binding bug where the shared portions store was being
written by both language ingredient lists. CreateIngredientList now
accepts a bindable portions prop; the English list uses it with
useStore=false to stay isolated from the German value.
Every prayer card now vibrates on tap — non-decade cards advance to the
next section, decade cards increment the Ave Maria counter with auto-scroll
at 10. Two profiles (bead vs card) give distinct tactile feel; the 10th
bead fires the heavier card haptic to mark decade completion.
Native Android path via AndroidBridge.forceVibrate uses VibrationAttributes
USAGE_ACCESSIBILITY so vibration bypasses silent / Do-Not-Disturb inside
the Tauri app. Browser falls back to the web-haptics npm package. Haptic
fires on pointerdown with touch-action: manipulation for near-zero tap
latency; state change stays on click so scroll gestures don't advance.
- Remove CounterButton (whole card is now the tap target)
- Replace emoji with Lucide BookOpen icon, restyle citation as an
understated inline typographic link (no background chip)
- Drop decade min-height leftover from the pre-auto-advance layout
Bumps site to 1.27.0 and Tauri app to 0.5.0 (new Android capability).
Shift pop-b and pop-c selectors so accent colors appear sooner in the
grid and the light/white pop-c repeats more frequently (every 5th
instead of every 7th item).
- Play/Stop button replaces checkmark for duration-only exercises
- Green countdown bar with auto-completion and rest timer chaining
- Display duration in seconds (SEC) instead of minutes for holds
- ActiveWorkout model now preserves distance/duration fields on sync
- Hold timer state syncs across devices via SSE
- Workout summary shows per-set hold times for duration exercises
- Template diff compares and displays duration changes correctly
Exercises used by the Day 6 stretching template were only in
exercisedb-map.ts but missing from exercises.ts, causing the
template detail to show raw IDs instead of proper names.
Use Android TYPE_STEP_DETECTOR sensor in LocationForegroundService to
count steps in a 15s rolling window. Cadence (spm) is computed at each
GPS point and stored alongside lat/lng/altitude/speed. Session detail
page shows cadence chart when data is available.
No additional permissions required — step detector is not a restricted
sensor. Gracefully skipped on devices without the sensor.
Replace auto-seed with a browsable template library. Users can
selectively add built-in templates to their collection via a
BookOpen icon or the empty-state prompt. Each library template
tracks its origin via libraryId to prevent duplicates.
- Extract default templates to shared $lib/data/defaultTemplates.ts
- Add GET/POST /api/fitness/templates/library endpoint
- Add library modal with add/added state per template
- Keep seed endpoint as fallback (imports from shared data)
Full-body stretching session (~30 min) covering all major muscle
groups with 15 bodyweight exercises: neck, shoulders, chest, back,
spine, hips, hamstrings, quads, glutes, calves, and arms.
Each exercise has 2 sets of 60-90s holds with 15s rest.
When no workout is logged for the day, look up the next template
in the schedule rotation and show the kcal from its most recent
session as a projection. Tappable toggle includes/excludes it
from the calorie goal, ring, and macro bars for meal planning.
shoppingCatalog.json was missing all 22 new entries (11 icons
with aliases) added to catalog.json, so new icons like stroh80
were never matched at runtime.