Commit Graph

235 Commits

Author SHA1 Message Date
Alexander 71ae0a2212 fix: align MysterySelector buttons with site-wide design language
Replace hardcoded Nord values and manual dark/light overrides with
semantic CSS variables (--color-surface, --color-primary, --shadow-sm,
--radius-card, etc.). Use scale:1.02 hover pattern and remove all
@media(prefers-color-scheme) and :global(:root[data-theme]) blocks.
2026-04-09 22:08:14 +02:00
Alexander c439f2f6b0 feat: redesign LinksGrid with semantic theming, rounded corners, and new layout
- Use semantic CSS variables (--color-surface, --shadow-sm, etc.) instead
  of hardcoded Nord values and manual dark mode overrides
- Add border-radius and overflow:hidden for rounded card corners
- Move icon fill variables (--grid-fill-*) into app.css theme system:
  colorful (red/orange/green) in light, cool blues in dark
- Mottled fill distribution via prime-offset nth-child selectors
- Reorder homepage links: Recipes, Shopping, Fitness, Faith, Tasks first
- Add Nutrition direct link with heart-pulse icon
- Document site-wide design language in CLAUDE.md
2026-04-09 22:05:09 +02:00
Alexander a7491d6f08 fix: extend recipe hero images into status bar safe area
Account for env(safe-area-inset-top) in the hero negative margin-top
so images fill the status bar area on edge-to-edge Android instead of
leaving empty space.
2026-04-09 21:33:53 +02:00
Alexander 29059b8197 fix: use gradient overlay instead of box-shadow for status bar shadow
The box-shadow rendered outside the pseudo-element, placing the shadow
below the status bar boundary. Switch to a multi-stop linear gradient
inside the element so the shadow fades smoothly through the status bar
area (+20% overshoot for softer transition).
2026-04-09 21:31:26 +02:00
Alexander 1e23ed02c2 feat: add "round off this day" nutrition suggestions
Suggest optimal 1-3 food combinations to fill remaining macro budget using
weighted least-squares solver over a curated pantry (~55 foods) plus user
favorites/recents. Recipes scored individually (no combining). Features:

- Combinatorial solver (singles, pairs, triples) with macro-weighted scoring
- MealTypePicker component (extracted from quick-log, shared)
- Hero card with fit%, macro delta icons (Beef/Droplet/Wheat), ingredient
  cards, animated +/X toggle for logging
- Responsive layout: sidebar on mobile, center column on desktop
- MongoDB cache with ±5% tolerance, SSR on cache hit, TTL auto-expiry
- Cache invalidation on food-log/favorites/custom-meals CRUD
- Recipe per100g backfill admin endpoint
2026-04-09 20:47:32 +02:00
Alexander 6029cfe18c feat: add food detail pages for OFF and custom meal sources
Extend the nutrition detail page to support OpenFoodFacts items (looked up
by barcode) and custom meals (with ingredient breakdown). All food diary
cards and search results now link to detail pages regardless of source.
2026-04-09 18:17:43 +02:00
Alexander 765fbf4613 feat: add muscle visualization to exercise detail page
New MuscleMap component highlights primary muscles at full opacity and
secondary muscles at 40% using the existing body SVG diagrams. Only
renders front/back views that have active muscles.

Responsive layout: centered inline on mobile, sticky sidebar on desktop.
2026-04-09 00:27:05 +02:00
Alexander 234c3adcf3 feat: add concise bilingual overviews for all 254 exercises
- Fix ExerciseDB data quality (remove empty calf raise, fix Wall Sit,
  correct muscles, typos)
- Rewrite verbose AI-generated English overviews to concise one-sentence
  descriptions
- Add German translations for all 199 EDB exercises (name, instructions,
  overview)
