{
"app": {
"name": "EverShelf",
"loading": "Loading..."
},
"nav": {
"title": "EverShelf",
"home": "Home",
"inventory": "Pantry",
"recipes": "Recipes",
"shopping": "Shopping",
"log": "Log",
"settings": "Settings"
},
"btn": {
"back": "β Back",
"save": "πΎ Save",
"cancel": "β Cancel",
"close": "Close",
"add": "β
Add",
"delete": "Delete",
"edit": "βοΈ Edit",
"use": "Use",
"edit_item": "Edit",
"search": "π Search",
"go": "β
Go",
"toggle_password": "ποΈ Show/Hide",
"load_more": "Load more...",
"save_config": "πΎ Save Configuration",
"save_product": "πΎ Save Product",
"restart": "βΊ Restart",
"reset_default": "βΊ Reset to default",
"save_info": "πΎ Save information",
"retry": "π Retry",
"yes_short": "Yes",
"no_short": "No"
},
"form": {
"select_placeholder": "-- Select --"
},
"locations": {
"dispensa": "Pantry",
"frigo": "Fridge",
"freezer": "Freezer",
"altro": "Other"
},
"categories": {
"latticini": "Dairy",
"carne": "Meat",
"pesce": "Fish",
"frutta": "Fruit",
"verdura": "Vegetables",
"pasta": "Pasta & Rice",
"pane": "Bread & Bakery",
"surgelati": "Frozen",
"bevande": "Beverages",
"condimenti": "Condiments",
"snack": "Snacks & Sweets",
"conserve": "Canned Goods",
"cereali": "Cereals & Legumes",
"igiene": "Hygiene",
"pulizia": "Household",
"altro": "Other",
"select": "-- Select --"
},
"units": {
"pz": "pcs",
"conf": "pkg",
"g": "g",
"ml": "ml",
"pieces": "Pieces",
"grams": "Grams",
"box": "Package",
"boxes": "Packages",
"millilitres": "Millilitres",
"from": "of"
},
"shopping_sections": {
"frutta_verdura": "Fruits & Vegetables",
"carne_pesce": "Meat & Fish",
"latticini": "Dairy & Fresh",
"pane_dolci": "Bread & Sweets",
"pasta": "Pasta & Cereals",
"conserve": "Canned & Sauces",
"surgelati": "Frozen",
"bevande": "Beverages",
"pulizia_igiene": "Cleaning & Hygiene",
"altro": "Other"
},
"dashboard": {
"expired_title": "π« Expired",
"expiring_title": "β° Expiring Soon",
"stats_period": "π Last 30 days",
"opened_title": "π¦ Opened Products",
"review_title": "π To Review",
"review_hint": "Quantities that seem unusual. Confirm if correct or modify.",
"quick_recipe": "Quick recipe with expiring products",
"banner_review_title": "Anomalous quantity",
"banner_review_action_ok": "It's correct",
"banner_review_action_finish": "ποΈ All gone",
"banner_review_action_edit": "Correct",
"banner_review_action_weigh": "Weigh",
"banner_review_dismiss": "Dismiss",
"banner_prediction_title": "Consumption to review",
"banner_prediction_hint": "The consumption estimate adapts to recent data: confirm only if the current quantity is correct.",
"banner_prediction_action_confirm": "Confirm {qty} {unit}",
"banner_prediction_action_weigh": "Weigh now",
"banner_prediction_action_edit": "Update quantity",
"banner_expired_title": "Expired product",
"banner_expired_today": "Expired today",
"banner_expired_days": "Expired {days} days ago",
"banner_expired_action_use": "Use anyway",
"banner_expired_action_finished": "I finished it!",
"banner_expired_action_throw": "I threw it away",
"banner_expired_action_edit": "Fix date",
"banner_expired_action_modify": "Edit",
"banner_expired_action_vacuum": "Put in vacuum seal",
"banner_anomaly_action_edit": "Fix inventory",
"banner_anomaly_action_dismiss": "Quantity is correct",
"banner_no_expiry_title": "Missing expiry: {name}",
"banner_no_expiry_detail": "This product has no expiry date. Would you like to add one, or confirm it doesn't expire?",
"banner_no_expiry_action_set": "Set expiry date",
"banner_no_expiry_action_dismiss": "Doesn't expire β",
"banner_no_expiry_toast_dismissed": "Marked as 'no expiry'",
"banner_expiring_title": "Expiring soon",
"banner_expiring_today": "Expires today!",
"banner_expiring_tomorrow": "Expires tomorrow",
"banner_expiring_days": "Expires in {days} days",
"banner_expiring_action_use": "Use now",
"banner_finished_title": "finished?",
"banner_finished_detail": "I recorded that {name} reached zero stock. Is it really gone, or do you still have some?",
"banner_finished_action_yes": "Yes, it's done",
"banner_finished_action_no": "No, I still have some",
"banner_review_unusual_pkg_title": "Unusual package size",
"banner_review_unusual_pkg_detail": "You set a package of {qty} {unit} β the size seems very large. Check if correct or edit.",
"banner_review_low_qty_title": "Very low quantity",
"banner_review_low_qty_detail": "You only have {qty} in stock β seems very little, could be a typo. Confirm if correct.",
"banner_review_high_qty_title": "Unusually high quantity",
"banner_review_high_qty_detail": "You have {qty} in stock β the figure seems very high. Confirm if correct or edit.",
"banner_prediction_rate_day": "Average ~{n} {unit}/day",
"banner_prediction_rate_week": "Average ~{n} {unit}/week",
"banner_prediction_days_ago": "{n} days ago you restocked",
"banner_prediction_more": "previous estimate: {expected} {unit}{time}; current quantity: {actual} {unit}.",
"banner_prediction_less": "estimate: {expected} {unit}{time}; current quantity: {actual} {unit}. If your usage pace changed, the forecast updates automatically.",
"banner_finished_zero": "Inventory shows zero, but recorded movements suggest it shouldn't be empty.",
"banner_finished_vanished": "This product no longer appears in inventory, but recorded movements suggest it shouldn't be empty.",
"banner_finished_expected": "According to records you should still have {qty} {unit}.",
"banner_finished_check": "Can you check?",
"banner_finished_action_restore": "Restore {qty} {unit}",
"banner_anomaly_phantom_title": "you have more stock than expected",
"banner_anomaly_phantom_detail": "Inventory shows {inv_qty} {unit}, but based on records you should only have {expected_qty} {unit}. Did you add stock without recording it?",
"banner_anomaly_untracked_title": "stock not recorded as an entry",
"banner_anomaly_untracked_detail": "You have {inv_qty} {unit} in inventory, but recorded outflows exceed inflows β the initial stock was likely never added as an \"in\" transaction. You can correct the quantity or log the missing entries.",
"banner_anomaly_ghost_title": "you have less stock than expected",
"banner_anomaly_ghost_detail": "Based on recorded operations you should have {expected_qty} {unit} of {name}, but inventory shows only {inv_qty} {unit}. Did you take stock without recording it?",
"banner_dup_loss_title": "Double-consume check: {name}",
"banner_dup_loss_detail": "Possible duplicate entry in {location}: two close out events ({qty_pair}) in ~{seconds}s. Please verify and fix if needed.",
"banner_dup_loss_action_fix": "Fix quantity",
"banner_dup_loss_action_open": "Open product card",
"banner_dup_loss_action_done": "Already checked",
"banner_dup_loss_toast_done": "Check marked as reviewed",
"consumed": "Consumed: {n} ({pct}%)",
"wasted": "Wasted: {n} ({pct}%)",
"more_opened": "and {n} more opened...",
"banner_expired_detail": "{when} Β· you still have {qty}.",
"banner_opened_detail": "{when} in {location} Β· you still have {qty}.",
"banner_explain_title": "Ask Gemini for an explanation",
"banner_explain_btn": "Explain",
"banner_analyzing": "π€ Analyzingβ¦",
"banner_prediction_confirmed": "β
Confirmed β forecasts will recalculate from your next entries",
"banner_anomaly_explain_fail": "Could not get AI explanation",
"banner_anomaly_dismissed": "Anomaly dismissed",
"banner_finished_restore_prompt": "How many {unit} of {name} do you still have? (system estimate: {qty})"
},
"inventory": {
"title": "Pantry",
"filter_all": "All",
"search_placeholder": "π Search product...",
"recent_title": "π Recently used",
"popular_title": "β Most used",
"empty": "No products here.\nScan a product to add it!",
"no_items_found": "No inventory items found",
"qty_remainder_suffix": "left",
"vacuum_badge": "π« Vacuum sealed",
"opened_badge": "π Opened",
"label_expiry": "π
Expiry",
"label_storage": "π« Storage",
"label_status": "π Status",
"opened_since": "Opened since {date}",
"label_position": "π Location",
"label_quantity": "π¦ Quantity",
"label_added": "π
Added",
"empty_text": "No products here.
Scan a product to add it!",
"empty_db": "No products in the database.
Scan a product to get started!",
"qty_trace": "< 1"
},
"scan": {
"title": "Scan",
"mode_shopping": "π Shopping Mode",
"mode_shopping_end": "β
End shopping",
"spesa_btn": "π Shopping",
"zoom": "Zoom",
"tab_barcode": "Barcode",
"tab_name": "Name",
"tab_ai": "AI",
"recents_label": "Recent",
"torch_hint": "Torch",
"torch_on": "Torch on",
"torch_off": "Torch off",
"torch_unavailable": "Torch not available on this device",
"flip_hint": "Flip camera",
"flip_front": "Front camera",
"flip_back": "Rear camera",
"num_ocr_btn": "π’ Read numbers with AI",
"num_ocr_searching": "Looking for barcode with AI...",
"num_ocr_found": "Code found: {code}",
"num_ocr_not_found": "No barcode found in image",
"barcode_placeholder": "Enter barcode...",
"quick_name_divider": "or type the name",
"quick_name_placeholder": "E.g.: Apples, Zucchini, Bread...",
"manual_entry": "βοΈ Manual Entry",
"ai_identify": "π€ Identify with AI",
"hint": "Scan the barcode, type the product name, or use AI to identify it",
"debug_toggle": "π Debug Log",
"barcode_acquired": "π Barcode scanned: {code}",
"scan_barcode": "π Scan Barcode",
"create_named": "Create {name}",
"new_without_barcode": "New product without barcode",
"stock_in_pantry": "Already in pantry:",
"status_ready": "Point camera at barcode",
"status_scanning": "Scanning...",
"status_partial": "Detected: {code} β verifying...",
"status_invalid": "Invalid: {code} β retrying",
"status_confirmed": "Confirmed!",
"status_parallel": "Using combined scan methods...",
"status_ocr_searching": "Reading the barcode digits...",
"status_ai_visual_searching": "Now trying to recognize the product...",
"method_ai_ocr": "Gemini OCR",
"method_ai_vision": "Gemini Vision",
"ai_fallback_searching": "AI identifying product...",
"ai_fallback_found": "Product identified by AI",
"ai_fallback_not_found": "AI: product not recognized",
"ai_fallback_exhausted": "AI: product not recognized β try scanning the barcode",
"ai_overlay_msg": "Gemini Vision is analyzing the product...",
"ai_retry_btn": "Retry with AI",
"ai_match_title": "Product recognized by AI",
"ai_match_subtitle": "Choose an existing pantry item or add the detected one.",
"ai_match_existing": "Possible pantry matches",
"ai_match_none": "No similar pantry products found.",
"ai_match_use_btn": "Use this",
"ai_match_add_btn": "Add \"{name}\"",
"ai_detected_label": "AI detected",
"mode_shopping_activated": "π Shopping mode activated!"
},
"action": {
"title": "What do you want to do?",
"add_btn": "π₯ ADD",
"add_sub": "to pantry/fridge",
"use_btn": "USE",
"use_sub": "from pantry/fridge",
"have_title": "π¦ Already in stock!",
"add_more_sub": "add more",
"use_qty_sub": "how much you used",
"throw_btn": "ποΈ DISCARD",
"throw_sub": "throw away",
"edit_sub": "expiry, locationβ¦",
"create_recipe_btn": "Recipe",
"related_stock_title": "Also at home"
},
"add": {
"title": "Add to Pantry",
"location_label": "π Where do you put it?",
"quantity_label": "π¦ Quantity",
"conf_size_label": "π¦ Each package contains:",
"conf_size_placeholder": "e.g. 300",
"vacuum_label": "π« Vacuum sealed",
"vacuum_hint": "Expiry date will be extended automatically",
"submit": "β
Add",
"purchase_type_label": "π This product is...",
"new_btn": "π Just bought",
"existing_btn": "π¦ I already had it",
"remaining_label": "π¦ Remaining quantity",
"remaining_hint": "Approximately how much is left?",
"remaining_full": "π’ Full",
"remaining_half": "π Half",
"estimated_expiry": "Estimated expiry:",
"suffix_freezer": "(freezer)",
"suffix_vacuum": "(vacuum sealed)",
"hint_modify": "π You can change the date or scan it with the camera",
"scan_expiry_title": "π· Scan Expiry Date",
"product_added": "β
{name} added!{qty}",
"suffix_freezer_vacuum": "(freezer + vacuum sealed)",
"history_badge_tip": "Average from {n} previous entries",
"vacuum_question": "Vacuum sealed?",
"vacuum_saved": "π Vacuum sealed!"
},
"use": {
"title": "Use / Consume",
"location_label": "π From where?",
"quantity_label": "How much did you use?",
"change": "change",
"partial_hint": "Or specify the quantity used:",
"partial_piece_hint": "Did you use only a part?",
"piece": "piece",
"one_whole": "1 whole",
"use_all": "ποΈ Used ALL / Finished",
"submit": "π€ Use this quantity",
"available": "π¦ Available:",
"opened_badge": "OPENED",
"not_in_inventory": "β οΈ Product not in inventory.",
"expiry_warning": "β οΈ Use first the one{loc} that expires on {date} β {when}!",
"expiry_warning_opened": "β οΈ The one{loc} has been open for {when} β use it first!",
"throw_title": "ποΈ Discard Product",
"throw_all": "ποΈ Discard ALL ({qty})",
"throw_qty_label": "How much to discard?",
"throw_qty_hint": "or enter a quantity:",
"throw_partial_btn": "ποΈ Discard this quantity",
"when_expired": "expired {n} days ago",
"when_today": "expires today",
"when_tomorrow": "expires tomorrow",
"when_days": "expires in {n} days",
"toast_used": "π€ Used {qty} of {name}",
"toast_bring": "π Product finished β added to Bring!",
"toast_opened_finished": "π Opened package of {name} finished!",
"disambiguation_hint": "What do you mean by \"all done\"?",
"disambiguation_one_conf": "Finished 1 package ({qty})",
"disambiguation_all": "ποΈ Finish EVERYTHING ({qty})",
"toast_one_conf_finished": "π¦ 1 package of {name} finished!",
"error_exceeds_stock": "β οΈ You cannot use more than you have available!",
"use_all_confirm_title": "β
Finish everything",
"use_all_confirm_msg": "Confirm that you have finished the product:",
"use_all_confirm_btn": "β
Yes, finished",
"throw_all_confirm_title": "ποΈ Discard everything",
"throw_all_confirm_msg": "Do you really want to throw away the whole product?",
"throw_all_confirm_btn": "ποΈ Yes, discard",
"locations_short": "places"
},
"product": {
"title_new": "New Product",
"title_edit": "Edit Product",
"ai_fill": "π· Take photo and identify with AI",
"ai_fill_hint": "AI will automatically fill in the product fields",
"name_label": "π·οΈ Product Name *",
"name_placeholder": "E.g.: Whole milk, Penne pasta...",
"brand_label": "π’ Brand",
"brand_placeholder": "E.g.: Barilla, Granarolo, Mutti...",
"category_label": "π Category",
"unit_label": "π Unit of measure",
"default_qty_label": "π’ Default quantity",
"conf_size_label": "π¦ Each package contains:",
"conf_size_placeholder": "e.g. 300",
"notes_label": "π Notes",
"notes_placeholder": "E.g.: lactose free, organic, store in fridge after opening...",
"barcode_label": "π Barcode",
"barcode_placeholder": "Barcode (if available)",
"barcode_hint": "β οΈ Add the barcode so next time you just need to scan it!",
"submit": "πΎ Save Product",
"name_required": "Enter the product name",
"conf_size_required": "Specify the package content",
"expiry_estimated": "Estimated expiry:",
"scan_expiry": "Scan expiry date",
"expiry_hint": "π You can edit the date or scan it with the camera",
"add_batch": "π¦ + Batch with different expiry",
"package_info": "π¦ Package: {info}",
"edit_catalog": "βοΈ Edit product info (name, brand, categoryβ¦)",
"not_recognized": "β οΈ Product not recognized",
"edit_info": "βοΈ Edit information",
"modify_details": "EDIT\nexpiry, locationβ¦",
"already_in_pantry": "π Already in pantry",
"no_barcode": "No barcode",
"unknown_product": "Unrecognized product",
"edit_name_brand": "Edit name/brand",
"weight_label": "Weight",
"origin_label": "Origin",
"labels_label": "Labels",
"select_variant": "Select the exact variant or use AI data:",
"history_badge": "π history",
"from_history": " (from history)"
},
"products": {
"title": "π¦ All Products",
"search_placeholder": "π Search product...",
"empty": "No products in database.\nScan a product to get started!",
"no_category": "No products in this category"
},
"recipes": {
"title": "π³ Recipes",
"generate": "β¨ Generate new recipe",
"archive_empty": "No recipes saved. Generate your first recipe!",
"dialog_title": "π³ Recipe",
"dialog_desc": "I will generate a healthy recipe using pantry ingredients, prioritizing expiring items.",
"meal_label": "π Which meal?",
"persons_label": "π₯ How many people?",
"meal_type_label": "π― Meal type",
"opt_fast": "β‘ Quick meal",
"opt_light": "π₯ Light appetite",
"opt_expiry": "β° Prioritize expiring items",
"opt_healthy": "π Extra healthy",
"opt_opened": "π¦ Prioritize opened items",
"opt_zero_waste": "β»οΈ Zero waste",
"generate_btn": "β¨ Generate Recipe",
"loading_msg": "Preparing your recipe...",
"start_cooking": "π¨βπ³ Cooking Mode",
"regenerate": "π Generate another one",
"regen_choice_title": "What do you want to do with this recipe?",
"regen_replace": "π Generate another (discard this one)",
"regen_save_new": "πΎ Save to archive & generate a new one",
"close_btn": "β
Close",
"ingredients_title": "π§Ύ Ingredients",
"tools_title": "Equipment needed",
"steps_title": "π¨βπ³ Steps",
"no_steps": "No steps available",
"generate_error": "Generation error",
"stream_interrupted": "Generation interrupted (incomplete server response). Check logs or try again.",
"persons_short": "serv.",
"use_ingredient_title": "Use ingredient",
"recipe_qty_label": "Recipe",
"from_where_label": "From where?",
"amount_label": "How much",
"use_amount_btn": "Use this amount",
"use_all_btn": "Use ALL / Finished",
"packs_label": "Packs",
"quantity_in_total": "Quantity in {unit} (total: {total})",
"packs_of_have": "Packs of {size} (you have {count} packs)",
"scale_wait_stable": "Wait 10s of stable weight for auto-fillβ¦",
"ingredient_scaled_toast": "π¦ Ingredient deducted from pantry!",
"finished_added_bring_toast": "π Finished product β added to Bring!",
"load_error": "Loading error",
"favorite": "Add to favourites",
"unfavorite": "Remove from favourites",
"adjust_persons": "Persons",
"nutrition_title": "Nutritional values (per serving)",
"nutrition_kcal": "Calories",
"nutrition_protein": "Protein",
"nutrition_carbs": "Carbs",
"nutrition_fat": "Fat",
"nutrition_per_serving": "Estimated values per serving",
"storage_title": "How to store leftovers",
"storage_days": "{n} days",
"storage_immediately": "Best eaten immediately",
"ing_stock_line": "You have {have} Β· {remain} left after use",
"ing_use_all_note": "use all (<5% of full package left)"
},
"shopping": {
"title": "π Shopping List",
"bring_loading": "Connecting to Bring!...",
"bring_not_configured": "Bring! is not configured. Add your email and password in settings.",
"tab_to_buy": "ποΈ To buy",
"tab_forecast": "π§ Forecast",
"total_label": "π° Estimated total",
"section_to_buy": "ποΈ To buy",
"suggestions_title": "π‘ AI Suggestions",
"suggestions_add": "β
Add selected to Bring!",
"search_prices": "π Search all prices",
"suggest_btn": "Suggest what to buy",
"smart_title": "π§ Smart Predictions",
"smart_empty": "No predictions available.
Add products to your pantry to receive smart predictions.",
"smart_filter_all": "All",
"smart_filter_critical": "π΄ Urgent",
"smart_filter_high": "π Soon",
"smart_filter_medium": "π‘ Plan",
"smart_filter_low": "π’ Forecast",
"smart_add": "π Add selected to Bring!",
"empty": "Shopping list empty!\nUse the button below to generate suggestions.",
"already_in_list": "π \"{name}\" is already in the shopping list",
"already_in_list_short": "βΉοΈ Already in the shopping list",
"add_prompt": "Do you want to add it to the shopping list?",
"smart_already": "π Smart shopping already predicts {name}",
"all_searched": "All products have already been searched. Use π to search individual ones.",
"search_complete": "Search complete: {count} products",
"removed_sufficient": "π§Ή {removed} product(s) with sufficient stock removed from the list",
"suggest_buy": "π Buy: {qty} {unit}",
"suggest_buy_approx": "π At least: {qty} {unit}",
"suggest_buy_tip": "Suggested quantity based on your last 14 days of consumption",
"suggest_buy_approx_tip": "Minimum estimate based on consumption (buy the nearest package size)",
"bring_badge": "π Already on Bring!",
"add_urgent_toast": "π΄ {n} urgent product(s) automatically added to Bring!",
"migration_done": "β
{migrated} updated, {skipped} already ok",
"added_to_bring": "π {n} products added to Bring!",
"added_to_bring_skip": "{n} already present",
"all_on_bring": "All products were already on Bring!",
"freq_high": "π Frequent",
"freq_regular": "π Regular",
"freq_occasional": "π Occasional",
"out_of_stock": "Out of stock",
"scan_toast": "π· Scan: {name}",
"empty_category": "No products in this category",
"session_empty": "π No products yet",
"urgency_critical": "Urgent",
"urgency_high": "Soon",
"urgency_medium": "Plan",
"urgency_low": "Forecast",
"urgency_medium_short": "Medium",
"urgency_low_short": "Ok",
"tag_urgent": "π΄ Urgent",
"tag_priority": "β Priority",
"tag_check": "β
Check",
"smart_already_predicted": "π Smart shopping already predicts {name}{urgency}.",
"item_removed": "β
{name} removed from list!",
"urgency_spec_critical": "β‘ Urgent",
"urgency_spec_high": "π Soon",
"bring_add_n": "Add {n} to Bring!",
"bring_add_selected": "Add selected to Bring!",
"bring_adding": "Adding...",
"bring_added_one": "1 product added to Bring!",
"bring_added_many": "{n} products added to Bring!",
"bring_skipped": "({n} already in list)",
"force_sync": "Force Bring! sync",
"scan_target_label": "You are looking for",
"scan_target_found": "Found! Remove from list",
"bring_add_one": "Add 1 product to Bring!",
"bring_add_many": "Add {n} products to Bring!",
"syncing": "Syncingβ¦",
"sync_done": "Sync completed",
"price_searching": "Searching...",
"search_action": "Search",
"open_action": "Open",
"not_found": "Not found",
"search_price": "Search price",
"tap_to_scan": "Tap to scan",
"tag_title": "Tag",
"remove_title": "Remove",
"found_count": "{found}/{total} products found",
"savings_offers": "Β· π·οΈ You save β¬{amount} with offers",
"searching_progress": "Searching {current}/{total}...",
"remove_error": "Removal error",
"btn_fetch_prices": "Find prices",
"price_total_label": "π° Estimated total:",
"price_total_short": "estimated total",
"price_loading": "Looking up pricesβ¦",
"price_not_found": "price n/a",
"suggest_loading": "Analyzing...",
"suggest_error": "Suggestion generation error",
"priority_high": "High",
"priority_medium": "Medium",
"priority_low": "Low",
"smart_last_update": "Updated {time}",
"names_already_updated": "All names are already up to date",
"pantry_hint": "Already at home: {qty}",
"bring_names_migrated": "π {n} names generalized in Bring!"
},
"ai": {
"title": "π€ AI Identification",
"capture": "πΈ Take Photo",
"retake": "π Retake",
"hint": "Take a photo of the product and AI will try to identify it",
"identifying": "π€ Identifying product...",
"no_api_key": "β οΈ Gemini API key not configured.\nAdd GEMINI_API_KEY to the .env file on the server.",
"fields_filled": "β
Fields filled by AI",
"use_data": "β
Use AI data",
"use_data_no_barcode": "β
Use AI data (no barcode)",
"conservation_hint": "π€ AI: store in {location}"
},
"log": {
"title": "π Operations Log",
"type_added": "Added",
"type_waste": "Discarded",
"type_used": "Used",
"type_bring": "Added to Bring!",
"undone_badge": "Undone",
"undo_title": "Undo this operation",
"load_error": "Error loading log",
"empty": "No operations recorded.",
"undo_action_remove": "removal of",
"undo_action_restore": "restock of",
"undo_confirm": "Undo this operation?\nβ {action} {name}",
"undo_success": "β© Operation undone for {name}",
"already_undone": "Operation already undone",
"too_old": "Cannot undo operations older than 24 hours",
"undo_error": "Error during undo",
"recipe_prefix": "Recipe"
},
"chat": {
"title": "Gemini Chef",
"welcome": "Hi! I'm your kitchen assistant",
"welcome_desc": "Ask me to make you a juice, a snack, a quick dish... I know your pantry, your appliances and your preferences!",
"suggestion_snack": "πΏ Quick snack",
"suggestion_juice": "π₯€ Juice/Smoothie",
"suggestion_light": "π₯ Something light",
"suggestion_expiry": "β° Use expiring items",
"clear": "New conversation",
"placeholder": "Ask something...",
"cleared": "Chat cleared",
"suggestion_snack_text": "What can I make for a quick snack?",
"suggestion_juice_text": "Make me a juice or smoothie with what I have",
"suggestion_light_text": "I'm hungry but want something light",
"suggestion_expiry_text": "What's about to expire and how can I use it?",
"transfer_to_recipes": "Transfer to Recipes",
"transferring": "Transferring...",
"transferred": "Added to Recipes!",
"open_recipe": "Open recipe",
"quick_recipe_prompt": "Suggest a quick recipe FOR ONE PERSON using the products that expire first! Ignore freezer items, focus on fridge and pantry."
},
"cooking": {
"close": "Close",
"tts_btn": "Read aloud",
"restart": "βΊ Restart",
"replay": "π Replay",
"timer": "β±οΈ {time} Β· Timer",
"prev": "β Previous",
"next": "Next βΆ",
"ingredient_used": "βοΈ Deducted",
"ingredient_use_btn": "Use",
"ingredient_deduct_title": "Deduct from pantry",
"timer_expired_tts": "Timer {label} expired!",
"timer_warning_tts": "Heads up! {label}: 10 seconds left!",
"recipe_done_tts": "Recipe complete! Enjoy your meal!",
"expires_chip": "exp. {date}",
"finish": "β
Finish",
"step_fallback": "Step {n}",
"zerowaste_label": "β»οΈ Scrap",
"zerowaste_tip_title": "Zero-waste tip"
},
"settings": {
"title": "βοΈ Settings",
"tab_api": "API Keys",
"tab_bring": "Bring!",
"tab_recipe": "Recipes",
"tab_mealplan": "Weekly Plan",
"tab_appliances": "Appliances",
"tab_spesa": "Online Shopping",
"tab_camera": "Camera",
"tab_security": "Security",
"tab_tts": "Voice (TTS)",
"tab_language": "Language",
"tab_scale": "Smart Scale",
"gemini": {
"title": "π€ Google Gemini AI",
"hint": "API key for product identification, expiry dates and recipes.",
"key_label": "Gemini API Key"
},
"bring": {
"title": "π Bring! Shopping List",
"hint": "Credentials for the Bring! shopping list integration.",
"email_label": "π§ Bring! Email",
"password_label": "π Bring! Password"
},
"price": {
"title": "π° Price Estimation (AI)",
"hint": "Show estimated cost per product in the shopping list using AI.",
"enabled_label": "Enable price estimation",
"country_label": "π Reference country",
"currency_label": "π± Currency",
"update_label": "π Refresh prices every",
"update_suffix": "months"
},
"recipe": {
"title": "π³ Recipe Preferences",
"hint": "Configure the default options for recipe generation.",
"persons_label": "π₯ Default servings",
"options_label": "π― Default recipe options",
"fast": "β‘ Quick Meal",
"light": "π₯ Light Meal",
"expiry": "β° Expiry Priority",
"healthy": "π Extra Healthy",
"opened": "π¦ Open Items Priority",
"zerowaste": "β»οΈ Zero Waste",
"dietary_label": "π« Intolerances / Restrictions",
"dietary_placeholder": "E.g.: gluten free, lactose free, vegetarian..."
},
"mealplan": {
"title": "π
Weekly Meal Plan",
"hint": "Set the meal type for each day. It will be used as a guide in recipe generation.",
"enabled": "β
Enable weekly meal plan",
"legend": "π€οΈ = Lunch Β· π = Dinner Β· Tap a badge to change it.",
"types_title": "π Available types",
"reset_btn": "βΊ Restore defaults"
},
"appliances": {
"title": "π Available Appliances",
"hint": "Indicate the appliances you have. They will be considered in recipe generation.",
"new_placeholder": "E.g.: Bread machine, Thermomix, Air fryer...",
"quick_title": "Quick add:",
"oven": "π₯ Oven",
"microwave": "π‘ Microwave",
"air_fryer": "π Air fryer",
"bread_maker": "π Bread maker",
"bimby": "π€ Thermomix/Cookeo",
"mixer": "π Stand mixer",
"steamer": "β¨οΈ Steamer",
"pressure_cooker": "π« Pressure cooker",
"toaster": "π Toaster",
"blender": "πΉ Blender",
"empty": "No appliances added"
},
"spesa": {
"title": "ποΈ Online Shopping",
"hint": "Configure the online shopping provider.",
"provider_label": "πͺ Provider",
"email_label": "π§ Email",
"password_label": "π Password",
"login_btn": "π Login",
"ai_prompt_label": "π€ AI product selection prompt",
"ai_prompt_placeholder": "Instructions for AI when choosing between multiple products...",
"ai_prompt_hint": "AI uses this prompt to choose the most appropriate product from results. Leave empty for default behavior.",
"configure_first": "Configure Online Shopping in settings first",
"missing_credentials": "Enter email and password",
"login_in_progress": "Signing in...",
"login_error_prefix": "Error:",
"login_network_error_prefix": "Network error:",
"login_success_default": "Login successful!",
"result_name_label": "Name",
"result_card_label": "Card",
"result_pickup_label": "Pickup point",
"result_points_label": "Loyalty points",
"connected_relogin": "β
Connected β Sign in again",
"connected_as": "Connected as {name}"
},
"camera": {
"title": "π· Camera",
"hint": "Choose which camera to use for barcode scanning and AI identification.",
"device_label": "πΈ Default camera",
"back": "π± Rear (default)",
"front": "π€³ Front",
"devices_hint": "If you have multiple cameras, you can select a specific one from the list above after granting permissions.",
"detect_btn": "π Detect cameras",
"ai_fallback_label": "AI visual identification (5s fallback)",
"ai_fallback_hint": "If no barcode is read within 5 seconds, a frame is automatically sent to AI to visually identify the product. Requires Gemini configured."
},
"security": {
"title": "π HTTPS Certificate",
"hint": "If the browser shows the error \"Your connection is not private\" (ERR_CERT_AUTHORITY_INVALID), you need to install the CA certificate on the device.",
"download_btn": "π₯ Download CA Certificate",
"token_title": "π Settings Token",
"token_label": "Access token",
"token_hint": "If `SETTINGS_TOKEN` is configured in the server's `.env`, enter the token here before saving settings. Leave empty if not configured.",
"token_placeholder": "(empty = no protection)",
"token_required_hint": "π This server requires a token to save settings.",
"cert_instructions": "Instructions for Chrome (Android):
1. Download the certificate above
2. Go to Settings → Security & Privacy → More security settings → Install from device storage
3. Select the downloaded EverShelf_CA.crt file
4. Choose \"CA\" and confirm
5. Restart Chrome
Instructions for Chrome (PC):
1. Download the certificate above
2. Go to chrome://settings/certificates (or Settings → Privacy and security → Security → Manage certificates)
3. Tab \"Authorities\" → Import → select the file
4. Check \"Trust this certificate for identifying websites\"
5. Restart Chrome"
},
"tts": {
"title": "π Voice & TTS",
"hint": "Configure text-to-speech via any external REST API. Recipe steps and expired timers will be sent to the configured endpoint.",
"enabled": "β
Enable TTS",
"engine_label": "βοΈ TTS Engine",
"engine_browser": "π Browser (offline, no configuration required)",
"engine_server": "π External server (Home Assistant, REST API...)",
"voice_label": "π£οΈ Voice",
"rate_label": "β‘ Speed",
"pitch_label": "π΅ Pitch",
"url_label": "π Endpoint URL",
"method_label": "π‘ HTTP Method",
"auth_label": "π Authentication",
"auth_bearer": "Bearer Token",
"auth_custom": "Custom Header",
"auth_none": "None",
"token_label": "π Bearer Token",
"custom_header_name": "π Header name",
"custom_header_value": "π Header value",
"content_type_label": "π Content-Type",
"payload_key_label": "ποΈ Text field in payload",
"payload_key_hint": "Name of the JSON field that will contain the text to read (e.g.: message, text).",
"extra_fields_label": "β Extra fields (JSON)",
"extra_fields_placeholder": "{\"entity_id\": \"media_player.living_room\"}",
"extra_fields_hint": "Additional fields to include in the payload, in JSON format. Leave empty if not needed.",
"test_sound_btn": "π Run Sound Test",
"test_btn": "π Send Test Voice",
"voices_loading": "Loading voicesβ¦",
"voice_not_supported": "Voice not supported by this browser",
"voices_none": "No voices available on this device",
"voices_hint": "Available voices depend on the OS and browser. On macOS/iOS the Paola (Italian) voice is available. Press βΊ if the list does not load.",
"url_missing": "β οΈ Endpoint URL missing.",
"test_sending": "β³ Sendingβ¦",
"test_ok": "β
Response {code} β check that the speaker has spoken.",
"heard_question": "Did you hear the voice?",
"heard_yes": "Yes, I heard it",
"heard_no": "No, I didn't hear it",
"test_ok_kiosk": "TTS is working.",
"test_fail_steps": "Check: 1) media volume is not 0; 2) Google Text-to-Speech is installed and updated; 3) Italian voice package is downloaded in Android TTS settings."
},
"language": {
"title": "π Language",
"hint": "Select the interface language.",
"label": "π Language",
"restart_notice": "The page will reload to apply the new language."
},
"screensaver": {
"label": "Enable screensaver",
"card_title": "π Screensaver",
"card_hint": "Shows a clock with useful facts after 5 minutes of inactivity. Disabled by default.",
"timeout_1": "1 minute",
"timeout_2": "2 minutes",
"timeout_5": "5 minutes",
"timeout_10": "10 minutes",
"timeout_15": "15 minutes",
"timeout_30": "30 minutes",
"timeout_60": "1 hour",
"start_after": "β±οΈ Start after"
},
"scale": {
"title": "βοΈ Smart Scale",
"hint": "Connect a Bluetooth scale via the Android gateway to automatically read weight.",
"tab": "Smart Scale",
"enabled": "β
Enable smart scale",
"url_label": "π WebSocket Gateway URL",
"url_placeholder": "ws://192.168.1.x:8765",
"url_hint": "URL shown by the Android app (same Wi-Fi network). E.g.:",
"test_btn": "π Test connection",
"download_btn": "π₯ Download Android Gateway (APK)",
"download_hint": "Android app that bridges your BLE scale and EverShelf.",
"download_sub": "Source: evershelf-scale-gateway/ in the project root",
"live_weight": "real-time weight",
"auto_reconnect": "π Reconnect: automatic",
"kiosk_title": "π‘ BLE Scale integrated in Kiosk",
"kiosk_hint": "The scale is directly managed by the internal BLE Gateway of the kiosk. To pair a new device, use the configuration wizard.",
"kiosk_reconfigure": "π Reconfigure BLE Scale",
"ble_protocols": "
π Supported BLE protocols:
http://localhost/?code=4%2F0A...) and paste it here.",
"gdrive_code_submit": "Submit",
"gdrive_code_empty": "Paste the URL or authorization code first",
"gdrive_redirect_uri_label": "Redirect URI (add this in Google Cloud Console):",
"gdrive_oauth_authorize": "Authorize with Google",
"gdrive_oauth_authorized": "Authorized",
"gdrive_oauth_not_authorized": "Not authorized yet",
"gdrive_oauth_window_opened": "Browser window opened β authorize and come back",
"gdrive_oauth_how_to": "How to set up OAuth 2.0 (step by step)",
"gdrive_oauth_steps": "http://localhost (a connection error is expected): copy the URL from the address bar and paste it in the field that appears below