Commit Graph

940 Commits

Author SHA1 Message Date
Alexander 0ef8ee38c5 feat(fitness): classify exercises by type and redesign filter UI
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.
2026-04-13 08:59:12 +02:00
Alexander 4692bf9bf7 feat(recipes): redesign cake-form and baking info with collapsible card pattern
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.
2026-04-12 21:46:51 +02:00
Alexander f108e9ceaa feat: align recipe edit page with viewer design
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.
2026-04-12 21:22:53 +02:00
Alexander 69c2e05462 feat: add tactile haptic feedback to rosary prayer cards
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).
2026-04-12 20:15:40 +02:00
Alexander cfd1d953fb fix: adjust LinksGrid nth-child offsets for earlier, more frequent color pops
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).
2026-04-11 21:34:23 +02:00
Alexander a8f07ad800 feat: add chat.bocken.org link to homepage links grid 2026-04-11 19:39:32 +02:00
Alexander db1cd76bb6 feat: add hold timer for timed exercises with full sync support
- 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
2026-04-11 17:40:58 +02:00
Alexander c80827b41e fix: add 15 stretching exercises to exercise database
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.
2026-04-11 16:14:34 +02:00
Alexander 1434580c3f feat: record cadence from step detector during GPS workouts
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.
2026-04-11 15:28:27 +02:00
Alexander 4ae3793c06 feat: add elevation chart and gain/loss stats to GPS workout detail 2026-04-11 15:17:34 +02:00
Alexander 079e14c605 feat: add template library for browsing and adding defaults
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)
2026-04-11 15:02:58 +02:00
Alexander 9f5263a0a5 feat: add Day 6 stretching template to seed defaults
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.
2026-04-11 13:17:05 +02:00
Alexander b895088ad8 feat: project exercise kcal from next scheduled template
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.
2026-04-11 13:11:32 +02:00
Alexander d4af6ff5ff fix: increase shopping icon sizes for better visibility
List icons: 44→56px desktop, 36→48px mobile.
Icon picker modal: 42→56px grid cells.
2026-04-11 10:19:17 +02:00
Alexander 45c6be21a1 fix: sync runtime shopping catalog with source catalog
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.
2026-04-11 10:14:32 +02:00
Alexander 5a7da0b513 fix: correct ~100 misassigned shopping icon categories
The embedding model assigned many items to wrong categories
(e.g. rum→Milchprodukte, zahnbürsten→Fleisch, pflaumen→Hygiene).
Manually reviewed and corrected all 419 entries.
2026-04-11 09:39:31 +02:00
Alexander f732f897e0 feat: add 11 new shopping icons and processing script
Add processed icons for glasnudeln, grünkohl, kokosnuss, lychee,
mangold, pak choi, pastinaken, reisnudeln, rettich, stroh 80, and
topinambur. Add ImageMagick script to remove Gemini watermark and
black background from raw icons. Update catalog and re-embed.
2026-04-11 09:33:09 +02:00
Alexander 9aa8d87cb7 fix: make macro progress bar labels concise with goal context
Show remaining as "10/150g left" and over as "10g over 150g".
Remove redundant per-day goal from label. Shorten "remaining" to "left".
2026-04-11 08:44:26 +02:00
Alexander 1c313c8db0 fix: make custom meal logging reactive by updating entries locally
logCustomMeal and inlineLogCustomMeal relied on goto() to re-run the
page load function, but SvelteKit skips it when the URL doesn't change.
Now they update the entries array directly like the other log functions.
2026-04-11 08:43:50 +02:00
Alexander 6a701bd51e fix: use Atwater calories for consistent macro/calorie tracking
Calorie ring and macro progress bars now both use Atwater-derived
calories (P×4 + F×9 + C×4) instead of DB calories, so hitting all
three macro goals guarantees hitting the calorie goal exactly.

Also: show full daily TDEE (not time-based), show BMR/NEAT multiplier
breakdown in info tooltip, display macro goal grams on progress bars,
fix TDEE tooltip z-index on desktop.
2026-04-10 21:22:24 +02:00
Alexander ae4b664ac1 feat: restyle recipe info cards with grid layout and lucide icons
Align recipe metadata cards with site-wide design language using
surface colors, borders, and rounded corners. Add distinct lucide
icons per card type (Timer, Wheat, Croissant, Flame, CookingPot,
UtensilsCrossed) and switch from flex-wrap to CSS grid for uniform
card widths.
2026-04-10 20:55:48 +02:00
Alexander 212f35f4fc feat: path-based month URLs for workout history with month navigation
Add ?month=YYYY-MM filter to sessions API. Migrate history page to
/fitness/history/[[month]] optional param route. Default view shows last
2 months; specific month view via /fitness/history/2026-04. Replace
load-more button with prev/next month anchor navigation.
2026-04-10 08:57:13 +02:00
Alexander 768c09eeb1 feat: use path-based date URLs for nutrition page
Migrate /fitness/nutrition?date=YYYY-MM-DD to /fitness/nutrition/YYYY-MM-DD
using SvelteKit optional param [[date=fitnessDate]]. Replace date nav
buttons with anchor tags for native browser navigation. Today resolves to
the clean /fitness/nutrition path without a date segment.
2026-04-10 08:47:48 +02:00
Alexander 636f02d110 feat: replace all native date inputs with custom DatePicker component
Add theme-aware DatePicker with pill display, calendar dropdown, prev/next
day arrows, bilingual month/weekday names, and min/max support. Replace all
15 native <input type="date"> elements across fitness, tasks, and cospend.
2026-04-10 08:36:33 +02:00
Alexander 624e4649bb feat: inline measurement form on /fitness/measure, remove /add route
Move weight hero card, body fat and body parts accordions directly
onto the main measure page. SaveFab only appears when a field has
been changed. After saving, form resets and history updates in place.
Fix response unwrapping (created.measurement) that caused Invalid Date.
2026-04-10 08:22:23 +02:00
Alexander 728417c001 feat: redesign measurement add page with weight-focused layout
Replace flat form with hero weight card (±0.1 stepper, last-weight
placeholder, clear button) and collapsible accordion sections for
body fat and body part measurements. Body parts grouped by region.
2026-04-10 08:12:18 +02:00
Alexander 07fefb1bde fix: compute macro targets dynamically from protein goal and body weight
Fat/carb percentages were stored as absolute values that didn't account
for protein g/kg varying with body weight. Now protein calories are
computed first, and remaining calories are split between fat and carbs
by their stored ratio — guaranteeing all macros sum to the calorie goal.