- Add English and German overviews for 55 static-only exercises
- Display overview above instructions on exercise detail page
2026-04-09 00:21:10 +02:00
Alexander 28f927126f feat: add recipe food detail route with hero image, favorites, and logged nutrition
Recipes logged in the food diary now link to a dedicated detail page at
/fitness/nutrition/food/recipe/{id} showing full nutritional breakdown,
hero image, and a link back to the recipe page. When opened from the
diary, the logged per100g snapshot is used; otherwise current recipe
nutrition is computed. Recipe favorites are now supported across the
favorite-ingredients API, nutrition lookup, and search endpoints.
2026-04-08 23:08:52 +02:00
Alexander c2af12c8d7 refactor: extract RingGraph, StatsRingGraph, MacroBreakdown components
Consolidate 6 duplicated instances of the SVG arc ring pattern into a
composable component hierarchy: RingGraph (base ring), StatsRingGraph
(ring with target markers), and MacroBreakdown (3 rings + kcal + detail
table). Removes ~400 lines of duplicated SVG/CSS from FoodSearch,
nutrition page, meals page, stats page, food detail page, and recipe
NutritionSummary.
2026-04-08 22:21:24 +02:00
Alexander fb0a33daa3 feat: custom meal detail screen, favorites tab, enhanced food search detail
- Replace inline amount row with full detail screen for custom meals
  showing calorie headline, macro rings, macro breakdown, and ingredients
- Add Favorites tab (with filter) between Search and Custom Meals tabs
- Search tab no longer prepends unmatched favorites
- Enhance FoodSearch selected view with macro rings and nutrient breakdown
- Add filter input to custom meals tab
- Document --color-primary/--color-text-on-primary in CLAUDE.md
2026-04-08 21:38:49 +02:00
Alexander a1ae8889f5 feat: quick-log sidebar with favorites and recent foods
Desktop sidebar (1600px+) for one-click food logging with inline amount
input. Favorites and recent items (last 3 days) shown with meal type
auto-selected by time of day. New /api/nutrition/lookup endpoint for
exact source+id food data retrieval. Parent container width override
via JS class toggle for reliable SvelteKit client-side navigation.
2026-04-08 20:30:13 +02:00
Alexander 4e5ff0f597 feat: two-column desktop layout for nutrition page
At 1024px+, nutrition page switches from single-column (600px max) to a
two-column grid: sticky sidebar (summary, goals, water) + scrollable
meals column. Mobile layout unchanged via display:contents fallback.
2026-04-08 17:22:16 +02:00
Alexander ead3a1a1cd fix: remove redundant back links from nutrition sub-pages
Header navigation and browser history already provide this
functionality — the inline back links were unnecessary clutter.
2026-04-08 16:58:37 +02:00
Alexander 72ed5ef016 fix: calorie balance uses per-day TDEE from SMA trend weight + workout kcal
Balance is now intake minus estimated expenditure rather than intake
minus calorie goal. TDEE computed per day using that day's SMA trend
weight (Mifflin-St Jeor BMR × NEAT multiplier) plus tracked workout
calories, so a -500 kcal cut shows ~-500 on the balance card.
2026-04-08 16:58:15 +02:00
Alexander 376fbf1ba7 feat: replace browser confirm() with reusable ConfirmDialog component
Promise-based modal dialog with backdrop, keyboard support, and animations,
replacing all 18 native confirm() call sites across fitness, cospend, recipes,
and tasks pages.
2026-04-08 16:47:22 +02:00
Alexander 7fb47717f4 fix: macro split sidebar breakpoint to 750px, polish legend icons
Lower desktop breakpoint from 1024px to 750px so the macro column
appears on more screens. Legend now uses horseshoe arc for actual
and rounded triangle for target.
2026-04-08 16:34:24 +02:00
Alexander 71a43475fa fix: invert shopping list icons to black in light mode
White PNG icons were invisible on light backgrounds. Added semantic
--shopping-icon-filter variable (invert(1) in light, none in dark)
applied to card and picker icons.
2026-04-08 16:30:06 +02:00
Alexander ba5e08971d feat: desktop layout — macro split sidebar next to muscle heatmap
On desktop (≥1024px), protein/balance/adherence cards sit in a row above
the muscle heatmap, with the macro split card as a vertical sidebar on the
right spanning the full height. Includes ring/triangle legend for
actual vs target. Mobile layout unchanged.
2026-04-08 16:26:02 +02:00
Alexander 4a3e85bcf7 feat: add info popover tooltips to calorie balance and adherence cards
Clicking the (i) icon on the calorie balance or adherence card now shows
a floating popover explaining how each metric is calculated, with EN/DE
translations.
2026-04-08 16:14:58 +02:00
Alexander 47b690257e feat: auto-track liquids from custom meal ingredients in hydration tracker
When logging a custom meal, liquid ingredients (BLS drinks, water, beverages)
are detected and their volume stored as `liquidMl` on the food log entry.
The liquid tracker cups and list now include these meal-sourced liquids.
2026-04-08 16:06:12 +02:00
Alexander 9af36b0c14 feat: add EN/DE internationalization to cospend section
Move cospend routes to parameterized [cospendRoot=cospendRoot] supporting
both /cospend (DE) and /expenses (EN). Add cospendI18n.ts with 100+
translation keys covering all pages, components, categories, frequency
descriptions, and error messages. Translate BarChart legend, ImageUpload,
UsersList, SplitMethodSelector, DebtBreakdown, EnhancedBalance, and
PaymentModal. Update LanguageSelector and hooks.server.ts for /expenses.
2026-04-08 15:46:01 +02:00
Alexander b7c7b37c94 feat: add Swiss German aliases for shopping list categorization
Add Rahm, Rüebli, Poulet, Cervelat, Crevetten, Weggli, Bürli, Zopf,
Glacé, Konfitüre, Nüsslisalat, Federkohl, Peperoni, and other Swiss
German terms to category items and alias map so they categorize correctly
instead of falling back to embedding similarity (e.g. Rahm→Schwamm).
2026-04-08 14:15:24 +02:00
Alexander 39ffe1732f fix: eliminate all 167 svelte-check warnings
Refactor page components to use $derived + invalidateAll() where data
is read-only or re-fetched after mutations. Suppress state_referenced_locally
for intentional patterns (form state, optimistic updates, pagination).
Fix a11y issues with role="presentation", add standard line-clamp properties,
remove unused CSS selectors and empty rulesets.
2026-04-08 14:06:15 +02:00
Alexander 4bbd733968 feat: inline custom meals, calorie ring overflow animation, theme fixes
Add custom meals tab to inline food add section with search/meals toggle.
Animate calorie ring overflow (red) after primary fill completes, with
separate glow elements so red overflow glows red independently. Apply same
delayed overflow animation to macro progress bars. Replace hardcoded nord8
with --color-primary throughout nutrition page (today badge, ring, tabs,
buttons). Add custom clear button to FoodSearch, hide number input spinners
globally.
2026-04-08 13:15:48 +02:00
Alexander f4cb56291a feat: add nutrition statistics to fitness stats page
Add protein g/kg (7-day avg using trend weight), calorie balance
(surplus/deficit vs goal), diet adherence (since first tracked day),
and macro split rings with target markers to the stats dashboard.
2026-04-08 12:39:03 +02:00
Alexander 3c7bc03379 feat: add liquid tracking card to nutrition page with water cups and beverage detection
Track water intake via interactive SVG cups (fill/drain animations) using
BLS Trinkwasser entries for mineral tracking. Detect beverages from food log
(BLS N-codes + name patterns) and include in liquid totals. Configurable
daily goal stored in localStorage. Cups show beverage fills (amber) as
non-removable and water fills (blue) as adjustable.
2026-04-08 10:24:12 +02:00
Alexander e92fc1cc25 feat: shareable shopping list links with token-based guest access
- Generate temporary share links (default 24h) that allow unauthenticated
  users to view and edit the shopping list
