- Add max_total_min to RecipeRequest schema and TypeScript interface
- Add _within_time() helper to recipe_engine using parse_time_effort()
with graceful degradation (empty directions or no signals -> pass)
- Wire max_total_min filter into suggest() loop after max_time_min
- Add time_first_layout to allowed settings keys
- Add timeFirstLayout ref to settings store (preserves sensoryPreferences)
- Add maxTotalMin ref to recipes store, wired into _buildRequest()
- Add time bucket selector UI (15/30/45/60/90 min) in RecipesView
Find tab, gated by timeFirstLayout != 'normal'
- Add time-first layout selector section in SettingsView
- Add 5 _within_time unit tests and 2 settings key tests
Shopping links previously hardcoded to US storefronts. Users in other regions
got broken Amazon Fresh and Instacart links. Now locale is stored as a user
setting and passed to GroceryLinkBuilder at request time.
- locale_config.py: per-locale Amazon domain/dept config (already existed)
- grocery_links.py: GroceryLinkBuilder accepts locale=; routes Instacart to .ca
for Canada, uses amazon_domain per locale, Instacart/Walmart US/CA only
- settings.py: adds 'shopping_locale' to allowed settings keys
- shopping.py: reads locale from user's stored setting on all list/add/update paths
- SettingsView.vue: Shopping Region selector (NA, Europe, APAC, LATAM)
- stores/settings.ts: shoppingLocale reactive state, saves via settings API
- Settings: add unit_system key (metric | imperial, default metric)
- Recipe LLM prompts: inject unit instruction into L3 and L4 prompts
so generated recipes use the user's preferred units throughout
- Frontend: new utils/units.ts converter (mirrors Python units.py)
- Inventory list: display quantities converted to preferred units
- Settings view: metric/imperial toggle with save button
- Settings store: load/save unit_system alongside cooking_equipment
Closes#81