Exercise burned calories also flow into fat/carb targets via a new
effectiveCalorieGoal derived. Goal editor ring preview and labels
updated to show computed actual percentages.
2026-04-10 08:01:08 +02:00
Alexander 208c630bca fix: include exercise calories in diet adherence calculation
Adherence was comparing intake against the flat calorie goal, ignoring
burned workout calories. Now the per-day target is goal + exercise kcal.
Also expanded workout query from 7 to 30 days to cover the full
adherence window.
2026-04-10 07:53:19 +02:00
Alexander a8b1c1d858 fix: correct week count in period tracker relative dates
Math.floor(days/7) was off by one — e.g. 12 days away showed "in 1 week"
instead of "in 2 weeks". Using Math.ceil matches colloquial usage.
2026-04-09 23:51:07 +02:00
Alexander 1cdcf845d2 fix: show round-off suggestions on future days, not just today
Allow meal prep planning by relaxing the isToday check to isTodayOrFuture
in both SSR and client-side rendering of the round-off card.
2026-04-09 23:51:00 +02:00
Alexander c3e829d3ca feat: SSR shopping list by fetching initial data server-side
Server load now fetches the shopping list from the DB and passes it as
initialList. The sync layer seeds state immediately in the script block
(not onMount) so SSR renders the full list. SSE connects client-side
in onMount for real-time updates.
2026-04-09 23:20:12 +02:00
Alexander 6c4367b939 feat: add 7 new shopping icons and deploy hook
Add Gemini-generated icons: aperol, bulgur, emmentaler, magerquark,
quinoa, raeucherlachs, tortilla_wraps. Update catalog with 11 new
entries (including aliases), regenerate embeddings and categories.
Add post-commit hook to rsync shopping icons to bocken.org.
2026-04-09 23:09:09 +02:00
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 32a26f781e fix: compute round-off card visibility server-side to prevent flicker
Server pre-computes initialShowRoundOff from food log totals and goals.
SSR uses this value; client $effect sets hasHydrated=true after mount,
switching to the reactive $derived for live updates.
2026-04-09 21:13:08 +02:00
Alexander d8c472c594 feat: include custom meals in round-off combinatorial food pool
Custom meals are now resolved to per100g nutrition data and added
to the base food pool, allowing them to appear in 1-3 food combo
suggestions alongside pantry items and favorites.
2026-04-09 21:06:31 +02:00
Alexander f3f55f1cae feat: replace P/F/C text labels with Lucide macro icons across fitness routes
Use Beef (protein), Droplet (fat), Wheat (carbs) icons consistently in
ring graphs, macro bars, food cards, detail rows, ingredient lists, and
stats page. Add labelIcon snippet prop to RingGraph/StatsRingGraph. Show
macro split legend always (was hidden on mobile) and group it with the
title in horizontal layout.
2026-04-09 21:00:46 +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 1b7eb4eb44 fix: use --color-text-on-primary for all primary button text
Replace hardcoded white/#fff text on --color-primary buttons with
var(--color-text-on-primary) for proper theme contrast across:
- nutrition meals page (create btn + modal buttons)
- history detail page (save btn + start workout btn)
- recipe page (active filter chips)
- nutrition quick-log confirm button
2026-04-08 21:44:36 +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 1f20601103 feat: add Today quick-navigate button to nutrition and period tracker
Shows a Today button when not viewing current date/month. Nutrition
page button appears right-aligned in the date nav. Period tracker
button appears top-right of the calendar header with centered
month title and chevrons.
2026-04-08 20:46:58 +02:00
Alexander d8ae18ec5a fix: SSR improvements for nutrition desktop layout
Move favorites and recent foods fetching to server load (parallel with
existing queries). Replace client-side $effect DOM manipulation for
fitness-content max-width with reactive CSS variable in layout via
route detection. Removes client-side fetch-on-mount pattern.
2026-04-08 20:42:46 +02:00
Alexander 7be5161757 feat: add favorite toggle to food detail page
Heart button in food header to add/remove favorites via the
existing favorite-ingredients API. Checks status on load, toggles
optimistically with error handling.
2026-04-08 20:38:18 +02:00