- Share token management modal: create, copy, delete, and adjust TTL
- Token auth bypasses hooks middleware for /cospend/list routes only
- Guest users see only the Liste nav item, other cospend tabs are hidden
- All list API endpoints accept ?token= query param as alternative auth
- MongoDB TTL index auto-expires tokens
2026-04-08 09:04:58 +02:00
Alexander 96bf1beca8 feat: add colored category icons, quantity badges, and remove collapsing in shopping list
Add Lucide icons and Nord colors per category, parse quantities from item names
(e.g. "10L Milch" → badge "10L" + name "Milch"), and remove category collapse toggling.
2026-04-08 00:12:38 +02:00
Alexander 5e161c4b0c feat: add real-time collaborative shopping list at /cospend/list
Real-time shopping list with SSE sync between multiple clients, automatic
item categorization using embedding-based classification + Bring icon
matching, and card-based UI with category grouping.

- SSE broadcast for live sync (add/check/remove items across tabs)
- Hybrid categorizer: direct catalog lookup → category-scoped embedding
  search → per-category default icons, with DB caching
- 388 Bring catalog icons matched via multilingual-e5-base embeddings
- 170+ English→German icon aliases for reliable cross-language matching
- Move cospend dashboard to /cospend/dash, /cospend redirects to list
- Shopping icon on homepage links to /cospend/list
2026-04-07 23:50:54 +02:00
Alexander 2b85d3f2a1 fix: restore backdrop-filter blur in production builds
Lightning CSS was deduplicating manually written backdrop-filter +
-webkit-backdrop-filter to just the webkit version, breaking blur on
Firefox. Remove manual webkit prefixes and let Lightning CSS auto-prefix
via browser targets in vite.config.ts.
2026-04-07 21:46:05 +02:00
Alexander 973783cf53 feat: tap-to-preview stickers in gallery with glow effect
Add full rarity glow to gallery stickers matching the reward popup style.
Tapping an owned sticker opens a large preview card. Allow calendar
stickers to overdraw their cell on hover.
2026-04-07 20:38:06 +02:00
Alexander a26fa5d005 feat: add seasonal badge to Regina Caeli link during Eastertide
Shows an "In season" / "Zur Zeit" / "Tempore" pill on the Regina
Caeli card in the faith links grid when it replaces the Angelus.
2026-04-07 20:25:18 +02:00
Alexander 474b4c3add feat: show exercise weights in template preview and quick start
Template detail modal now shows the initial weight per exercise.
Quick start hero shows the first exercise name and weight to help
with rack preparation before starting.
2026-04-07 20:19:32 +02:00
Alexander 0b67f5b687 fix: period end date set to yesterday and show fertile range during ongoing period
Clicking "Period Ended" now records yesterday as the end date, since
you only know the period ended the day after. Also added the missing
fertile date range to the ongoing-period status view.
2026-04-07 20:14:21 +02:00
Alexander 02bb889629 security: enforce auth on all API write endpoints, remove mario-kart
- Remove all mario-kart routes and model (zero auth, unused)
- Add requireGroup() helper to auth middleware
- Recipe write APIs (add/edit/delete/img/*): require rezepte_users group
- Translate endpoint: require rezepte_users (was fully unauthenticated)
- Nutrition overwrites: require auth (was no-op)
- Nutrition generate-all: require rezepte_users (was no-op)
- Alt-text/color endpoints: require rezepte_users group
- Image delete/mv: add path traversal protection
- Period shared endpoint: normalize username for consistent lookup
2026-04-07 20:10:49 +02:00
Alexander 0fe6990df9 fix: remove keyed each on recipe tags to handle duplicate tag names
Duplicate tags (e.g. "Butter" at two indexes) caused a Svelte
each_key_duplicate error that broke rendering on /recipes.
Also use past tense for angelus streak button to match rosary.
2026-04-07 20:03:17 +02:00
Alexander 35721237b4 fix: use dynamic recipeLang in API calls instead of hardcoded /api/rezepte
Client-side navigation to /recipes hung because getUserFavorites and
other endpoints were hardcoded to /api/rezepte, causing fetch mismatches
during SvelteKit's client-side routing.
2026-04-07 19:50:35 +02:00
Alexander e59947dd97 fix: move clear filter button from muscle diagram to filter pills area 2026-04-06 21:30:24 +02:00
Alexander e80f84d152 feat: play double-beep sound when rest timer completes 2026-04-06 21:23:46 +02:00
Alexander 6db928e524 feat: ExerciseDB integration with muscle heatmap, SVG body filter, and enriched exercises
Integrate ExerciseDB v2 data layer (muscleMap.ts, exercisedb.ts) to enrich
the 77 static exercises with detailed muscle targeting, similar exercises,
and expand the catalog to 254 exercises. Add interactive SVG muscle body
diagrams for both the stats page heatmap and exercise list filtering, with
split front/back views flanking the exercise list on desktop. Replace body
part dropdown with unified muscle group multi-select with pill tags.
2026-04-06 20:57:49 +02:00
Alexander 3562b4f106 feat: redesign nutrition goal editor with wizard flow, macro ring, and TDEE comparison
Replaces flat goal editor with a 3-step wizard (preset → calories → macros),
adds preset cards with diet descriptions, live macro donut ring preview,
overlaid TDEE vs target comparison bar, TDEE missing-data warning with
explanation, and surfaces latest weight used for TDEE calculation.
2026-04-06 15:38:19 +02:00
Alexander f4e0617fc7 feat: add period tracker with calendar, predictions, fertility tracking, and sharing
Full period tracking system for the fitness measure page:
- Period logging with start/end dates, edit/delete support
- EMA-based cycle and period length predictions (α=0.3, 12 future cycles)
- Calendar view with connected range strips, overflow days, today marker
- Fertility window, peak fertility, ovulation, and luteal phase visualization
- Period sharing between users with profile picture avatars
- Cycle/period stats with 95% CI below calendar
- Redesigned profile card as inline header metadata with Venus/Mars icons
- Collapsible weight and period history sections
- Full DE/EN i18n support
2026-04-06 15:12:03 +02:00
Alexander 98c67070f6 perf: parallelize DB queries across routes, clean up fitness UI
Parallelize sequential DB queries in 11 API routes and page loaders
using Promise.all — measurements/latest, stats/overview, goal streak,
exercises, sessions, task stats, monthly expenses, icon page, offline-db.

Move calorie tracking out of /fitness/measure (now under /fitness/nutrition
only). Remove fade-in entrance animations from nutrition page.

Progressive streak computation: scan 3 months first, widen only if needed.

Bump versions to 1.1.1 / 0.2.1.
2026-04-06 13:12:29 +02:00
Alexander 1fa2e350d7 feat: major dependency upgrades, remove Redis, fix mongoose 9 types
Dependencies upgraded:
- svelte 5.38→5.55, @sveltejs/kit 2.37→2.56, adapter-node 5.3→5.5
- mongoose 8→9, sharp 0.33→0.34, typescript 5→6
- lucide-svelte → @lucide/svelte 1.7 (Svelte 5 native package)
- vite 7→8 with rolldown (build time 33s→14s)
- Removed terser (esbuild/oxc default minifier is 20-100x faster)

Infrastructure:
- Removed Redis/ioredis cache layer — MongoDB handles caching natively
- Deleted src/lib/server/cache.ts and all cache.get/set/invalidate usage
- Removed redis-cli from deploy workflow, Redis env vars from .env.example

Mongoose 9 migration:
- Replaced deprecated `new: true` with `returnDocument: 'after'` (16 files)
- Fixed strict query filter types for ObjectId/paymentId fields
- Fixed season param type (string→number) in recipe API
- Removed unused @ts-expect-error in WorkoutSession model
2026-04-06 12:21:26 +02:00
Alexander a38f19cfcc feat: styled offline page with app install hint, bump versions
Replace bare offline fallback with styled page matching the app's
design (glass nav, dark/light mode, wifi-off icon, retry button).
Add hint to install Android APK or PWA for offline use.

Site: 1.0.0 → 1.1.0
Android/Tauri: 0.1.0 → 0.2.0
2026-04-06 00:21:03 +02:00
Alexander 039d37b410 feat: add barcode scanner with OpenFoodFacts integration
- Camera-based barcode scanning in FoodSearch using barcode-detector (ZXing WASM)
- Import script to load OFF MongoDB dump into lean openfoodfacts collection
  with kJ→kcal fallback and dedup handling
- Barcode lookup API with live OFF API fallback that caches results locally,
  progressively enhancing the local database
- Add 'off' source to food log, custom meal, and favorite ingredient models
- OpenFoodFact mongoose model for the openfoodfacts collection
2026-04-05 11:57:28 +02:00
Alexander 54a345224e nutrition: use SvelteKit read() for embedding files instead of fs
Replace fragile CWD-based readFileSync path resolution with SvelteKit's
read() + Vite ?url asset imports. This lets the build system manage the
embedding files as hashed immutable assets, fixing ENOENT errors in
production where the working directory didn't match expectations.
2026-04-03 08:43:12 +02:00
Alexander d41416e9f3 nutrition: fix embedding file paths for production and copy to dist
resolve() uses CWD which in production (adapter-node) is dist/, not the
project root. Detect the correct data directory at startup and add a
postbuild step to copy the embedding JSON files into dist/data/.
2026-04-02 21:08:54 +02:00
Alexander fe17af66fc nutrition: pre-download HuggingFace models at build time
The deployment server couldn't fetch transformer models at runtime due to
restricted network access and permission errors writing to node_modules.
Add a prebuild script to download models during build and document
TRANSFORMERS_CACHE env var for configuring a shared writable cache path.
2026-04-02 20:47:10 +02:00