diff --git a/apps/api/src/routes/onboarding.ts b/apps/api/src/routes/onboarding.ts
new file mode 100644
index 0000000..d593dd5
--- /dev/null
+++ b/apps/api/src/routes/onboarding.ts
@@ -0,0 +1,246 @@
+import type { FastifyInstance } from "fastify";
+import { eq } from "drizzle-orm";
+import { z } from "zod";
+import { schema } from "@app/database";
+import { quickStartInputSchema, onboardingInputSchema } from "@app/validation";
+import { errors, parse } from "../lib/errors.js";
+import { audit, generateInviteCode, getActiveHouseholdId } from "../lib/helpers.js";
+import { KNOWN_FLAGS } from "@app/feature-flags";
+
+/**
+ * Progressive onboarding (FAS 1b): 3-layer flow.
+ * Step A = immediate value (goal + precision mode).
+ * Step B = after first value (diet, allergens, household).
+ * Step C = contextual (health profile, deep preferences).
+ *
+ * Preserves existing /v1/me/onboarding for backward compatibility.
+ */
+export async function onboardingRoutes(app: FastifyInstance) {
+ const auth = { preHandler: [app.authenticate] };
+
+ /** GET /v1/onboarding/status – where is the user in the progressive flow? */
+ app.get("/v1/onboarding/status", auth, async (req) => {
+ const [user] = await app.db
+ .select({
+ onboardingCompleted: schema.users.onboardingCompleted,
+ onboardingStep: schema.users.onboardingStep,
+ })
+ .from(schema.users)
+ .where(eq(schema.users.id, req.userId))
+ .limit(1);
+ if (!user) throw errors.notFound();
+
+ const householdId = await getActiveHouseholdId(app.db, req.userId);
+ const [health] = await app.db
+ .select({ userId: schema.userHealthProfiles.userId })
+ .from(schema.userHealthProfiles)
+ .where(eq(schema.userHealthProfiles.userId, req.userId))
+ .limit(1);
+ const [prefs] = await app.db
+ .select({ userId: schema.userPreferences.userId })
+ .from(schema.userPreferences)
+ .where(eq(schema.userPreferences.userId, req.userId))
+ .limit(1);
+
+ // Feature-flag: progressive onboarding rollout
+ const progressiveEnabled = await app.flags.isEnabled(
+ KNOWN_FLAGS.PROGRESSIVE_ONBOARDING,
+ req.userId,
+ );
+
+ return {
+ step: user.onboardingStep,
+ onboardingCompleted: user.onboardingCompleted,
+ hasHousehold: householdId != null,
+ hasHealthProfile: health != null,
+ hasPreferences: prefs != null,
+ progressiveEnabled,
+ };
+ });
+
+ /** POST /v1/onboarding/quick-start – complete Step A (minimal, immediate value). */
+ app.post("/v1/onboarding/quick-start", auth, async (req) => {
+ const input = parse(quickStartInputSchema, req.body);
+
+ // Upsert minimal preferences
+ await app.db
+ .insert(schema.userPreferences)
+ .values({
+ userId: req.userId,
+ ...(input.primaryGoal ? { primaryGoal: input.primaryGoal } : {}),
+ })
+ .onConflictDoUpdate({
+ target: schema.userPreferences.userId,
+ set: {
+ ...(input.primaryGoal ? { primaryGoal: input.primaryGoal } : {}),
+ updatedAt: new Date(),
+ },
+ });
+
+ // Advance to step B
+ const [user] = await app.db
+ .update(schema.users)
+ .set({
+ precisionMode: input.precisionMode,
+ onboardingStep: "b",
+ updatedAt: new Date(),
+ })
+ .where(eq(schema.users.id, req.userId))
+ .returning();
+
+ await audit(app.db, {
+ actorUserId: req.userId,
+ action: "onboarding.quick_start",
+ metadata: { primaryGoal: input.primaryGoal, precisionMode: input.precisionMode },
+ ip: req.ip,
+ correlationId: req.correlationId,
+ });
+
+ return {
+ ok: true,
+ step: user!.onboardingStep,
+ onboardingCompleted: user!.onboardingCompleted,
+ };
+ });
+
+ /** POST /v1/onboarding/complete-b – complete Step B (diet, allergens, household). */
+ app.post("/v1/onboarding/complete-b", auth, async (req) => {
+ const input = parse(onboardingInputSchema, req.body);
+
+ if (input.preferences) {
+ await app.db
+ .insert(schema.userPreferences)
+ .values({ userId: req.userId, ...input.preferences })
+ .onConflictDoUpdate({
+ target: schema.userPreferences.userId,
+ set: { ...input.preferences, updatedAt: new Date() },
+ });
+ }
+
+ let householdId: string | null = await getActiveHouseholdId(app.db, req.userId);
+ if (input.householdChoice.kind === "create" && !householdId) {
+ const [household] = await app.db
+ .insert(schema.households)
+ .values({ name: input.householdChoice.name, inviteCode: generateInviteCode() })
+ .returning();
+ await app.db.insert(schema.householdMembers).values({
+ householdId: household!.id,
+ userId: req.userId,
+ role: "owner",
+ });
+ await app.db.insert(schema.storageLocations).values([
+ { householdId: household!.id, type: "fridge", name: "Kylen", sortOrder: 0 },
+ { householdId: household!.id, type: "freezer", name: "Frysen", sortOrder: 1 },
+ { householdId: household!.id, type: "pantry", name: "Skafferiet", sortOrder: 2 },
+ ]);
+ householdId = household!.id;
+ } else if (input.householdChoice.kind === "join") {
+ const [household] = await app.db
+ .select()
+ .from(schema.households)
+ .where(eq(schema.households.inviteCode, input.householdChoice.inviteCode.toUpperCase()))
+ .limit(1);
+ if (!household) throw errors.notFound("Ingen hushållsinbjudan matchar koden.");
+ await app.db
+ .insert(schema.householdMembers)
+ .values({ householdId: household.id, userId: req.userId, role: "adult" })
+ .onConflictDoNothing();
+ householdId = household.id;
+ }
+
+ // Advance to step C (or mark completed if no health profile needed)
+ const [user] = await app.db
+ .update(schema.users)
+ .set({
+ precisionMode: input.precisionMode,
+ onboardingStep: "c",
+ updatedAt: new Date(),
+ })
+ .where(eq(schema.users.id, req.userId))
+ .returning();
+
+ await audit(app.db, {
+ actorUserId: req.userId,
+ action: "onboarding.complete_b",
+ metadata: { householdId, hasPreferences: !!input.preferences },
+ ip: req.ip,
+ correlationId: req.correlationId,
+ });
+
+ return { ok: true, step: user!.onboardingStep, householdId };
+ });
+
+ /** POST /v1/onboarding/complete-c – complete Step C (health profile, final). */
+ app.post("/v1/onboarding/complete-c", auth, async (req) => {
+ const input = parse(onboardingInputSchema, req.body);
+
+ if (input.healthProfile) {
+ await app.db
+ .insert(schema.userHealthProfiles)
+ .values({ userId: req.userId, ...input.healthProfile })
+ .onConflictDoUpdate({
+ target: schema.userHealthProfiles.userId,
+ set: { ...input.healthProfile, updatedAt: new Date() },
+ });
+ }
+
+ if (input.preferences) {
+ await app.db
+ .insert(schema.userPreferences)
+ .values({ userId: req.userId, ...input.preferences })
+ .onConflictDoUpdate({
+ target: schema.userPreferences.userId,
+ set: { ...input.preferences, updatedAt: new Date() },
+ });
+ }
+
+ const [user] = await app.db
+ .update(schema.users)
+ .set({
+ precisionMode: input.precisionMode,
+ onboardingStep: "c",
+ onboardingCompleted: true,
+ updatedAt: new Date(),
+ })
+ .where(eq(schema.users.id, req.userId))
+ .returning();
+
+ await audit(app.db, {
+ actorUserId: req.userId,
+ action: "onboarding.complete_c",
+ metadata: { hasHealthProfile: !!input.healthProfile },
+ ip: req.ip,
+ correlationId: req.correlationId,
+ });
+
+ return { ok: true, onboardingCompleted: user!.onboardingCompleted };
+ });
+
+ /** POST /v1/onboarding/skip – skip remaining steps (GDPR-friendly, user's choice). */
+ app.post("/v1/onboarding/skip", auth, async (req) => {
+ const body = parse(
+ z.object({ step: z.enum(["b", "c"]).optional() }),
+ req.body,
+ );
+
+ const [user] = await app.db
+ .update(schema.users)
+ .set({
+ onboardingStep: "c",
+ onboardingCompleted: true,
+ updatedAt: new Date(),
+ })
+ .where(eq(schema.users.id, req.userId))
+ .returning();
+
+ await audit(app.db, {
+ actorUserId: req.userId,
+ action: "onboarding.skipped",
+ metadata: { skippedStep: body.step ?? "all" },
+ ip: req.ip,
+ correlationId: req.correlationId,
+ });
+
+ return { ok: true, onboardingCompleted: user!.onboardingCompleted };
+ });
+}
diff --git a/apps/api/src/server.ts b/apps/api/src/server.ts
index 20ae6ef..535a351 100644
--- a/apps/api/src/server.ts
+++ b/apps/api/src/server.ts
@@ -25,6 +25,7 @@ import { adminAnalyticsRoutes } from "./routes/admin-analytics.js";
import { adminReleaseGateRoutes } from "./routes/admin-release-gates.js";
import { adminWorkersRoutes } from "./routes/admin-workers.js";
import { analyticsRoutes } from "./routes/analytics.js";
+import { onboardingRoutes } from "./routes/onboarding.js";
declare module "fastify" {
interface FastifyInstance {
@@ -88,6 +89,7 @@ export async function buildServer(config: AppConfig) {
await app.register(adminReleaseGateRoutes);
await app.register(adminWorkersRoutes);
await app.register(analyticsRoutes);
+ await app.register(onboardingRoutes);
return app;
}
diff --git a/apps/api/test/onboarding.test.ts b/apps/api/test/onboarding.test.ts
new file mode 100644
index 0000000..34fb144
--- /dev/null
+++ b/apps/api/test/onboarding.test.ts
@@ -0,0 +1,73 @@
+import { describe, expect, it } from "vitest";
+import { quickStartInputSchema, onboardingStatusSchema } from "@app/validation";
+import { parse, ApiError } from "../src/lib/errors.js";
+
+describe("progressive onboarding validering (FAS 1b)", () => {
+ it("quick-start accepterar mål och precision", () => {
+ const result = parse(quickStartInputSchema, {
+ primaryGoal: "lose_weight",
+ precisionMode: "exact",
+ });
+ expect(result.primaryGoal).toBe("lose_weight");
+ expect(result.precisionMode).toBe("exact");
+ });
+
+ it("quick-start är valfri – endast precision får default", () => {
+ const result = parse(quickStartInputSchema, {});
+ expect(result.primaryGoal).toBeUndefined();
+ expect(result.precisionMode).toBe("simple");
+ });
+
+ it("quick-start avvisar ogiltigt mål", () => {
+ expect(() =>
+ parse(quickStartInputSchema, { primaryGoal: "invalid_goal" }),
+ ).toThrowError(ApiError);
+ });
+
+ it("quick-start avvisar ogiltig precision", () => {
+ expect(() =>
+ parse(quickStartInputSchema, { precisionMode: "medium" }),
+ ).toThrowError(ApiError);
+ });
+
+ it("onboarding-status schema validerar korrekt struktur", () => {
+ const valid = {
+ step: "b",
+ onboardingCompleted: false,
+ hasHousehold: true,
+ hasHealthProfile: false,
+ hasPreferences: true,
+ };
+ const result = parse(onboardingStatusSchema, valid);
+ expect(result.step).toBe("b");
+ expect(result.hasHousehold).toBe(true);
+ });
+
+ it("onboarding-status avvisar ogiltig steg", () => {
+ expect(() =>
+ parse(onboardingStatusSchema, {
+ step: "d",
+ onboardingCompleted: false,
+ hasHousehold: false,
+ hasHealthProfile: false,
+ hasPreferences: false,
+ }),
+ ).toThrowError(ApiError);
+ });
+});
+
+describe("progressive onboarding feature flag", () => {
+ it("PROGRESSIVE_ONBOARDING finns i KNOWN_FLAGS", async () => {
+ const { KNOWN_FLAGS } = await import("@app/feature-flags");
+ expect(KNOWN_FLAGS.PROGRESSIVE_ONBOARDING).toBe("progressive_onboarding");
+ });
+
+ it("bucketFor ger stabil hash 0–99", async () => {
+ const { bucketFor } = await import("@app/feature-flags");
+ const b1 = bucketFor("progressive_onboarding", "user-123");
+ const b2 = bucketFor("progressive_onboarding", "user-123");
+ expect(b1).toBe(b2);
+ expect(b1).toBeGreaterThanOrEqual(0);
+ expect(b1).toBeLessThan(100);
+ });
+});
diff --git a/apps/mobile/src/app/(auth)/register.tsx b/apps/mobile/src/app/(auth)/register.tsx
index 8beb60b..f29b877 100644
--- a/apps/mobile/src/app/(auth)/register.tsx
+++ b/apps/mobile/src/app/(auth)/register.tsx
@@ -17,6 +17,7 @@ interface RegisterResponse {
export default function RegisterScreen() {
const setSession = useAuth((s) => s.setSession);
const setOnboardingCompleted = useAuth((s) => s.setOnboardingCompleted);
+ const setOnboardingStep = useAuth((s) => s.setOnboardingStep);
const [displayName, setDisplayName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
@@ -65,6 +66,7 @@ export default function RegisterScreen() {
await persistLanguageTag(deviceTag);
}
setOnboardingCompleted(false);
+ setOnboardingStep("a");
router.replace("/onboarding");
} catch (err) {
setError(err instanceof Error ? err.message : t("common.error"));
diff --git a/apps/mobile/src/app/(tabs)/_layout.tsx b/apps/mobile/src/app/(tabs)/_layout.tsx
index fef008e..fb321dd 100644
--- a/apps/mobile/src/app/(tabs)/_layout.tsx
+++ b/apps/mobile/src/app/(tabs)/_layout.tsx
@@ -36,10 +36,12 @@ function useApplyLocalePreferences(enabled: boolean) {
export default function TabsLayout() {
const accessToken = useAuth((s) => s.accessToken);
const onboardingCompleted = useAuth((s) => s.onboardingCompleted);
+ const onboardingStep = useAuth((s) => s.onboardingStep);
useApplyLocalePreferences(Boolean(accessToken));
if (!accessToken) return ;
- if (!onboardingCompleted) return ;
+ // Progressive onboarding (FAS 1b): only block if step A not done
+ if (!onboardingCompleted && onboardingStep === "a") return ;
return (
s.setOnboardingCompleted);
- const [step, setStep] = useState(0);
+ const setOnboardingStep = useAuth((s) => s.setOnboardingStep);
+ const savedStep = useAuth((s) => s.onboardingStep);
+ const [layer, setLayer] = useState(savedStep ?? "a");
+
+ // Step A state
const [goal, setGoal] = useState(null);
+ const [mode, setMode] = useState<"simple" | "exact">("simple");
+
+ // Step B state
const [diet, setDiet] = useState("omnivore");
const [allergens, setAllergens] = useState([]);
- const [mode, setMode] = useState<"simple" | "exact">("simple");
const [householdKind, setHouseholdKind] = useState<"create" | "join" | "skip">("create");
const [householdName, setHouseholdName] = useState(t("onboarding.householdDefaultName"));
const [inviteCode, setInviteCode] = useState("");
+
+ // Step C state
const [weightKg, setWeightKg] = useState("");
const [heightCm, setHeightCm] = useState("");
const [birthYear, setBirthYear] = useState("");
+
const [busy, setBusy] = useState(false);
const [error, setError] = useState(null);
const toggleAllergen = (id: string) =>
setAllergens((prev) => (prev.includes(id) ? prev.filter((a) => a !== id) : [...prev, id]));
- const finish = async () => {
+ const finishStepA = async () => {
setBusy(true);
setError(null);
try {
- await api("/v1/me/onboarding", {
+ const res = await api<{ step: "a" | "b" | "c" }>("/v1/onboarding/quick-start", {
+ method: "POST",
+ body: {
+ ...(goal ? { primaryGoal: goal } : {}),
+ precisionMode: mode,
+ },
+ });
+ setOnboardingStep(res.step);
+ setLayer("b");
+ // Let user into the app – Step B will be shown contextually later
+ router.replace("/(tabs)");
+ } catch (err) {
+ setError(err instanceof Error ? err.message : t("common.error"));
+ } finally {
+ setBusy(false);
+ }
+ };
+
+ const finishStepB = async () => {
+ setBusy(true);
+ setError(null);
+ try {
+ const res = await api<{ step: "a" | "b" | "c" }>("/v1/onboarding/complete-b", {
method: "POST",
body: {
precisionMode: mode,
- healthProfile: {
- ...(weightKg ? { weightKg: Number(weightKg) } : {}),
- ...(heightCm ? { heightCm: Number(heightCm) } : {}),
- ...(birthYear ? { birthYear: Number(birthYear) } : {}),
- },
preferences: {
- ...(goal ? { primaryGoal: goal } : {}),
dietPattern: diet,
allergens,
},
@@ -91,7 +125,32 @@ export default function OnboardingScreen() {
: { kind: "skip" },
},
});
+ setOnboardingStep(res.step);
+ setLayer("c");
+ } catch (err) {
+ setError(err instanceof Error ? err.message : t("common.error"));
+ } finally {
+ setBusy(false);
+ }
+ };
+
+ const finishStepC = async () => {
+ setBusy(true);
+ setError(null);
+ try {
+ await api("/v1/onboarding/complete-c", {
+ method: "POST",
+ body: {
+ precisionMode: mode,
+ healthProfile: {
+ ...(weightKg ? { weightKg: Number(weightKg) } : {}),
+ ...(heightCm ? { heightCm: Number(heightCm) } : {}),
+ ...(birthYear ? { birthYear: Number(birthYear) } : {}),
+ },
+ },
+ });
setOnboardingCompleted(true);
+ setOnboardingStep("c");
router.replace("/(tabs)");
} catch (err) {
setError(err instanceof Error ? err.message : t("common.error"));
@@ -100,48 +159,158 @@ export default function OnboardingScreen() {
}
};
- const steps = [
- // 0: Mål
-
- {t("onboarding.goal")}
- {GOALS.map((id) => (
+ const skip = async (targetLayer?: OnboardingLayer) => {
+ setBusy(true);
+ try {
+ await api("/v1/onboarding/skip", {
+ method: "POST",
+ body: { step: targetLayer },
+ });
+ setOnboardingCompleted(true);
+ setOnboardingStep("c");
+ router.replace("/(tabs)");
+ } catch (err) {
+ setError(err instanceof Error ? err.message : t("common.error"));
+ } finally {
+ setBusy(false);
+ }
+ };
+
+ // Render Step A: Immediate value
+ if (layer === "a") {
+ return (
+
+ {t("onboarding.title")}
+ {t("onboarding.subtitle")}
+
+
+ {t("onboarding.goal")}
+
+ {GOALS.map((id) => (
+ setGoal(id)}
+ />
+ ))}
+
+
+
+ {t("onboarding.mode")}
+ setMode("simple")} style={mode === "simple" ? sel : undefined}>
+ {t("onboarding.modeSimple")}
+ {t("onboarding.modeSimpleDesc")}
+
+ setMode("exact")} style={mode === "exact" ? sel : undefined}>
+ {t("onboarding.modeExact")}
+ {t("onboarding.modeExactDesc")}
+
+ {t("onboarding.modesCombine")}
+
+ {error && {error}}
+
+
+
+
+
+
+
+ {t("onboarding.notMedical")}
+
+ );
+ }
+
+ // Render Step B: After first value
+ if (layer === "b") {
+ return (
+
+ {t("onboarding.stepBTitle")}
+ {t("onboarding.stepBSubtitle")}
+
+
+ {t("onboarding.diet")}
+
+ {DIETS.map((id) => (
+ setDiet(id)}
+ />
+ ))}
+
+
+
+ {t("onboarding.allergies")}
+
+ {ALLERGENS.map((id) => (
+ toggleAllergen(id)}
+ />
+ ))}
+
+ {t("onboarding.allergyNote")}
+
+
+ {t("onboarding.household")}
setGoal(id)}
+ label={t("onboarding.householdCreate")}
+ selected={householdKind === "create"}
+ onPress={() => setHouseholdKind("create")}
/>
- ))}
- ,
- // 1: Kost + allergier
-
- {t("onboarding.diet")}
-
- {DIETS.map((id) => (
- setDiet(id)}
+ {householdKind === "create" && (
+
- ))}
-
-
- {t("onboarding.allergies")}
-
- {ALLERGENS.map((id) => (
- toggleAllergen(id)}
+ )}
+ setHouseholdKind("join")}
+ />
+ {householdKind === "join" && (
+
- ))}
-
- {t("onboarding.allergyNote")}
- ,
- // 2: Kroppsdata (frivilligt, för energiberäkning)
-
+ )}
+ setHouseholdKind("skip")}
+ />
+
+ {error && {error}}
+
+
+
+
+
+
+
+
+ );
+ }
+
+ // Render Step C: Contextual (health profile)
+ return (
+
+ {t("onboarding.stepCTitle")}
+ {t("onboarding.stepCSubtitle")}
+
+
{t("onboarding.bodyTitle")}
{t("onboarding.notMedical")}
- ,
- // 3: Hushåll
-
- {t("onboarding.household")}
- setHouseholdKind("create")}
- />
- {householdKind === "create" && (
-
- )}
- setHouseholdKind("join")}
- />
- {householdKind === "join" && (
-
- )}
- setHouseholdKind("skip")}
- />
- ,
- // 4: Läge (spec §5)
-
- {t("onboarding.mode")}
- setMode("simple")} style={mode === "simple" ? sel : undefined}>
- {t("onboarding.modeSimple")}
- {t("onboarding.modeSimpleDesc")}
-
- setMode("exact")} style={mode === "exact" ? sel : undefined}>
- {t("onboarding.modeExact")}
- {t("onboarding.modeExactDesc")}
-
- {t("onboarding.modesCombine")}
- ,
- ];
- const last = step === steps.length - 1;
- return (
-
- {t("onboarding.title")}
- {t("onboarding.subtitle")}
-
- {steps.map((_, i) => (
-
- ))}
-
- {steps[step]}
{error && {error}}
- {step > 0 && (
-
-
- )}
+
+
-
diff --git a/apps/mobile/src/lib/auth.ts b/apps/mobile/src/lib/auth.ts
index 727ed1d..7003cd6 100644
--- a/apps/mobile/src/lib/auth.ts
+++ b/apps/mobile/src/lib/auth.ts
@@ -30,6 +30,7 @@ interface AuthState {
accessToken: string | null;
user: AuthUser | null;
onboardingCompleted: boolean;
+ onboardingStep: "a" | "b" | "c";
hydrate: () => Promise;
setSession: (
tokens: { accessToken: string; refreshToken: string },
@@ -37,6 +38,7 @@ interface AuthState {
) => Promise;
setAccessToken: (token: string) => void;
setOnboardingCompleted: (done: boolean) => void;
+ setOnboardingStep: (step: "a" | "b" | "c") => void;
getRefreshToken: () => Promise;
logout: () => Promise;
}
@@ -46,6 +48,7 @@ export const useAuth = create((set) => ({
accessToken: null,
user: null,
onboardingCompleted: true,
+ onboardingStep: "a",
hydrate: async () => {
try {
@@ -77,6 +80,7 @@ export const useAuth = create((set) => ({
},
setOnboardingCompleted: (done) => set({ onboardingCompleted: done }),
+ setOnboardingStep: (step) => set({ onboardingStep: step }),
getRefreshToken: () => SecureStore.getItemAsync(REFRESH_KEY),
diff --git a/apps/mobile/src/locales/da/common.json b/apps/mobile/src/locales/da/common.json
index 34d80f0..5d6aba7 100644
--- a/apps/mobile/src/locales/da/common.json
+++ b/apps/mobile/src/locales/da/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Indlæser …",
+ "auth.backToLogin": "Tilbage til login",
+ "auth.displayName": "Hvad skal vi kalde dig?",
+ "auth.email": "E-mail",
+ "auth.forgotBody": "Indtast din e-mail, så sender vi et link, hvis kontoen findes.",
+ "auth.forgotLink": "Glemt adgangskode?",
+ "auth.forgotSentBody": "Hvis adressen har en konto, har vi sendt et link, der gælder i 30 minutter. Åbn det på denne enhed.",
+ "auth.forgotSentTitle": "Tjek din indbakke",
+ "auth.forgotSubmit": "Send link",
+ "auth.forgotTitle": "Nulstil adgangskode",
+ "auth.hasAccount": "Har du allerede en konto? Log ind",
+ "auth.login": "Log ind",
+ "auth.newPassword": "Ny adgangskode (mindst 10 tegn)",
+ "auth.noAccount": "Ny her? Opret en konto",
+ "auth.password": "Adgangskode",
+ "auth.register": "Opret konto",
+ "auth.resetBody": "Linket gælder i 30 minutter og kan kun bruges én gang. Alle enheder logges ud.",
+ "auth.resetDoneBody": "Din adgangskode er ændret. Log ind med den nye.",
+ "auth.resetDoneTitle": "Færdig!",
+ "auth.resetSubmit": "Skift adgangskode",
+ "auth.resetTitle": "Vælg en ny adgangskode",
+ "auth.resetTokenPlaceholder": "Indsæt koden fra e-mailen",
+ "auth.trialNote": "7 dages fuld adgang – uden kort.",
+ "auth.verifyDoneBody": "Tak! Din konto er nu verificeret.",
+ "auth.verifyDoneTitle": "E-mail bekræftet",
+ "auth.verifyFailedBody": "Linket er ugyldigt eller udløbet. Anmod om et nyt fra profilen.",
+ "auth.verifyFailedTitle": "Linket virkede ikke",
+ "barcode.addPrompt": "Tilføj til madlageret?",
+ "barcode.aim": "Ret kameraet mod stregkoden",
+ "barcode.allowCamera": "Tillad kamera",
+ "barcode.cameraBody": "{brand} skal bruge kameraet til at scanne stregkoder.",
+ "barcode.cameraTitle": "Kameraet er nødvendigt",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Du skal først have en husstand.",
+ "barcode.noLocation": "Ingen opbevaringssteder fundet.",
+ "barcode.noNutrition": "Ingen næringsdata",
+ "barcode.photoPackage": "Tag billede af emballagen",
+ "barcode.unknownBody": "Produktet er ikke i databasen endnu. Tag et billede af forsiden og næringsdeklarationen, så tilføjer vi det.",
+ "barcode.unknownTitle": "Ukendt produkt",
+ "common.add": "Tilføj",
+ "common.back": "Tilbage",
+ "common.cancel": "Annuller",
+ "common.done": "Færdig",
"common.error": "Noget gik galt. Prøv igen.",
+ "common.estimate": "Estimat",
+ "common.loading": "Indlæser …",
+ "common.next": "Næste",
+ "common.off": "Fra",
+ "common.offline": "Offline – viser senest hentede data",
+ "common.on": "Til",
+ "common.oops": "Ups",
+ "common.remove": "Fjern",
"common.retry": "Prøv igen",
"common.save": "Gem",
- "common.cancel": "Annuller",
- "common.next": "Næste",
- "common.back": "Tilbage",
- "common.done": "Færdig",
"common.skip": "Spring over",
- "common.offline": "Offline – viser senest hentede data",
- "common.estimate": "Estimat",
- "tabs.whatToEat": "Hvad skal vi spise?",
- "tabs.scan": "Scan",
- "tabs.myDay": "Min dag",
- "tabs.home": "Derhjemme",
- "auth.login": "Log ind",
- "auth.register": "Opret konto",
- "auth.email": "E-mail",
- "auth.password": "Adgangskode",
- "auth.displayName": "Hvad skal vi kalde dig?",
- "auth.noAccount": "Ny her? Opret en konto",
- "auth.hasAccount": "Har du allerede en konto? Log ind",
- "auth.trialNote": "7 dages fuld adgang – uden kort.",
- "auth.forgotLink": "Glemt adgangskode?",
- "auth.forgotTitle": "Nulstil adgangskode",
- "auth.forgotBody": "Indtast din e-mail, så sender vi et link, hvis kontoen findes.",
- "auth.forgotSubmit": "Send link",
- "auth.forgotSentTitle": "Tjek din indbakke",
- "auth.forgotSentBody": "Hvis adressen har en konto, har vi sendt et link, der gælder i 30 minutter. Åbn det på denne enhed.",
- "auth.backToLogin": "Tilbage til login",
- "auth.resetTitle": "Vælg en ny adgangskode",
- "auth.resetBody": "Linket gælder i 30 minutter og kan kun bruges én gang. Alle enheder logges ud.",
- "auth.resetTokenPlaceholder": "Indsæt koden fra e-mailen",
- "auth.newPassword": "Ny adgangskode (mindst 10 tegn)",
- "auth.resetSubmit": "Skift adgangskode",
- "auth.resetDoneTitle": "Færdig!",
- "auth.resetDoneBody": "Din adgangskode er ændret. Log ind med den nye.",
- "auth.verifyDoneTitle": "E-mail bekræftet",
- "auth.verifyDoneBody": "Tak! Din konto er nu verificeret.",
- "auth.verifyFailedTitle": "Linket virkede ikke",
- "auth.verifyFailedBody": "Linket er ugyldigt eller udløbet. Anmod om et nyt fra profilen.",
- "onboarding.title": "Fortæl os lidt om dig",
- "onboarding.subtitle": "Alt er frivilligt og kan ændres når som helst. Jo mere du udfylder, jo bedre forslag.",
- "onboarding.goal": "Hvad er dit vigtigste mål?",
- "onboarding.diet": "Hvordan spiser du?",
+ "common.undo": "Fortryd",
+ "cooked.deductPantry": "Træk ingredienser fra lageret",
+ "cooked.deductPantryNote": "Ingredienserne trækkes fra madlageret – det, der udløber først, bruges først.",
+ "cooked.mealBoxes": "Portioner til madpakker",
+ "cooked.portionsCooked": "Portioner lavet",
+ "cooked.rate": "Bedøm",
+ "cooked.title": "Hvordan gik det?",
+ "cooked.whoAte": "Hvem spiste?",
+ "cooking.finish": "Færdig – registrér måltidet",
+ "cooking.keepAwake": "Skærmen forbliver tændt, mens du laver mad",
+ "cooking.scale": "Portioner",
+ "cooking.step": "Trin {current} af {total}",
+ "cooking.timer": "Start timer",
+ "cooking.timerDone": "Færdig!",
+ "cooking.timerRunning": "{time} tilbage",
+ "home.budget": "Madbudget",
+ "home.emptyInventory": "Lageret er tomt. Scan køleskabet eller tilføj varer manuelt.",
+ "home.expired": "Udløbet",
+ "home.expiresIn_one": "1 dag tilbage",
+ "home.expiresIn_other": "{days} dage tilbage",
+ "home.expiresToday": "Udløber i dag",
+ "home.household": "Husstand",
+ "home.inventory": "Madlager",
+ "home.mealBoxes": "Madpakker",
+ "home.moreItems_one": "+ 1 mere …",
+ "home.moreItems_other": "+ {count} flere …",
+ "home.pastBestBefore": "Bedst før er overskredet – lugt og smag først",
+ "home.shopping": "Indkøbsliste",
+ "home.thisWeek": "Denne uge",
+ "home.title": "Derhjemme",
+ "home.useSoon": "Brug snart",
+ "home.useSoonHint": "Bedst før handler om kvalitet – lugt, se og smag, før du smider ud. Sidste anvendelsesdato skal derimod respekteres.",
+ "home.waste": "Madspild",
+ "home.wasteWeek": "Madspild denne uge",
+ "household.empty": "Du har ingen husstand endnu. Opret en i onboarding, eller deltag med en kode.",
+ "household.invite": "Invitér med kode: {code}",
+ "household.locations": "Opbevaringssteder",
+ "household.members": "Medlemmer",
+ "household.portionFactor": "×{factor} portion",
+ "household.private": "Privat pr. person: mål, allergier, helbredsdata og måltidshistorik.",
+ "household.role.adult": "Voksen",
+ "household.role.child": "Barn",
+ "household.role.member": "Medlem",
+ "household.role.owner": "Ejer",
+ "household.shareCode": "Del koden med familien, så deler I madlager, liste og plan.",
+ "household.shared": "Deles i husstanden: madlager, indkøbsliste, ugeplan, madpakker og budget.",
+ "logmeal.manualTitle": "Manuelt",
+ "logmeal.mealTypeTitle": "Måltidstype",
+ "logmeal.photoTip": "Tip: tag et billede af tallerkenen under Scan, så estimerer appen for dig – du bekræfter altid.",
+ "logmeal.proteinPlaceholder": "protein (g)",
+ "logmeal.quickSubtitle": "Logger de samme næringsværdier som sidst.",
+ "logmeal.quickTitle": "Hurtig genlogning",
+ "logmeal.validationBody": "Navn og kalorier kræves ved manuel logning.",
+ "logmeal.validationTitle": "Udfyld",
+ "logmeal.whatPlaceholder": "Hvad spiste du?",
+ "mealbox.eat": "Spis nu",
+ "mealbox.eatBy": "Spis senest {date}",
+ "mealbox.empty": "Ingen madpakker lige nu. Når du laver mad, kan du gemme portioner her.",
+ "mealbox.enjoyBody": "Portionen er logget i Min dag.",
+ "mealbox.enjoyTitle": "Velbekomme!",
+ "mealbox.guidanceNote": "Den anbefalede frist er vejledende – stol på lugt og smag.",
+ "mealbox.portionsLeft_one": "1 portion tilbage",
+ "mealbox.portionsLeft_other": "{count} portioner tilbage",
+ "mealbox.title": "Madpakker",
+ "memory.delete": "Slet",
+ "memory.deleteAll": "Slet al hukommelse",
+ "memory.deleteAllTitle": "Slet al hukommelse?",
+ "memory.empty": "{brand} har ikke lært noget om dig endnu.",
+ "memory.irreversible": "Dette kan ikke fortrydes.",
+ "memory.origin.ai_inferred": "AI-antagelse",
+ "memory.origin.observed": "Observeret mønster",
+ "memory.origin.user_stated": "Du har fortalt det",
+ "memory.pause": "Pause",
+ "memory.paused": "På pause",
+ "memory.resume": "Genoptag",
+ "memory.subtitle": "Fuld indsigt. Ret fejl, sæt på pause eller slet – du ejer din hukommelse.",
+ "memory.title": "Hvad {brand} ved om mig",
+ "memory.verified": "Bekræftet",
+ "memory.verify": "Korrekt",
+ "myday.calories": "Kalorier",
+ "myday.carbs": "Kulhydrater",
+ "myday.estimateNote": "Værdier med ~ er estimater, du kan justere.",
+ "myday.estimateRange": "{min}–{max} kcal, sandsynligvis {kcal}",
+ "myday.fat": "Fedt",
+ "myday.fiber": "Fibre",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
+ "myday.logMeal": "Registrér måltid",
+ "myday.mealType.breakfast": "Morgenmad",
+ "myday.mealType.dessert": "Dessert",
+ "myday.mealType.dinner": "Aftensmad",
+ "myday.mealType.lunch": "Frokost",
+ "myday.mealType.snack": "Mellemmåltid",
+ "myday.noMeals": "Ingen måltider registreret i dag.",
+ "myday.over": "{kcal} kcal over målet",
+ "myday.overRecommended": "Over det anbefalede",
+ "myday.protein": "Protein",
+ "myday.remaining": "{kcal} kcal tilbage",
+ "myday.salt": "Salt",
+ "myday.targetsNote": "Målene er vejledning, ikke lægelig rådgivning.",
+ "myday.title": "Min dag",
+ "myday.todaysMeals": "Dagens måltider",
+ "onboarding.allergen.crustaceans": "Skaldyr",
+ "onboarding.allergen.eggs": "Æg",
+ "onboarding.allergen.fish": "Fisk",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Mælk/laktose",
+ "onboarding.allergen.peanuts": "Jordnødder",
+ "onboarding.allergen.sesame": "Sesam",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Nødder",
"onboarding.allergies": "Allergier og intolerancer",
"onboarding.allergyNote": "Allergifiltrering er altid streng – retter med dine allergener vises aldrig.",
+ "onboarding.birthYearPlaceholder": "Fødselsår",
+ "onboarding.bodyTitle": "Til personlige kaloriemål (valgfrit)",
+ "onboarding.diet": "Hvordan spiser du?",
+ "onboarding.diet.flexitarian": "Flexitar",
+ "onboarding.diet.omnivore": "Altædende",
+ "onboarding.diet.pescatarian": "Pescetar",
+ "onboarding.diet.vegan": "Veganer",
+ "onboarding.diet.vegetarian": "Vegetar",
+ "onboarding.goal": "Hvad er dit vigtigste mål?",
+ "onboarding.goal.build_muscle": "Opbygge muskler",
+ "onboarding.goal.cook_more": "Lave mere mad hjemme",
+ "onboarding.goal.less_waste": "Mindske madspild",
+ "onboarding.goal.lose_weight": "Tabe mig",
+ "onboarding.goal.lower_cost": "Bruge færre penge på mad",
+ "onboarding.goal.maintain_weight": "Holde vægten",
+ "onboarding.goal.more_protein": "Spise mere protein",
+ "onboarding.heightPlaceholder": "Højde (cm)",
"onboarding.household": "Din husstand",
"onboarding.householdCreate": "Opret husstand",
+ "onboarding.householdDefaultName": "Hjemme",
"onboarding.householdJoin": "Deltag med kode",
"onboarding.householdName": "Husstandens navn",
"onboarding.inviteCode": "Invitationskode",
"onboarding.mode": "Hvor præcis vil du være?",
- "onboarding.modeSimple": "Enkel tilstand",
- "onboarding.modeSimpleDesc": "Tag billeder af maden, accepter estimater, minimalt besvær.",
"onboarding.modeExact": "Præcis tilstand",
"onboarding.modeExactDesc": "Vej maden, indtast gram, fuld kontrol over tallene.",
+ "onboarding.modesCombine": "Tilstandene kan kombineres – enkelt til hverdag, præcist når du vil.",
+ "onboarding.modeSimple": "Enkel tilstand",
+ "onboarding.modeSimpleDesc": "Tag billeder af maden, accepter estimater, minimalt besvær.",
"onboarding.notMedical": "{brand} giver vejledning – ikke lægelig rådgivning.",
- "wte.title": "Hvad skal vi spise?",
- "wte.subtitle": "Ud fra hvad I har derhjemme, hvad der snart skal bruges, og hvad I kan lide.",
- "wte.cravingPlaceholder": "Jeg har lyst til … (fx cremet, asiatisk, under 500 kcal)",
- "wte.mealBoxFirst": "Færdig mad derhjemme",
- "wte.whyTitle": "Hvorfor dette forslag?",
- "wte.coverage": "{pct} % derhjemme",
- "wte.missing": "Mangler: {items}",
- "wte.empty": "Ingen forslag endnu – læg lidt mad på lager eller løsn filtrene.",
- "wte.refresh": "Nye forslag",
- "scan.title": "Scan",
- "scan.subtitle": "Fyld madlageret eller registrér et måltid med kameraet.",
- "scan.fridge": "Køleskab",
- "scan.freezer": "Fryser",
- "scan.pantry": "Spisekammer",
- "scan.ingredients": "Ingredienser",
- "scan.plate": "Tallerken",
- "scan.receipt": "Kvittering",
- "scan.barcode": "Stregkode",
- "scan.expiry": "Bedst før-dato",
- "scan.nutrition": "Næringsdeklaration",
- "scan.takePhoto": "Tag billede",
- "scan.tips.title": "Sådan bliver analysen bedst",
- "scan.tips.overview": "Start med et oversigtsbillede",
- "scan.tips.shelf": "Fotografér hylde for hylde",
- "scan.tips.light": "Undgå mørke og skygger",
- "scan.tips.move": "Flyt varer, der skjuler hinanden",
- "scan.analyzing": "Analyserer …",
- "scan.quotaLeft_one": "1 AI-scanning tilbage denne måned",
- "scan.quotaLeft_other": "{count} AI-scanninger tilbage denne måned",
- "scan.review.title": "Gennemgå resultatet",
- "scan.review.subtitle": "AI'en er nogle gange usikker – du bestemmer. Ret, fjern eller tilføj, før du gemmer.",
- "scan.review.uncertain": "Usikker – tjek",
- "scan.review.approveAll": "Gem på lageret",
- "scan.review.rejected": "Fjernet",
- "scan.failed": "Analysen mislykkedes. Prøv igen eller registrér manuelt.",
- "myday.title": "Min dag",
- "myday.calories": "Kalorier",
- "myday.protein": "Protein",
- "myday.carbs": "Kulhydrater",
- "myday.fat": "Fedt",
- "myday.fiber": "Fibre",
- "myday.salt": "Salt",
- "myday.remaining": "{kcal} kcal tilbage",
- "myday.over": "{kcal} kcal over målet",
- "myday.logMeal": "Registrér måltid",
- "myday.noMeals": "Ingen måltider registreret i dag.",
- "myday.estimateNote": "Værdier med ~ er estimater, du kan justere.",
- "myday.targetsNote": "Målene er vejledning, ikke lægelig rådgivning.",
- "home.title": "Derhjemme",
- "home.inventory": "Madlager",
- "home.useSoon": "Brug snart",
- "home.mealBoxes": "Madpakker",
- "home.shopping": "Indkøbsliste",
- "home.budget": "Madbudget",
- "home.household": "Husstand",
- "home.waste": "Madspild",
- "home.emptyInventory": "Lageret er tomt. Scan køleskabet eller tilføj varer manuelt.",
- "home.expiresIn_one": "1 dag tilbage",
- "home.expiresIn_other": "{days} dage tilbage",
- "home.expiresToday": "Udløber i dag",
- "home.expired": "Udløbet",
- "home.pastBestBefore": "Bedst før er overskredet – lugt og smag først",
+ "onboarding.stepBSubtitle": "Tilpas din profil for bedre forslag.",
+ "onboarding.stepBTitle": "Fortsæt opsætning",
+ "onboarding.stepCSubtitle": "Valgfrit – bruges til personlige kaloriemål.",
+ "onboarding.stepCTitle": "Din sundhedsprofil",
+ "onboarding.subtitle": "Alt er frivilligt og kan ændres når som helst. Jo mere du udfylder, jo bedre forslag.",
+ "onboarding.title": "Fortæl os lidt om dig",
+ "onboarding.weightPlaceholder": "Vægt (kg)",
+ "paywall.choose": "Vælg",
+ "paywall.fairUse": "Fair use-kvote for AI-scanninger inkluderet.",
+ "paywall.family": "Family · op til 6 personer",
+ "paywall.freeNote": "Gratis: 10 AI-scanninger/md., manuelt lager, gemte opskrifter og enkel registrering.",
+ "paywall.household": "Household · op til 3 personer",
+ "paywall.large": "Large Household · op til 12 personer",
+ "paywall.perMonth": "{price}/md.",
+ "paywall.popular": "Mest populær",
+ "paywall.restore": "Gendan køb",
+ "paywall.soonBody": "Køb aktiveres via App Store/Google Play, når butiksintegrationen slås til (fase 7). Backend-flowet er allerede klar.",
+ "paywall.soonTitle": "Snart!",
+ "paywall.subtitle": "Hele husstandens mad-OS: ubegrænset lager, ugeplan og deling.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "1 dag tilbage af din prøveperiode",
+ "paywall.trialActive_other": "{days} dage tilbage af din prøveperiode",
+ "profile.aiScansUsed": "AI-scanninger: {used} / {total} denne måned",
+ "profile.consent.anonymized_improvement": "Anonymiseret forbedring af AI'en",
+ "profile.consent.health_integration": "Sundhedsdata (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Mine billeder må bruges til træning",
+ "profile.consent.location_weather": "Placering til vejrbaserede forslag",
+ "profile.consent.personalization": "Personlige funktioner (hukommelse & smagsprofil)",
+ "profile.consent.product_analytics": "Produktanalyse",
+ "profile.consent.push_notifications": "Push-notifikationer",
+ "profile.consents": "Samtykker & data",
+ "profile.consentsNote": "Samtykkerne er adskilte – personlige funktioner kræver aldrig træningssamtykke.",
+ "profile.deleteAccount": "Slet konto",
+ "profile.deleteBody": "Alle dine data slettes permanent i henhold til GDPR.",
+ "profile.deleteTitle": "Slet kontoen?",
+ "profile.emailUnverified": "E-mailadressen er ikke bekræftet",
+ "profile.export": "Eksportér mine data",
+ "profile.goals": "Mål & kost",
+ "profile.language": "Sprog",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Log ud",
+ "profile.memory": "Hvad {brand} ved om mig",
+ "profile.memorySubtitle": "Se, ret, sæt på pause eller slet det, platformen har lært.",
+ "profile.modeLabel": "Tilstand:",
+ "profile.resendVerification": "Send bekræftelsesmail igen",
+ "profile.subscription": "Abonnement",
+ "profile.title": "Profil",
+ "profile.verificationSent": "Sendt! Tjek din indbakke.",
+ "recipe.avgRating": "Gennemsnit {avg} af {count} bedømmelser",
+ "recipe.cook": "Lav mad nu",
+ "recipe.cost": "ca. {amount}/portion",
+ "recipe.iCookedThis": "Jeg har lavet denne",
+ "recipe.ingredients": "Ingredienser",
+ "recipe.notSafe": "Passer ikke til dine kostindstillinger",
+ "recipe.perPortion": "pr. portion",
"recipe.portions_one": "1 portion",
"recipe.portions_other": "{count} portioner",
- "recipe.time": "{min} min",
- "recipe.perPortion": "pr. portion",
- "recipe.ingredients": "Ingredienser",
+ "recipe.save": "Gem",
+ "recipe.saved": "Gemt",
"recipe.steps": "Fremgangsmåde",
- "recipe.cook": "Lav mad nu",
- "recipe.notSafe": "Passer ikke til dine kostindstillinger",
"recipe.substitutions": "Erstat",
- "recipe.iCookedThis": "Jeg har lavet denne",
- "recipe.cost": "ca. {amount}/portion",
- "cooking.step": "Trin {current} af {total}",
- "cooking.timer": "Start timer",
- "cooking.timerRunning": "{time} tilbage",
- "cooking.finish": "Færdig – registrér måltidet",
- "cooking.scale": "Portioner",
- "cooking.keepAwake": "Skærmen forbliver tændt, mens du laver mad",
- "cooked.title": "Hvordan gik det?",
- "cooked.portionsCooked": "Portioner lavet",
- "cooked.whoAte": "Hvem spiste?",
- "cooked.mealBoxes": "Portioner til madpakker",
- "cooked.deductPantry": "Træk ingredienser fra lageret",
- "cooked.rate": "Bedøm",
- "shopping.title": "Indkøbsliste",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analyserer …",
+ "scan.barcode": "Stregkode",
+ "scan.expiry": "Bedst før-dato",
+ "scan.failed": "Analysen mislykkedes. Prøv igen eller registrér manuelt.",
+ "scan.freezer": "Fryser",
+ "scan.fridge": "Køleskab",
+ "scan.ingredients": "Ingredienser",
+ "scan.nutrition": "Næringsdeklaration",
+ "scan.pantry": "Spisekammer",
+ "scan.plate": "Tallerken",
+ "scan.quotaLeft_one": "1 AI-scanning tilbage denne måned",
+ "scan.quotaLeft_other": "{count} AI-scanninger tilbage denne måned",
+ "scan.receipt": "Kvittering",
+ "scan.review.addItem": "+ Tilføj vare",
+ "scan.review.approveAll": "Gem på lageret",
+ "scan.review.bestBeforeNote": "Kvalitetsdato – varen kan sagtens holde længere. Lugt og smag, før du smider ud.",
+ "scan.review.dateKindBestBefore": "Bedst før",
+ "scan.review.dateKindUseBy": "Sidste anvendelsesdato",
+ "scan.review.datePlaceholder": "ÅÅÅÅ-MM-DD (valgfrit)",
+ "scan.review.itemPlaceholder": "Vare",
+ "scan.review.quantityPlaceholder": "Mængde",
+ "scan.review.rejected": "Fjernet",
+ "scan.review.subtitle": "AI'en er nogle gange usikker – du bestemmer. Ret, fjern eller tilføj, før du gemmer.",
+ "scan.review.title": "Gennemgå resultatet",
+ "scan.review.uncertain": "Usikker – tjek",
+ "scan.review.unitPlaceholder": "Enhed (g, l, stk. …)",
+ "scan.review.unknownItem": "Ukendt vare",
+ "scan.review.useByNote": "Sikkerhedsdato – spis ikke efter denne dato.",
+ "scan.subtitle": "Fyld madlageret eller registrér et måltid med kameraet.",
+ "scan.takePhoto": "Tag billede",
+ "scan.tips.light": "Undgå mørke og skygger",
+ "scan.tips.move": "Flyt varer, der skjuler hinanden",
+ "scan.tips.overview": "Start med et oversigtsbillede",
+ "scan.tips.shelf": "Fotografér hylde for hylde",
+ "scan.tips.title": "Sådan bliver analysen bedst",
+ "scan.title": "Scan",
"shopping.addPlaceholder": "Tilføj vare …",
"shopping.complete": "Afslut indkøbsturen",
+ "shopping.completedBody_one": "1 vare blev lagt i madlageret.",
+ "shopping.completedBody_other": "{count} varer blev lagt i madlageret.",
+ "shopping.completedTitle": "Færdig!",
"shopping.completeNote": "Afkrydsede varer lægges på madlageret.",
"shopping.empty": "Listen er tom.",
"shopping.estimated": "ca. {amount}",
"shopping.estimatedTotal": "Anslået i alt: ca. {amount}",
- "mealbox.title": "Madpakker",
- "mealbox.eatBy": "Spis senest {date}",
- "mealbox.portionsLeft_one": "1 portion tilbage",
- "mealbox.portionsLeft_other": "{count} portioner tilbage",
- "mealbox.eat": "Spis nu",
- "mealbox.empty": "Ingen madpakker lige nu. Når du laver mad, kan du gemme portioner her.",
- "household.members": "Medlemmer",
- "household.invite": "Invitér med kode: {code}",
- "household.shared": "Deles i husstanden: madlager, indkøbsliste, ugeplan, madpakker og budget.",
- "household.private": "Privat pr. person: mål, allergier, helbredsdata og måltidshistorik.",
- "memory.title": "Hvad {brand} ved om mig",
- "memory.subtitle": "Fuld indsigt. Ret fejl, sæt på pause eller slet – du ejer din hukommelse.",
- "memory.paused": "På pause",
- "memory.verify": "Korrekt",
- "memory.pause": "Pause",
- "memory.delete": "Slet",
- "memory.deleteAll": "Slet al hukommelse",
- "memory.empty": "{brand} har ikke lært noget om dig endnu.",
- "memory.origin.user_stated": "Du har fortalt det",
- "memory.origin.observed": "Observeret mønster",
- "memory.origin.ai_inferred": "AI-antagelse",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "Hele husstandens mad-OS: ubegrænset lager, ugeplan og deling.",
- "paywall.trialActive_one": "1 dag tilbage af din prøveperiode",
- "paywall.trialActive_other": "{days} dage tilbage af din prøveperiode",
- "paywall.household": "Household · op til 3 personer",
- "paywall.family": "Family · op til 6 personer",
- "paywall.large": "Large Household · op til 12 personer",
- "paywall.perMonth": "{price}/md.",
- "paywall.fairUse": "Fair use-kvote for AI-scanninger inkluderet.",
- "paywall.restore": "Gendan køb",
- "paywall.freeNote": "Gratis: 10 AI-scanninger/md., manuelt lager, gemte opskrifter og enkel registrering.",
- "profile.title": "Profil",
- "profile.goals": "Mål & kost",
- "profile.consents": "Samtykker & data",
- "profile.memory": "Hvad {brand} ved om mig",
- "profile.subscription": "Abonnement",
- "profile.logout": "Log ud",
- "profile.export": "Eksportér mine data",
- "profile.deleteAccount": "Slet konto",
- "profile.language": "Sprog",
- "profile.emailUnverified": "E-mailadressen er ikke bekræftet",
- "profile.resendVerification": "Send bekræftelsesmail igen",
- "profile.verificationSent": "Sendt! Tjek din indbakke.",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Ups",
- "common.undo": "Fortryd",
- "common.remove": "Fjern",
- "common.add": "Tilføj",
- "common.on": "Til",
- "common.off": "Fra",
- "home.thisWeek": "Denne uge",
- "home.wasteWeek": "Madspild denne uge",
- "home.useSoonHint": "Bedst før handler om kvalitet – lugt, se og smag, før du smider ud. Sidste anvendelsesdato skal derimod respekteres.",
- "scan.review.itemPlaceholder": "Vare",
- "scan.review.quantityPlaceholder": "Mængde",
- "scan.review.unitPlaceholder": "Enhed (g, l, stk. …)",
- "scan.review.datePlaceholder": "ÅÅÅÅ-MM-DD (valgfrit)",
- "scan.review.dateKindBestBefore": "Bedst før",
- "scan.review.dateKindUseBy": "Sidste anvendelsesdato",
- "scan.review.bestBeforeNote": "Kvalitetsdato – varen kan sagtens holde længere. Lugt og smag, før du smider ud.",
- "scan.review.useByNote": "Sikkerhedsdato – spis ikke efter denne dato.",
- "scan.review.addItem": "+ Tilføj vare",
- "scan.review.unknownItem": "Ukendt vare",
- "barcode.aim": "Ret kameraet mod stregkoden",
- "barcode.addPrompt": "Tilføj til madlageret?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Ingen næringsdata",
- "barcode.unknownTitle": "Ukendt produkt",
- "barcode.unknownBody": "Produktet er ikke i databasen endnu. Tag et billede af forsiden og næringsdeklarationen, så tilføjer vi det.",
- "barcode.photoPackage": "Tag billede af emballagen",
- "barcode.needHousehold": "Du skal først have en husstand.",
- "barcode.noLocation": "Ingen opbevaringssteder fundet.",
- "barcode.cameraTitle": "Kameraet er nødvendigt",
- "barcode.cameraBody": "{brand} skal bruge kameraet til at scanne stregkoder.",
- "barcode.allowCamera": "Tillad kamera",
- "onboarding.goal.lose_weight": "Tabe mig",
- "onboarding.goal.build_muscle": "Opbygge muskler",
- "onboarding.goal.maintain_weight": "Holde vægten",
- "onboarding.goal.more_protein": "Spise mere protein",
- "onboarding.goal.less_waste": "Mindske madspild",
- "onboarding.goal.lower_cost": "Bruge færre penge på mad",
- "onboarding.goal.cook_more": "Lave mere mad hjemme",
- "onboarding.diet.omnivore": "Altædende",
- "onboarding.diet.flexitarian": "Flexitar",
- "onboarding.diet.pescatarian": "Pescetar",
- "onboarding.diet.vegetarian": "Vegetar",
- "onboarding.diet.vegan": "Veganer",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Mælk/laktose",
- "onboarding.allergen.eggs": "Æg",
- "onboarding.allergen.tree_nuts": "Nødder",
- "onboarding.allergen.peanuts": "Jordnødder",
- "onboarding.allergen.fish": "Fisk",
- "onboarding.allergen.crustaceans": "Skaldyr",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sesam",
- "onboarding.bodyTitle": "Til personlige kaloriemål (valgfrit)",
- "onboarding.weightPlaceholder": "Vægt (kg)",
- "onboarding.heightPlaceholder": "Højde (cm)",
- "onboarding.birthYearPlaceholder": "Fødselsår",
- "onboarding.householdDefaultName": "Hjemme",
- "onboarding.modesCombine": "Tilstandene kan kombineres – enkelt til hverdag, præcist når du vil.",
- "myday.mealType.breakfast": "Morgenmad",
- "myday.mealType.lunch": "Frokost",
- "myday.mealType.dinner": "Aftensmad",
- "myday.mealType.snack": "Mellemmåltid",
- "myday.mealType.dessert": "Dessert",
- "myday.overRecommended": "Over det anbefalede",
- "myday.todaysMeals": "Dagens måltider",
- "myday.estimateRange": "{min}–{max} kcal, sandsynligvis {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
- "logmeal.mealTypeTitle": "Måltidstype",
- "logmeal.quickTitle": "Hurtig genlogning",
- "logmeal.quickSubtitle": "Logger de samme næringsværdier som sidst.",
- "logmeal.manualTitle": "Manuelt",
- "logmeal.whatPlaceholder": "Hvad spiste du?",
- "logmeal.proteinPlaceholder": "protein (g)",
- "logmeal.validationTitle": "Udfyld",
- "logmeal.validationBody": "Navn og kalorier kræves ved manuel logning.",
- "logmeal.photoTip": "Tip: tag et billede af tallerkenen under Scan, så estimerer appen for dig – du bekræfter altid.",
- "shopping.section.frukt_gront": "Frugt & grønt",
"shopping.section.brod": "Brød",
- "shopping.section.mejeri": "Mejeri",
- "shopping.section.kott_fagel": "Kød & fjerkræ",
- "shopping.section.fisk": "Fisk",
"shopping.section.chark": "Pålæg",
- "shopping.section.frys": "Frost",
- "shopping.section.skafferi": "Kolonial",
- "shopping.section.konserver": "Konserves",
- "shopping.section.kryddor_bak": "Krydderier & bagning",
"shopping.section.dryck": "Drikkevarer",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Fisk",
+ "shopping.section.frukt_gront": "Frugt & grønt",
+ "shopping.section.frys": "Frost",
"shopping.section.hygien_ovrigt": "Andet",
- "shopping.completedTitle": "Færdig!",
- "household.role.owner": "Ejer",
- "household.role.adult": "Voksen",
- "household.role.member": "Medlem",
- "household.role.child": "Barn",
- "household.empty": "Du har ingen husstand endnu. Opret en i onboarding, eller deltag med en kode.",
- "household.shareCode": "Del koden med familien, så deler I madlager, liste og plan.",
- "household.locations": "Opbevaringssteder",
- "household.portionFactor": "×{factor} portion",
- "mealbox.enjoyTitle": "Velbekomme!",
- "mealbox.enjoyBody": "Portionen er logget i Min dag.",
- "mealbox.guidanceNote": "Den anbefalede frist er vejledende – stol på lugt og smag.",
- "paywall.soonTitle": "Snart!",
- "paywall.soonBody": "Køb aktiveres via App Store/Google Play, når butiksintegrationen slås til (fase 7). Backend-flowet er allerede klar.",
- "paywall.popular": "Mest populær",
- "paywall.choose": "Vælg",
- "recipe.saved": "Gemt",
- "recipe.save": "Gem",
- "recipe.avgRating": "Gennemsnit {avg} af {count} bedømmelser",
- "memory.verified": "Bekræftet",
- "memory.resume": "Genoptag",
- "memory.deleteAllTitle": "Slet al hukommelse?",
- "memory.irreversible": "Dette kan ikke fortrydes.",
- "profile.consent.personalization": "Personlige funktioner (hukommelse & smagsprofil)",
- "profile.consent.anonymized_improvement": "Anonymiseret forbedring af AI'en",
- "profile.consent.image_training": "Mine billeder må bruges til træning",
- "profile.consent.health_integration": "Sundhedsdata (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Placering til vejrbaserede forslag",
- "profile.consent.push_notifications": "Push-notifikationer",
- "profile.modeLabel": "Tilstand:",
- "profile.memorySubtitle": "Se, ret, sæt på pause eller slet det, platformen har lært.",
- "profile.consentsNote": "Samtykkerne er adskilte – personlige funktioner kræver aldrig træningssamtykke.",
- "profile.aiScansUsed": "AI-scanninger: {used} / {total} denne måned",
- "profile.deleteTitle": "Slet kontoen?",
- "profile.deleteBody": "Alle dine data slettes permanent i henhold til GDPR.",
- "cooking.timerDone": "Færdig!",
- "cooked.deductPantryNote": "Ingredienserne trækkes fra madlageret – det, der udløber først, bruges først.",
- "home.moreItems_one": "+ 1 mere …",
- "home.moreItems_other": "+ {count} flere …",
- "shopping.completedBody_one": "1 vare blev lagt i madlageret.",
- "shopping.completedBody_other": "{count} varer blev lagt i madlageret.",
- "profile.consent.product_analytics": "Produktanalyse"
+ "shopping.section.konserver": "Konserves",
+ "shopping.section.kott_fagel": "Kød & fjerkræ",
+ "shopping.section.kryddor_bak": "Krydderier & bagning",
+ "shopping.section.mejeri": "Mejeri",
+ "shopping.section.skafferi": "Kolonial",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Indkøbsliste",
+ "tabs.home": "Derhjemme",
+ "tabs.myDay": "Min dag",
+ "tabs.scan": "Scan",
+ "tabs.whatToEat": "Hvad skal vi spise?",
+ "wte.coverage": "{pct} % derhjemme",
+ "wte.cravingPlaceholder": "Jeg har lyst til … (fx cremet, asiatisk, under 500 kcal)",
+ "wte.empty": "Ingen forslag endnu – læg lidt mad på lager eller løsn filtrene.",
+ "wte.mealBoxFirst": "Færdig mad derhjemme",
+ "wte.missing": "Mangler: {items}",
+ "wte.refresh": "Nye forslag",
+ "wte.subtitle": "Ud fra hvad I har derhjemme, hvad der snart skal bruges, og hvad I kan lide.",
+ "wte.title": "Hvad skal vi spise?",
+ "wte.whyTitle": "Hvorfor dette forslag?"
}
diff --git a/apps/mobile/src/locales/de/common.json b/apps/mobile/src/locales/de/common.json
index ab09d01..18c69f9 100644
--- a/apps/mobile/src/locales/de/common.json
+++ b/apps/mobile/src/locales/de/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Wird geladen …",
+ "auth.backToLogin": "Zurück zur Anmeldung",
+ "auth.displayName": "Wie sollen wir dich nennen?",
+ "auth.email": "E-Mail",
+ "auth.forgotBody": "Gib deine E-Mail-Adresse ein – wir senden einen Link, falls das Konto existiert.",
+ "auth.forgotLink": "Passwort vergessen?",
+ "auth.forgotSentBody": "Falls die Adresse ein Konto hat, haben wir einen 30 Minuten gültigen Link gesendet. Öffne ihn auf diesem Gerät.",
+ "auth.forgotSentTitle": "Prüfe dein Postfach",
+ "auth.forgotSubmit": "Link senden",
+ "auth.forgotTitle": "Passwort zurücksetzen",
+ "auth.hasAccount": "Schon ein Konto? Anmelden",
+ "auth.login": "Anmelden",
+ "auth.newPassword": "Neues Passwort (mind. 10 Zeichen)",
+ "auth.noAccount": "Neu hier? Konto erstellen",
+ "auth.password": "Passwort",
+ "auth.register": "Konto erstellen",
+ "auth.resetBody": "Der Link ist 30 Minuten gültig und nur einmal verwendbar. Alle Geräte werden abgemeldet.",
+ "auth.resetDoneBody": "Dein Passwort wurde geändert. Melde dich mit dem neuen an.",
+ "auth.resetDoneTitle": "Fertig!",
+ "auth.resetSubmit": "Passwort ändern",
+ "auth.resetTitle": "Neues Passwort wählen",
+ "auth.resetTokenPlaceholder": "Code aus der E-Mail einfügen",
+ "auth.trialNote": "7 Tage voller Zugriff – ohne Karte.",
+ "auth.verifyDoneBody": "Danke! Dein Konto ist jetzt verifiziert.",
+ "auth.verifyDoneTitle": "E-Mail bestätigt",
+ "auth.verifyFailedBody": "Der Link ist ungültig oder abgelaufen. Fordere im Profil einen neuen an.",
+ "auth.verifyFailedTitle": "Der Link hat nicht funktioniert",
+ "barcode.addPrompt": "Zum Vorrat hinzufügen?",
+ "barcode.aim": "Richte die Kamera auf den Barcode",
+ "barcode.allowCamera": "Kamera erlauben",
+ "barcode.cameraBody": "{brand} benötigt die Kamera, um Barcodes zu scannen.",
+ "barcode.cameraTitle": "Kamera erforderlich",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Du brauchst zuerst einen Haushalt.",
+ "barcode.noLocation": "Kein Lagerort gefunden.",
+ "barcode.noNutrition": "Keine Nährwertdaten",
+ "barcode.photoPackage": "Verpackung fotografieren",
+ "barcode.unknownBody": "Dieses Produkt ist noch nicht in der Datenbank. Fotografiere Vorderseite und Nährwerttabelle, dann fügen wir es hinzu.",
+ "barcode.unknownTitle": "Unbekanntes Produkt",
+ "common.add": "Hinzufügen",
+ "common.back": "Zurück",
+ "common.cancel": "Abbrechen",
+ "common.done": "Fertig",
"common.error": "Etwas ist schiefgelaufen. Bitte erneut versuchen.",
+ "common.estimate": "Schätzung",
+ "common.loading": "Wird geladen …",
+ "common.next": "Weiter",
+ "common.off": "Aus",
+ "common.offline": "Offline – zuletzt geladene Daten",
+ "common.on": "An",
+ "common.oops": "Hoppla",
+ "common.remove": "Entfernen",
"common.retry": "Erneut versuchen",
"common.save": "Speichern",
- "common.cancel": "Abbrechen",
- "common.next": "Weiter",
- "common.back": "Zurück",
- "common.done": "Fertig",
"common.skip": "Überspringen",
- "common.offline": "Offline – zuletzt geladene Daten",
- "common.estimate": "Schätzung",
- "tabs.whatToEat": "Was essen wir?",
- "tabs.scan": "Scannen",
- "tabs.myDay": "Mein Tag",
- "tabs.home": "Zuhause",
- "auth.login": "Anmelden",
- "auth.register": "Konto erstellen",
- "auth.email": "E-Mail",
- "auth.password": "Passwort",
- "auth.displayName": "Wie sollen wir dich nennen?",
- "auth.noAccount": "Neu hier? Konto erstellen",
- "auth.hasAccount": "Schon ein Konto? Anmelden",
- "auth.trialNote": "7 Tage voller Zugriff – ohne Karte.",
- "auth.forgotLink": "Passwort vergessen?",
- "auth.forgotTitle": "Passwort zurücksetzen",
- "auth.forgotBody": "Gib deine E-Mail-Adresse ein – wir senden einen Link, falls das Konto existiert.",
- "auth.forgotSubmit": "Link senden",
- "auth.forgotSentTitle": "Prüfe dein Postfach",
- "auth.forgotSentBody": "Falls die Adresse ein Konto hat, haben wir einen 30 Minuten gültigen Link gesendet. Öffne ihn auf diesem Gerät.",
- "auth.backToLogin": "Zurück zur Anmeldung",
- "auth.resetTitle": "Neues Passwort wählen",
- "auth.resetBody": "Der Link ist 30 Minuten gültig und nur einmal verwendbar. Alle Geräte werden abgemeldet.",
- "auth.resetTokenPlaceholder": "Code aus der E-Mail einfügen",
- "auth.newPassword": "Neues Passwort (mind. 10 Zeichen)",
- "auth.resetSubmit": "Passwort ändern",
- "auth.resetDoneTitle": "Fertig!",
- "auth.resetDoneBody": "Dein Passwort wurde geändert. Melde dich mit dem neuen an.",
- "auth.verifyDoneTitle": "E-Mail bestätigt",
- "auth.verifyDoneBody": "Danke! Dein Konto ist jetzt verifiziert.",
- "auth.verifyFailedTitle": "Der Link hat nicht funktioniert",
- "auth.verifyFailedBody": "Der Link ist ungültig oder abgelaufen. Fordere im Profil einen neuen an.",
- "onboarding.title": "Erzähl uns etwas über dich",
- "onboarding.subtitle": "Alles ist optional und jederzeit änderbar. Je mehr du ausfüllst, desto besser die Vorschläge.",
- "onboarding.goal": "Was ist dein wichtigstes Ziel?",
- "onboarding.diet": "Wie isst du?",
+ "common.undo": "Rückgängig",
+ "cooked.deductPantry": "Zutaten vom Vorrat abziehen",
+ "cooked.deductPantryNote": "Zutaten werden nach dem Prinzip zuerst-ablaufend-zuerst vom Vorrat abgezogen.",
+ "cooked.mealBoxes": "Portionen für Meal-Prep-Boxen",
+ "cooked.portionsCooked": "Gekochte Portionen",
+ "cooked.rate": "Bewerten",
+ "cooked.title": "Wie ist es gelaufen?",
+ "cooked.whoAte": "Wer hat gegessen?",
+ "cooking.finish": "Fertig – Mahlzeit erfassen",
+ "cooking.keepAwake": "Der Bildschirm bleibt beim Kochen an",
+ "cooking.scale": "Portionen",
+ "cooking.step": "Schritt {current} von {total}",
+ "cooking.timer": "Timer starten",
+ "cooking.timerDone": "Fertig!",
+ "cooking.timerRunning": "{time} übrig",
+ "home.budget": "Essensbudget",
+ "home.emptyInventory": "Der Vorrat ist leer. Scanne den Kühlschrank oder füge manuell hinzu.",
+ "home.expired": "Abgelaufen",
+ "home.expiresIn_one": "Noch 1 Tag",
+ "home.expiresIn_other": "Noch {days} Tage",
+ "home.expiresToday": "Läuft heute ab",
+ "home.household": "Haushalt",
+ "home.inventory": "Vorrat",
+ "home.mealBoxes": "Meal-Prep-Boxen",
+ "home.moreItems_one": "+ 1 weiterer …",
+ "home.moreItems_other": "+ {count} weitere …",
+ "home.pastBestBefore": "MHD überschritten – erst riechen und probieren",
+ "home.shopping": "Einkaufsliste",
+ "home.thisWeek": "Diese Woche",
+ "home.title": "Zuhause",
+ "home.useSoon": "Bald verbrauchen",
+ "home.useSoonHint": "Das Mindesthaltbarkeitsdatum ist eine Qualitätsgrenze – erst riechen, ansehen und probieren, bevor etwas weggeworfen wird. Das Verbrauchsdatum dagegen gilt strikt.",
+ "home.waste": "Lebensmittelabfall",
+ "home.wasteWeek": "Lebensmittelabfall diese Woche",
+ "household.empty": "Du hast noch keinen Haushalt. Lege einen im Onboarding an oder tritt per Code bei.",
+ "household.invite": "Einladen mit Code: {code}",
+ "household.locations": "Lagerorte",
+ "household.members": "Mitglieder",
+ "household.portionFactor": "×{factor} Portion",
+ "household.private": "Privat pro Person: Ziele, Allergien, Gesundheitsdaten und Essenshistorie.",
+ "household.role.adult": "Erwachsener",
+ "household.role.child": "Kind",
+ "household.role.member": "Mitglied",
+ "household.role.owner": "Inhaber",
+ "household.shareCode": "Teile den Code mit der Familie – dann teilt ihr Vorrat, Liste und Plan.",
+ "household.shared": "Im Haushalt geteilt: Vorrat, Einkaufsliste, Wochenplan, Boxen und Budget.",
+ "logmeal.manualTitle": "Manuell",
+ "logmeal.mealTypeTitle": "Mahlzeitentyp",
+ "logmeal.photoTip": "Tipp: Fotografiere den Teller unter Scannen – die App schätzt für dich, du bestätigst immer.",
+ "logmeal.proteinPlaceholder": "Protein (g)",
+ "logmeal.quickSubtitle": "Übernimmt dieselben Nährwerte wie beim letzten Mal.",
+ "logmeal.quickTitle": "Schnell erneut loggen",
+ "logmeal.validationBody": "Für manuelles Loggen sind Name und Kalorien nötig.",
+ "logmeal.validationTitle": "Angaben fehlen",
+ "logmeal.whatPlaceholder": "Was hast du gegessen?",
+ "mealbox.eat": "Jetzt essen",
+ "mealbox.eatBy": "Verzehren bis {date}",
+ "mealbox.empty": "Gerade keine Boxen. Beim Kochen kannst du hier Portionen aufheben.",
+ "mealbox.enjoyBody": "Die Portion wurde in Mein Tag geloggt.",
+ "mealbox.enjoyTitle": "Guten Appetit!",
+ "mealbox.guidanceNote": "Die empfohlene Frist ist eine Orientierung – verlass dich auf Geruch und Geschmack.",
+ "mealbox.portionsLeft_one": "Noch 1 Portion",
+ "mealbox.portionsLeft_other": "Noch {count} Portionen",
+ "mealbox.title": "Meal-Prep-Boxen",
+ "memory.delete": "Löschen",
+ "memory.deleteAll": "Gesamtes Gedächtnis löschen",
+ "memory.deleteAllTitle": "Gesamtes Gedächtnis löschen?",
+ "memory.empty": "{brand} hat noch nichts über dich gelernt.",
+ "memory.irreversible": "Das lässt sich nicht rückgängig machen.",
+ "memory.origin.ai_inferred": "KI-Annahme",
+ "memory.origin.observed": "Beobachtetes Muster",
+ "memory.origin.user_stated": "Von dir erzählt",
+ "memory.pause": "Pausieren",
+ "memory.paused": "Pausiert",
+ "memory.resume": "Fortsetzen",
+ "memory.subtitle": "Volle Transparenz. Korrigiere Fehler, pausiere oder lösche – dein Gedächtnis gehört dir.",
+ "memory.title": "Was {brand} über mich weiß",
+ "memory.verified": "Bestätigt",
+ "memory.verify": "Stimmt",
+ "myday.calories": "Kalorien",
+ "myday.carbs": "Kohlenhydrate",
+ "myday.estimateNote": "Werte mit ~ sind Schätzungen, die du anpassen kannst.",
+ "myday.estimateRange": "{min}–{max} kcal, wahrscheinlich {kcal}",
+ "myday.fat": "Fett",
+ "myday.fiber": "Ballaststoffe",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g Protein",
+ "myday.logMeal": "Mahlzeit erfassen",
+ "myday.mealType.breakfast": "Frühstück",
+ "myday.mealType.dessert": "Nachtisch",
+ "myday.mealType.dinner": "Abendessen",
+ "myday.mealType.lunch": "Mittagessen",
+ "myday.mealType.snack": "Snack",
+ "myday.noMeals": "Heute noch keine Mahlzeiten erfasst.",
+ "myday.over": "{kcal} kcal über dem Ziel",
+ "myday.overRecommended": "Über der Empfehlung",
+ "myday.protein": "Eiweiß",
+ "myday.remaining": "{kcal} kcal übrig",
+ "myday.salt": "Salz",
+ "myday.targetsNote": "Ziele sind Orientierung, keine medizinische Beratung.",
+ "myday.title": "Mein Tag",
+ "myday.todaysMeals": "Heutige Mahlzeiten",
+ "onboarding.allergen.crustaceans": "Krebstiere",
+ "onboarding.allergen.eggs": "Eier",
+ "onboarding.allergen.fish": "Fisch",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Milch/Laktose",
+ "onboarding.allergen.peanuts": "Erdnüsse",
+ "onboarding.allergen.sesame": "Sesam",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Schalenfrüchte",
"onboarding.allergies": "Allergien und Unverträglichkeiten",
"onboarding.allergyNote": "Der Allergiefilter ist immer strikt – Gerichte mit deinen Allergenen werden nie angezeigt.",
+ "onboarding.birthYearPlaceholder": "Geburtsjahr",
+ "onboarding.bodyTitle": "Für persönliche Kalorienziele (optional)",
+ "onboarding.diet": "Wie isst du?",
+ "onboarding.diet.flexitarian": "Flexitarier",
+ "onboarding.diet.omnivore": "Allesesser",
+ "onboarding.diet.pescatarian": "Pescetarier",
+ "onboarding.diet.vegan": "Veganer",
+ "onboarding.diet.vegetarian": "Vegetarier",
+ "onboarding.goal": "Was ist dein wichtigstes Ziel?",
+ "onboarding.goal.build_muscle": "Muskeln aufbauen",
+ "onboarding.goal.cook_more": "Öfter selbst kochen",
+ "onboarding.goal.less_waste": "Weniger wegwerfen",
+ "onboarding.goal.lose_weight": "Abnehmen",
+ "onboarding.goal.lower_cost": "Weniger für Essen ausgeben",
+ "onboarding.goal.maintain_weight": "Gewicht halten",
+ "onboarding.goal.more_protein": "Mehr Protein essen",
+ "onboarding.heightPlaceholder": "Größe (cm)",
"onboarding.household": "Dein Haushalt",
"onboarding.householdCreate": "Haushalt erstellen",
+ "onboarding.householdDefaultName": "Zuhause",
"onboarding.householdJoin": "Mit Code beitreten",
"onboarding.householdName": "Name des Haushalts",
"onboarding.inviteCode": "Einladungscode",
"onboarding.mode": "Wie genau möchtest du es?",
- "onboarding.modeSimple": "Einfacher Modus",
- "onboarding.modeSimpleDesc": "Essen fotografieren, Schätzungen akzeptieren, kein Aufwand.",
"onboarding.modeExact": "Exakter Modus",
"onboarding.modeExactDesc": "Essen wiegen, Gramm eingeben, volle Kontrolle über die Zahlen.",
+ "onboarding.modesCombine": "Die Modi lassen sich kombinieren – im Alltag einfach, exakt wenn du willst.",
+ "onboarding.modeSimple": "Einfacher Modus",
+ "onboarding.modeSimpleDesc": "Essen fotografieren, Schätzungen akzeptieren, kein Aufwand.",
"onboarding.notMedical": "{brand} bietet Orientierung – keine medizinische Beratung.",
- "wte.title": "Was essen wir?",
- "wte.subtitle": "Basierend auf dem, was ihr zuhause habt, was bald verbraucht werden sollte und was ihr mögt.",
- "wte.cravingPlaceholder": "Ich habe Lust auf … (z. B. cremig, asiatisch, unter 500 kcal)",
- "wte.mealBoxFirst": "Fertiges Essen zuhause",
- "wte.whyTitle": "Warum dieser Vorschlag?",
- "wte.coverage": "{pct} % zuhause",
- "wte.missing": "Fehlt: {items}",
- "wte.empty": "Noch keine Vorschläge – fülle den Vorrat oder lockere die Filter.",
- "wte.refresh": "Neue Vorschläge",
- "scan.title": "Scannen",
- "scan.subtitle": "Fülle deinen Vorrat oder erfasse eine Mahlzeit mit der Kamera.",
- "scan.fridge": "Kühlschrank",
- "scan.freezer": "Gefrierschrank",
- "scan.pantry": "Vorratsschrank",
- "scan.ingredients": "Zutaten",
- "scan.plate": "Teller",
- "scan.receipt": "Kassenbon",
- "scan.barcode": "Barcode",
- "scan.expiry": "Mindesthaltbarkeitsdatum",
- "scan.nutrition": "Nährwertangaben",
- "scan.takePhoto": "Foto aufnehmen",
- "scan.tips.title": "So gelingt die Analyse am besten",
- "scan.tips.overview": "Beginne mit einem Übersichtsfoto",
- "scan.tips.shelf": "Fotografiere Fach für Fach",
- "scan.tips.light": "Vermeide Dunkelheit und Schatten",
- "scan.tips.move": "Rücke verdeckte Produkte frei",
- "scan.analyzing": "Analyse läuft …",
- "scan.quotaLeft_one": "1 KI-Scan diesen Monat übrig",
- "scan.quotaLeft_other": "{count} KI-Scans diesen Monat übrig",
- "scan.review.title": "Ergebnis prüfen",
- "scan.review.subtitle": "Die KI ist manchmal unsicher – du entscheidest. Bearbeite, entferne oder ergänze vor dem Speichern.",
- "scan.review.uncertain": "Unsicher – bitte prüfen",
- "scan.review.approveAll": "In den Vorrat speichern",
- "scan.review.rejected": "Entfernt",
- "scan.failed": "Analyse fehlgeschlagen. Erneut versuchen oder manuell erfassen.",
- "myday.title": "Mein Tag",
- "myday.calories": "Kalorien",
- "myday.protein": "Eiweiß",
- "myday.carbs": "Kohlenhydrate",
- "myday.fat": "Fett",
- "myday.fiber": "Ballaststoffe",
- "myday.salt": "Salz",
- "myday.remaining": "{kcal} kcal übrig",
- "myday.over": "{kcal} kcal über dem Ziel",
- "myday.logMeal": "Mahlzeit erfassen",
- "myday.noMeals": "Heute noch keine Mahlzeiten erfasst.",
- "myday.estimateNote": "Werte mit ~ sind Schätzungen, die du anpassen kannst.",
- "myday.targetsNote": "Ziele sind Orientierung, keine medizinische Beratung.",
- "home.title": "Zuhause",
- "home.inventory": "Vorrat",
- "home.useSoon": "Bald verbrauchen",
- "home.mealBoxes": "Meal-Prep-Boxen",
- "home.shopping": "Einkaufsliste",
- "home.budget": "Essensbudget",
- "home.household": "Haushalt",
- "home.waste": "Lebensmittelabfall",
- "home.emptyInventory": "Der Vorrat ist leer. Scanne den Kühlschrank oder füge manuell hinzu.",
- "home.expiresIn_one": "Noch 1 Tag",
- "home.expiresIn_other": "Noch {days} Tage",
- "home.expiresToday": "Läuft heute ab",
- "home.expired": "Abgelaufen",
- "home.pastBestBefore": "MHD überschritten – erst riechen und probieren",
+ "onboarding.stepBSubtitle": "Passe dein Profil für bessere Vorschläge an.",
+ "onboarding.stepBTitle": "Einrichtung fortsetzen",
+ "onboarding.stepCSubtitle": "Optional – wird für persönliche Kalorienziele verwendet.",
+ "onboarding.stepCTitle": "Dein Gesundheitsprofil",
+ "onboarding.subtitle": "Alles ist optional und jederzeit änderbar. Je mehr du ausfüllst, desto besser die Vorschläge.",
+ "onboarding.title": "Erzähl uns etwas über dich",
+ "onboarding.weightPlaceholder": "Gewicht (kg)",
+ "paywall.choose": "Wählen",
+ "paywall.fairUse": "Fair-Use-Kontingent für KI-Scans inklusive.",
+ "paywall.family": "Family · bis zu 6 Personen",
+ "paywall.freeNote": "Gratis: 10 KI-Scans/Monat, manueller Vorrat, gespeicherte Rezepte und einfaches Tracking.",
+ "paywall.household": "Household · bis zu 3 Personen",
+ "paywall.large": "Large Household · bis zu 12 Personen",
+ "paywall.perMonth": "{price}/Monat",
+ "paywall.popular": "Am beliebtesten",
+ "paywall.restore": "Käufe wiederherstellen",
+ "paywall.soonBody": "Käufe laufen über App Store/Google Play, sobald die Store-Integration aktiviert ist (Phase 7). Das Backend ist bereits fertig.",
+ "paywall.soonTitle": "Bald!",
+ "paywall.subtitle": "Das Food-Betriebssystem für den ganzen Haushalt: unbegrenzter Vorrat, Wochenplan und Teilen.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "Noch 1 Tag Testzeitraum",
+ "paywall.trialActive_other": "Noch {days} Tage Testzeitraum",
+ "profile.aiScansUsed": "KI-Scans: {used} / {total} diesen Monat",
+ "profile.consent.anonymized_improvement": "Anonymisierte Verbesserung der KI",
+ "profile.consent.health_integration": "Gesundheitsdaten (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Meine Bilder dürfen fürs Training genutzt werden",
+ "profile.consent.location_weather": "Standort für wetterbasierte Vorschläge",
+ "profile.consent.personalization": "Persönliche Funktionen (Gedächtnis & Geschmacksprofil)",
+ "profile.consent.product_analytics": "Produktanalyse",
+ "profile.consent.push_notifications": "Push-Benachrichtigungen",
+ "profile.consents": "Einwilligungen & Daten",
+ "profile.consentsNote": "Die Einwilligungen sind getrennt – persönliche Funktionen erfordern nie eine Trainings-Einwilligung.",
+ "profile.deleteAccount": "Konto löschen",
+ "profile.deleteBody": "Alle deine Daten werden gemäß DSGVO dauerhaft gelöscht.",
+ "profile.deleteTitle": "Konto löschen?",
+ "profile.emailUnverified": "E-Mail-Adresse nicht bestätigt",
+ "profile.export": "Meine Daten exportieren",
+ "profile.goals": "Ziele & Ernährung",
+ "profile.language": "Sprache",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Abmelden",
+ "profile.memory": "Was {brand} über mich weiß",
+ "profile.memorySubtitle": "Sieh, korrigiere, pausiere oder lösche, was die Plattform gelernt hat.",
+ "profile.modeLabel": "Modus:",
+ "profile.resendVerification": "Bestätigungsmail erneut senden",
+ "profile.subscription": "Abo",
+ "profile.title": "Profil",
+ "profile.verificationSent": "Gesendet! Prüfe dein Postfach.",
+ "recipe.avgRating": "Schnitt {avg} bei {count} Bewertungen",
+ "recipe.cook": "Jetzt kochen",
+ "recipe.cost": "ca. {amount}/Portion",
+ "recipe.iCookedThis": "Habe ich gekocht",
+ "recipe.ingredients": "Zutaten",
+ "recipe.notSafe": "Passt nicht zu deinen Ernährungseinstellungen",
+ "recipe.perPortion": "pro Portion",
"recipe.portions_one": "1 Portion",
"recipe.portions_other": "{count} Portionen",
- "recipe.time": "{min} Min.",
- "recipe.perPortion": "pro Portion",
- "recipe.ingredients": "Zutaten",
+ "recipe.save": "Speichern",
+ "recipe.saved": "Gespeichert",
"recipe.steps": "Zubereitung",
- "recipe.cook": "Jetzt kochen",
- "recipe.notSafe": "Passt nicht zu deinen Ernährungseinstellungen",
"recipe.substitutions": "Ersetzen",
- "recipe.iCookedThis": "Habe ich gekocht",
- "recipe.cost": "ca. {amount}/Portion",
- "cooking.step": "Schritt {current} von {total}",
- "cooking.timer": "Timer starten",
- "cooking.timerRunning": "{time} übrig",
- "cooking.finish": "Fertig – Mahlzeit erfassen",
- "cooking.scale": "Portionen",
- "cooking.keepAwake": "Der Bildschirm bleibt beim Kochen an",
- "cooked.title": "Wie ist es gelaufen?",
- "cooked.portionsCooked": "Gekochte Portionen",
- "cooked.whoAte": "Wer hat gegessen?",
- "cooked.mealBoxes": "Portionen für Meal-Prep-Boxen",
- "cooked.deductPantry": "Zutaten vom Vorrat abziehen",
- "cooked.rate": "Bewerten",
- "shopping.title": "Einkaufsliste",
+ "recipe.time": "{min} Min.",
+ "scan.analyzing": "Analyse läuft …",
+ "scan.barcode": "Barcode",
+ "scan.expiry": "Mindesthaltbarkeitsdatum",
+ "scan.failed": "Analyse fehlgeschlagen. Erneut versuchen oder manuell erfassen.",
+ "scan.freezer": "Gefrierschrank",
+ "scan.fridge": "Kühlschrank",
+ "scan.ingredients": "Zutaten",
+ "scan.nutrition": "Nährwertangaben",
+ "scan.pantry": "Vorratsschrank",
+ "scan.plate": "Teller",
+ "scan.quotaLeft_one": "1 KI-Scan diesen Monat übrig",
+ "scan.quotaLeft_other": "{count} KI-Scans diesen Monat übrig",
+ "scan.receipt": "Kassenbon",
+ "scan.review.addItem": "+ Artikel hinzufügen",
+ "scan.review.approveAll": "In den Vorrat speichern",
+ "scan.review.bestBeforeNote": "Qualitätsdatum – oft ist das Lebensmittel danach noch gut. Erst riechen und probieren.",
+ "scan.review.dateKindBestBefore": "Mindesthaltbarkeit (MHD)",
+ "scan.review.dateKindUseBy": "Verbrauchsdatum",
+ "scan.review.datePlaceholder": "JJJJ-MM-TT (optional)",
+ "scan.review.itemPlaceholder": "Artikel",
+ "scan.review.quantityPlaceholder": "Menge",
+ "scan.review.rejected": "Entfernt",
+ "scan.review.subtitle": "Die KI ist manchmal unsicher – du entscheidest. Bearbeite, entferne oder ergänze vor dem Speichern.",
+ "scan.review.title": "Ergebnis prüfen",
+ "scan.review.uncertain": "Unsicher – bitte prüfen",
+ "scan.review.unitPlaceholder": "Einheit (g, l, Stk. …)",
+ "scan.review.unknownItem": "Unbekannter Artikel",
+ "scan.review.useByNote": "Sicherheitsdatum – danach nicht mehr essen.",
+ "scan.subtitle": "Fülle deinen Vorrat oder erfasse eine Mahlzeit mit der Kamera.",
+ "scan.takePhoto": "Foto aufnehmen",
+ "scan.tips.light": "Vermeide Dunkelheit und Schatten",
+ "scan.tips.move": "Rücke verdeckte Produkte frei",
+ "scan.tips.overview": "Beginne mit einem Übersichtsfoto",
+ "scan.tips.shelf": "Fotografiere Fach für Fach",
+ "scan.tips.title": "So gelingt die Analyse am besten",
+ "scan.title": "Scannen",
"shopping.addPlaceholder": "Artikel hinzufügen …",
"shopping.complete": "Einkauf abschließen",
+ "shopping.completedBody_one": "1 Artikel wurde in den Vorrat übernommen.",
+ "shopping.completedBody_other": "{count} Artikel wurden in den Vorrat übernommen.",
+ "shopping.completedTitle": "Fertig!",
"shopping.completeNote": "Abgehakte Artikel wandern in den Vorrat.",
"shopping.empty": "Die Liste ist leer.",
"shopping.estimated": "ca. {amount}",
"shopping.estimatedTotal": "Geschätzte Summe: ca. {amount}",
- "mealbox.title": "Meal-Prep-Boxen",
- "mealbox.eatBy": "Verzehren bis {date}",
- "mealbox.portionsLeft_one": "Noch 1 Portion",
- "mealbox.portionsLeft_other": "Noch {count} Portionen",
- "mealbox.eat": "Jetzt essen",
- "mealbox.empty": "Gerade keine Boxen. Beim Kochen kannst du hier Portionen aufheben.",
- "household.members": "Mitglieder",
- "household.invite": "Einladen mit Code: {code}",
- "household.shared": "Im Haushalt geteilt: Vorrat, Einkaufsliste, Wochenplan, Boxen und Budget.",
- "household.private": "Privat pro Person: Ziele, Allergien, Gesundheitsdaten und Essenshistorie.",
- "memory.title": "Was {brand} über mich weiß",
- "memory.subtitle": "Volle Transparenz. Korrigiere Fehler, pausiere oder lösche – dein Gedächtnis gehört dir.",
- "memory.paused": "Pausiert",
- "memory.verify": "Stimmt",
- "memory.pause": "Pausieren",
- "memory.delete": "Löschen",
- "memory.deleteAll": "Gesamtes Gedächtnis löschen",
- "memory.empty": "{brand} hat noch nichts über dich gelernt.",
- "memory.origin.user_stated": "Von dir erzählt",
- "memory.origin.observed": "Beobachtetes Muster",
- "memory.origin.ai_inferred": "KI-Annahme",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "Das Food-Betriebssystem für den ganzen Haushalt: unbegrenzter Vorrat, Wochenplan und Teilen.",
- "paywall.trialActive_one": "Noch 1 Tag Testzeitraum",
- "paywall.trialActive_other": "Noch {days} Tage Testzeitraum",
- "paywall.household": "Household · bis zu 3 Personen",
- "paywall.family": "Family · bis zu 6 Personen",
- "paywall.large": "Large Household · bis zu 12 Personen",
- "paywall.perMonth": "{price}/Monat",
- "paywall.fairUse": "Fair-Use-Kontingent für KI-Scans inklusive.",
- "paywall.restore": "Käufe wiederherstellen",
- "paywall.freeNote": "Gratis: 10 KI-Scans/Monat, manueller Vorrat, gespeicherte Rezepte und einfaches Tracking.",
- "profile.title": "Profil",
- "profile.goals": "Ziele & Ernährung",
- "profile.consents": "Einwilligungen & Daten",
- "profile.memory": "Was {brand} über mich weiß",
- "profile.subscription": "Abo",
- "profile.logout": "Abmelden",
- "profile.export": "Meine Daten exportieren",
- "profile.deleteAccount": "Konto löschen",
- "profile.language": "Sprache",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.emailUnverified": "E-Mail-Adresse nicht bestätigt",
- "profile.resendVerification": "Bestätigungsmail erneut senden",
- "profile.verificationSent": "Gesendet! Prüfe dein Postfach.",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Hoppla",
- "common.undo": "Rückgängig",
- "common.remove": "Entfernen",
- "common.add": "Hinzufügen",
- "common.on": "An",
- "common.off": "Aus",
- "home.thisWeek": "Diese Woche",
- "home.wasteWeek": "Lebensmittelabfall diese Woche",
- "home.useSoonHint": "Das Mindesthaltbarkeitsdatum ist eine Qualitätsgrenze – erst riechen, ansehen und probieren, bevor etwas weggeworfen wird. Das Verbrauchsdatum dagegen gilt strikt.",
- "scan.review.itemPlaceholder": "Artikel",
- "scan.review.quantityPlaceholder": "Menge",
- "scan.review.unitPlaceholder": "Einheit (g, l, Stk. …)",
- "scan.review.datePlaceholder": "JJJJ-MM-TT (optional)",
- "scan.review.dateKindBestBefore": "Mindesthaltbarkeit (MHD)",
- "scan.review.dateKindUseBy": "Verbrauchsdatum",
- "scan.review.bestBeforeNote": "Qualitätsdatum – oft ist das Lebensmittel danach noch gut. Erst riechen und probieren.",
- "scan.review.useByNote": "Sicherheitsdatum – danach nicht mehr essen.",
- "scan.review.addItem": "+ Artikel hinzufügen",
- "scan.review.unknownItem": "Unbekannter Artikel",
- "barcode.aim": "Richte die Kamera auf den Barcode",
- "barcode.addPrompt": "Zum Vorrat hinzufügen?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Keine Nährwertdaten",
- "barcode.unknownTitle": "Unbekanntes Produkt",
- "barcode.unknownBody": "Dieses Produkt ist noch nicht in der Datenbank. Fotografiere Vorderseite und Nährwerttabelle, dann fügen wir es hinzu.",
- "barcode.photoPackage": "Verpackung fotografieren",
- "barcode.needHousehold": "Du brauchst zuerst einen Haushalt.",
- "barcode.noLocation": "Kein Lagerort gefunden.",
- "barcode.cameraTitle": "Kamera erforderlich",
- "barcode.cameraBody": "{brand} benötigt die Kamera, um Barcodes zu scannen.",
- "barcode.allowCamera": "Kamera erlauben",
- "onboarding.goal.lose_weight": "Abnehmen",
- "onboarding.goal.build_muscle": "Muskeln aufbauen",
- "onboarding.goal.maintain_weight": "Gewicht halten",
- "onboarding.goal.more_protein": "Mehr Protein essen",
- "onboarding.goal.less_waste": "Weniger wegwerfen",
- "onboarding.goal.lower_cost": "Weniger für Essen ausgeben",
- "onboarding.goal.cook_more": "Öfter selbst kochen",
- "onboarding.diet.omnivore": "Allesesser",
- "onboarding.diet.flexitarian": "Flexitarier",
- "onboarding.diet.pescatarian": "Pescetarier",
- "onboarding.diet.vegetarian": "Vegetarier",
- "onboarding.diet.vegan": "Veganer",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Milch/Laktose",
- "onboarding.allergen.eggs": "Eier",
- "onboarding.allergen.tree_nuts": "Schalenfrüchte",
- "onboarding.allergen.peanuts": "Erdnüsse",
- "onboarding.allergen.fish": "Fisch",
- "onboarding.allergen.crustaceans": "Krebstiere",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sesam",
- "onboarding.bodyTitle": "Für persönliche Kalorienziele (optional)",
- "onboarding.weightPlaceholder": "Gewicht (kg)",
- "onboarding.heightPlaceholder": "Größe (cm)",
- "onboarding.birthYearPlaceholder": "Geburtsjahr",
- "onboarding.householdDefaultName": "Zuhause",
- "onboarding.modesCombine": "Die Modi lassen sich kombinieren – im Alltag einfach, exakt wenn du willst.",
- "myday.mealType.breakfast": "Frühstück",
- "myday.mealType.lunch": "Mittagessen",
- "myday.mealType.dinner": "Abendessen",
- "myday.mealType.snack": "Snack",
- "myday.mealType.dessert": "Nachtisch",
- "myday.overRecommended": "Über der Empfehlung",
- "myday.todaysMeals": "Heutige Mahlzeiten",
- "myday.estimateRange": "{min}–{max} kcal, wahrscheinlich {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g Protein",
- "logmeal.mealTypeTitle": "Mahlzeitentyp",
- "logmeal.quickTitle": "Schnell erneut loggen",
- "logmeal.quickSubtitle": "Übernimmt dieselben Nährwerte wie beim letzten Mal.",
- "logmeal.manualTitle": "Manuell",
- "logmeal.whatPlaceholder": "Was hast du gegessen?",
- "logmeal.proteinPlaceholder": "Protein (g)",
- "logmeal.validationTitle": "Angaben fehlen",
- "logmeal.validationBody": "Für manuelles Loggen sind Name und Kalorien nötig.",
- "logmeal.photoTip": "Tipp: Fotografiere den Teller unter Scannen – die App schätzt für dich, du bestätigst immer.",
- "shopping.section.frukt_gront": "Obst & Gemüse",
"shopping.section.brod": "Brot",
- "shopping.section.mejeri": "Molkereiprodukte",
- "shopping.section.kott_fagel": "Fleisch & Geflügel",
- "shopping.section.fisk": "Fisch",
"shopping.section.chark": "Wurstwaren",
- "shopping.section.frys": "Tiefkühl",
- "shopping.section.skafferi": "Vorratsschrank",
- "shopping.section.konserver": "Konserven",
- "shopping.section.kryddor_bak": "Gewürze & Backen",
"shopping.section.dryck": "Getränke",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Fisch",
+ "shopping.section.frukt_gront": "Obst & Gemüse",
+ "shopping.section.frys": "Tiefkühl",
"shopping.section.hygien_ovrigt": "Sonstiges",
- "shopping.completedTitle": "Fertig!",
- "household.role.owner": "Inhaber",
- "household.role.adult": "Erwachsener",
- "household.role.member": "Mitglied",
- "household.role.child": "Kind",
- "household.empty": "Du hast noch keinen Haushalt. Lege einen im Onboarding an oder tritt per Code bei.",
- "household.shareCode": "Teile den Code mit der Familie – dann teilt ihr Vorrat, Liste und Plan.",
- "household.locations": "Lagerorte",
- "household.portionFactor": "×{factor} Portion",
- "mealbox.enjoyTitle": "Guten Appetit!",
- "mealbox.enjoyBody": "Die Portion wurde in Mein Tag geloggt.",
- "mealbox.guidanceNote": "Die empfohlene Frist ist eine Orientierung – verlass dich auf Geruch und Geschmack.",
- "paywall.soonTitle": "Bald!",
- "paywall.soonBody": "Käufe laufen über App Store/Google Play, sobald die Store-Integration aktiviert ist (Phase 7). Das Backend ist bereits fertig.",
- "paywall.popular": "Am beliebtesten",
- "paywall.choose": "Wählen",
- "recipe.saved": "Gespeichert",
- "recipe.save": "Speichern",
- "recipe.avgRating": "Schnitt {avg} bei {count} Bewertungen",
- "memory.verified": "Bestätigt",
- "memory.resume": "Fortsetzen",
- "memory.deleteAllTitle": "Gesamtes Gedächtnis löschen?",
- "memory.irreversible": "Das lässt sich nicht rückgängig machen.",
- "profile.consent.personalization": "Persönliche Funktionen (Gedächtnis & Geschmacksprofil)",
- "profile.consent.anonymized_improvement": "Anonymisierte Verbesserung der KI",
- "profile.consent.image_training": "Meine Bilder dürfen fürs Training genutzt werden",
- "profile.consent.health_integration": "Gesundheitsdaten (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Standort für wetterbasierte Vorschläge",
- "profile.consent.push_notifications": "Push-Benachrichtigungen",
- "profile.modeLabel": "Modus:",
- "profile.memorySubtitle": "Sieh, korrigiere, pausiere oder lösche, was die Plattform gelernt hat.",
- "profile.consentsNote": "Die Einwilligungen sind getrennt – persönliche Funktionen erfordern nie eine Trainings-Einwilligung.",
- "profile.aiScansUsed": "KI-Scans: {used} / {total} diesen Monat",
- "profile.deleteTitle": "Konto löschen?",
- "profile.deleteBody": "Alle deine Daten werden gemäß DSGVO dauerhaft gelöscht.",
- "cooking.timerDone": "Fertig!",
- "cooked.deductPantryNote": "Zutaten werden nach dem Prinzip zuerst-ablaufend-zuerst vom Vorrat abgezogen.",
- "home.moreItems_one": "+ 1 weiterer …",
- "home.moreItems_other": "+ {count} weitere …",
- "shopping.completedBody_one": "1 Artikel wurde in den Vorrat übernommen.",
- "shopping.completedBody_other": "{count} Artikel wurden in den Vorrat übernommen.",
- "profile.consent.product_analytics": "Produktanalyse"
+ "shopping.section.konserver": "Konserven",
+ "shopping.section.kott_fagel": "Fleisch & Geflügel",
+ "shopping.section.kryddor_bak": "Gewürze & Backen",
+ "shopping.section.mejeri": "Molkereiprodukte",
+ "shopping.section.skafferi": "Vorratsschrank",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Einkaufsliste",
+ "tabs.home": "Zuhause",
+ "tabs.myDay": "Mein Tag",
+ "tabs.scan": "Scannen",
+ "tabs.whatToEat": "Was essen wir?",
+ "wte.coverage": "{pct} % zuhause",
+ "wte.cravingPlaceholder": "Ich habe Lust auf … (z. B. cremig, asiatisch, unter 500 kcal)",
+ "wte.empty": "Noch keine Vorschläge – fülle den Vorrat oder lockere die Filter.",
+ "wte.mealBoxFirst": "Fertiges Essen zuhause",
+ "wte.missing": "Fehlt: {items}",
+ "wte.refresh": "Neue Vorschläge",
+ "wte.subtitle": "Basierend auf dem, was ihr zuhause habt, was bald verbraucht werden sollte und was ihr mögt.",
+ "wte.title": "Was essen wir?",
+ "wte.whyTitle": "Warum dieser Vorschlag?"
}
diff --git a/apps/mobile/src/locales/en/common.json b/apps/mobile/src/locales/en/common.json
index 543d8e9..abe5ca9 100644
--- a/apps/mobile/src/locales/en/common.json
+++ b/apps/mobile/src/locales/en/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Loading …",
+ "auth.backToLogin": "Back to login",
+ "auth.displayName": "What should we call you?",
+ "auth.email": "Email",
+ "auth.forgotBody": "Enter your email and we'll send a reset link if the account exists.",
+ "auth.forgotLink": "Forgot your password?",
+ "auth.forgotSentBody": "If the address has an account, we've sent a link valid for 30 minutes. Open it on this device.",
+ "auth.forgotSentTitle": "Check your inbox",
+ "auth.forgotSubmit": "Send link",
+ "auth.forgotTitle": "Reset password",
+ "auth.hasAccount": "Already have an account? Log in",
+ "auth.login": "Log in",
+ "auth.newPassword": "New password (at least 10 characters)",
+ "auth.noAccount": "New here? Create an account",
+ "auth.password": "Password",
+ "auth.register": "Create account",
+ "auth.resetBody": "The link is valid for 30 minutes and can only be used once. All devices are signed out when the password changes.",
+ "auth.resetDoneBody": "Your password has been changed. Log in with your new password.",
+ "auth.resetDoneTitle": "Done!",
+ "auth.resetSubmit": "Change password",
+ "auth.resetTitle": "Choose a new password",
+ "auth.resetTokenPlaceholder": "Paste the code from the email",
+ "auth.trialNote": "7 days of full access – no card required.",
+ "auth.verifyDoneBody": "Thanks! Your account is now verified.",
+ "auth.verifyDoneTitle": "Email confirmed",
+ "auth.verifyFailedBody": "The link is invalid or has expired. Request a new one from your profile.",
+ "auth.verifyFailedTitle": "The link didn't work",
+ "barcode.addPrompt": "Add to your inventory?",
+ "barcode.aim": "Point the camera at the barcode",
+ "barcode.allowCamera": "Allow camera",
+ "barcode.cameraBody": "{brand} needs the camera to scan barcodes.",
+ "barcode.cameraTitle": "Camera needed",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "You need a household first.",
+ "barcode.noLocation": "No storage location found.",
+ "barcode.noNutrition": "No nutrition data",
+ "barcode.photoPackage": "Photograph the package",
+ "barcode.unknownBody": "This product isn't in the database yet. Photograph the front and the nutrition label and we'll add it.",
+ "barcode.unknownTitle": "Unknown product",
+ "common.add": "Add",
+ "common.back": "Back",
+ "common.cancel": "Cancel",
+ "common.done": "Done",
"common.error": "Something went wrong. Please try again.",
+ "common.estimate": "Estimate",
+ "common.loading": "Loading …",
+ "common.next": "Next",
+ "common.off": "Off",
+ "common.offline": "Offline – showing last fetched data",
+ "common.on": "On",
+ "common.oops": "Oops",
+ "common.remove": "Remove",
"common.retry": "Try again",
"common.save": "Save",
- "common.cancel": "Cancel",
- "common.next": "Next",
- "common.back": "Back",
- "common.done": "Done",
"common.skip": "Skip",
- "common.offline": "Offline – showing last fetched data",
- "common.estimate": "Estimate",
- "tabs.whatToEat": "What's for dinner?",
- "tabs.scan": "Scan",
- "tabs.myDay": "My day",
- "tabs.home": "At home",
- "auth.login": "Log in",
- "auth.register": "Create account",
- "auth.email": "Email",
- "auth.password": "Password",
- "auth.displayName": "What should we call you?",
- "auth.noAccount": "New here? Create an account",
- "auth.hasAccount": "Already have an account? Log in",
- "auth.trialNote": "7 days of full access – no card required.",
- "onboarding.title": "Tell us a little about yourself",
- "onboarding.subtitle": "Everything is optional and can be changed at any time. The more you fill in, the better the suggestions.",
- "onboarding.goal": "What is your main goal?",
- "onboarding.diet": "How do you eat?",
+ "common.undo": "Undo",
+ "cooked.deductPantry": "Deduct ingredients from inventory",
+ "cooked.deductPantryNote": "Ingredients are deducted from your inventory, first-expiring first.",
+ "cooked.mealBoxes": "Servings to meal boxes",
+ "cooked.portionsCooked": "Servings cooked",
+ "cooked.rate": "Rate it",
+ "cooked.title": "How did it go?",
+ "cooked.whoAte": "Who ate?",
+ "cooking.finish": "Done – log the meal",
+ "cooking.keepAwake": "The screen stays awake while you cook",
+ "cooking.scale": "Servings",
+ "cooking.step": "Step {current} of {total}",
+ "cooking.timer": "Start timer",
+ "cooking.timerDone": "Done!",
+ "cooking.timerRunning": "{time} left",
+ "home.budget": "Food budget",
+ "home.emptyInventory": "Your inventory is empty. Scan the fridge or add items manually.",
+ "home.expired": "Expired",
+ "home.expiresIn_one": "1 day left",
+ "home.expiresIn_other": "{days} days left",
+ "home.expiresToday": "Expires today",
+ "home.household": "Household",
+ "home.inventory": "Food inventory",
+ "home.mealBoxes": "Meal boxes",
+ "home.moreItems_one": "+ 1 more …",
+ "home.moreItems_other": "+ {count} more …",
+ "home.pastBestBefore": "Past best before – smell and taste first",
+ "home.shopping": "Shopping list",
+ "home.thisWeek": "This week",
+ "home.title": "At home",
+ "home.useSoon": "Use soon",
+ "home.useSoonHint": "Best before is about quality – smell, look and taste before you throw anything away. Use-by dates, however, should be respected.",
+ "home.waste": "Food waste",
+ "home.wasteWeek": "Food waste this week",
+ "household.empty": "You don't have a household yet. Create one in onboarding or join with a code.",
+ "household.invite": "Invite with code: {code}",
+ "household.locations": "Storage locations",
+ "household.members": "Members",
+ "household.portionFactor": "×{factor} portion",
+ "household.private": "Private per person: goals, allergies, health data and meal history.",
+ "household.role.adult": "Adult",
+ "household.role.child": "Child",
+ "household.role.member": "Member",
+ "household.role.owner": "Owner",
+ "household.shareCode": "Share the code with your family to share inventory, list and plan.",
+ "household.shared": "Shared in the household: food inventory, shopping list, week plan, meal boxes and budget.",
+ "logmeal.manualTitle": "Manual",
+ "logmeal.mealTypeTitle": "Meal type",
+ "logmeal.photoTip": "Tip: photograph your plate under Scan and the app estimates for you – you always confirm.",
+ "logmeal.proteinPlaceholder": "protein (g)",
+ "logmeal.quickSubtitle": "Logs the same nutrition values as last time.",
+ "logmeal.quickTitle": "Quick re-log",
+ "logmeal.validationBody": "Name and calories are required for manual logging.",
+ "logmeal.validationTitle": "Missing info",
+ "logmeal.whatPlaceholder": "What did you eat?",
+ "mealbox.eat": "Eat now",
+ "mealbox.eatBy": "Eat by {date}",
+ "mealbox.empty": "No meal boxes right now. When you cook, you can save servings here.",
+ "mealbox.enjoyBody": "The portion is logged in My day.",
+ "mealbox.enjoyTitle": "Enjoy your meal!",
+ "mealbox.guidanceNote": "The recommended use-by is guidance – trust smell and taste.",
+ "mealbox.portionsLeft_one": "1 serving left",
+ "mealbox.portionsLeft_other": "{count} servings left",
+ "mealbox.title": "Meal boxes",
+ "memory.delete": "Delete",
+ "memory.deleteAll": "Delete all memory",
+ "memory.deleteAllTitle": "Delete all memory?",
+ "memory.empty": "{brand} hasn't learned anything about you yet.",
+ "memory.irreversible": "This cannot be undone.",
+ "memory.origin.ai_inferred": "AI assumption",
+ "memory.origin.observed": "Observed pattern",
+ "memory.origin.user_stated": "You told us",
+ "memory.pause": "Pause",
+ "memory.paused": "Paused",
+ "memory.resume": "Resume",
+ "memory.subtitle": "Full transparency. Correct what's wrong, pause or delete – you own your memory.",
+ "memory.title": "What {brand} knows about me",
+ "memory.verified": "Verified",
+ "memory.verify": "Correct",
+ "myday.calories": "Calories",
+ "myday.carbs": "Carbohydrates",
+ "myday.estimateNote": "Values marked with ~ are estimates you can adjust.",
+ "myday.estimateRange": "{min}–{max} kcal, likely {kcal}",
+ "myday.fat": "Fat",
+ "myday.fiber": "Fiber",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
+ "myday.logMeal": "Log meal",
+ "myday.mealType.breakfast": "Breakfast",
+ "myday.mealType.dessert": "Dessert",
+ "myday.mealType.dinner": "Dinner",
+ "myday.mealType.lunch": "Lunch",
+ "myday.mealType.snack": "Snack",
+ "myday.noMeals": "No meals logged today.",
+ "myday.over": "{kcal} kcal over target",
+ "myday.overRecommended": "Above recommended",
+ "myday.protein": "Protein",
+ "myday.remaining": "{kcal} kcal remaining",
+ "myday.salt": "Salt",
+ "myday.targetsNote": "Targets are guidance, not medical advice.",
+ "myday.title": "My day",
+ "myday.todaysMeals": "Today's meals",
+ "onboarding.allergen.crustaceans": "Crustaceans",
+ "onboarding.allergen.eggs": "Eggs",
+ "onboarding.allergen.fish": "Fish",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Milk/lactose",
+ "onboarding.allergen.peanuts": "Peanuts",
+ "onboarding.allergen.sesame": "Sesame",
+ "onboarding.allergen.soy": "Soy",
+ "onboarding.allergen.tree_nuts": "Tree nuts",
"onboarding.allergies": "Allergies and intolerances",
"onboarding.allergyNote": "Allergy filtering is always strict – dishes with your allergens are never shown.",
+ "onboarding.birthYearPlaceholder": "Birth year",
+ "onboarding.bodyTitle": "For personal calorie targets (optional)",
+ "onboarding.diet": "How do you eat?",
+ "onboarding.diet.flexitarian": "Flexitarian",
+ "onboarding.diet.omnivore": "Omnivore",
+ "onboarding.diet.pescatarian": "Pescatarian",
+ "onboarding.diet.vegan": "Vegan",
+ "onboarding.diet.vegetarian": "Vegetarian",
+ "onboarding.goal": "What is your main goal?",
+ "onboarding.goal.build_muscle": "Build muscle",
+ "onboarding.goal.cook_more": "Cook more at home",
+ "onboarding.goal.less_waste": "Reduce food waste",
+ "onboarding.goal.lose_weight": "Lose weight",
+ "onboarding.goal.lower_cost": "Spend less on food",
+ "onboarding.goal.maintain_weight": "Maintain weight",
+ "onboarding.goal.more_protein": "Eat more protein",
+ "onboarding.heightPlaceholder": "Height (cm)",
"onboarding.household": "Your household",
"onboarding.householdCreate": "Create household",
+ "onboarding.householdDefaultName": "Home",
"onboarding.householdJoin": "Join with a code",
"onboarding.householdName": "Household name",
"onboarding.inviteCode": "Invite code",
"onboarding.mode": "How precise do you want to be?",
- "onboarding.modeSimple": "Simple mode",
- "onboarding.modeSimpleDesc": "Snap photos of your food, accept estimates, minimal fuss.",
"onboarding.modeExact": "Exact mode",
"onboarding.modeExactDesc": "Weigh food, enter grams, full control of the numbers.",
+ "onboarding.modesCombine": "You can mix modes – simple day to day, exact when you want.",
+ "onboarding.modeSimple": "Simple mode",
+ "onboarding.modeSimpleDesc": "Snap photos of your food, accept estimates, minimal fuss.",
"onboarding.notMedical": "{brand} provides guidance – not medical advice.",
- "wte.title": "What's for dinner?",
- "wte.subtitle": "Based on what you have at home, what should be used up, and what you like.",
- "wte.cravingPlaceholder": "I'm craving … (e.g. creamy, Asian, under 500 kcal)",
- "wte.mealBoxFirst": "Ready-made food at home",
- "wte.whyTitle": "Why this suggestion?",
- "wte.coverage": "{pct}% at home",
- "wte.missing": "Missing: {items}",
- "wte.empty": "No suggestions yet – add some food to your inventory or loosen the filters.",
- "wte.refresh": "New suggestions",
- "scan.title": "Scan",
- "scan.subtitle": "Stock your food inventory or log a meal with the camera.",
- "scan.fridge": "Fridge",
- "scan.freezer": "Freezer",
- "scan.pantry": "Pantry",
- "scan.ingredients": "Ingredients",
- "scan.plate": "Plate",
- "scan.receipt": "Receipt",
- "scan.barcode": "Barcode",
- "scan.expiry": "Best-before date",
- "scan.nutrition": "Nutrition label",
- "scan.takePhoto": "Take photo",
- "scan.tips.title": "How to get the best analysis",
- "scan.tips.overview": "Start with an overview photo",
- "scan.tips.shelf": "Photograph shelf by shelf",
- "scan.tips.light": "Avoid darkness and shadows",
- "scan.tips.move": "Move items that block each other",
- "scan.analyzing": "Analyzing …",
- "scan.quotaLeft_one": "1 AI scan left this month",
- "scan.quotaLeft_other": "{count} AI scans left this month",
- "scan.review.title": "Review the result",
- "scan.review.subtitle": "AI is sometimes uncertain – you decide. Edit, remove or add before saving.",
- "scan.review.uncertain": "Uncertain – please check",
- "scan.review.approveAll": "Save to inventory",
- "scan.review.rejected": "Removed",
- "scan.failed": "The analysis failed. Try again or add items manually.",
- "myday.title": "My day",
- "myday.calories": "Calories",
- "myday.protein": "Protein",
- "myday.carbs": "Carbohydrates",
- "myday.fat": "Fat",
- "myday.fiber": "Fiber",
- "myday.salt": "Salt",
- "myday.remaining": "{kcal} kcal remaining",
- "myday.over": "{kcal} kcal over target",
- "myday.logMeal": "Log meal",
- "myday.noMeals": "No meals logged today.",
- "myday.estimateNote": "Values marked with ~ are estimates you can adjust.",
- "myday.targetsNote": "Targets are guidance, not medical advice.",
- "home.title": "At home",
- "home.inventory": "Food inventory",
- "home.useSoon": "Use soon",
- "home.mealBoxes": "Meal boxes",
- "home.shopping": "Shopping list",
- "home.budget": "Food budget",
- "home.household": "Household",
- "home.waste": "Food waste",
- "home.emptyInventory": "Your inventory is empty. Scan the fridge or add items manually.",
- "home.expiresIn_one": "1 day left",
- "home.expiresIn_other": "{days} days left",
- "home.expiresToday": "Expires today",
- "home.expired": "Expired",
- "home.pastBestBefore": "Past best before – smell and taste first",
+ "onboarding.stepBSubtitle": "Customize your profile for better suggestions.",
+ "onboarding.stepBTitle": "Continue setup",
+ "onboarding.stepCSubtitle": "Optional – used for personal calorie targets.",
+ "onboarding.stepCTitle": "Your health profile",
+ "onboarding.subtitle": "Everything is optional and can be changed at any time. The more you fill in, the better the suggestions.",
+ "onboarding.title": "Tell us a little about yourself",
+ "onboarding.weightPlaceholder": "Weight (kg)",
+ "paywall.choose": "Choose",
+ "paywall.fairUse": "Fair-use quota for AI scans included.",
+ "paywall.family": "Family · up to 6 people",
+ "paywall.freeNote": "Free: 10 AI scans/month, manual inventory, saved recipes and simple logging.",
+ "paywall.household": "Household · up to 3 people",
+ "paywall.large": "Large Household · up to 12 people",
+ "paywall.perMonth": "{price}/month",
+ "paywall.popular": "Most popular",
+ "paywall.restore": "Restore purchases",
+ "paywall.soonBody": "Purchases activate via App Store/Google Play once store integration is switched on (phase 7). The backend flow is already done.",
+ "paywall.soonTitle": "Coming soon!",
+ "paywall.subtitle": "The whole household's food OS: unlimited inventory, week planning and sharing.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "1 day left of your trial",
+ "paywall.trialActive_other": "{days} days left of your trial",
+ "profile.aiScansUsed": "AI scans: {used} / {total} this month",
+ "profile.consent.anonymized_improvement": "Anonymised AI improvement",
+ "profile.consent.health_integration": "Health data (Apple Health / Health Connect)",
+ "profile.consent.image_training": "My photos may be used for training",
+ "profile.consent.location_weather": "Location for weather-based suggestions",
+ "profile.consent.personalization": "Personal features (memory & taste profile)",
+ "profile.consent.product_analytics": "Product analytics",
+ "profile.consent.push_notifications": "Push notifications",
+ "profile.consents": "Consents & data",
+ "profile.consentsNote": "Consents are separate – personal features never require training consent.",
+ "profile.deleteAccount": "Delete account",
+ "profile.deleteBody": "All your data is permanently deleted in line with GDPR.",
+ "profile.deleteTitle": "Delete your account?",
+ "profile.emailUnverified": "Email address not confirmed",
+ "profile.export": "Export my data",
+ "profile.goals": "Goals & diet",
+ "profile.language": "Language",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Log out",
+ "profile.memory": "What {brand} knows about me",
+ "profile.memorySubtitle": "See, correct, pause or delete what the platform has learned.",
+ "profile.modeLabel": "Mode:",
+ "profile.resendVerification": "Resend confirmation email",
+ "profile.subscription": "Subscription",
+ "profile.title": "Profile",
+ "profile.verificationSent": "Sent! Check your inbox.",
+ "recipe.avgRating": "Average {avg} from {count} ratings",
+ "recipe.cook": "Cook now",
+ "recipe.cost": "approx. {amount}/serving",
+ "recipe.iCookedThis": "I cooked this",
+ "recipe.ingredients": "Ingredients",
+ "recipe.notSafe": "Doesn't match your dietary settings",
+ "recipe.perPortion": "per serving",
"recipe.portions_one": "1 serving",
"recipe.portions_other": "{count} servings",
- "recipe.time": "{min} min",
- "recipe.perPortion": "per serving",
- "recipe.ingredients": "Ingredients",
+ "recipe.save": "Save",
+ "recipe.saved": "Saved",
"recipe.steps": "Instructions",
- "recipe.cook": "Cook now",
- "recipe.notSafe": "Doesn't match your dietary settings",
"recipe.substitutions": "Substitute",
- "recipe.iCookedThis": "I cooked this",
- "recipe.cost": "approx. {amount}/serving",
- "cooking.step": "Step {current} of {total}",
- "cooking.timer": "Start timer",
- "cooking.timerRunning": "{time} left",
- "cooking.finish": "Done – log the meal",
- "cooking.scale": "Servings",
- "cooking.keepAwake": "The screen stays awake while you cook",
- "cooked.title": "How did it go?",
- "cooked.portionsCooked": "Servings cooked",
- "cooked.whoAte": "Who ate?",
- "cooked.mealBoxes": "Servings to meal boxes",
- "cooked.deductPantry": "Deduct ingredients from inventory",
- "cooked.rate": "Rate it",
- "shopping.title": "Shopping list",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analyzing …",
+ "scan.barcode": "Barcode",
+ "scan.expiry": "Best-before date",
+ "scan.failed": "The analysis failed. Try again or add items manually.",
+ "scan.freezer": "Freezer",
+ "scan.fridge": "Fridge",
+ "scan.ingredients": "Ingredients",
+ "scan.nutrition": "Nutrition label",
+ "scan.pantry": "Pantry",
+ "scan.plate": "Plate",
+ "scan.quotaLeft_one": "1 AI scan left this month",
+ "scan.quotaLeft_other": "{count} AI scans left this month",
+ "scan.receipt": "Receipt",
+ "scan.review.addItem": "+ Add item",
+ "scan.review.approveAll": "Save to inventory",
+ "scan.review.bestBeforeNote": "Quality date – the food can be fine well beyond it. Smell and taste before discarding.",
+ "scan.review.dateKindBestBefore": "Best before",
+ "scan.review.dateKindUseBy": "Use by",
+ "scan.review.datePlaceholder": "YYYY-MM-DD (optional)",
+ "scan.review.itemPlaceholder": "Item",
+ "scan.review.quantityPlaceholder": "Amount",
+ "scan.review.rejected": "Removed",
+ "scan.review.subtitle": "AI is sometimes uncertain – you decide. Edit, remove or add before saving.",
+ "scan.review.title": "Review the result",
+ "scan.review.uncertain": "Uncertain – please check",
+ "scan.review.unitPlaceholder": "Unit (g, l, pcs …)",
+ "scan.review.unknownItem": "Unknown item",
+ "scan.review.useByNote": "Safety date – do not eat after this date.",
+ "scan.subtitle": "Stock your food inventory or log a meal with the camera.",
+ "scan.takePhoto": "Take photo",
+ "scan.tips.light": "Avoid darkness and shadows",
+ "scan.tips.move": "Move items that block each other",
+ "scan.tips.overview": "Start with an overview photo",
+ "scan.tips.shelf": "Photograph shelf by shelf",
+ "scan.tips.title": "How to get the best analysis",
+ "scan.title": "Scan",
"shopping.addPlaceholder": "Add item …",
"shopping.complete": "Finish shopping trip",
+ "shopping.completedBody_one": "1 item was added to your inventory.",
+ "shopping.completedBody_other": "{count} items were added to your inventory.",
+ "shopping.completedTitle": "Done!",
"shopping.completeNote": "Checked items are added to your food inventory.",
"shopping.empty": "The list is empty.",
"shopping.estimated": "approx. {amount}",
"shopping.estimatedTotal": "Estimated total: approx. {amount}",
- "mealbox.title": "Meal boxes",
- "mealbox.eatBy": "Eat by {date}",
- "mealbox.portionsLeft_one": "1 serving left",
- "mealbox.portionsLeft_other": "{count} servings left",
- "mealbox.eat": "Eat now",
- "mealbox.empty": "No meal boxes right now. When you cook, you can save servings here.",
- "household.members": "Members",
- "household.invite": "Invite with code: {code}",
- "household.shared": "Shared in the household: food inventory, shopping list, week plan, meal boxes and budget.",
- "household.private": "Private per person: goals, allergies, health data and meal history.",
- "memory.title": "What {brand} knows about me",
- "memory.subtitle": "Full transparency. Correct what's wrong, pause or delete – you own your memory.",
- "memory.paused": "Paused",
- "memory.verify": "Correct",
- "memory.pause": "Pause",
- "memory.delete": "Delete",
- "memory.deleteAll": "Delete all memory",
- "memory.empty": "{brand} hasn't learned anything about you yet.",
- "memory.origin.user_stated": "You told us",
- "memory.origin.observed": "Observed pattern",
- "memory.origin.ai_inferred": "AI assumption",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "The whole household's food OS: unlimited inventory, week planning and sharing.",
- "paywall.trialActive_one": "1 day left of your trial",
- "paywall.trialActive_other": "{days} days left of your trial",
- "paywall.household": "Household · up to 3 people",
- "paywall.family": "Family · up to 6 people",
- "paywall.large": "Large Household · up to 12 people",
- "paywall.perMonth": "{price}/month",
- "paywall.fairUse": "Fair-use quota for AI scans included.",
- "paywall.restore": "Restore purchases",
- "paywall.freeNote": "Free: 10 AI scans/month, manual inventory, saved recipes and simple logging.",
- "profile.title": "Profile",
- "profile.goals": "Goals & diet",
- "profile.consents": "Consents & data",
- "profile.memory": "What {brand} knows about me",
- "profile.subscription": "Subscription",
- "profile.logout": "Log out",
- "profile.export": "Export my data",
- "profile.deleteAccount": "Delete account",
- "profile.language": "Language",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "auth.forgotLink": "Forgot your password?",
- "auth.forgotTitle": "Reset password",
- "auth.forgotBody": "Enter your email and we'll send a reset link if the account exists.",
- "auth.forgotSubmit": "Send link",
- "auth.forgotSentTitle": "Check your inbox",
- "auth.forgotSentBody": "If the address has an account, we've sent a link valid for 30 minutes. Open it on this device.",
- "auth.backToLogin": "Back to login",
- "auth.resetTitle": "Choose a new password",
- "auth.resetBody": "The link is valid for 30 minutes and can only be used once. All devices are signed out when the password changes.",
- "auth.resetTokenPlaceholder": "Paste the code from the email",
- "auth.newPassword": "New password (at least 10 characters)",
- "auth.resetSubmit": "Change password",
- "auth.resetDoneTitle": "Done!",
- "auth.resetDoneBody": "Your password has been changed. Log in with your new password.",
- "auth.verifyDoneTitle": "Email confirmed",
- "auth.verifyDoneBody": "Thanks! Your account is now verified.",
- "auth.verifyFailedTitle": "The link didn't work",
- "auth.verifyFailedBody": "The link is invalid or has expired. Request a new one from your profile.",
- "profile.emailUnverified": "Email address not confirmed",
- "profile.resendVerification": "Resend confirmation email",
- "profile.verificationSent": "Sent! Check your inbox.",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Oops",
- "common.undo": "Undo",
- "common.remove": "Remove",
- "common.add": "Add",
- "common.on": "On",
- "common.off": "Off",
- "home.thisWeek": "This week",
- "home.wasteWeek": "Food waste this week",
- "home.useSoonHint": "Best before is about quality – smell, look and taste before you throw anything away. Use-by dates, however, should be respected.",
- "scan.review.itemPlaceholder": "Item",
- "scan.review.quantityPlaceholder": "Amount",
- "scan.review.unitPlaceholder": "Unit (g, l, pcs …)",
- "scan.review.datePlaceholder": "YYYY-MM-DD (optional)",
- "scan.review.dateKindBestBefore": "Best before",
- "scan.review.dateKindUseBy": "Use by",
- "scan.review.bestBeforeNote": "Quality date – the food can be fine well beyond it. Smell and taste before discarding.",
- "scan.review.useByNote": "Safety date – do not eat after this date.",
- "scan.review.addItem": "+ Add item",
- "scan.review.unknownItem": "Unknown item",
- "barcode.aim": "Point the camera at the barcode",
- "barcode.addPrompt": "Add to your inventory?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "No nutrition data",
- "barcode.unknownTitle": "Unknown product",
- "barcode.unknownBody": "This product isn't in the database yet. Photograph the front and the nutrition label and we'll add it.",
- "barcode.photoPackage": "Photograph the package",
- "barcode.needHousehold": "You need a household first.",
- "barcode.noLocation": "No storage location found.",
- "barcode.cameraTitle": "Camera needed",
- "barcode.cameraBody": "{brand} needs the camera to scan barcodes.",
- "barcode.allowCamera": "Allow camera",
- "onboarding.goal.lose_weight": "Lose weight",
- "onboarding.goal.build_muscle": "Build muscle",
- "onboarding.goal.maintain_weight": "Maintain weight",
- "onboarding.goal.more_protein": "Eat more protein",
- "onboarding.goal.less_waste": "Reduce food waste",
- "onboarding.goal.lower_cost": "Spend less on food",
- "onboarding.goal.cook_more": "Cook more at home",
- "onboarding.diet.omnivore": "Omnivore",
- "onboarding.diet.flexitarian": "Flexitarian",
- "onboarding.diet.pescatarian": "Pescatarian",
- "onboarding.diet.vegetarian": "Vegetarian",
- "onboarding.diet.vegan": "Vegan",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Milk/lactose",
- "onboarding.allergen.eggs": "Eggs",
- "onboarding.allergen.tree_nuts": "Tree nuts",
- "onboarding.allergen.peanuts": "Peanuts",
- "onboarding.allergen.fish": "Fish",
- "onboarding.allergen.crustaceans": "Crustaceans",
- "onboarding.allergen.soy": "Soy",
- "onboarding.allergen.sesame": "Sesame",
- "onboarding.bodyTitle": "For personal calorie targets (optional)",
- "onboarding.weightPlaceholder": "Weight (kg)",
- "onboarding.heightPlaceholder": "Height (cm)",
- "onboarding.birthYearPlaceholder": "Birth year",
- "onboarding.householdDefaultName": "Home",
- "onboarding.modesCombine": "You can mix modes – simple day to day, exact when you want.",
- "myday.mealType.breakfast": "Breakfast",
- "myday.mealType.lunch": "Lunch",
- "myday.mealType.dinner": "Dinner",
- "myday.mealType.snack": "Snack",
- "myday.mealType.dessert": "Dessert",
- "myday.overRecommended": "Above recommended",
- "myday.todaysMeals": "Today's meals",
- "myday.estimateRange": "{min}–{max} kcal, likely {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
- "logmeal.mealTypeTitle": "Meal type",
- "logmeal.quickTitle": "Quick re-log",
- "logmeal.quickSubtitle": "Logs the same nutrition values as last time.",
- "logmeal.manualTitle": "Manual",
- "logmeal.whatPlaceholder": "What did you eat?",
- "logmeal.proteinPlaceholder": "protein (g)",
- "logmeal.validationTitle": "Missing info",
- "logmeal.validationBody": "Name and calories are required for manual logging.",
- "logmeal.photoTip": "Tip: photograph your plate under Scan and the app estimates for you – you always confirm.",
- "shopping.section.frukt_gront": "Fruit & veg",
"shopping.section.brod": "Bread",
- "shopping.section.mejeri": "Dairy",
- "shopping.section.kott_fagel": "Meat & poultry",
- "shopping.section.fisk": "Fish",
"shopping.section.chark": "Deli & cold cuts",
- "shopping.section.frys": "Frozen",
- "shopping.section.skafferi": "Pantry",
- "shopping.section.konserver": "Canned goods",
- "shopping.section.kryddor_bak": "Spices & baking",
"shopping.section.dryck": "Drinks",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Fish",
+ "shopping.section.frukt_gront": "Fruit & veg",
+ "shopping.section.frys": "Frozen",
"shopping.section.hygien_ovrigt": "Other",
- "shopping.completedTitle": "Done!",
- "household.role.owner": "Owner",
- "household.role.adult": "Adult",
- "household.role.member": "Member",
- "household.role.child": "Child",
- "household.empty": "You don't have a household yet. Create one in onboarding or join with a code.",
- "household.shareCode": "Share the code with your family to share inventory, list and plan.",
- "household.locations": "Storage locations",
- "household.portionFactor": "×{factor} portion",
- "mealbox.enjoyTitle": "Enjoy your meal!",
- "mealbox.enjoyBody": "The portion is logged in My day.",
- "mealbox.guidanceNote": "The recommended use-by is guidance – trust smell and taste.",
- "paywall.soonTitle": "Coming soon!",
- "paywall.soonBody": "Purchases activate via App Store/Google Play once store integration is switched on (phase 7). The backend flow is already done.",
- "paywall.popular": "Most popular",
- "paywall.choose": "Choose",
- "recipe.saved": "Saved",
- "recipe.save": "Save",
- "recipe.avgRating": "Average {avg} from {count} ratings",
- "memory.verified": "Verified",
- "memory.resume": "Resume",
- "memory.deleteAllTitle": "Delete all memory?",
- "memory.irreversible": "This cannot be undone.",
- "profile.consent.personalization": "Personal features (memory & taste profile)",
- "profile.consent.anonymized_improvement": "Anonymised AI improvement",
- "profile.consent.image_training": "My photos may be used for training",
- "profile.consent.health_integration": "Health data (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Location for weather-based suggestions",
- "profile.consent.push_notifications": "Push notifications",
- "profile.modeLabel": "Mode:",
- "profile.memorySubtitle": "See, correct, pause or delete what the platform has learned.",
- "profile.consentsNote": "Consents are separate – personal features never require training consent.",
- "profile.aiScansUsed": "AI scans: {used} / {total} this month",
- "profile.deleteTitle": "Delete your account?",
- "profile.deleteBody": "All your data is permanently deleted in line with GDPR.",
- "cooking.timerDone": "Done!",
- "cooked.deductPantryNote": "Ingredients are deducted from your inventory, first-expiring first.",
- "home.moreItems_one": "+ 1 more …",
- "home.moreItems_other": "+ {count} more …",
- "shopping.completedBody_one": "1 item was added to your inventory.",
- "shopping.completedBody_other": "{count} items were added to your inventory.",
- "profile.consent.product_analytics": "Product analytics"
+ "shopping.section.konserver": "Canned goods",
+ "shopping.section.kott_fagel": "Meat & poultry",
+ "shopping.section.kryddor_bak": "Spices & baking",
+ "shopping.section.mejeri": "Dairy",
+ "shopping.section.skafferi": "Pantry",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Shopping list",
+ "tabs.home": "At home",
+ "tabs.myDay": "My day",
+ "tabs.scan": "Scan",
+ "tabs.whatToEat": "What's for dinner?",
+ "wte.coverage": "{pct}% at home",
+ "wte.cravingPlaceholder": "I'm craving … (e.g. creamy, Asian, under 500 kcal)",
+ "wte.empty": "No suggestions yet – add some food to your inventory or loosen the filters.",
+ "wte.mealBoxFirst": "Ready-made food at home",
+ "wte.missing": "Missing: {items}",
+ "wte.refresh": "New suggestions",
+ "wte.subtitle": "Based on what you have at home, what should be used up, and what you like.",
+ "wte.title": "What's for dinner?",
+ "wte.whyTitle": "Why this suggestion?"
}
diff --git a/apps/mobile/src/locales/es/common.json b/apps/mobile/src/locales/es/common.json
index e330756..1562cc0 100644
--- a/apps/mobile/src/locales/es/common.json
+++ b/apps/mobile/src/locales/es/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Cargando …",
+ "auth.backToLogin": "Volver a iniciar sesión",
+ "auth.displayName": "¿Cómo te llamamos?",
+ "auth.email": "Correo electrónico",
+ "auth.forgotBody": "Introduce tu correo y te enviaremos un enlace si la cuenta existe.",
+ "auth.forgotLink": "¿Olvidaste tu contraseña?",
+ "auth.forgotSentBody": "Si la dirección tiene una cuenta, hemos enviado un enlace válido durante 30 minutos. Ábrelo en este dispositivo.",
+ "auth.forgotSentTitle": "Revisa tu bandeja de entrada",
+ "auth.forgotSubmit": "Enviar enlace",
+ "auth.forgotTitle": "Restablecer contraseña",
+ "auth.hasAccount": "¿Ya tienes cuenta? Inicia sesión",
+ "auth.login": "Iniciar sesión",
+ "auth.newPassword": "Nueva contraseña (mínimo 10 caracteres)",
+ "auth.noAccount": "¿Nuevo aquí? Crea una cuenta",
+ "auth.password": "Contraseña",
+ "auth.register": "Crear cuenta",
+ "auth.resetBody": "El enlace es válido durante 30 minutos y solo se puede usar una vez. Todos los dispositivos se desconectarán.",
+ "auth.resetDoneBody": "Tu contraseña se ha cambiado. Inicia sesión con la nueva.",
+ "auth.resetDoneTitle": "¡Listo!",
+ "auth.resetSubmit": "Cambiar contraseña",
+ "auth.resetTitle": "Elige una nueva contraseña",
+ "auth.resetTokenPlaceholder": "Pega el código del correo",
+ "auth.trialNote": "7 días de acceso completo – sin tarjeta.",
+ "auth.verifyDoneBody": "¡Gracias! Tu cuenta está verificada.",
+ "auth.verifyDoneTitle": "Correo confirmado",
+ "auth.verifyFailedBody": "El enlace no es válido o ha caducado. Solicita uno nuevo desde tu perfil.",
+ "auth.verifyFailedTitle": "El enlace no funcionó",
+ "barcode.addPrompt": "¿Añadir al inventario?",
+ "barcode.aim": "Apunta la cámara al código de barras",
+ "barcode.allowCamera": "Permitir cámara",
+ "barcode.cameraBody": "{brand} necesita la cámara para escanear códigos de barras.",
+ "barcode.cameraTitle": "Se necesita la cámara",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Primero necesitas un hogar.",
+ "barcode.noLocation": "No se encontró ningún lugar de almacenamiento.",
+ "barcode.noNutrition": "Sin datos nutricionales",
+ "barcode.photoPackage": "Fotografiar el envase",
+ "barcode.unknownBody": "Este producto aún no está en la base de datos. Fotografía el frontal y la etiqueta nutricional y lo añadiremos.",
+ "barcode.unknownTitle": "Producto desconocido",
+ "common.add": "Añadir",
+ "common.back": "Atrás",
+ "common.cancel": "Cancelar",
+ "common.done": "Listo",
"common.error": "Algo salió mal. Inténtalo de nuevo.",
+ "common.estimate": "Estimación",
+ "common.loading": "Cargando …",
+ "common.next": "Siguiente",
+ "common.off": "Desactivado",
+ "common.offline": "Sin conexión – mostrando los últimos datos",
+ "common.on": "Activado",
+ "common.oops": "Vaya",
+ "common.remove": "Quitar",
"common.retry": "Reintentar",
"common.save": "Guardar",
- "common.cancel": "Cancelar",
- "common.next": "Siguiente",
- "common.back": "Atrás",
- "common.done": "Listo",
"common.skip": "Omitir",
- "common.offline": "Sin conexión – mostrando los últimos datos",
- "common.estimate": "Estimación",
- "tabs.whatToEat": "¿Qué comemos?",
- "tabs.scan": "Escanear",
- "tabs.myDay": "Mi día",
- "tabs.home": "En casa",
- "auth.login": "Iniciar sesión",
- "auth.register": "Crear cuenta",
- "auth.email": "Correo electrónico",
- "auth.password": "Contraseña",
- "auth.displayName": "¿Cómo te llamamos?",
- "auth.noAccount": "¿Nuevo aquí? Crea una cuenta",
- "auth.hasAccount": "¿Ya tienes cuenta? Inicia sesión",
- "auth.trialNote": "7 días de acceso completo – sin tarjeta.",
- "auth.forgotLink": "¿Olvidaste tu contraseña?",
- "auth.forgotTitle": "Restablecer contraseña",
- "auth.forgotBody": "Introduce tu correo y te enviaremos un enlace si la cuenta existe.",
- "auth.forgotSubmit": "Enviar enlace",
- "auth.forgotSentTitle": "Revisa tu bandeja de entrada",
- "auth.forgotSentBody": "Si la dirección tiene una cuenta, hemos enviado un enlace válido durante 30 minutos. Ábrelo en este dispositivo.",
- "auth.backToLogin": "Volver a iniciar sesión",
- "auth.resetTitle": "Elige una nueva contraseña",
- "auth.resetBody": "El enlace es válido durante 30 minutos y solo se puede usar una vez. Todos los dispositivos se desconectarán.",
- "auth.resetTokenPlaceholder": "Pega el código del correo",
- "auth.newPassword": "Nueva contraseña (mínimo 10 caracteres)",
- "auth.resetSubmit": "Cambiar contraseña",
- "auth.resetDoneTitle": "¡Listo!",
- "auth.resetDoneBody": "Tu contraseña se ha cambiado. Inicia sesión con la nueva.",
- "auth.verifyDoneTitle": "Correo confirmado",
- "auth.verifyDoneBody": "¡Gracias! Tu cuenta está verificada.",
- "auth.verifyFailedTitle": "El enlace no funcionó",
- "auth.verifyFailedBody": "El enlace no es válido o ha caducado. Solicita uno nuevo desde tu perfil.",
- "onboarding.title": "Cuéntanos un poco sobre ti",
- "onboarding.subtitle": "Todo es opcional y se puede cambiar cuando quieras. Cuanto más completes, mejores serán las sugerencias.",
- "onboarding.goal": "¿Cuál es tu objetivo principal?",
- "onboarding.diet": "¿Cómo comes?",
+ "common.undo": "Deshacer",
+ "cooked.deductPantry": "Descontar ingredientes del inventario",
+ "cooked.deductPantryNote": "Los ingredientes se descuentan del inventario: primero los que caducan antes.",
+ "cooked.mealBoxes": "Raciones para táperes",
+ "cooked.portionsCooked": "Raciones cocinadas",
+ "cooked.rate": "Valorar",
+ "cooked.title": "¿Qué tal ha ido?",
+ "cooked.whoAte": "¿Quiénes comieron?",
+ "cooking.finish": "Hecho – registrar la comida",
+ "cooking.keepAwake": "La pantalla permanece encendida mientras cocinas",
+ "cooking.scale": "Raciones",
+ "cooking.step": "Paso {current} de {total}",
+ "cooking.timer": "Iniciar temporizador",
+ "cooking.timerDone": "¡Listo!",
+ "cooking.timerRunning": "Quedan {time}",
+ "home.budget": "Presupuesto",
+ "home.emptyInventory": "El inventario está vacío. Escanea la nevera o añade productos manualmente.",
+ "home.expired": "Caducado",
+ "home.expiresIn_one": "Queda 1 día",
+ "home.expiresIn_other": "Quedan {days} días",
+ "home.expiresToday": "Caduca hoy",
+ "home.household": "Hogar",
+ "home.inventory": "Inventario",
+ "home.mealBoxes": "Táperes",
+ "home.moreItems_one": "+ 1 más …",
+ "home.moreItems_other": "+ {count} más …",
+ "home.pastBestBefore": "Pasada la fecha preferente: huele y prueba primero",
+ "home.shopping": "Lista de la compra",
+ "home.thisWeek": "Esta semana",
+ "home.title": "En casa",
+ "home.useSoon": "Usar pronto",
+ "home.useSoonHint": "La fecha de consumo preferente es de calidad: huele, mira y prueba antes de tirar nada. La fecha de caducidad, en cambio, debe respetarse.",
+ "home.waste": "Desperdicio",
+ "home.wasteWeek": "Desperdicio esta semana",
+ "household.empty": "Aún no tienes un hogar. Crea uno en la configuración inicial o únete con un código.",
+ "household.invite": "Invita con el código: {code}",
+ "household.locations": "Lugares de almacenamiento",
+ "household.members": "Miembros",
+ "household.portionFactor": "×{factor} ración",
+ "household.private": "Privado por persona: objetivos, alergias, datos de salud e historial de comidas.",
+ "household.role.adult": "Adulto",
+ "household.role.child": "Niño",
+ "household.role.member": "Miembro",
+ "household.role.owner": "Propietario",
+ "household.shareCode": "Comparte el código con tu familia para compartir inventario, lista y plan.",
+ "household.shared": "Compartido en el hogar: inventario, lista de la compra, plan semanal, táperes y presupuesto.",
+ "logmeal.manualTitle": "Manual",
+ "logmeal.mealTypeTitle": "Tipo de comida",
+ "logmeal.photoTip": "Consejo: fotografía el plato en Escanear y la app lo estimará por ti; tú siempre confirmas.",
+ "logmeal.proteinPlaceholder": "proteína (g)",
+ "logmeal.quickSubtitle": "Registra los mismos valores nutricionales que la última vez.",
+ "logmeal.quickTitle": "Registro rápido",
+ "logmeal.validationBody": "Para el registro manual se necesitan nombre y calorías.",
+ "logmeal.validationTitle": "Faltan datos",
+ "logmeal.whatPlaceholder": "¿Qué has comido?",
+ "mealbox.eat": "Comer ahora",
+ "mealbox.eatBy": "Consumir antes del {date}",
+ "mealbox.empty": "No hay táperes ahora mismo. Al cocinar puedes guardar raciones aquí.",
+ "mealbox.enjoyBody": "La ración se ha registrado en Mi día.",
+ "mealbox.enjoyTitle": "¡Buen provecho!",
+ "mealbox.guidanceNote": "El plazo recomendado es orientativo: confía en el olfato y el gusto.",
+ "mealbox.portionsLeft_one": "Queda 1 ración",
+ "mealbox.portionsLeft_other": "Quedan {count} raciones",
+ "mealbox.title": "Táperes",
+ "memory.delete": "Eliminar",
+ "memory.deleteAll": "Eliminar toda la memoria",
+ "memory.deleteAllTitle": "¿Borrar toda la memoria?",
+ "memory.empty": "{brand} aún no ha aprendido nada sobre ti.",
+ "memory.irreversible": "Esto no se puede deshacer.",
+ "memory.origin.ai_inferred": "Suposición de la IA",
+ "memory.origin.observed": "Patrón observado",
+ "memory.origin.user_stated": "Nos lo contaste",
+ "memory.pause": "Pausar",
+ "memory.paused": "En pausa",
+ "memory.resume": "Reanudar",
+ "memory.subtitle": "Transparencia total. Corrige lo que esté mal, pausa o elimina: tu memoria es tuya.",
+ "memory.title": "Lo que {brand} sabe de mí",
+ "memory.verified": "Verificado",
+ "memory.verify": "Correcto",
+ "myday.calories": "Calorías",
+ "myday.carbs": "Hidratos",
+ "myday.estimateNote": "Los valores con ~ son estimaciones que puedes ajustar.",
+ "myday.estimateRange": "{min}–{max} kcal, probablemente {kcal}",
+ "myday.fat": "Grasas",
+ "myday.fiber": "Fibra",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g de proteína",
+ "myday.logMeal": "Registrar comida",
+ "myday.mealType.breakfast": "Desayuno",
+ "myday.mealType.dessert": "Postre",
+ "myday.mealType.dinner": "Cena",
+ "myday.mealType.lunch": "Almuerzo",
+ "myday.mealType.snack": "Tentempié",
+ "myday.noMeals": "No hay comidas registradas hoy.",
+ "myday.over": "{kcal} kcal por encima del objetivo",
+ "myday.overRecommended": "Por encima de lo recomendado",
+ "myday.protein": "Proteínas",
+ "myday.remaining": "{kcal} kcal restantes",
+ "myday.salt": "Sal",
+ "myday.targetsNote": "Los objetivos son orientación, no consejo médico.",
+ "myday.title": "Mi día",
+ "myday.todaysMeals": "Comidas de hoy",
+ "onboarding.allergen.crustaceans": "Crustáceos",
+ "onboarding.allergen.eggs": "Huevo",
+ "onboarding.allergen.fish": "Pescado",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Leche/lactosa",
+ "onboarding.allergen.peanuts": "Cacahuetes",
+ "onboarding.allergen.sesame": "Sésamo",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Frutos de cáscara",
"onboarding.allergies": "Alergias e intolerancias",
"onboarding.allergyNote": "El filtro de alergias es siempre estricto: los platos con tus alérgenos nunca se muestran.",
+ "onboarding.birthYearPlaceholder": "Año de nacimiento",
+ "onboarding.bodyTitle": "Para objetivos calóricos personales (opcional)",
+ "onboarding.diet": "¿Cómo comes?",
+ "onboarding.diet.flexitarian": "Flexitariano",
+ "onboarding.diet.omnivore": "Omnívoro",
+ "onboarding.diet.pescatarian": "Pescetariano",
+ "onboarding.diet.vegan": "Vegano",
+ "onboarding.diet.vegetarian": "Vegetariano",
+ "onboarding.goal": "¿Cuál es tu objetivo principal?",
+ "onboarding.goal.build_muscle": "Ganar músculo",
+ "onboarding.goal.cook_more": "Cocinar más en casa",
+ "onboarding.goal.less_waste": "Reducir el desperdicio",
+ "onboarding.goal.lose_weight": "Perder peso",
+ "onboarding.goal.lower_cost": "Gastar menos en comida",
+ "onboarding.goal.maintain_weight": "Mantener el peso",
+ "onboarding.goal.more_protein": "Comer más proteína",
+ "onboarding.heightPlaceholder": "Altura (cm)",
"onboarding.household": "Tu hogar",
"onboarding.householdCreate": "Crear hogar",
+ "onboarding.householdDefaultName": "Casa",
"onboarding.householdJoin": "Unirse con un código",
"onboarding.householdName": "Nombre del hogar",
"onboarding.inviteCode": "Código de invitación",
"onboarding.mode": "¿Cuánta precisión quieres?",
- "onboarding.modeSimple": "Modo sencillo",
- "onboarding.modeSimpleDesc": "Fotografía tu comida, acepta estimaciones, sin complicaciones.",
"onboarding.modeExact": "Modo exacto",
"onboarding.modeExactDesc": "Pesa la comida, introduce gramos, control total de las cifras.",
+ "onboarding.modesCombine": "Puedes combinar los modos: sencillo a diario, exacto cuando quieras.",
+ "onboarding.modeSimple": "Modo sencillo",
+ "onboarding.modeSimpleDesc": "Fotografía tu comida, acepta estimaciones, sin complicaciones.",
"onboarding.notMedical": "{brand} ofrece orientación, no consejo médico.",
- "wte.title": "¿Qué comemos?",
- "wte.subtitle": "Según lo que tenéis en casa, lo que conviene usar pronto y lo que os gusta.",
- "wte.cravingPlaceholder": "Me apetece … (p. ej. cremoso, asiático, menos de 500 kcal)",
- "wte.mealBoxFirst": "Comida preparada en casa",
- "wte.whyTitle": "¿Por qué esta sugerencia?",
- "wte.coverage": "{pct}% en casa",
- "wte.missing": "Falta: {items}",
- "wte.empty": "Aún no hay sugerencias: añade comida al inventario o relaja los filtros.",
- "wte.refresh": "Nuevas sugerencias",
- "scan.title": "Escanear",
- "scan.subtitle": "Llena tu inventario o registra una comida con la cámara.",
- "scan.fridge": "Nevera",
- "scan.freezer": "Congelador",
- "scan.pantry": "Despensa",
- "scan.ingredients": "Ingredientes",
- "scan.plate": "Plato",
- "scan.receipt": "Ticket",
- "scan.barcode": "Código de barras",
- "scan.expiry": "Fecha de consumo preferente",
- "scan.nutrition": "Etiqueta nutricional",
- "scan.takePhoto": "Hacer foto",
- "scan.tips.title": "Cómo obtener el mejor análisis",
- "scan.tips.overview": "Empieza con una foto general",
- "scan.tips.shelf": "Fotografía estante por estante",
- "scan.tips.light": "Evita la oscuridad y las sombras",
- "scan.tips.move": "Aparta los productos que se tapan entre sí",
- "scan.analyzing": "Analizando …",
- "scan.quotaLeft_one": "1 escaneo de IA restante este mes",
- "scan.quotaLeft_other": "{count} escaneos de IA restantes este mes",
- "scan.review.title": "Revisa el resultado",
- "scan.review.subtitle": "La IA a veces duda: tú decides. Edita, elimina o añade antes de guardar.",
- "scan.review.uncertain": "Dudoso – compruébalo",
- "scan.review.approveAll": "Guardar en el inventario",
- "scan.review.rejected": "Eliminado",
- "scan.failed": "El análisis falló. Inténtalo de nuevo o añade manualmente.",
- "myday.title": "Mi día",
- "myday.calories": "Calorías",
- "myday.protein": "Proteínas",
- "myday.carbs": "Hidratos",
- "myday.fat": "Grasas",
- "myday.fiber": "Fibra",
- "myday.salt": "Sal",
- "myday.remaining": "{kcal} kcal restantes",
- "myday.over": "{kcal} kcal por encima del objetivo",
- "myday.logMeal": "Registrar comida",
- "myday.noMeals": "No hay comidas registradas hoy.",
- "myday.estimateNote": "Los valores con ~ son estimaciones que puedes ajustar.",
- "myday.targetsNote": "Los objetivos son orientación, no consejo médico.",
- "home.title": "En casa",
- "home.inventory": "Inventario",
- "home.useSoon": "Usar pronto",
- "home.mealBoxes": "Táperes",
- "home.shopping": "Lista de la compra",
- "home.budget": "Presupuesto",
- "home.household": "Hogar",
- "home.waste": "Desperdicio",
- "home.emptyInventory": "El inventario está vacío. Escanea la nevera o añade productos manualmente.",
- "home.expiresIn_one": "Queda 1 día",
- "home.expiresIn_other": "Quedan {days} días",
- "home.expiresToday": "Caduca hoy",
- "home.expired": "Caducado",
- "home.pastBestBefore": "Pasada la fecha preferente: huele y prueba primero",
+ "onboarding.stepBSubtitle": "Personaliza tu perfil para mejores sugerencias.",
+ "onboarding.stepBTitle": "Continuar configuración",
+ "onboarding.stepCSubtitle": "Opcional – se usa para objetivos calóricos personales.",
+ "onboarding.stepCTitle": "Tu perfil de salud",
+ "onboarding.subtitle": "Todo es opcional y se puede cambiar cuando quieras. Cuanto más completes, mejores serán las sugerencias.",
+ "onboarding.title": "Cuéntanos un poco sobre ti",
+ "onboarding.weightPlaceholder": "Peso (kg)",
+ "paywall.choose": "Elegir",
+ "paywall.fairUse": "Cuota de uso razonable de escaneos de IA incluida.",
+ "paywall.family": "Family · hasta 6 personas",
+ "paywall.freeNote": "Gratis: 10 escaneos de IA/mes, inventario manual, recetas guardadas y registro sencillo.",
+ "paywall.household": "Household · hasta 3 personas",
+ "paywall.large": "Large Household · hasta 12 personas",
+ "paywall.perMonth": "{price}/mes",
+ "paywall.popular": "El más popular",
+ "paywall.restore": "Restaurar compras",
+ "paywall.soonBody": "Las compras se activarán a través del App Store/Google Play cuando se active la integración con las tiendas (fase 7). El flujo de backend ya está listo.",
+ "paywall.soonTitle": "¡Pronto!",
+ "paywall.subtitle": "El sistema operativo de comida de todo el hogar: inventario ilimitado, plan semanal y compartir.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "Queda 1 día de prueba",
+ "paywall.trialActive_other": "Quedan {days} días de prueba",
+ "profile.aiScansUsed": "Escaneos de IA: {used} / {total} este mes",
+ "profile.consent.anonymized_improvement": "Mejora anonimizada de la IA",
+ "profile.consent.health_integration": "Datos de salud (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Mis fotos pueden usarse para entrenamiento",
+ "profile.consent.location_weather": "Ubicación para sugerencias según el tiempo",
+ "profile.consent.personalization": "Funciones personales (memoria y perfil de gustos)",
+ "profile.consent.product_analytics": "Análisis de producto",
+ "profile.consent.push_notifications": "Notificaciones push",
+ "profile.consents": "Consentimientos y datos",
+ "profile.consentsNote": "Los consentimientos son independientes: las funciones personales nunca exigen consentimiento de entrenamiento.",
+ "profile.deleteAccount": "Eliminar cuenta",
+ "profile.deleteBody": "Todos tus datos se eliminarán de forma permanente conforme al RGPD.",
+ "profile.deleteTitle": "¿Borrar la cuenta?",
+ "profile.emailUnverified": "Correo electrónico sin confirmar",
+ "profile.export": "Exportar mis datos",
+ "profile.goals": "Objetivos y dieta",
+ "profile.language": "Idioma",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Cerrar sesión",
+ "profile.memory": "Lo que {brand} sabe de mí",
+ "profile.memorySubtitle": "Ve, corrige, pausa o borra lo que la plataforma ha aprendido.",
+ "profile.modeLabel": "Modo:",
+ "profile.resendVerification": "Reenviar correo de confirmación",
+ "profile.subscription": "Suscripción",
+ "profile.title": "Perfil",
+ "profile.verificationSent": "¡Enviado! Revisa tu bandeja de entrada.",
+ "recipe.avgRating": "Media de {avg} con {count} valoraciones",
+ "recipe.cook": "Cocinar ahora",
+ "recipe.cost": "aprox. {amount}/ración",
+ "recipe.iCookedThis": "Lo he cocinado",
+ "recipe.ingredients": "Ingredientes",
+ "recipe.notSafe": "No encaja con tu configuración dietética",
+ "recipe.perPortion": "por ración",
"recipe.portions_one": "1 ración",
"recipe.portions_other": "{count} raciones",
- "recipe.time": "{min} min",
- "recipe.perPortion": "por ración",
- "recipe.ingredients": "Ingredientes",
+ "recipe.save": "Guardar",
+ "recipe.saved": "Guardada",
"recipe.steps": "Preparación",
- "recipe.cook": "Cocinar ahora",
- "recipe.notSafe": "No encaja con tu configuración dietética",
"recipe.substitutions": "Sustituir",
- "recipe.iCookedThis": "Lo he cocinado",
- "recipe.cost": "aprox. {amount}/ración",
- "cooking.step": "Paso {current} de {total}",
- "cooking.timer": "Iniciar temporizador",
- "cooking.timerRunning": "Quedan {time}",
- "cooking.finish": "Hecho – registrar la comida",
- "cooking.scale": "Raciones",
- "cooking.keepAwake": "La pantalla permanece encendida mientras cocinas",
- "cooked.title": "¿Qué tal ha ido?",
- "cooked.portionsCooked": "Raciones cocinadas",
- "cooked.whoAte": "¿Quiénes comieron?",
- "cooked.mealBoxes": "Raciones para táperes",
- "cooked.deductPantry": "Descontar ingredientes del inventario",
- "cooked.rate": "Valorar",
- "shopping.title": "Lista de la compra",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analizando …",
+ "scan.barcode": "Código de barras",
+ "scan.expiry": "Fecha de consumo preferente",
+ "scan.failed": "El análisis falló. Inténtalo de nuevo o añade manualmente.",
+ "scan.freezer": "Congelador",
+ "scan.fridge": "Nevera",
+ "scan.ingredients": "Ingredientes",
+ "scan.nutrition": "Etiqueta nutricional",
+ "scan.pantry": "Despensa",
+ "scan.plate": "Plato",
+ "scan.quotaLeft_one": "1 escaneo de IA restante este mes",
+ "scan.quotaLeft_other": "{count} escaneos de IA restantes este mes",
+ "scan.receipt": "Ticket",
+ "scan.review.addItem": "+ Añadir producto",
+ "scan.review.approveAll": "Guardar en el inventario",
+ "scan.review.bestBeforeNote": "Fecha de calidad: el alimento puede estar bien más allá. Huele y prueba antes de tirar.",
+ "scan.review.dateKindBestBefore": "Consumo preferente",
+ "scan.review.dateKindUseBy": "Fecha de caducidad",
+ "scan.review.datePlaceholder": "AAAA-MM-DD (opcional)",
+ "scan.review.itemPlaceholder": "Producto",
+ "scan.review.quantityPlaceholder": "Cantidad",
+ "scan.review.rejected": "Eliminado",
+ "scan.review.subtitle": "La IA a veces duda: tú decides. Edita, elimina o añade antes de guardar.",
+ "scan.review.title": "Revisa el resultado",
+ "scan.review.uncertain": "Dudoso – compruébalo",
+ "scan.review.unitPlaceholder": "Unidad (g, l, uds …)",
+ "scan.review.unknownItem": "Producto desconocido",
+ "scan.review.useByNote": "Fecha de seguridad: no lo comas después de esta fecha.",
+ "scan.subtitle": "Llena tu inventario o registra una comida con la cámara.",
+ "scan.takePhoto": "Hacer foto",
+ "scan.tips.light": "Evita la oscuridad y las sombras",
+ "scan.tips.move": "Aparta los productos que se tapan entre sí",
+ "scan.tips.overview": "Empieza con una foto general",
+ "scan.tips.shelf": "Fotografía estante por estante",
+ "scan.tips.title": "Cómo obtener el mejor análisis",
+ "scan.title": "Escanear",
"shopping.addPlaceholder": "Añadir producto …",
"shopping.complete": "Terminar la compra",
+ "shopping.completedBody_one": "Se añadió 1 producto al inventario.",
+ "shopping.completedBody_other": "Se añadieron {count} productos al inventario.",
+ "shopping.completedTitle": "¡Listo!",
"shopping.completeNote": "Los productos marcados se añaden al inventario.",
"shopping.empty": "La lista está vacía.",
"shopping.estimated": "aprox. {amount}",
"shopping.estimatedTotal": "Total estimado: aprox. {amount}",
- "mealbox.title": "Táperes",
- "mealbox.eatBy": "Consumir antes del {date}",
- "mealbox.portionsLeft_one": "Queda 1 ración",
- "mealbox.portionsLeft_other": "Quedan {count} raciones",
- "mealbox.eat": "Comer ahora",
- "mealbox.empty": "No hay táperes ahora mismo. Al cocinar puedes guardar raciones aquí.",
- "household.members": "Miembros",
- "household.invite": "Invita con el código: {code}",
- "household.shared": "Compartido en el hogar: inventario, lista de la compra, plan semanal, táperes y presupuesto.",
- "household.private": "Privado por persona: objetivos, alergias, datos de salud e historial de comidas.",
- "memory.title": "Lo que {brand} sabe de mí",
- "memory.subtitle": "Transparencia total. Corrige lo que esté mal, pausa o elimina: tu memoria es tuya.",
- "memory.paused": "En pausa",
- "memory.verify": "Correcto",
- "memory.pause": "Pausar",
- "memory.delete": "Eliminar",
- "memory.deleteAll": "Eliminar toda la memoria",
- "memory.empty": "{brand} aún no ha aprendido nada sobre ti.",
- "memory.origin.user_stated": "Nos lo contaste",
- "memory.origin.observed": "Patrón observado",
- "memory.origin.ai_inferred": "Suposición de la IA",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "El sistema operativo de comida de todo el hogar: inventario ilimitado, plan semanal y compartir.",
- "paywall.trialActive_one": "Queda 1 día de prueba",
- "paywall.trialActive_other": "Quedan {days} días de prueba",
- "paywall.household": "Household · hasta 3 personas",
- "paywall.family": "Family · hasta 6 personas",
- "paywall.large": "Large Household · hasta 12 personas",
- "paywall.perMonth": "{price}/mes",
- "paywall.fairUse": "Cuota de uso razonable de escaneos de IA incluida.",
- "paywall.restore": "Restaurar compras",
- "paywall.freeNote": "Gratis: 10 escaneos de IA/mes, inventario manual, recetas guardadas y registro sencillo.",
- "profile.title": "Perfil",
- "profile.goals": "Objetivos y dieta",
- "profile.consents": "Consentimientos y datos",
- "profile.memory": "Lo que {brand} sabe de mí",
- "profile.subscription": "Suscripción",
- "profile.logout": "Cerrar sesión",
- "profile.export": "Exportar mis datos",
- "profile.deleteAccount": "Eliminar cuenta",
- "profile.language": "Idioma",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.emailUnverified": "Correo electrónico sin confirmar",
- "profile.resendVerification": "Reenviar correo de confirmación",
- "profile.verificationSent": "¡Enviado! Revisa tu bandeja de entrada.",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Vaya",
- "common.undo": "Deshacer",
- "common.remove": "Quitar",
- "common.add": "Añadir",
- "common.on": "Activado",
- "common.off": "Desactivado",
- "home.thisWeek": "Esta semana",
- "home.wasteWeek": "Desperdicio esta semana",
- "home.useSoonHint": "La fecha de consumo preferente es de calidad: huele, mira y prueba antes de tirar nada. La fecha de caducidad, en cambio, debe respetarse.",
- "scan.review.itemPlaceholder": "Producto",
- "scan.review.quantityPlaceholder": "Cantidad",
- "scan.review.unitPlaceholder": "Unidad (g, l, uds …)",
- "scan.review.datePlaceholder": "AAAA-MM-DD (opcional)",
- "scan.review.dateKindBestBefore": "Consumo preferente",
- "scan.review.dateKindUseBy": "Fecha de caducidad",
- "scan.review.bestBeforeNote": "Fecha de calidad: el alimento puede estar bien más allá. Huele y prueba antes de tirar.",
- "scan.review.useByNote": "Fecha de seguridad: no lo comas después de esta fecha.",
- "scan.review.addItem": "+ Añadir producto",
- "scan.review.unknownItem": "Producto desconocido",
- "barcode.aim": "Apunta la cámara al código de barras",
- "barcode.addPrompt": "¿Añadir al inventario?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Sin datos nutricionales",
- "barcode.unknownTitle": "Producto desconocido",
- "barcode.unknownBody": "Este producto aún no está en la base de datos. Fotografía el frontal y la etiqueta nutricional y lo añadiremos.",
- "barcode.photoPackage": "Fotografiar el envase",
- "barcode.needHousehold": "Primero necesitas un hogar.",
- "barcode.noLocation": "No se encontró ningún lugar de almacenamiento.",
- "barcode.cameraTitle": "Se necesita la cámara",
- "barcode.cameraBody": "{brand} necesita la cámara para escanear códigos de barras.",
- "barcode.allowCamera": "Permitir cámara",
- "onboarding.goal.lose_weight": "Perder peso",
- "onboarding.goal.build_muscle": "Ganar músculo",
- "onboarding.goal.maintain_weight": "Mantener el peso",
- "onboarding.goal.more_protein": "Comer más proteína",
- "onboarding.goal.less_waste": "Reducir el desperdicio",
- "onboarding.goal.lower_cost": "Gastar menos en comida",
- "onboarding.goal.cook_more": "Cocinar más en casa",
- "onboarding.diet.omnivore": "Omnívoro",
- "onboarding.diet.flexitarian": "Flexitariano",
- "onboarding.diet.pescatarian": "Pescetariano",
- "onboarding.diet.vegetarian": "Vegetariano",
- "onboarding.diet.vegan": "Vegano",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Leche/lactosa",
- "onboarding.allergen.eggs": "Huevo",
- "onboarding.allergen.tree_nuts": "Frutos de cáscara",
- "onboarding.allergen.peanuts": "Cacahuetes",
- "onboarding.allergen.fish": "Pescado",
- "onboarding.allergen.crustaceans": "Crustáceos",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sésamo",
- "onboarding.bodyTitle": "Para objetivos calóricos personales (opcional)",
- "onboarding.weightPlaceholder": "Peso (kg)",
- "onboarding.heightPlaceholder": "Altura (cm)",
- "onboarding.birthYearPlaceholder": "Año de nacimiento",
- "onboarding.householdDefaultName": "Casa",
- "onboarding.modesCombine": "Puedes combinar los modos: sencillo a diario, exacto cuando quieras.",
- "myday.mealType.breakfast": "Desayuno",
- "myday.mealType.lunch": "Almuerzo",
- "myday.mealType.dinner": "Cena",
- "myday.mealType.snack": "Tentempié",
- "myday.mealType.dessert": "Postre",
- "myday.overRecommended": "Por encima de lo recomendado",
- "myday.todaysMeals": "Comidas de hoy",
- "myday.estimateRange": "{min}–{max} kcal, probablemente {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g de proteína",
- "logmeal.mealTypeTitle": "Tipo de comida",
- "logmeal.quickTitle": "Registro rápido",
- "logmeal.quickSubtitle": "Registra los mismos valores nutricionales que la última vez.",
- "logmeal.manualTitle": "Manual",
- "logmeal.whatPlaceholder": "¿Qué has comido?",
- "logmeal.proteinPlaceholder": "proteína (g)",
- "logmeal.validationTitle": "Faltan datos",
- "logmeal.validationBody": "Para el registro manual se necesitan nombre y calorías.",
- "logmeal.photoTip": "Consejo: fotografía el plato en Escanear y la app lo estimará por ti; tú siempre confirmas.",
- "shopping.section.frukt_gront": "Fruta y verdura",
"shopping.section.brod": "Pan",
- "shopping.section.mejeri": "Lácteos",
- "shopping.section.kott_fagel": "Carne y aves",
- "shopping.section.fisk": "Pescado",
"shopping.section.chark": "Charcutería",
- "shopping.section.frys": "Congelados",
- "shopping.section.skafferi": "Despensa",
- "shopping.section.konserver": "Conservas",
- "shopping.section.kryddor_bak": "Especias y repostería",
"shopping.section.dryck": "Bebidas",
- "shopping.section.snacks": "Aperitivos",
+ "shopping.section.fisk": "Pescado",
+ "shopping.section.frukt_gront": "Fruta y verdura",
+ "shopping.section.frys": "Congelados",
"shopping.section.hygien_ovrigt": "Otros",
- "shopping.completedTitle": "¡Listo!",
- "household.role.owner": "Propietario",
- "household.role.adult": "Adulto",
- "household.role.member": "Miembro",
- "household.role.child": "Niño",
- "household.empty": "Aún no tienes un hogar. Crea uno en la configuración inicial o únete con un código.",
- "household.shareCode": "Comparte el código con tu familia para compartir inventario, lista y plan.",
- "household.locations": "Lugares de almacenamiento",
- "household.portionFactor": "×{factor} ración",
- "mealbox.enjoyTitle": "¡Buen provecho!",
- "mealbox.enjoyBody": "La ración se ha registrado en Mi día.",
- "mealbox.guidanceNote": "El plazo recomendado es orientativo: confía en el olfato y el gusto.",
- "paywall.soonTitle": "¡Pronto!",
- "paywall.soonBody": "Las compras se activarán a través del App Store/Google Play cuando se active la integración con las tiendas (fase 7). El flujo de backend ya está listo.",
- "paywall.popular": "El más popular",
- "paywall.choose": "Elegir",
- "recipe.saved": "Guardada",
- "recipe.save": "Guardar",
- "recipe.avgRating": "Media de {avg} con {count} valoraciones",
- "memory.verified": "Verificado",
- "memory.resume": "Reanudar",
- "memory.deleteAllTitle": "¿Borrar toda la memoria?",
- "memory.irreversible": "Esto no se puede deshacer.",
- "profile.consent.personalization": "Funciones personales (memoria y perfil de gustos)",
- "profile.consent.anonymized_improvement": "Mejora anonimizada de la IA",
- "profile.consent.image_training": "Mis fotos pueden usarse para entrenamiento",
- "profile.consent.health_integration": "Datos de salud (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Ubicación para sugerencias según el tiempo",
- "profile.consent.push_notifications": "Notificaciones push",
- "profile.modeLabel": "Modo:",
- "profile.memorySubtitle": "Ve, corrige, pausa o borra lo que la plataforma ha aprendido.",
- "profile.consentsNote": "Los consentimientos son independientes: las funciones personales nunca exigen consentimiento de entrenamiento.",
- "profile.aiScansUsed": "Escaneos de IA: {used} / {total} este mes",
- "profile.deleteTitle": "¿Borrar la cuenta?",
- "profile.deleteBody": "Todos tus datos se eliminarán de forma permanente conforme al RGPD.",
- "cooking.timerDone": "¡Listo!",
- "cooked.deductPantryNote": "Los ingredientes se descuentan del inventario: primero los que caducan antes.",
- "home.moreItems_one": "+ 1 más …",
- "home.moreItems_other": "+ {count} más …",
- "shopping.completedBody_one": "Se añadió 1 producto al inventario.",
- "shopping.completedBody_other": "Se añadieron {count} productos al inventario.",
- "profile.consent.product_analytics": "Análisis de producto"
+ "shopping.section.konserver": "Conservas",
+ "shopping.section.kott_fagel": "Carne y aves",
+ "shopping.section.kryddor_bak": "Especias y repostería",
+ "shopping.section.mejeri": "Lácteos",
+ "shopping.section.skafferi": "Despensa",
+ "shopping.section.snacks": "Aperitivos",
+ "shopping.title": "Lista de la compra",
+ "tabs.home": "En casa",
+ "tabs.myDay": "Mi día",
+ "tabs.scan": "Escanear",
+ "tabs.whatToEat": "¿Qué comemos?",
+ "wte.coverage": "{pct}% en casa",
+ "wte.cravingPlaceholder": "Me apetece … (p. ej. cremoso, asiático, menos de 500 kcal)",
+ "wte.empty": "Aún no hay sugerencias: añade comida al inventario o relaja los filtros.",
+ "wte.mealBoxFirst": "Comida preparada en casa",
+ "wte.missing": "Falta: {items}",
+ "wte.refresh": "Nuevas sugerencias",
+ "wte.subtitle": "Según lo que tenéis en casa, lo que conviene usar pronto y lo que os gusta.",
+ "wte.title": "¿Qué comemos?",
+ "wte.whyTitle": "¿Por qué esta sugerencia?"
}
diff --git a/apps/mobile/src/locales/fi/common.json b/apps/mobile/src/locales/fi/common.json
index 902c111..65e53e5 100644
--- a/apps/mobile/src/locales/fi/common.json
+++ b/apps/mobile/src/locales/fi/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Ladataan …",
+ "auth.backToLogin": "Takaisin kirjautumiseen",
+ "auth.displayName": "Miksi kutsumme sinua?",
+ "auth.email": "Sähköposti",
+ "auth.forgotBody": "Anna sähköpostiosoitteesi, niin lähetämme linkin, jos tili on olemassa.",
+ "auth.forgotLink": "Unohtuiko salasana?",
+ "auth.forgotSentBody": "Jos osoitteella on tili, lähetimme linkin, joka on voimassa 30 minuuttia. Avaa se tällä laitteella.",
+ "auth.forgotSentTitle": "Tarkista sähköpostisi",
+ "auth.forgotSubmit": "Lähetä linkki",
+ "auth.forgotTitle": "Nollaa salasana",
+ "auth.hasAccount": "Onko sinulla jo tili? Kirjaudu",
+ "auth.login": "Kirjaudu",
+ "auth.newPassword": "Uusi salasana (vähintään 10 merkkiä)",
+ "auth.noAccount": "Uusi täällä? Luo tili",
+ "auth.password": "Salasana",
+ "auth.register": "Luo tili",
+ "auth.resetBody": "Linkki on voimassa 30 minuuttia ja sitä voi käyttää vain kerran. Kaikki laitteet kirjataan ulos.",
+ "auth.resetDoneBody": "Salasanasi on vaihdettu. Kirjaudu uudella salasanalla.",
+ "auth.resetDoneTitle": "Valmis!",
+ "auth.resetSubmit": "Vaihda salasana",
+ "auth.resetTitle": "Valitse uusi salasana",
+ "auth.resetTokenPlaceholder": "Liitä koodi sähköpostista",
+ "auth.trialNote": "7 päivää täyttä käyttöä – ilman korttia.",
+ "auth.verifyDoneBody": "Kiitos! Tilisi on nyt vahvistettu.",
+ "auth.verifyDoneTitle": "Sähköposti vahvistettu",
+ "auth.verifyFailedBody": "Linkki on virheellinen tai vanhentunut. Pyydä uusi profiilista.",
+ "auth.verifyFailedTitle": "Linkki ei toiminut",
+ "barcode.addPrompt": "Lisätäänkö ruokavarastoon?",
+ "barcode.aim": "Suuntaa kamera viivakoodiin",
+ "barcode.allowCamera": "Salli kamera",
+ "barcode.cameraBody": "{brand} tarvitsee kameraa viivakoodien skannaamiseen.",
+ "barcode.cameraTitle": "Kamera tarvitaan",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Tarvitset ensin kotitalouden.",
+ "barcode.noLocation": "Säilytyspaikkaa ei löytynyt.",
+ "barcode.noNutrition": "Ei ravintotietoja",
+ "barcode.photoPackage": "Kuvaa pakkaus",
+ "barcode.unknownBody": "Tuotetta ei ole vielä tietokannassa. Kuvaa etupuoli ja ravintosisältö, niin lisäämme sen.",
+ "barcode.unknownTitle": "Tuntematon tuote",
+ "common.add": "Lisää",
+ "common.back": "Takaisin",
+ "common.cancel": "Peruuta",
+ "common.done": "Valmis",
"common.error": "Jokin meni pieleen. Yritä uudelleen.",
+ "common.estimate": "Arvio",
+ "common.loading": "Ladataan …",
+ "common.next": "Seuraava",
+ "common.off": "Pois",
+ "common.offline": "Offline – näytetään viimeksi haetut tiedot",
+ "common.on": "Päällä",
+ "common.oops": "Hups",
+ "common.remove": "Poista",
"common.retry": "Yritä uudelleen",
"common.save": "Tallenna",
- "common.cancel": "Peruuta",
- "common.next": "Seuraava",
- "common.back": "Takaisin",
- "common.done": "Valmis",
"common.skip": "Ohita",
- "common.offline": "Offline – näytetään viimeksi haetut tiedot",
- "common.estimate": "Arvio",
- "tabs.whatToEat": "Mitä syödään?",
- "tabs.scan": "Skannaa",
- "tabs.myDay": "Minun päiväni",
- "tabs.home": "Kotona",
- "auth.login": "Kirjaudu",
- "auth.register": "Luo tili",
- "auth.email": "Sähköposti",
- "auth.password": "Salasana",
- "auth.displayName": "Miksi kutsumme sinua?",
- "auth.noAccount": "Uusi täällä? Luo tili",
- "auth.hasAccount": "Onko sinulla jo tili? Kirjaudu",
- "auth.trialNote": "7 päivää täyttä käyttöä – ilman korttia.",
- "auth.forgotLink": "Unohtuiko salasana?",
- "auth.forgotTitle": "Nollaa salasana",
- "auth.forgotBody": "Anna sähköpostiosoitteesi, niin lähetämme linkin, jos tili on olemassa.",
- "auth.forgotSubmit": "Lähetä linkki",
- "auth.forgotSentTitle": "Tarkista sähköpostisi",
- "auth.forgotSentBody": "Jos osoitteella on tili, lähetimme linkin, joka on voimassa 30 minuuttia. Avaa se tällä laitteella.",
- "auth.backToLogin": "Takaisin kirjautumiseen",
- "auth.resetTitle": "Valitse uusi salasana",
- "auth.resetBody": "Linkki on voimassa 30 minuuttia ja sitä voi käyttää vain kerran. Kaikki laitteet kirjataan ulos.",
- "auth.resetTokenPlaceholder": "Liitä koodi sähköpostista",
- "auth.newPassword": "Uusi salasana (vähintään 10 merkkiä)",
- "auth.resetSubmit": "Vaihda salasana",
- "auth.resetDoneTitle": "Valmis!",
- "auth.resetDoneBody": "Salasanasi on vaihdettu. Kirjaudu uudella salasanalla.",
- "auth.verifyDoneTitle": "Sähköposti vahvistettu",
- "auth.verifyDoneBody": "Kiitos! Tilisi on nyt vahvistettu.",
- "auth.verifyFailedTitle": "Linkki ei toiminut",
- "auth.verifyFailedBody": "Linkki on virheellinen tai vanhentunut. Pyydä uusi profiilista.",
- "onboarding.title": "Kerro hieman itsestäsi",
- "onboarding.subtitle": "Kaikki on vapaaehtoista ja muutettavissa milloin tahansa. Mitä enemmän täytät, sitä paremmat ehdotukset.",
- "onboarding.goal": "Mikä on tärkein tavoitteesi?",
- "onboarding.diet": "Miten syöt?",
+ "common.undo": "Kumoa",
+ "cooked.deductPantry": "Vähennä ainekset varastosta",
+ "cooked.deductPantryNote": "Ainekset vähennetään ruokavarastosta – ensin erääntyvät ensin.",
+ "cooked.mealBoxes": "Annoksia eväsrasioihin",
+ "cooked.portionsCooked": "Valmistetut annokset",
+ "cooked.rate": "Arvioi",
+ "cooked.title": "Miten meni?",
+ "cooked.whoAte": "Ketkä söivät?",
+ "cooking.finish": "Valmis – kirjaa ateria",
+ "cooking.keepAwake": "Näyttö pysyy päällä, kun kokkaat",
+ "cooking.scale": "Annokset",
+ "cooking.step": "Vaihe {current}/{total}",
+ "cooking.timer": "Käynnistä ajastin",
+ "cooking.timerDone": "Valmis!",
+ "cooking.timerRunning": "{time} jäljellä",
+ "home.budget": "Ruokabudjetti",
+ "home.emptyInventory": "Varasto on tyhjä. Skannaa jääkaappi tai lisää tuotteita käsin.",
+ "home.expired": "Vanhentunut",
+ "home.expiresIn_one": "1 päivä jäljellä",
+ "home.expiresIn_other": "{days} päivää jäljellä",
+ "home.expiresToday": "Vanhenee tänään",
+ "home.household": "Kotitalous",
+ "home.inventory": "Ruokavarasto",
+ "home.mealBoxes": "Eväsrasiat",
+ "home.moreItems_one": "+ 1 lisää …",
+ "home.moreItems_other": "+ {count} lisää …",
+ "home.pastBestBefore": "Parasta ennen ylitetty – haista ja maista ensin",
+ "home.shopping": "Ostoslista",
+ "home.thisWeek": "Tällä viikolla",
+ "home.title": "Kotona",
+ "home.useSoon": "Käytä pian",
+ "home.useSoonHint": "Parasta ennen koskee laatua – haista, katso ja maista ennen kuin heität pois. Viimeistä käyttöpäivää sen sijaan on noudatettava.",
+ "home.waste": "Ruokahävikki",
+ "home.wasteWeek": "Hävikki tällä viikolla",
+ "household.empty": "Sinulla ei ole vielä kotitaloutta. Luo sellainen käyttöönotossa tai liity koodilla.",
+ "household.invite": "Kutsu koodilla: {code}",
+ "household.locations": "Säilytyspaikat",
+ "household.members": "Jäsenet",
+ "household.portionFactor": "×{factor} annos",
+ "household.private": "Yksityistä per henkilö: tavoitteet, allergiat, terveystiedot ja ateriahistoria.",
+ "household.role.adult": "Aikuinen",
+ "household.role.child": "Lapsi",
+ "household.role.member": "Jäsen",
+ "household.role.owner": "Omistaja",
+ "household.shareCode": "Jaa koodi perheelle, niin jaatte ruokavaraston, listan ja suunnitelman.",
+ "household.shared": "Jaettua kotitaloudessa: ruokavarasto, ostoslista, viikkosuunnitelma, eväsrasiat ja budjetti.",
+ "logmeal.manualTitle": "Manuaalisesti",
+ "logmeal.mealTypeTitle": "Ateriatyyppi",
+ "logmeal.photoTip": "Vinkki: kuvaa lautanen Skannaa-välilehdellä, niin sovellus arvioi puolestasi – sinä vahvistat aina.",
+ "logmeal.proteinPlaceholder": "proteiini (g)",
+ "logmeal.quickSubtitle": "Kirjaa samat ravintoarvot kuin viimeksi.",
+ "logmeal.quickTitle": "Nopea uudelleenkirjaus",
+ "logmeal.validationBody": "Manuaalinen kirjaus vaatii nimen ja kalorit.",
+ "logmeal.validationTitle": "Täydennä",
+ "logmeal.whatPlaceholder": "Mitä söit?",
+ "mealbox.eat": "Syö nyt",
+ "mealbox.eatBy": "Syö viimeistään {date}",
+ "mealbox.empty": "Ei eväsrasioita juuri nyt. Kokatessasi voit tallentaa annoksia tänne.",
+ "mealbox.enjoyBody": "Annos on kirjattu Minun päiväni -näkymään.",
+ "mealbox.enjoyTitle": "Hyvää ruokahalua!",
+ "mealbox.guidanceNote": "Suositeltu käyttöaika on ohjeellinen – luota hajuun ja makuun.",
+ "mealbox.portionsLeft_one": "1 annos jäljellä",
+ "mealbox.portionsLeft_other": "{count} annosta jäljellä",
+ "mealbox.title": "Eväsrasiat",
+ "memory.delete": "Poista",
+ "memory.deleteAll": "Poista koko muisti",
+ "memory.deleteAllTitle": "Poistetaanko koko muisti?",
+ "memory.empty": "{brand} ei ole vielä oppinut sinusta mitään.",
+ "memory.irreversible": "Tätä ei voi kumota.",
+ "memory.origin.ai_inferred": "AI:n oletus",
+ "memory.origin.observed": "Havaittu tapa",
+ "memory.origin.user_stated": "Kerroit itse",
+ "memory.pause": "Keskeytä",
+ "memory.paused": "Keskeytetty",
+ "memory.resume": "Jatka",
+ "memory.subtitle": "Täysi läpinäkyvyys. Korjaa virheet, keskeytä tai poista – omistat muistisi.",
+ "memory.title": "Mitä {brand} tietää minusta",
+ "memory.verified": "Vahvistettu",
+ "memory.verify": "Oikein",
+ "myday.calories": "Kalorit",
+ "myday.carbs": "Hiilihydraatit",
+ "myday.estimateNote": "Arvot, joissa on ~, ovat arvioita, joita voit säätää.",
+ "myday.estimateRange": "{min}–{max} kcal, todennäköisesti {kcal}",
+ "myday.fat": "Rasva",
+ "myday.fiber": "Kuitu",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g proteiinia",
+ "myday.logMeal": "Kirjaa ateria",
+ "myday.mealType.breakfast": "Aamiainen",
+ "myday.mealType.dessert": "Jälkiruoka",
+ "myday.mealType.dinner": "Päivällinen",
+ "myday.mealType.lunch": "Lounas",
+ "myday.mealType.snack": "Välipala",
+ "myday.noMeals": "Ei kirjattuja aterioita tänään.",
+ "myday.over": "{kcal} kcal yli tavoitteen",
+ "myday.overRecommended": "Yli suosituksen",
+ "myday.protein": "Proteiini",
+ "myday.remaining": "{kcal} kcal jäljellä",
+ "myday.salt": "Suola",
+ "myday.targetsNote": "Tavoitteet ovat ohjeellisia, eivät lääketieteellisiä neuvoja.",
+ "myday.title": "Minun päiväni",
+ "myday.todaysMeals": "Päivän ateriat",
+ "onboarding.allergen.crustaceans": "Äyriäiset",
+ "onboarding.allergen.eggs": "Kananmuna",
+ "onboarding.allergen.fish": "Kala",
+ "onboarding.allergen.gluten": "Gluteeni",
+ "onboarding.allergen.milk": "Maito/laktoosi",
+ "onboarding.allergen.peanuts": "Maapähkinät",
+ "onboarding.allergen.sesame": "Seesami",
+ "onboarding.allergen.soy": "Soija",
+ "onboarding.allergen.tree_nuts": "Pähkinät",
"onboarding.allergies": "Allergiat ja intoleranssit",
"onboarding.allergyNote": "Allergiasuodatus on aina tiukka – ruokia, joissa on allergeenejasi, ei koskaan näytetä.",
+ "onboarding.birthYearPlaceholder": "Syntymävuosi",
+ "onboarding.bodyTitle": "Henkilökohtaisia kaloritavoitteita varten (valinnainen)",
+ "onboarding.diet": "Miten syöt?",
+ "onboarding.diet.flexitarian": "Fleksitaristi",
+ "onboarding.diet.omnivore": "Sekasyöjä",
+ "onboarding.diet.pescatarian": "Pescetaristi",
+ "onboarding.diet.vegan": "Vegaani",
+ "onboarding.diet.vegetarian": "Kasvissyöjä",
+ "onboarding.goal": "Mikä on tärkein tavoitteesi?",
+ "onboarding.goal.build_muscle": "Kasvattaa lihasta",
+ "onboarding.goal.cook_more": "Kokata enemmän kotona",
+ "onboarding.goal.less_waste": "Vähentää hävikkiä",
+ "onboarding.goal.lose_weight": "Laihduttaa",
+ "onboarding.goal.lower_cost": "Säästää ruokakuluissa",
+ "onboarding.goal.maintain_weight": "Pitää painon ennallaan",
+ "onboarding.goal.more_protein": "Syödä enemmän proteiinia",
+ "onboarding.heightPlaceholder": "Pituus (cm)",
"onboarding.household": "Kotitaloutesi",
"onboarding.householdCreate": "Luo kotitalous",
+ "onboarding.householdDefaultName": "Koti",
"onboarding.householdJoin": "Liity koodilla",
"onboarding.householdName": "Kotitalouden nimi",
"onboarding.inviteCode": "Kutsukoodi",
"onboarding.mode": "Kuinka tarkka haluat olla?",
- "onboarding.modeSimple": "Helppo tila",
- "onboarding.modeSimpleDesc": "Kuvaa ruokasi, hyväksy arviot, mahdollisimman vaivatonta.",
"onboarding.modeExact": "Tarkka tila",
"onboarding.modeExactDesc": "Punnitse ruoka, syötä grammat, täysi hallinta lukuihin.",
+ "onboarding.modesCombine": "Tiloja voi yhdistellä – arjessa helposti, tarkasti kun haluat.",
+ "onboarding.modeSimple": "Helppo tila",
+ "onboarding.modeSimpleDesc": "Kuvaa ruokasi, hyväksy arviot, mahdollisimman vaivatonta.",
"onboarding.notMedical": "{brand} antaa ohjeita – ei lääketieteellisiä neuvoja.",
- "wte.title": "Mitä syödään?",
- "wte.subtitle": "Sen mukaan mitä kotona on, mikä pitäisi käyttää pian ja mistä pidätte.",
- "wte.cravingPlaceholder": "Tekisi mieli … (esim. kermaista, aasialaista, alle 500 kcal)",
- "wte.mealBoxFirst": "Valmista ruokaa kotona",
- "wte.whyTitle": "Miksi tämä ehdotus?",
- "wte.coverage": "{pct} % kotona",
- "wte.missing": "Puuttuu: {items}",
- "wte.empty": "Ei vielä ehdotuksia – lisää ruokaa varastoon tai löysää suodattimia.",
- "wte.refresh": "Uudet ehdotukset",
- "scan.title": "Skannaa",
- "scan.subtitle": "Täytä ruokavarasto tai kirjaa ateria kameralla.",
- "scan.fridge": "Jääkaappi",
- "scan.freezer": "Pakastin",
- "scan.pantry": "Ruokakomero",
- "scan.ingredients": "Ainekset",
- "scan.plate": "Lautanen",
- "scan.receipt": "Kuitti",
- "scan.barcode": "Viivakoodi",
- "scan.expiry": "Parasta ennen -päiväys",
- "scan.nutrition": "Ravintosisältö",
- "scan.takePhoto": "Ota kuva",
- "scan.tips.title": "Näin analyysi onnistuu parhaiten",
- "scan.tips.overview": "Aloita yleiskuvalla",
- "scan.tips.shelf": "Kuvaa hylly kerrallaan",
- "scan.tips.light": "Vältä pimeyttä ja varjoja",
- "scan.tips.move": "Siirrä toisiaan peittävät tuotteet",
- "scan.analyzing": "Analysoidaan …",
- "scan.quotaLeft_one": "1 AI-skannaus jäljellä tässä kuussa",
- "scan.quotaLeft_other": "{count} AI-skannausta jäljellä tässä kuussa",
- "scan.review.title": "Tarkista tulos",
- "scan.review.subtitle": "AI on joskus epävarma – sinä päätät. Muokkaa, poista tai lisää ennen tallennusta.",
- "scan.review.uncertain": "Epävarma – tarkista",
- "scan.review.approveAll": "Tallenna varastoon",
- "scan.review.rejected": "Poistettu",
- "scan.failed": "Analyysi epäonnistui. Yritä uudelleen tai lisää käsin.",
- "myday.title": "Minun päiväni",
- "myday.calories": "Kalorit",
- "myday.protein": "Proteiini",
- "myday.carbs": "Hiilihydraatit",
- "myday.fat": "Rasva",
- "myday.fiber": "Kuitu",
- "myday.salt": "Suola",
- "myday.remaining": "{kcal} kcal jäljellä",
- "myday.over": "{kcal} kcal yli tavoitteen",
- "myday.logMeal": "Kirjaa ateria",
- "myday.noMeals": "Ei kirjattuja aterioita tänään.",
- "myday.estimateNote": "Arvot, joissa on ~, ovat arvioita, joita voit säätää.",
- "myday.targetsNote": "Tavoitteet ovat ohjeellisia, eivät lääketieteellisiä neuvoja.",
- "home.title": "Kotona",
- "home.inventory": "Ruokavarasto",
- "home.useSoon": "Käytä pian",
- "home.mealBoxes": "Eväsrasiat",
- "home.shopping": "Ostoslista",
- "home.budget": "Ruokabudjetti",
- "home.household": "Kotitalous",
- "home.waste": "Ruokahävikki",
- "home.emptyInventory": "Varasto on tyhjä. Skannaa jääkaappi tai lisää tuotteita käsin.",
- "home.expiresIn_one": "1 päivä jäljellä",
- "home.expiresIn_other": "{days} päivää jäljellä",
- "home.expiresToday": "Vanhenee tänään",
- "home.expired": "Vanhentunut",
- "home.pastBestBefore": "Parasta ennen ylitetty – haista ja maista ensin",
+ "onboarding.stepBSubtitle": "Mukauta profiiliasi parempia ehdotuksia varten.",
+ "onboarding.stepBTitle": "Jatka asetuksia",
+ "onboarding.stepCSubtitle": "Valinnainen – käytetään henkilökohtaisiin kaloritavoitteisiin.",
+ "onboarding.stepCTitle": "Terveysprofiilisi",
+ "onboarding.subtitle": "Kaikki on vapaaehtoista ja muutettavissa milloin tahansa. Mitä enemmän täytät, sitä paremmat ehdotukset.",
+ "onboarding.title": "Kerro hieman itsestäsi",
+ "onboarding.weightPlaceholder": "Paino (kg)",
+ "paywall.choose": "Valitse",
+ "paywall.fairUse": "Kohtuukäytön AI-skannauskiintiö sisältyy.",
+ "paywall.family": "Family · enintään 6 henkilöä",
+ "paywall.freeNote": "Ilmainen: 10 AI-skannausta/kk, manuaalinen varasto, tallennetut reseptit ja helppo kirjaus.",
+ "paywall.household": "Household · enintään 3 henkilöä",
+ "paywall.large": "Large Household · enintään 12 henkilöä",
+ "paywall.perMonth": "{price}/kk",
+ "paywall.popular": "Suosituin",
+ "paywall.restore": "Palauta ostot",
+ "paywall.soonBody": "Ostot aktivoituvat App Storen/Google Playn kautta, kun kauppaintegraatio otetaan käyttöön (vaihe 7). Taustajärjestelmä on jo valmis.",
+ "paywall.soonTitle": "Pian!",
+ "paywall.subtitle": "Koko kotitalouden ruoka-OS: rajaton varasto, viikkosuunnitelma ja jakaminen.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "1 päivä kokeilua jäljellä",
+ "paywall.trialActive_other": "{days} päivää kokeilua jäljellä",
+ "profile.aiScansUsed": "AI-skannaukset: {used} / {total} tässä kuussa",
+ "profile.consent.anonymized_improvement": "Tekoälyn anonymisoitu parantaminen",
+ "profile.consent.health_integration": "Terveystiedot (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Kuviani saa käyttää koulutukseen",
+ "profile.consent.location_weather": "Sijainti sääpohjaisia ehdotuksia varten",
+ "profile.consent.personalization": "Henkilökohtaiset toiminnot (muisti & makuprofiili)",
+ "profile.consent.product_analytics": "Tuoteanalyysi",
+ "profile.consent.push_notifications": "Push-ilmoitukset",
+ "profile.consents": "Suostumukset & tiedot",
+ "profile.consentsNote": "Suostumukset ovat erillisiä – henkilökohtaiset toiminnot eivät koskaan vaadi koulutussuostumusta.",
+ "profile.deleteAccount": "Poista tili",
+ "profile.deleteBody": "Kaikki tietosi poistetaan pysyvästi GDPR:n mukaisesti.",
+ "profile.deleteTitle": "Poistetaanko tili?",
+ "profile.emailUnverified": "Sähköpostia ei ole vahvistettu",
+ "profile.export": "Vie tietoni",
+ "profile.goals": "Tavoitteet & ruokavalio",
+ "profile.language": "Kieli",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Kirjaudu ulos",
+ "profile.memory": "Mitä {brand} tietää minusta",
+ "profile.memorySubtitle": "Katso, korjaa, keskeytä tai poista se, mitä alusta on oppinut.",
+ "profile.modeLabel": "Tila:",
+ "profile.resendVerification": "Lähetä vahvistusviesti uudelleen",
+ "profile.subscription": "Tilaus",
+ "profile.title": "Profiili",
+ "profile.verificationSent": "Lähetetty! Tarkista sähköpostisi.",
+ "recipe.avgRating": "Keskiarvo {avg}, {count} arviota",
+ "recipe.cook": "Kokkaa nyt",
+ "recipe.cost": "n. {amount}/annos",
+ "recipe.iCookedThis": "Tein tämän",
+ "recipe.ingredients": "Ainekset",
+ "recipe.notSafe": "Ei sovi ruokavalioasetuksiisi",
+ "recipe.perPortion": "per annos",
"recipe.portions_one": "1 annos",
"recipe.portions_other": "{count} annosta",
- "recipe.time": "{min} min",
- "recipe.perPortion": "per annos",
- "recipe.ingredients": "Ainekset",
+ "recipe.save": "Tallenna",
+ "recipe.saved": "Tallennettu",
"recipe.steps": "Valmistus",
- "recipe.cook": "Kokkaa nyt",
- "recipe.notSafe": "Ei sovi ruokavalioasetuksiisi",
"recipe.substitutions": "Korvaa",
- "recipe.iCookedThis": "Tein tämän",
- "recipe.cost": "n. {amount}/annos",
- "cooking.step": "Vaihe {current}/{total}",
- "cooking.timer": "Käynnistä ajastin",
- "cooking.timerRunning": "{time} jäljellä",
- "cooking.finish": "Valmis – kirjaa ateria",
- "cooking.scale": "Annokset",
- "cooking.keepAwake": "Näyttö pysyy päällä, kun kokkaat",
- "cooked.title": "Miten meni?",
- "cooked.portionsCooked": "Valmistetut annokset",
- "cooked.whoAte": "Ketkä söivät?",
- "cooked.mealBoxes": "Annoksia eväsrasioihin",
- "cooked.deductPantry": "Vähennä ainekset varastosta",
- "cooked.rate": "Arvioi",
- "shopping.title": "Ostoslista",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analysoidaan …",
+ "scan.barcode": "Viivakoodi",
+ "scan.expiry": "Parasta ennen -päiväys",
+ "scan.failed": "Analyysi epäonnistui. Yritä uudelleen tai lisää käsin.",
+ "scan.freezer": "Pakastin",
+ "scan.fridge": "Jääkaappi",
+ "scan.ingredients": "Ainekset",
+ "scan.nutrition": "Ravintosisältö",
+ "scan.pantry": "Ruokakomero",
+ "scan.plate": "Lautanen",
+ "scan.quotaLeft_one": "1 AI-skannaus jäljellä tässä kuussa",
+ "scan.quotaLeft_other": "{count} AI-skannausta jäljellä tässä kuussa",
+ "scan.receipt": "Kuitti",
+ "scan.review.addItem": "+ Lisää tuote",
+ "scan.review.approveAll": "Tallenna varastoon",
+ "scan.review.bestBeforeNote": "Laatupäivä – tuote voi olla hyvää senkin jälkeen. Haista ja maista ennen poisheittoa.",
+ "scan.review.dateKindBestBefore": "Parasta ennen",
+ "scan.review.dateKindUseBy": "Viimeinen käyttöpäivä",
+ "scan.review.datePlaceholder": "VVVV-KK-PP (valinnainen)",
+ "scan.review.itemPlaceholder": "Tuote",
+ "scan.review.quantityPlaceholder": "Määrä",
+ "scan.review.rejected": "Poistettu",
+ "scan.review.subtitle": "AI on joskus epävarma – sinä päätät. Muokkaa, poista tai lisää ennen tallennusta.",
+ "scan.review.title": "Tarkista tulos",
+ "scan.review.uncertain": "Epävarma – tarkista",
+ "scan.review.unitPlaceholder": "Yksikkö (g, l, kpl …)",
+ "scan.review.unknownItem": "Tuntematon tuote",
+ "scan.review.useByNote": "Turvallisuusraja – älä syö tämän päivän jälkeen.",
+ "scan.subtitle": "Täytä ruokavarasto tai kirjaa ateria kameralla.",
+ "scan.takePhoto": "Ota kuva",
+ "scan.tips.light": "Vältä pimeyttä ja varjoja",
+ "scan.tips.move": "Siirrä toisiaan peittävät tuotteet",
+ "scan.tips.overview": "Aloita yleiskuvalla",
+ "scan.tips.shelf": "Kuvaa hylly kerrallaan",
+ "scan.tips.title": "Näin analyysi onnistuu parhaiten",
+ "scan.title": "Skannaa",
"shopping.addPlaceholder": "Lisää tuote …",
"shopping.complete": "Päätä ostosreissu",
+ "shopping.completedBody_one": "1 tuote lisättiin ruokavarastoon.",
+ "shopping.completedBody_other": "{count} tuotetta lisättiin ruokavarastoon.",
+ "shopping.completedTitle": "Valmis!",
"shopping.completeNote": "Merkityt tuotteet lisätään ruokavarastoon.",
"shopping.empty": "Lista on tyhjä.",
"shopping.estimated": "n. {amount}",
"shopping.estimatedTotal": "Arvioitu yhteensä: n. {amount}",
- "mealbox.title": "Eväsrasiat",
- "mealbox.eatBy": "Syö viimeistään {date}",
- "mealbox.portionsLeft_one": "1 annos jäljellä",
- "mealbox.portionsLeft_other": "{count} annosta jäljellä",
- "mealbox.eat": "Syö nyt",
- "mealbox.empty": "Ei eväsrasioita juuri nyt. Kokatessasi voit tallentaa annoksia tänne.",
- "household.members": "Jäsenet",
- "household.invite": "Kutsu koodilla: {code}",
- "household.shared": "Jaettua kotitaloudessa: ruokavarasto, ostoslista, viikkosuunnitelma, eväsrasiat ja budjetti.",
- "household.private": "Yksityistä per henkilö: tavoitteet, allergiat, terveystiedot ja ateriahistoria.",
- "memory.title": "Mitä {brand} tietää minusta",
- "memory.subtitle": "Täysi läpinäkyvyys. Korjaa virheet, keskeytä tai poista – omistat muistisi.",
- "memory.paused": "Keskeytetty",
- "memory.verify": "Oikein",
- "memory.pause": "Keskeytä",
- "memory.delete": "Poista",
- "memory.deleteAll": "Poista koko muisti",
- "memory.empty": "{brand} ei ole vielä oppinut sinusta mitään.",
- "memory.origin.user_stated": "Kerroit itse",
- "memory.origin.observed": "Havaittu tapa",
- "memory.origin.ai_inferred": "AI:n oletus",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "Koko kotitalouden ruoka-OS: rajaton varasto, viikkosuunnitelma ja jakaminen.",
- "paywall.trialActive_one": "1 päivä kokeilua jäljellä",
- "paywall.trialActive_other": "{days} päivää kokeilua jäljellä",
- "paywall.household": "Household · enintään 3 henkilöä",
- "paywall.family": "Family · enintään 6 henkilöä",
- "paywall.large": "Large Household · enintään 12 henkilöä",
- "paywall.perMonth": "{price}/kk",
- "paywall.fairUse": "Kohtuukäytön AI-skannauskiintiö sisältyy.",
- "paywall.restore": "Palauta ostot",
- "paywall.freeNote": "Ilmainen: 10 AI-skannausta/kk, manuaalinen varasto, tallennetut reseptit ja helppo kirjaus.",
- "profile.title": "Profiili",
- "profile.goals": "Tavoitteet & ruokavalio",
- "profile.consents": "Suostumukset & tiedot",
- "profile.memory": "Mitä {brand} tietää minusta",
- "profile.subscription": "Tilaus",
- "profile.logout": "Kirjaudu ulos",
- "profile.export": "Vie tietoni",
- "profile.deleteAccount": "Poista tili",
- "profile.language": "Kieli",
- "profile.emailUnverified": "Sähköpostia ei ole vahvistettu",
- "profile.resendVerification": "Lähetä vahvistusviesti uudelleen",
- "profile.verificationSent": "Lähetetty! Tarkista sähköpostisi.",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Hups",
- "common.undo": "Kumoa",
- "common.remove": "Poista",
- "common.add": "Lisää",
- "common.on": "Päällä",
- "common.off": "Pois",
- "home.thisWeek": "Tällä viikolla",
- "home.wasteWeek": "Hävikki tällä viikolla",
- "home.useSoonHint": "Parasta ennen koskee laatua – haista, katso ja maista ennen kuin heität pois. Viimeistä käyttöpäivää sen sijaan on noudatettava.",
- "scan.review.itemPlaceholder": "Tuote",
- "scan.review.quantityPlaceholder": "Määrä",
- "scan.review.unitPlaceholder": "Yksikkö (g, l, kpl …)",
- "scan.review.datePlaceholder": "VVVV-KK-PP (valinnainen)",
- "scan.review.dateKindBestBefore": "Parasta ennen",
- "scan.review.dateKindUseBy": "Viimeinen käyttöpäivä",
- "scan.review.bestBeforeNote": "Laatupäivä – tuote voi olla hyvää senkin jälkeen. Haista ja maista ennen poisheittoa.",
- "scan.review.useByNote": "Turvallisuusraja – älä syö tämän päivän jälkeen.",
- "scan.review.addItem": "+ Lisää tuote",
- "scan.review.unknownItem": "Tuntematon tuote",
- "barcode.aim": "Suuntaa kamera viivakoodiin",
- "barcode.addPrompt": "Lisätäänkö ruokavarastoon?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Ei ravintotietoja",
- "barcode.unknownTitle": "Tuntematon tuote",
- "barcode.unknownBody": "Tuotetta ei ole vielä tietokannassa. Kuvaa etupuoli ja ravintosisältö, niin lisäämme sen.",
- "barcode.photoPackage": "Kuvaa pakkaus",
- "barcode.needHousehold": "Tarvitset ensin kotitalouden.",
- "barcode.noLocation": "Säilytyspaikkaa ei löytynyt.",
- "barcode.cameraTitle": "Kamera tarvitaan",
- "barcode.cameraBody": "{brand} tarvitsee kameraa viivakoodien skannaamiseen.",
- "barcode.allowCamera": "Salli kamera",
- "onboarding.goal.lose_weight": "Laihduttaa",
- "onboarding.goal.build_muscle": "Kasvattaa lihasta",
- "onboarding.goal.maintain_weight": "Pitää painon ennallaan",
- "onboarding.goal.more_protein": "Syödä enemmän proteiinia",
- "onboarding.goal.less_waste": "Vähentää hävikkiä",
- "onboarding.goal.lower_cost": "Säästää ruokakuluissa",
- "onboarding.goal.cook_more": "Kokata enemmän kotona",
- "onboarding.diet.omnivore": "Sekasyöjä",
- "onboarding.diet.flexitarian": "Fleksitaristi",
- "onboarding.diet.pescatarian": "Pescetaristi",
- "onboarding.diet.vegetarian": "Kasvissyöjä",
- "onboarding.diet.vegan": "Vegaani",
- "onboarding.allergen.gluten": "Gluteeni",
- "onboarding.allergen.milk": "Maito/laktoosi",
- "onboarding.allergen.eggs": "Kananmuna",
- "onboarding.allergen.tree_nuts": "Pähkinät",
- "onboarding.allergen.peanuts": "Maapähkinät",
- "onboarding.allergen.fish": "Kala",
- "onboarding.allergen.crustaceans": "Äyriäiset",
- "onboarding.allergen.soy": "Soija",
- "onboarding.allergen.sesame": "Seesami",
- "onboarding.bodyTitle": "Henkilökohtaisia kaloritavoitteita varten (valinnainen)",
- "onboarding.weightPlaceholder": "Paino (kg)",
- "onboarding.heightPlaceholder": "Pituus (cm)",
- "onboarding.birthYearPlaceholder": "Syntymävuosi",
- "onboarding.householdDefaultName": "Koti",
- "onboarding.modesCombine": "Tiloja voi yhdistellä – arjessa helposti, tarkasti kun haluat.",
- "myday.mealType.breakfast": "Aamiainen",
- "myday.mealType.lunch": "Lounas",
- "myday.mealType.dinner": "Päivällinen",
- "myday.mealType.snack": "Välipala",
- "myday.mealType.dessert": "Jälkiruoka",
- "myday.overRecommended": "Yli suosituksen",
- "myday.todaysMeals": "Päivän ateriat",
- "myday.estimateRange": "{min}–{max} kcal, todennäköisesti {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g proteiinia",
- "logmeal.mealTypeTitle": "Ateriatyyppi",
- "logmeal.quickTitle": "Nopea uudelleenkirjaus",
- "logmeal.quickSubtitle": "Kirjaa samat ravintoarvot kuin viimeksi.",
- "logmeal.manualTitle": "Manuaalisesti",
- "logmeal.whatPlaceholder": "Mitä söit?",
- "logmeal.proteinPlaceholder": "proteiini (g)",
- "logmeal.validationTitle": "Täydennä",
- "logmeal.validationBody": "Manuaalinen kirjaus vaatii nimen ja kalorit.",
- "logmeal.photoTip": "Vinkki: kuvaa lautanen Skannaa-välilehdellä, niin sovellus arvioi puolestasi – sinä vahvistat aina.",
- "shopping.section.frukt_gront": "Hedelmät & vihannekset",
"shopping.section.brod": "Leipä",
- "shopping.section.mejeri": "Maitotuotteet",
- "shopping.section.kott_fagel": "Liha & siipikarja",
- "shopping.section.fisk": "Kala",
"shopping.section.chark": "Leikkeleet",
- "shopping.section.frys": "Pakasteet",
- "shopping.section.skafferi": "Kuivatuotteet",
- "shopping.section.konserver": "Säilykkeet",
- "shopping.section.kryddor_bak": "Mausteet & leivonta",
"shopping.section.dryck": "Juomat",
- "shopping.section.snacks": "Naposteltavat",
+ "shopping.section.fisk": "Kala",
+ "shopping.section.frukt_gront": "Hedelmät & vihannekset",
+ "shopping.section.frys": "Pakasteet",
"shopping.section.hygien_ovrigt": "Muut",
- "shopping.completedTitle": "Valmis!",
- "household.role.owner": "Omistaja",
- "household.role.adult": "Aikuinen",
- "household.role.member": "Jäsen",
- "household.role.child": "Lapsi",
- "household.empty": "Sinulla ei ole vielä kotitaloutta. Luo sellainen käyttöönotossa tai liity koodilla.",
- "household.shareCode": "Jaa koodi perheelle, niin jaatte ruokavaraston, listan ja suunnitelman.",
- "household.locations": "Säilytyspaikat",
- "household.portionFactor": "×{factor} annos",
- "mealbox.enjoyTitle": "Hyvää ruokahalua!",
- "mealbox.enjoyBody": "Annos on kirjattu Minun päiväni -näkymään.",
- "mealbox.guidanceNote": "Suositeltu käyttöaika on ohjeellinen – luota hajuun ja makuun.",
- "paywall.soonTitle": "Pian!",
- "paywall.soonBody": "Ostot aktivoituvat App Storen/Google Playn kautta, kun kauppaintegraatio otetaan käyttöön (vaihe 7). Taustajärjestelmä on jo valmis.",
- "paywall.popular": "Suosituin",
- "paywall.choose": "Valitse",
- "recipe.saved": "Tallennettu",
- "recipe.save": "Tallenna",
- "recipe.avgRating": "Keskiarvo {avg}, {count} arviota",
- "memory.verified": "Vahvistettu",
- "memory.resume": "Jatka",
- "memory.deleteAllTitle": "Poistetaanko koko muisti?",
- "memory.irreversible": "Tätä ei voi kumota.",
- "profile.consent.personalization": "Henkilökohtaiset toiminnot (muisti & makuprofiili)",
- "profile.consent.anonymized_improvement": "Tekoälyn anonymisoitu parantaminen",
- "profile.consent.image_training": "Kuviani saa käyttää koulutukseen",
- "profile.consent.health_integration": "Terveystiedot (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Sijainti sääpohjaisia ehdotuksia varten",
- "profile.consent.push_notifications": "Push-ilmoitukset",
- "profile.modeLabel": "Tila:",
- "profile.memorySubtitle": "Katso, korjaa, keskeytä tai poista se, mitä alusta on oppinut.",
- "profile.consentsNote": "Suostumukset ovat erillisiä – henkilökohtaiset toiminnot eivät koskaan vaadi koulutussuostumusta.",
- "profile.aiScansUsed": "AI-skannaukset: {used} / {total} tässä kuussa",
- "profile.deleteTitle": "Poistetaanko tili?",
- "profile.deleteBody": "Kaikki tietosi poistetaan pysyvästi GDPR:n mukaisesti.",
- "cooking.timerDone": "Valmis!",
- "cooked.deductPantryNote": "Ainekset vähennetään ruokavarastosta – ensin erääntyvät ensin.",
- "home.moreItems_one": "+ 1 lisää …",
- "home.moreItems_other": "+ {count} lisää …",
- "shopping.completedBody_one": "1 tuote lisättiin ruokavarastoon.",
- "shopping.completedBody_other": "{count} tuotetta lisättiin ruokavarastoon.",
- "profile.consent.product_analytics": "Tuoteanalyysi"
+ "shopping.section.konserver": "Säilykkeet",
+ "shopping.section.kott_fagel": "Liha & siipikarja",
+ "shopping.section.kryddor_bak": "Mausteet & leivonta",
+ "shopping.section.mejeri": "Maitotuotteet",
+ "shopping.section.skafferi": "Kuivatuotteet",
+ "shopping.section.snacks": "Naposteltavat",
+ "shopping.title": "Ostoslista",
+ "tabs.home": "Kotona",
+ "tabs.myDay": "Minun päiväni",
+ "tabs.scan": "Skannaa",
+ "tabs.whatToEat": "Mitä syödään?",
+ "wte.coverage": "{pct} % kotona",
+ "wte.cravingPlaceholder": "Tekisi mieli … (esim. kermaista, aasialaista, alle 500 kcal)",
+ "wte.empty": "Ei vielä ehdotuksia – lisää ruokaa varastoon tai löysää suodattimia.",
+ "wte.mealBoxFirst": "Valmista ruokaa kotona",
+ "wte.missing": "Puuttuu: {items}",
+ "wte.refresh": "Uudet ehdotukset",
+ "wte.subtitle": "Sen mukaan mitä kotona on, mikä pitäisi käyttää pian ja mistä pidätte.",
+ "wte.title": "Mitä syödään?",
+ "wte.whyTitle": "Miksi tämä ehdotus?"
}
diff --git a/apps/mobile/src/locales/fr/common.json b/apps/mobile/src/locales/fr/common.json
index e53099f..cbaf4e2 100644
--- a/apps/mobile/src/locales/fr/common.json
+++ b/apps/mobile/src/locales/fr/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Chargement …",
+ "auth.backToLogin": "Retour à la connexion",
+ "auth.displayName": "Comment vous appeler ?",
+ "auth.email": "E-mail",
+ "auth.forgotBody": "Saisissez votre e-mail : nous enverrons un lien si le compte existe.",
+ "auth.forgotLink": "Mot de passe oublié ?",
+ "auth.forgotSentBody": "Si l'adresse possède un compte, un lien valable 30 minutes a été envoyé. Ouvrez-le sur cet appareil.",
+ "auth.forgotSentTitle": "Vérifiez votre boîte mail",
+ "auth.forgotSubmit": "Envoyer le lien",
+ "auth.forgotTitle": "Réinitialiser le mot de passe",
+ "auth.hasAccount": "Déjà un compte ? Connectez-vous",
+ "auth.login": "Se connecter",
+ "auth.newPassword": "Nouveau mot de passe (10 caractères min.)",
+ "auth.noAccount": "Nouveau ? Créez un compte",
+ "auth.password": "Mot de passe",
+ "auth.register": "Créer un compte",
+ "auth.resetBody": "Le lien est valable 30 minutes et à usage unique. Tous les appareils seront déconnectés.",
+ "auth.resetDoneBody": "Votre mot de passe a été changé. Connectez-vous avec le nouveau.",
+ "auth.resetDoneTitle": "C'est fait !",
+ "auth.resetSubmit": "Changer le mot de passe",
+ "auth.resetTitle": "Choisissez un nouveau mot de passe",
+ "auth.resetTokenPlaceholder": "Collez le code reçu par e-mail",
+ "auth.trialNote": "7 jours d'accès complet – sans carte.",
+ "auth.verifyDoneBody": "Merci ! Votre compte est vérifié.",
+ "auth.verifyDoneTitle": "E-mail confirmé",
+ "auth.verifyFailedBody": "Le lien est invalide ou expiré. Demandez-en un nouveau depuis votre profil.",
+ "auth.verifyFailedTitle": "Le lien n'a pas fonctionné",
+ "barcode.addPrompt": "Ajouter au stock ?",
+ "barcode.aim": "Visez le code-barres avec l'appareil photo",
+ "barcode.allowCamera": "Autoriser l'appareil photo",
+ "barcode.cameraBody": "{brand} a besoin de l'appareil photo pour scanner les codes-barres.",
+ "barcode.cameraTitle": "Appareil photo requis",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Il vous faut d'abord un foyer.",
+ "barcode.noLocation": "Aucun lieu de stockage trouvé.",
+ "barcode.noNutrition": "Pas de données nutritionnelles",
+ "barcode.photoPackage": "Photographier l'emballage",
+ "barcode.unknownBody": "Ce produit n'est pas encore dans la base. Photographiez l'avant et l'étiquette nutritionnelle et nous l'ajouterons.",
+ "barcode.unknownTitle": "Produit inconnu",
+ "common.add": "Ajouter",
+ "common.back": "Retour",
+ "common.cancel": "Annuler",
+ "common.done": "Terminé",
"common.error": "Un problème est survenu. Réessayez.",
+ "common.estimate": "Estimation",
+ "common.loading": "Chargement …",
+ "common.next": "Suivant",
+ "common.off": "Désactivé",
+ "common.offline": "Hors ligne – dernières données chargées",
+ "common.on": "Activé",
+ "common.oops": "Oups",
+ "common.remove": "Retirer",
"common.retry": "Réessayer",
"common.save": "Enregistrer",
- "common.cancel": "Annuler",
- "common.next": "Suivant",
- "common.back": "Retour",
- "common.done": "Terminé",
"common.skip": "Passer",
- "common.offline": "Hors ligne – dernières données chargées",
- "common.estimate": "Estimation",
- "tabs.whatToEat": "On mange quoi ?",
- "tabs.scan": "Scanner",
- "tabs.myDay": "Ma journée",
- "tabs.home": "À la maison",
- "auth.login": "Se connecter",
- "auth.register": "Créer un compte",
- "auth.email": "E-mail",
- "auth.password": "Mot de passe",
- "auth.displayName": "Comment vous appeler ?",
- "auth.noAccount": "Nouveau ? Créez un compte",
- "auth.hasAccount": "Déjà un compte ? Connectez-vous",
- "auth.trialNote": "7 jours d'accès complet – sans carte.",
- "auth.forgotLink": "Mot de passe oublié ?",
- "auth.forgotTitle": "Réinitialiser le mot de passe",
- "auth.forgotBody": "Saisissez votre e-mail : nous enverrons un lien si le compte existe.",
- "auth.forgotSubmit": "Envoyer le lien",
- "auth.forgotSentTitle": "Vérifiez votre boîte mail",
- "auth.forgotSentBody": "Si l'adresse possède un compte, un lien valable 30 minutes a été envoyé. Ouvrez-le sur cet appareil.",
- "auth.backToLogin": "Retour à la connexion",
- "auth.resetTitle": "Choisissez un nouveau mot de passe",
- "auth.resetBody": "Le lien est valable 30 minutes et à usage unique. Tous les appareils seront déconnectés.",
- "auth.resetTokenPlaceholder": "Collez le code reçu par e-mail",
- "auth.newPassword": "Nouveau mot de passe (10 caractères min.)",
- "auth.resetSubmit": "Changer le mot de passe",
- "auth.resetDoneTitle": "C'est fait !",
- "auth.resetDoneBody": "Votre mot de passe a été changé. Connectez-vous avec le nouveau.",
- "auth.verifyDoneTitle": "E-mail confirmé",
- "auth.verifyDoneBody": "Merci ! Votre compte est vérifié.",
- "auth.verifyFailedTitle": "Le lien n'a pas fonctionné",
- "auth.verifyFailedBody": "Le lien est invalide ou expiré. Demandez-en un nouveau depuis votre profil.",
- "onboarding.title": "Parlez-nous un peu de vous",
- "onboarding.subtitle": "Tout est facultatif et modifiable à tout moment. Plus vous en dites, meilleures sont les suggestions.",
- "onboarding.goal": "Quel est votre objectif principal ?",
- "onboarding.diet": "Comment mangez-vous ?",
+ "common.undo": "Rétablir",
+ "cooked.deductPantry": "Déduire les ingrédients du stock",
+ "cooked.deductPantryNote": "Les ingrédients sont déduits du stock, en commençant par ceux qui expirent en premier.",
+ "cooked.mealBoxes": "Portions en lunchbox",
+ "cooked.portionsCooked": "Portions cuisinées",
+ "cooked.rate": "Noter",
+ "cooked.title": "Alors, verdict ?",
+ "cooked.whoAte": "Qui a mangé ?",
+ "cooking.finish": "Terminé – enregistrer le repas",
+ "cooking.keepAwake": "L'écran reste allumé pendant que vous cuisinez",
+ "cooking.scale": "Portions",
+ "cooking.step": "Étape {current} sur {total}",
+ "cooking.timer": "Lancer le minuteur",
+ "cooking.timerDone": "Terminé !",
+ "cooking.timerRunning": "{time} restants",
+ "home.budget": "Budget",
+ "home.emptyInventory": "Le stock est vide. Scannez le frigo ou ajoutez manuellement.",
+ "home.expired": "Expiré",
+ "home.expiresIn_one": "1 jour restant",
+ "home.expiresIn_other": "{days} jours restants",
+ "home.expiresToday": "Expire aujourd'hui",
+ "home.household": "Foyer",
+ "home.inventory": "Stock",
+ "home.mealBoxes": "Lunchbox",
+ "home.moreItems_one": "+ 1 autre …",
+ "home.moreItems_other": "+ {count} autres …",
+ "home.pastBestBefore": "DLUO dépassée : sentez et goûtez d'abord",
+ "home.shopping": "Liste de courses",
+ "home.thisWeek": "Cette semaine",
+ "home.title": "À la maison",
+ "home.useSoon": "À consommer vite",
+ "home.useSoonHint": "La DDM (à consommer de préférence) concerne la qualité : sentez, regardez et goûtez avant de jeter. La DLC doit en revanche être respectée.",
+ "home.waste": "Gaspillage",
+ "home.wasteWeek": "Gaspillage cette semaine",
+ "household.empty": "Vous n'avez pas encore de foyer. Créez-en un lors de l'intégration ou rejoignez-en un avec un code.",
+ "household.invite": "Inviter avec le code : {code}",
+ "household.locations": "Lieux de stockage",
+ "household.members": "Membres",
+ "household.portionFactor": "×{factor} portion",
+ "household.private": "Privé par personne : objectifs, allergies, données de santé et historique des repas.",
+ "household.role.adult": "Adulte",
+ "household.role.child": "Enfant",
+ "household.role.member": "Membre",
+ "household.role.owner": "Propriétaire",
+ "household.shareCode": "Partagez le code avec votre famille pour partager stock, liste et planning.",
+ "household.shared": "Partagé dans le foyer : stock, liste de courses, plan de semaine, lunchbox et budget.",
+ "logmeal.manualTitle": "Manuel",
+ "logmeal.mealTypeTitle": "Type de repas",
+ "logmeal.photoTip": "Astuce : photographiez l'assiette dans Scanner, l'app estime pour vous – vous confirmez toujours.",
+ "logmeal.proteinPlaceholder": "protéines (g)",
+ "logmeal.quickSubtitle": "Enregistre les mêmes valeurs nutritionnelles que la dernière fois.",
+ "logmeal.quickTitle": "Enregistrement rapide",
+ "logmeal.validationBody": "Le nom et les calories sont requis pour un enregistrement manuel.",
+ "logmeal.validationTitle": "Infos manquantes",
+ "logmeal.whatPlaceholder": "Qu'avez-vous mangé ?",
+ "mealbox.eat": "Manger maintenant",
+ "mealbox.eatBy": "À consommer avant le {date}",
+ "mealbox.empty": "Aucune lunchbox pour l'instant. En cuisinant, gardez des portions ici.",
+ "mealbox.enjoyBody": "La portion est enregistrée dans Ma journée.",
+ "mealbox.enjoyTitle": "Bon appétit !",
+ "mealbox.guidanceNote": "Le délai recommandé est indicatif : fiez-vous à l'odeur et au goût.",
+ "mealbox.portionsLeft_one": "1 portion restante",
+ "mealbox.portionsLeft_other": "{count} portions restantes",
+ "mealbox.title": "Lunchbox",
+ "memory.delete": "Supprimer",
+ "memory.deleteAll": "Supprimer toute la mémoire",
+ "memory.deleteAllTitle": "Supprimer toute la mémoire ?",
+ "memory.empty": "{brand} n'a encore rien appris sur vous.",
+ "memory.irreversible": "Cette action est irréversible.",
+ "memory.origin.ai_inferred": "Hypothèse de l'IA",
+ "memory.origin.observed": "Habitude observée",
+ "memory.origin.user_stated": "Vous nous l'avez dit",
+ "memory.pause": "Pause",
+ "memory.paused": "En pause",
+ "memory.resume": "Reprendre",
+ "memory.subtitle": "Transparence totale. Corrigez, mettez en pause ou supprimez : votre mémoire vous appartient.",
+ "memory.title": "Ce que {brand} sait de moi",
+ "memory.verified": "Vérifié",
+ "memory.verify": "Exact",
+ "myday.calories": "Calories",
+ "myday.carbs": "Glucides",
+ "myday.estimateNote": "Les valeurs avec ~ sont des estimations ajustables.",
+ "myday.estimateRange": "{min}–{max} kcal, probablement {kcal}",
+ "myday.fat": "Lipides",
+ "myday.fiber": "Fibres",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g de protéines",
+ "myday.logMeal": "Enregistrer un repas",
+ "myday.mealType.breakfast": "Petit-déjeuner",
+ "myday.mealType.dessert": "Dessert",
+ "myday.mealType.dinner": "Dîner",
+ "myday.mealType.lunch": "Déjeuner",
+ "myday.mealType.snack": "Encas",
+ "myday.noMeals": "Aucun repas enregistré aujourd'hui.",
+ "myday.over": "{kcal} kcal au-dessus de l'objectif",
+ "myday.overRecommended": "Au-dessus du recommandé",
+ "myday.protein": "Protéines",
+ "myday.remaining": "{kcal} kcal restantes",
+ "myday.salt": "Sel",
+ "myday.targetsNote": "Les objectifs sont des repères, pas un avis médical.",
+ "myday.title": "Ma journée",
+ "myday.todaysMeals": "Repas du jour",
+ "onboarding.allergen.crustaceans": "Crustacés",
+ "onboarding.allergen.eggs": "Œufs",
+ "onboarding.allergen.fish": "Poisson",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Lait/lactose",
+ "onboarding.allergen.peanuts": "Arachides",
+ "onboarding.allergen.sesame": "Sésame",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Fruits à coque",
"onboarding.allergies": "Allergies et intolérances",
"onboarding.allergyNote": "Le filtre allergies est toujours strict : les plats contenant vos allergènes ne sont jamais affichés.",
+ "onboarding.birthYearPlaceholder": "Année de naissance",
+ "onboarding.bodyTitle": "Pour des objectifs caloriques personnalisés (facultatif)",
+ "onboarding.diet": "Comment mangez-vous ?",
+ "onboarding.diet.flexitarian": "Flexitarien",
+ "onboarding.diet.omnivore": "Omnivore",
+ "onboarding.diet.pescatarian": "Pescétarien",
+ "onboarding.diet.vegan": "Végane",
+ "onboarding.diet.vegetarian": "Végétarien",
+ "onboarding.goal": "Quel est votre objectif principal ?",
+ "onboarding.goal.build_muscle": "Prendre du muscle",
+ "onboarding.goal.cook_more": "Cuisiner plus à la maison",
+ "onboarding.goal.less_waste": "Réduire le gaspillage",
+ "onboarding.goal.lose_weight": "Perdre du poids",
+ "onboarding.goal.lower_cost": "Dépenser moins en courses",
+ "onboarding.goal.maintain_weight": "Maintenir mon poids",
+ "onboarding.goal.more_protein": "Manger plus de protéines",
+ "onboarding.heightPlaceholder": "Taille (cm)",
"onboarding.household": "Votre foyer",
"onboarding.householdCreate": "Créer un foyer",
+ "onboarding.householdDefaultName": "Maison",
"onboarding.householdJoin": "Rejoindre avec un code",
"onboarding.householdName": "Nom du foyer",
"onboarding.inviteCode": "Code d'invitation",
"onboarding.mode": "Quel niveau de précision ?",
- "onboarding.modeSimple": "Mode simple",
- "onboarding.modeSimpleDesc": "Photographiez vos aliments, acceptez les estimations, zéro prise de tête.",
"onboarding.modeExact": "Mode exact",
"onboarding.modeExactDesc": "Pesez, saisissez les grammes, contrôle total des chiffres.",
+ "onboarding.modesCombine": "Les modes se combinent : simple au quotidien, précis quand vous voulez.",
+ "onboarding.modeSimple": "Mode simple",
+ "onboarding.modeSimpleDesc": "Photographiez vos aliments, acceptez les estimations, zéro prise de tête.",
"onboarding.notMedical": "{brand} fournit des repères, pas un avis médical.",
- "wte.title": "On mange quoi ?",
- "wte.subtitle": "Selon ce que vous avez chez vous, ce qu'il faut consommer vite et vos goûts.",
- "wte.cravingPlaceholder": "J'ai envie de … (ex. crémeux, asiatique, moins de 500 kcal)",
- "wte.mealBoxFirst": "Plats prêts à la maison",
- "wte.whyTitle": "Pourquoi cette suggestion ?",
- "wte.coverage": "{pct} % à la maison",
- "wte.missing": "Il manque : {items}",
- "wte.empty": "Pas encore de suggestions : ajoutez des aliments ou assouplissez les filtres.",
- "wte.refresh": "Nouvelles suggestions",
- "scan.title": "Scanner",
- "scan.subtitle": "Remplissez votre stock ou enregistrez un repas avec l'appareil photo.",
- "scan.fridge": "Frigo",
- "scan.freezer": "Congélateur",
- "scan.pantry": "Placard",
- "scan.ingredients": "Ingrédients",
- "scan.plate": "Assiette",
- "scan.receipt": "Ticket de caisse",
- "scan.barcode": "Code-barres",
- "scan.expiry": "Date limite",
- "scan.nutrition": "Étiquette nutritionnelle",
- "scan.takePhoto": "Prendre une photo",
- "scan.tips.title": "Pour une analyse optimale",
- "scan.tips.overview": "Commencez par une vue d'ensemble",
- "scan.tips.shelf": "Photographiez étagère par étagère",
- "scan.tips.light": "Évitez l'obscurité et les ombres",
- "scan.tips.move": "Écartez les produits qui se cachent",
- "scan.analyzing": "Analyse en cours …",
- "scan.quotaLeft_one": "1 scan IA restant ce mois-ci",
- "scan.quotaLeft_other": "{count} scans IA restants ce mois-ci",
- "scan.review.title": "Vérifiez le résultat",
- "scan.review.subtitle": "L'IA doute parfois : c'est vous qui décidez. Modifiez, supprimez ou ajoutez avant d'enregistrer.",
- "scan.review.uncertain": "Incertain – à vérifier",
- "scan.review.approveAll": "Enregistrer dans le stock",
- "scan.review.rejected": "Supprimé",
- "scan.failed": "L'analyse a échoué. Réessayez ou saisissez manuellement.",
- "myday.title": "Ma journée",
- "myday.calories": "Calories",
- "myday.protein": "Protéines",
- "myday.carbs": "Glucides",
- "myday.fat": "Lipides",
- "myday.fiber": "Fibres",
- "myday.salt": "Sel",
- "myday.remaining": "{kcal} kcal restantes",
- "myday.over": "{kcal} kcal au-dessus de l'objectif",
- "myday.logMeal": "Enregistrer un repas",
- "myday.noMeals": "Aucun repas enregistré aujourd'hui.",
- "myday.estimateNote": "Les valeurs avec ~ sont des estimations ajustables.",
- "myday.targetsNote": "Les objectifs sont des repères, pas un avis médical.",
- "home.title": "À la maison",
- "home.inventory": "Stock",
- "home.useSoon": "À consommer vite",
- "home.mealBoxes": "Lunchbox",
- "home.shopping": "Liste de courses",
- "home.budget": "Budget",
- "home.household": "Foyer",
- "home.waste": "Gaspillage",
- "home.emptyInventory": "Le stock est vide. Scannez le frigo ou ajoutez manuellement.",
- "home.expiresIn_one": "1 jour restant",
- "home.expiresIn_other": "{days} jours restants",
- "home.expiresToday": "Expire aujourd'hui",
- "home.expired": "Expiré",
- "home.pastBestBefore": "DLUO dépassée : sentez et goûtez d'abord",
+ "onboarding.stepBSubtitle": "Personnalisez votre profil pour de meilleures suggestions.",
+ "onboarding.stepBTitle": "Continuer la configuration",
+ "onboarding.stepCSubtitle": "Facultatif – utilisé pour les objectifs caloriques personnels.",
+ "onboarding.stepCTitle": "Votre profil de santé",
+ "onboarding.subtitle": "Tout est facultatif et modifiable à tout moment. Plus vous en dites, meilleures sont les suggestions.",
+ "onboarding.title": "Parlez-nous un peu de vous",
+ "onboarding.weightPlaceholder": "Poids (kg)",
+ "paywall.choose": "Choisir",
+ "paywall.fairUse": "Quota d'usage raisonnable de scans IA inclus.",
+ "paywall.family": "Family · jusqu'à 6 personnes",
+ "paywall.freeNote": "Gratuit : 10 scans IA/mois, stock manuel, recettes enregistrées et suivi simple.",
+ "paywall.household": "Household · jusqu'à 3 personnes",
+ "paywall.large": "Large Household · jusqu'à 12 personnes",
+ "paywall.perMonth": "{price}/mois",
+ "paywall.popular": "Le plus populaire",
+ "paywall.restore": "Restaurer les achats",
+ "paywall.soonBody": "Les achats s'activeront via l'App Store/Google Play quand l'intégration boutique sera lancée (phase 7). Le backend est déjà prêt.",
+ "paywall.soonTitle": "Bientôt !",
+ "paywall.subtitle": "L'OS alimentaire de tout le foyer : stock illimité, plan de semaine et partage.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "1 jour d'essai restant",
+ "paywall.trialActive_other": "{days} jours d'essai restants",
+ "profile.aiScansUsed": "Scans IA : {used} / {total} ce mois-ci",
+ "profile.consent.anonymized_improvement": "Amélioration anonymisée de l'IA",
+ "profile.consent.health_integration": "Données de santé (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Mes photos peuvent servir à l'entraînement",
+ "profile.consent.location_weather": "Position pour des suggestions selon la météo",
+ "profile.consent.personalization": "Fonctions personnelles (mémoire & profil de goûts)",
+ "profile.consent.product_analytics": "Analyse produit",
+ "profile.consent.push_notifications": "Notifications push",
+ "profile.consents": "Consentements & données",
+ "profile.consentsNote": "Les consentements sont distincts : les fonctions personnelles n'exigent jamais le consentement d'entraînement.",
+ "profile.deleteAccount": "Supprimer le compte",
+ "profile.deleteBody": "Toutes vos données seront supprimées définitivement conformément au RGPD.",
+ "profile.deleteTitle": "Supprimer le compte ?",
+ "profile.emailUnverified": "Adresse e-mail non confirmée",
+ "profile.export": "Exporter mes données",
+ "profile.goals": "Objectifs & alimentation",
+ "profile.language": "Langue",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Se déconnecter",
+ "profile.memory": "Ce que {brand} sait de moi",
+ "profile.memorySubtitle": "Voyez, corrigez, mettez en pause ou supprimez ce que la plateforme a appris.",
+ "profile.modeLabel": "Mode :",
+ "profile.resendVerification": "Renvoyer l'e-mail de confirmation",
+ "profile.subscription": "Abonnement",
+ "profile.title": "Profil",
+ "profile.verificationSent": "Envoyé ! Vérifiez votre boîte mail.",
+ "recipe.avgRating": "Moyenne {avg} sur {count} avis",
+ "recipe.cook": "Cuisiner maintenant",
+ "recipe.cost": "env. {amount}/portion",
+ "recipe.iCookedThis": "Je l'ai cuisiné",
+ "recipe.ingredients": "Ingrédients",
+ "recipe.notSafe": "Incompatible avec vos réglages alimentaires",
+ "recipe.perPortion": "par portion",
"recipe.portions_one": "1 portion",
"recipe.portions_other": "{count} portions",
- "recipe.time": "{min} min",
- "recipe.perPortion": "par portion",
- "recipe.ingredients": "Ingrédients",
+ "recipe.save": "Enregistrer",
+ "recipe.saved": "Enregistrée",
"recipe.steps": "Préparation",
- "recipe.cook": "Cuisiner maintenant",
- "recipe.notSafe": "Incompatible avec vos réglages alimentaires",
"recipe.substitutions": "Remplacer",
- "recipe.iCookedThis": "Je l'ai cuisiné",
- "recipe.cost": "env. {amount}/portion",
- "cooking.step": "Étape {current} sur {total}",
- "cooking.timer": "Lancer le minuteur",
- "cooking.timerRunning": "{time} restants",
- "cooking.finish": "Terminé – enregistrer le repas",
- "cooking.scale": "Portions",
- "cooking.keepAwake": "L'écran reste allumé pendant que vous cuisinez",
- "cooked.title": "Alors, verdict ?",
- "cooked.portionsCooked": "Portions cuisinées",
- "cooked.whoAte": "Qui a mangé ?",
- "cooked.mealBoxes": "Portions en lunchbox",
- "cooked.deductPantry": "Déduire les ingrédients du stock",
- "cooked.rate": "Noter",
- "shopping.title": "Liste de courses",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analyse en cours …",
+ "scan.barcode": "Code-barres",
+ "scan.expiry": "Date limite",
+ "scan.failed": "L'analyse a échoué. Réessayez ou saisissez manuellement.",
+ "scan.freezer": "Congélateur",
+ "scan.fridge": "Frigo",
+ "scan.ingredients": "Ingrédients",
+ "scan.nutrition": "Étiquette nutritionnelle",
+ "scan.pantry": "Placard",
+ "scan.plate": "Assiette",
+ "scan.quotaLeft_one": "1 scan IA restant ce mois-ci",
+ "scan.quotaLeft_other": "{count} scans IA restants ce mois-ci",
+ "scan.receipt": "Ticket de caisse",
+ "scan.review.addItem": "+ Ajouter un article",
+ "scan.review.approveAll": "Enregistrer dans le stock",
+ "scan.review.bestBeforeNote": "Date de qualité : l'aliment peut rester bon après. Sentez et goûtez avant de jeter.",
+ "scan.review.dateKindBestBefore": "DDM – de préférence",
+ "scan.review.dateKindUseBy": "DLC – à consommer jusqu'au",
+ "scan.review.datePlaceholder": "AAAA-MM-JJ (facultatif)",
+ "scan.review.itemPlaceholder": "Article",
+ "scan.review.quantityPlaceholder": "Quantité",
+ "scan.review.rejected": "Supprimé",
+ "scan.review.subtitle": "L'IA doute parfois : c'est vous qui décidez. Modifiez, supprimez ou ajoutez avant d'enregistrer.",
+ "scan.review.title": "Vérifiez le résultat",
+ "scan.review.uncertain": "Incertain – à vérifier",
+ "scan.review.unitPlaceholder": "Unité (g, l, pcs …)",
+ "scan.review.unknownItem": "Article inconnu",
+ "scan.review.useByNote": "Date de sécurité : ne pas consommer après cette date.",
+ "scan.subtitle": "Remplissez votre stock ou enregistrez un repas avec l'appareil photo.",
+ "scan.takePhoto": "Prendre une photo",
+ "scan.tips.light": "Évitez l'obscurité et les ombres",
+ "scan.tips.move": "Écartez les produits qui se cachent",
+ "scan.tips.overview": "Commencez par une vue d'ensemble",
+ "scan.tips.shelf": "Photographiez étagère par étagère",
+ "scan.tips.title": "Pour une analyse optimale",
+ "scan.title": "Scanner",
"shopping.addPlaceholder": "Ajouter un article …",
"shopping.complete": "Terminer les courses",
+ "shopping.completedBody_one": "1 article a été ajouté au stock.",
+ "shopping.completedBody_other": "{count} articles ont été ajoutés au stock.",
+ "shopping.completedTitle": "Terminé !",
"shopping.completeNote": "Les articles cochés rejoignent le stock.",
"shopping.empty": "La liste est vide.",
"shopping.estimated": "env. {amount}",
"shopping.estimatedTotal": "Total estimé : env. {amount}",
- "mealbox.title": "Lunchbox",
- "mealbox.eatBy": "À consommer avant le {date}",
- "mealbox.portionsLeft_one": "1 portion restante",
- "mealbox.portionsLeft_other": "{count} portions restantes",
- "mealbox.eat": "Manger maintenant",
- "mealbox.empty": "Aucune lunchbox pour l'instant. En cuisinant, gardez des portions ici.",
- "household.members": "Membres",
- "household.invite": "Inviter avec le code : {code}",
- "household.shared": "Partagé dans le foyer : stock, liste de courses, plan de semaine, lunchbox et budget.",
- "household.private": "Privé par personne : objectifs, allergies, données de santé et historique des repas.",
- "memory.title": "Ce que {brand} sait de moi",
- "memory.subtitle": "Transparence totale. Corrigez, mettez en pause ou supprimez : votre mémoire vous appartient.",
- "memory.paused": "En pause",
- "memory.verify": "Exact",
- "memory.pause": "Pause",
- "memory.delete": "Supprimer",
- "memory.deleteAll": "Supprimer toute la mémoire",
- "memory.empty": "{brand} n'a encore rien appris sur vous.",
- "memory.origin.user_stated": "Vous nous l'avez dit",
- "memory.origin.observed": "Habitude observée",
- "memory.origin.ai_inferred": "Hypothèse de l'IA",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "L'OS alimentaire de tout le foyer : stock illimité, plan de semaine et partage.",
- "paywall.trialActive_one": "1 jour d'essai restant",
- "paywall.trialActive_other": "{days} jours d'essai restants",
- "paywall.household": "Household · jusqu'à 3 personnes",
- "paywall.family": "Family · jusqu'à 6 personnes",
- "paywall.large": "Large Household · jusqu'à 12 personnes",
- "paywall.perMonth": "{price}/mois",
- "paywall.fairUse": "Quota d'usage raisonnable de scans IA inclus.",
- "paywall.restore": "Restaurer les achats",
- "paywall.freeNote": "Gratuit : 10 scans IA/mois, stock manuel, recettes enregistrées et suivi simple.",
- "profile.title": "Profil",
- "profile.goals": "Objectifs & alimentation",
- "profile.consents": "Consentements & données",
- "profile.memory": "Ce que {brand} sait de moi",
- "profile.subscription": "Abonnement",
- "profile.logout": "Se déconnecter",
- "profile.export": "Exporter mes données",
- "profile.deleteAccount": "Supprimer le compte",
- "profile.language": "Langue",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.emailUnverified": "Adresse e-mail non confirmée",
- "profile.resendVerification": "Renvoyer l'e-mail de confirmation",
- "profile.verificationSent": "Envoyé ! Vérifiez votre boîte mail.",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Oups",
- "common.undo": "Rétablir",
- "common.remove": "Retirer",
- "common.add": "Ajouter",
- "common.on": "Activé",
- "common.off": "Désactivé",
- "home.thisWeek": "Cette semaine",
- "home.wasteWeek": "Gaspillage cette semaine",
- "home.useSoonHint": "La DDM (à consommer de préférence) concerne la qualité : sentez, regardez et goûtez avant de jeter. La DLC doit en revanche être respectée.",
- "scan.review.itemPlaceholder": "Article",
- "scan.review.quantityPlaceholder": "Quantité",
- "scan.review.unitPlaceholder": "Unité (g, l, pcs …)",
- "scan.review.datePlaceholder": "AAAA-MM-JJ (facultatif)",
- "scan.review.dateKindBestBefore": "DDM – de préférence",
- "scan.review.dateKindUseBy": "DLC – à consommer jusqu'au",
- "scan.review.bestBeforeNote": "Date de qualité : l'aliment peut rester bon après. Sentez et goûtez avant de jeter.",
- "scan.review.useByNote": "Date de sécurité : ne pas consommer après cette date.",
- "scan.review.addItem": "+ Ajouter un article",
- "scan.review.unknownItem": "Article inconnu",
- "barcode.aim": "Visez le code-barres avec l'appareil photo",
- "barcode.addPrompt": "Ajouter au stock ?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Pas de données nutritionnelles",
- "barcode.unknownTitle": "Produit inconnu",
- "barcode.unknownBody": "Ce produit n'est pas encore dans la base. Photographiez l'avant et l'étiquette nutritionnelle et nous l'ajouterons.",
- "barcode.photoPackage": "Photographier l'emballage",
- "barcode.needHousehold": "Il vous faut d'abord un foyer.",
- "barcode.noLocation": "Aucun lieu de stockage trouvé.",
- "barcode.cameraTitle": "Appareil photo requis",
- "barcode.cameraBody": "{brand} a besoin de l'appareil photo pour scanner les codes-barres.",
- "barcode.allowCamera": "Autoriser l'appareil photo",
- "onboarding.goal.lose_weight": "Perdre du poids",
- "onboarding.goal.build_muscle": "Prendre du muscle",
- "onboarding.goal.maintain_weight": "Maintenir mon poids",
- "onboarding.goal.more_protein": "Manger plus de protéines",
- "onboarding.goal.less_waste": "Réduire le gaspillage",
- "onboarding.goal.lower_cost": "Dépenser moins en courses",
- "onboarding.goal.cook_more": "Cuisiner plus à la maison",
- "onboarding.diet.omnivore": "Omnivore",
- "onboarding.diet.flexitarian": "Flexitarien",
- "onboarding.diet.pescatarian": "Pescétarien",
- "onboarding.diet.vegetarian": "Végétarien",
- "onboarding.diet.vegan": "Végane",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Lait/lactose",
- "onboarding.allergen.eggs": "Œufs",
- "onboarding.allergen.tree_nuts": "Fruits à coque",
- "onboarding.allergen.peanuts": "Arachides",
- "onboarding.allergen.fish": "Poisson",
- "onboarding.allergen.crustaceans": "Crustacés",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sésame",
- "onboarding.bodyTitle": "Pour des objectifs caloriques personnalisés (facultatif)",
- "onboarding.weightPlaceholder": "Poids (kg)",
- "onboarding.heightPlaceholder": "Taille (cm)",
- "onboarding.birthYearPlaceholder": "Année de naissance",
- "onboarding.householdDefaultName": "Maison",
- "onboarding.modesCombine": "Les modes se combinent : simple au quotidien, précis quand vous voulez.",
- "myday.mealType.breakfast": "Petit-déjeuner",
- "myday.mealType.lunch": "Déjeuner",
- "myday.mealType.dinner": "Dîner",
- "myday.mealType.snack": "Encas",
- "myday.mealType.dessert": "Dessert",
- "myday.overRecommended": "Au-dessus du recommandé",
- "myday.todaysMeals": "Repas du jour",
- "myday.estimateRange": "{min}–{max} kcal, probablement {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g de protéines",
- "logmeal.mealTypeTitle": "Type de repas",
- "logmeal.quickTitle": "Enregistrement rapide",
- "logmeal.quickSubtitle": "Enregistre les mêmes valeurs nutritionnelles que la dernière fois.",
- "logmeal.manualTitle": "Manuel",
- "logmeal.whatPlaceholder": "Qu'avez-vous mangé ?",
- "logmeal.proteinPlaceholder": "protéines (g)",
- "logmeal.validationTitle": "Infos manquantes",
- "logmeal.validationBody": "Le nom et les calories sont requis pour un enregistrement manuel.",
- "logmeal.photoTip": "Astuce : photographiez l'assiette dans Scanner, l'app estime pour vous – vous confirmez toujours.",
- "shopping.section.frukt_gront": "Fruits & légumes",
"shopping.section.brod": "Pain",
- "shopping.section.mejeri": "Produits laitiers",
- "shopping.section.kott_fagel": "Viande & volaille",
- "shopping.section.fisk": "Poisson",
"shopping.section.chark": "Charcuterie",
- "shopping.section.frys": "Surgelés",
- "shopping.section.skafferi": "Épicerie",
- "shopping.section.konserver": "Conserves",
- "shopping.section.kryddor_bak": "Épices & pâtisserie",
"shopping.section.dryck": "Boissons",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Poisson",
+ "shopping.section.frukt_gront": "Fruits & légumes",
+ "shopping.section.frys": "Surgelés",
"shopping.section.hygien_ovrigt": "Divers",
- "shopping.completedTitle": "Terminé !",
- "household.role.owner": "Propriétaire",
- "household.role.adult": "Adulte",
- "household.role.member": "Membre",
- "household.role.child": "Enfant",
- "household.empty": "Vous n'avez pas encore de foyer. Créez-en un lors de l'intégration ou rejoignez-en un avec un code.",
- "household.shareCode": "Partagez le code avec votre famille pour partager stock, liste et planning.",
- "household.locations": "Lieux de stockage",
- "household.portionFactor": "×{factor} portion",
- "mealbox.enjoyTitle": "Bon appétit !",
- "mealbox.enjoyBody": "La portion est enregistrée dans Ma journée.",
- "mealbox.guidanceNote": "Le délai recommandé est indicatif : fiez-vous à l'odeur et au goût.",
- "paywall.soonTitle": "Bientôt !",
- "paywall.soonBody": "Les achats s'activeront via l'App Store/Google Play quand l'intégration boutique sera lancée (phase 7). Le backend est déjà prêt.",
- "paywall.popular": "Le plus populaire",
- "paywall.choose": "Choisir",
- "recipe.saved": "Enregistrée",
- "recipe.save": "Enregistrer",
- "recipe.avgRating": "Moyenne {avg} sur {count} avis",
- "memory.verified": "Vérifié",
- "memory.resume": "Reprendre",
- "memory.deleteAllTitle": "Supprimer toute la mémoire ?",
- "memory.irreversible": "Cette action est irréversible.",
- "profile.consent.personalization": "Fonctions personnelles (mémoire & profil de goûts)",
- "profile.consent.anonymized_improvement": "Amélioration anonymisée de l'IA",
- "profile.consent.image_training": "Mes photos peuvent servir à l'entraînement",
- "profile.consent.health_integration": "Données de santé (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Position pour des suggestions selon la météo",
- "profile.consent.push_notifications": "Notifications push",
- "profile.modeLabel": "Mode :",
- "profile.memorySubtitle": "Voyez, corrigez, mettez en pause ou supprimez ce que la plateforme a appris.",
- "profile.consentsNote": "Les consentements sont distincts : les fonctions personnelles n'exigent jamais le consentement d'entraînement.",
- "profile.aiScansUsed": "Scans IA : {used} / {total} ce mois-ci",
- "profile.deleteTitle": "Supprimer le compte ?",
- "profile.deleteBody": "Toutes vos données seront supprimées définitivement conformément au RGPD.",
- "cooking.timerDone": "Terminé !",
- "cooked.deductPantryNote": "Les ingrédients sont déduits du stock, en commençant par ceux qui expirent en premier.",
- "home.moreItems_one": "+ 1 autre …",
- "home.moreItems_other": "+ {count} autres …",
- "shopping.completedBody_one": "1 article a été ajouté au stock.",
- "shopping.completedBody_other": "{count} articles ont été ajoutés au stock.",
- "profile.consent.product_analytics": "Analyse produit"
+ "shopping.section.konserver": "Conserves",
+ "shopping.section.kott_fagel": "Viande & volaille",
+ "shopping.section.kryddor_bak": "Épices & pâtisserie",
+ "shopping.section.mejeri": "Produits laitiers",
+ "shopping.section.skafferi": "Épicerie",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Liste de courses",
+ "tabs.home": "À la maison",
+ "tabs.myDay": "Ma journée",
+ "tabs.scan": "Scanner",
+ "tabs.whatToEat": "On mange quoi ?",
+ "wte.coverage": "{pct} % à la maison",
+ "wte.cravingPlaceholder": "J'ai envie de … (ex. crémeux, asiatique, moins de 500 kcal)",
+ "wte.empty": "Pas encore de suggestions : ajoutez des aliments ou assouplissez les filtres.",
+ "wte.mealBoxFirst": "Plats prêts à la maison",
+ "wte.missing": "Il manque : {items}",
+ "wte.refresh": "Nouvelles suggestions",
+ "wte.subtitle": "Selon ce que vous avez chez vous, ce qu'il faut consommer vite et vos goûts.",
+ "wte.title": "On mange quoi ?",
+ "wte.whyTitle": "Pourquoi cette suggestion ?"
}
diff --git a/apps/mobile/src/locales/it/common.json b/apps/mobile/src/locales/it/common.json
index 59b8030..54424f3 100644
--- a/apps/mobile/src/locales/it/common.json
+++ b/apps/mobile/src/locales/it/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Caricamento …",
+ "auth.backToLogin": "Torna all'accesso",
+ "auth.displayName": "Come ti chiamiamo?",
+ "auth.email": "Email",
+ "auth.forgotBody": "Inserisci la tua email e ti invieremo un link se l'account esiste.",
+ "auth.forgotLink": "Password dimenticata?",
+ "auth.forgotSentBody": "Se l'indirizzo ha un account, abbiamo inviato un link valido per 30 minuti. Aprilo su questo dispositivo.",
+ "auth.forgotSentTitle": "Controlla la tua casella",
+ "auth.forgotSubmit": "Invia link",
+ "auth.forgotTitle": "Reimposta la password",
+ "auth.hasAccount": "Hai già un account? Accedi",
+ "auth.login": "Accedi",
+ "auth.newPassword": "Nuova password (almeno 10 caratteri)",
+ "auth.noAccount": "Nuovo qui? Crea un account",
+ "auth.password": "Password",
+ "auth.register": "Crea account",
+ "auth.resetBody": "Il link è valido per 30 minuti e si può usare una sola volta. Tutti i dispositivi verranno disconnessi.",
+ "auth.resetDoneBody": "La password è stata cambiata. Accedi con quella nuova.",
+ "auth.resetDoneTitle": "Fatto!",
+ "auth.resetSubmit": "Cambia password",
+ "auth.resetTitle": "Scegli una nuova password",
+ "auth.resetTokenPlaceholder": "Incolla il codice dall'email",
+ "auth.trialNote": "7 giorni di accesso completo – senza carta.",
+ "auth.verifyDoneBody": "Grazie! Il tuo account è verificato.",
+ "auth.verifyDoneTitle": "Email confermata",
+ "auth.verifyFailedBody": "Il link non è valido o è scaduto. Richiedine uno nuovo dal profilo.",
+ "auth.verifyFailedTitle": "Il link non ha funzionato",
+ "barcode.addPrompt": "Aggiungere alla dispensa?",
+ "barcode.aim": "Inquadra il codice a barre",
+ "barcode.allowCamera": "Consenti fotocamera",
+ "barcode.cameraBody": "{brand} ha bisogno della fotocamera per leggere i codici a barre.",
+ "barcode.cameraTitle": "Serve la fotocamera",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Prima ti serve una famiglia.",
+ "barcode.noLocation": "Nessun luogo di conservazione trovato.",
+ "barcode.noNutrition": "Dati nutrizionali mancanti",
+ "barcode.photoPackage": "Fotografa la confezione",
+ "barcode.unknownBody": "Questo prodotto non è ancora nel database. Fotografa il fronte e l'etichetta nutrizionale e lo aggiungeremo.",
+ "barcode.unknownTitle": "Prodotto sconosciuto",
+ "common.add": "Aggiungi",
+ "common.back": "Indietro",
+ "common.cancel": "Annulla",
+ "common.done": "Fatto",
"common.error": "Qualcosa è andato storto. Riprova.",
+ "common.estimate": "Stima",
+ "common.loading": "Caricamento …",
+ "common.next": "Avanti",
+ "common.off": "Disattivato",
+ "common.offline": "Offline – dati dell'ultimo aggiornamento",
+ "common.on": "Attivato",
+ "common.oops": "Ops",
+ "common.remove": "Rimuovi",
"common.retry": "Riprova",
"common.save": "Salva",
- "common.cancel": "Annulla",
- "common.next": "Avanti",
- "common.back": "Indietro",
- "common.done": "Fatto",
"common.skip": "Salta",
- "common.offline": "Offline – dati dell'ultimo aggiornamento",
- "common.estimate": "Stima",
- "tabs.whatToEat": "Cosa mangiamo?",
- "tabs.scan": "Scansiona",
- "tabs.myDay": "La mia giornata",
- "tabs.home": "A casa",
- "auth.login": "Accedi",
- "auth.register": "Crea account",
- "auth.email": "Email",
- "auth.password": "Password",
- "auth.displayName": "Come ti chiamiamo?",
- "auth.noAccount": "Nuovo qui? Crea un account",
- "auth.hasAccount": "Hai già un account? Accedi",
- "auth.trialNote": "7 giorni di accesso completo – senza carta.",
- "auth.forgotLink": "Password dimenticata?",
- "auth.forgotTitle": "Reimposta la password",
- "auth.forgotBody": "Inserisci la tua email e ti invieremo un link se l'account esiste.",
- "auth.forgotSubmit": "Invia link",
- "auth.forgotSentTitle": "Controlla la tua casella",
- "auth.forgotSentBody": "Se l'indirizzo ha un account, abbiamo inviato un link valido per 30 minuti. Aprilo su questo dispositivo.",
- "auth.backToLogin": "Torna all'accesso",
- "auth.resetTitle": "Scegli una nuova password",
- "auth.resetBody": "Il link è valido per 30 minuti e si può usare una sola volta. Tutti i dispositivi verranno disconnessi.",
- "auth.resetTokenPlaceholder": "Incolla il codice dall'email",
- "auth.newPassword": "Nuova password (almeno 10 caratteri)",
- "auth.resetSubmit": "Cambia password",
- "auth.resetDoneTitle": "Fatto!",
- "auth.resetDoneBody": "La password è stata cambiata. Accedi con quella nuova.",
- "auth.verifyDoneTitle": "Email confermata",
- "auth.verifyDoneBody": "Grazie! Il tuo account è verificato.",
- "auth.verifyFailedTitle": "Il link non ha funzionato",
- "auth.verifyFailedBody": "Il link non è valido o è scaduto. Richiedine uno nuovo dal profilo.",
- "onboarding.title": "Raccontaci qualcosa di te",
- "onboarding.subtitle": "Tutto è facoltativo e modificabile in qualsiasi momento. Più compili, migliori saranno i suggerimenti.",
- "onboarding.goal": "Qual è il tuo obiettivo principale?",
- "onboarding.diet": "Come mangi?",
+ "common.undo": "Ripristina",
+ "cooked.deductPantry": "Scala gli ingredienti dalla dispensa",
+ "cooked.deductPantryNote": "Gli ingredienti vengono scalati dalla dispensa: prima quelli in scadenza.",
+ "cooked.mealBoxes": "Porzioni nei porta pranzo",
+ "cooked.portionsCooked": "Porzioni cucinate",
+ "cooked.rate": "Valuta",
+ "cooked.title": "Com'è andata?",
+ "cooked.whoAte": "Chi ha mangiato?",
+ "cooking.finish": "Fatto – registra il pasto",
+ "cooking.keepAwake": "Lo schermo resta acceso mentre cucini",
+ "cooking.scale": "Porzioni",
+ "cooking.step": "Passo {current} di {total}",
+ "cooking.timer": "Avvia timer",
+ "cooking.timerDone": "Fatto!",
+ "cooking.timerRunning": "{time} rimasti",
+ "home.budget": "Budget",
+ "home.emptyInventory": "La dispensa è vuota. Scansiona il frigo o aggiungi manualmente.",
+ "home.expired": "Scaduto",
+ "home.expiresIn_one": "1 giorno rimasto",
+ "home.expiresIn_other": "{days} giorni rimasti",
+ "home.expiresToday": "Scade oggi",
+ "home.household": "Famiglia",
+ "home.inventory": "Dispensa",
+ "home.mealBoxes": "Porta pranzo",
+ "home.moreItems_one": "+ 1 altro …",
+ "home.moreItems_other": "+ {count} altri …",
+ "home.pastBestBefore": "Oltre il termine minimo: annusa e assaggia prima",
+ "home.shopping": "Lista della spesa",
+ "home.thisWeek": "Questa settimana",
+ "home.title": "A casa",
+ "home.useSoon": "Da consumare presto",
+ "home.useSoonHint": "Il termine minimo di conservazione riguarda la qualità: annusa, osserva e assaggia prima di buttare. La data di scadenza va invece rispettata.",
+ "home.waste": "Sprechi",
+ "home.wasteWeek": "Sprechi questa settimana",
+ "household.empty": "Non hai ancora una famiglia. Creane una nell'onboarding o unisciti con un codice.",
+ "household.invite": "Invita con il codice: {code}",
+ "household.locations": "Luoghi di conservazione",
+ "household.members": "Membri",
+ "household.portionFactor": "×{factor} porzione",
+ "household.private": "Privato per persona: obiettivi, allergie, dati sanitari e cronologia dei pasti.",
+ "household.role.adult": "Adulto",
+ "household.role.child": "Bambino",
+ "household.role.member": "Membro",
+ "household.role.owner": "Proprietario",
+ "household.shareCode": "Condividi il codice con la famiglia per condividere dispensa, lista e piano.",
+ "household.shared": "Condiviso in famiglia: dispensa, lista della spesa, piano settimanale, porta pranzo e budget.",
+ "logmeal.manualTitle": "Manuale",
+ "logmeal.mealTypeTitle": "Tipo di pasto",
+ "logmeal.photoTip": "Suggerimento: fotografa il piatto in Scansiona e l'app stimerà per te; confermi sempre tu.",
+ "logmeal.proteinPlaceholder": "proteine (g)",
+ "logmeal.quickSubtitle": "Registra gli stessi valori nutrizionali dell'ultima volta.",
+ "logmeal.quickTitle": "Registrazione rapida",
+ "logmeal.validationBody": "Per la registrazione manuale servono nome e calorie.",
+ "logmeal.validationTitle": "Dati mancanti",
+ "logmeal.whatPlaceholder": "Cosa hai mangiato?",
+ "mealbox.eat": "Mangia ora",
+ "mealbox.eatBy": "Consumare entro il {date}",
+ "mealbox.empty": "Nessun porta pranzo al momento. Quando cucini puoi salvare qui le porzioni.",
+ "mealbox.enjoyBody": "La porzione è registrata in La mia giornata.",
+ "mealbox.enjoyTitle": "Buon appetito!",
+ "mealbox.guidanceNote": "Il termine consigliato è indicativo: fidati di olfatto e gusto.",
+ "mealbox.portionsLeft_one": "1 porzione rimasta",
+ "mealbox.portionsLeft_other": "{count} porzioni rimaste",
+ "mealbox.title": "Porta pranzo",
+ "memory.delete": "Elimina",
+ "memory.deleteAll": "Elimina tutta la memoria",
+ "memory.deleteAllTitle": "Eliminare tutta la memoria?",
+ "memory.empty": "{brand} non ha ancora imparato nulla su di te.",
+ "memory.irreversible": "Questa operazione non può essere annullata.",
+ "memory.origin.ai_inferred": "Ipotesi dell'IA",
+ "memory.origin.observed": "Schema osservato",
+ "memory.origin.user_stated": "Ce l'hai detto tu",
+ "memory.pause": "Pausa",
+ "memory.paused": "In pausa",
+ "memory.resume": "Riprendi",
+ "memory.subtitle": "Trasparenza totale. Correggi, metti in pausa o elimina: la memoria è tua.",
+ "memory.title": "Cosa sa {brand} di me",
+ "memory.verified": "Verificato",
+ "memory.verify": "Corretto",
+ "myday.calories": "Calorie",
+ "myday.carbs": "Carboidrati",
+ "myday.estimateNote": "I valori con ~ sono stime che puoi correggere.",
+ "myday.estimateRange": "{min}–{max} kcal, probabilmente {kcal}",
+ "myday.fat": "Grassi",
+ "myday.fiber": "Fibre",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g di proteine",
+ "myday.logMeal": "Registra pasto",
+ "myday.mealType.breakfast": "Colazione",
+ "myday.mealType.dessert": "Dolce",
+ "myday.mealType.dinner": "Cena",
+ "myday.mealType.lunch": "Pranzo",
+ "myday.mealType.snack": "Spuntino",
+ "myday.noMeals": "Nessun pasto registrato oggi.",
+ "myday.over": "{kcal} kcal oltre l'obiettivo",
+ "myday.overRecommended": "Oltre il consigliato",
+ "myday.protein": "Proteine",
+ "myday.remaining": "{kcal} kcal rimanenti",
+ "myday.salt": "Sale",
+ "myday.targetsNote": "Gli obiettivi sono indicazioni, non consigli medici.",
+ "myday.title": "La mia giornata",
+ "myday.todaysMeals": "Pasti di oggi",
+ "onboarding.allergen.crustaceans": "Crostacei",
+ "onboarding.allergen.eggs": "Uova",
+ "onboarding.allergen.fish": "Pesce",
+ "onboarding.allergen.gluten": "Glutine",
+ "onboarding.allergen.milk": "Latte/lattosio",
+ "onboarding.allergen.peanuts": "Arachidi",
+ "onboarding.allergen.sesame": "Sesamo",
+ "onboarding.allergen.soy": "Soia",
+ "onboarding.allergen.tree_nuts": "Frutta a guscio",
"onboarding.allergies": "Allergie e intolleranze",
"onboarding.allergyNote": "Il filtro allergie è sempre rigoroso: i piatti con i tuoi allergeni non vengono mai mostrati.",
+ "onboarding.birthYearPlaceholder": "Anno di nascita",
+ "onboarding.bodyTitle": "Per obiettivi calorici personali (facoltativo)",
+ "onboarding.diet": "Come mangi?",
+ "onboarding.diet.flexitarian": "Flexitariano",
+ "onboarding.diet.omnivore": "Onnivoro",
+ "onboarding.diet.pescatarian": "Pescetariano",
+ "onboarding.diet.vegan": "Vegano",
+ "onboarding.diet.vegetarian": "Vegetariano",
+ "onboarding.goal": "Qual è il tuo obiettivo principale?",
+ "onboarding.goal.build_muscle": "Aumentare la massa muscolare",
+ "onboarding.goal.cook_more": "Cucinare di più a casa",
+ "onboarding.goal.less_waste": "Ridurre gli sprechi",
+ "onboarding.goal.lose_weight": "Perdere peso",
+ "onboarding.goal.lower_cost": "Spendere meno per il cibo",
+ "onboarding.goal.maintain_weight": "Mantenere il peso",
+ "onboarding.goal.more_protein": "Mangiare più proteine",
+ "onboarding.heightPlaceholder": "Altezza (cm)",
"onboarding.household": "La tua famiglia",
"onboarding.householdCreate": "Crea famiglia",
+ "onboarding.householdDefaultName": "Casa",
"onboarding.householdJoin": "Unisciti con un codice",
"onboarding.householdName": "Nome della famiglia",
"onboarding.inviteCode": "Codice di invito",
"onboarding.mode": "Quanta precisione vuoi?",
- "onboarding.modeSimple": "Modalità semplice",
- "onboarding.modeSimpleDesc": "Fotografa il cibo, accetta le stime, zero complicazioni.",
"onboarding.modeExact": "Modalità esatta",
"onboarding.modeExactDesc": "Pesa il cibo, inserisci i grammi, pieno controllo dei numeri.",
+ "onboarding.modesCombine": "Le modalità si possono combinare: semplice ogni giorno, esatta quando vuoi.",
+ "onboarding.modeSimple": "Modalità semplice",
+ "onboarding.modeSimpleDesc": "Fotografa il cibo, accetta le stime, zero complicazioni.",
"onboarding.notMedical": "{brand} offre indicazioni, non consigli medici.",
- "wte.title": "Cosa mangiamo?",
- "wte.subtitle": "In base a ciò che avete in casa, a cosa va consumato presto e ai vostri gusti.",
- "wte.cravingPlaceholder": "Ho voglia di … (es. cremoso, asiatico, meno di 500 kcal)",
- "wte.mealBoxFirst": "Cibo pronto in casa",
- "wte.whyTitle": "Perché questo suggerimento?",
- "wte.coverage": "{pct}% in casa",
- "wte.missing": "Manca: {items}",
- "wte.empty": "Ancora nessun suggerimento: aggiungi cibo alla dispensa o allenta i filtri.",
- "wte.refresh": "Nuovi suggerimenti",
- "scan.title": "Scansiona",
- "scan.subtitle": "Riempi la dispensa o registra un pasto con la fotocamera.",
- "scan.fridge": "Frigo",
- "scan.freezer": "Congelatore",
- "scan.pantry": "Dispensa",
- "scan.ingredients": "Ingredienti",
- "scan.plate": "Piatto",
- "scan.receipt": "Scontrino",
- "scan.barcode": "Codice a barre",
- "scan.expiry": "Data di scadenza",
- "scan.nutrition": "Etichetta nutrizionale",
- "scan.takePhoto": "Scatta foto",
- "scan.tips.title": "Come ottenere la migliore analisi",
- "scan.tips.overview": "Inizia con una foto d'insieme",
- "scan.tips.shelf": "Fotografa ripiano per ripiano",
- "scan.tips.light": "Evita buio e ombre",
- "scan.tips.move": "Sposta i prodotti che si coprono a vicenda",
- "scan.analyzing": "Analisi in corso …",
- "scan.quotaLeft_one": "1 scansione IA rimasta questo mese",
- "scan.quotaLeft_other": "{count} scansioni IA rimaste questo mese",
- "scan.review.title": "Controlla il risultato",
- "scan.review.subtitle": "L'IA a volte è incerta: decidi tu. Modifica, elimina o aggiungi prima di salvare.",
- "scan.review.uncertain": "Incerto – controlla",
- "scan.review.approveAll": "Salva nella dispensa",
- "scan.review.rejected": "Rimosso",
- "scan.failed": "Analisi non riuscita. Riprova o inserisci manualmente.",
- "myday.title": "La mia giornata",
- "myday.calories": "Calorie",
- "myday.protein": "Proteine",
- "myday.carbs": "Carboidrati",
- "myday.fat": "Grassi",
- "myday.fiber": "Fibre",
- "myday.salt": "Sale",
- "myday.remaining": "{kcal} kcal rimanenti",
- "myday.over": "{kcal} kcal oltre l'obiettivo",
- "myday.logMeal": "Registra pasto",
- "myday.noMeals": "Nessun pasto registrato oggi.",
- "myday.estimateNote": "I valori con ~ sono stime che puoi correggere.",
- "myday.targetsNote": "Gli obiettivi sono indicazioni, non consigli medici.",
- "home.title": "A casa",
- "home.inventory": "Dispensa",
- "home.useSoon": "Da consumare presto",
- "home.mealBoxes": "Porta pranzo",
- "home.shopping": "Lista della spesa",
- "home.budget": "Budget",
- "home.household": "Famiglia",
- "home.waste": "Sprechi",
- "home.emptyInventory": "La dispensa è vuota. Scansiona il frigo o aggiungi manualmente.",
- "home.expiresIn_one": "1 giorno rimasto",
- "home.expiresIn_other": "{days} giorni rimasti",
- "home.expiresToday": "Scade oggi",
- "home.expired": "Scaduto",
- "home.pastBestBefore": "Oltre il termine minimo: annusa e assaggia prima",
+ "onboarding.stepBSubtitle": "Personalizza il profilo per suggerimenti migliori.",
+ "onboarding.stepBTitle": "Continua configurazione",
+ "onboarding.stepCSubtitle": "Opzionale – usato per obiettivi calorici personali.",
+ "onboarding.stepCTitle": "Il tuo profilo salute",
+ "onboarding.subtitle": "Tutto è facoltativo e modificabile in qualsiasi momento. Più compili, migliori saranno i suggerimenti.",
+ "onboarding.title": "Raccontaci qualcosa di te",
+ "onboarding.weightPlaceholder": "Peso (kg)",
+ "paywall.choose": "Scegli",
+ "paywall.fairUse": "Quota fair use di scansioni IA inclusa.",
+ "paywall.family": "Family · fino a 6 persone",
+ "paywall.freeNote": "Gratis: 10 scansioni IA/mese, dispensa manuale, ricette salvate e registrazione semplice.",
+ "paywall.household": "Household · fino a 3 persone",
+ "paywall.large": "Large Household · fino a 12 persone",
+ "paywall.perMonth": "{price}/mese",
+ "paywall.popular": "Il più scelto",
+ "paywall.restore": "Ripristina acquisti",
+ "paywall.soonBody": "Gli acquisti si attivano tramite App Store/Google Play quando l'integrazione con gli store sarà attiva (fase 7). Il flusso backend è già pronto.",
+ "paywall.soonTitle": "Presto!",
+ "paywall.subtitle": "Il sistema operativo del cibo per tutta la famiglia: dispensa illimitata, piano settimanale e condivisione.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "1 giorno di prova rimasto",
+ "paywall.trialActive_other": "{days} giorni di prova rimasti",
+ "profile.aiScansUsed": "Scansioni IA: {used} / {total} questo mese",
+ "profile.consent.anonymized_improvement": "Miglioramento anonimo dell'IA",
+ "profile.consent.health_integration": "Dati sanitari (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Le mie foto possono essere usate per l'addestramento",
+ "profile.consent.location_weather": "Posizione per suggerimenti in base al meteo",
+ "profile.consent.personalization": "Funzioni personali (memoria e profilo dei gusti)",
+ "profile.consent.product_analytics": "Analisi del prodotto",
+ "profile.consent.push_notifications": "Notifiche push",
+ "profile.consents": "Consensi e dati",
+ "profile.consentsNote": "I consensi sono separati: le funzioni personali non richiedono mai il consenso all'addestramento.",
+ "profile.deleteAccount": "Elimina account",
+ "profile.deleteBody": "Tutti i tuoi dati saranno eliminati definitivamente secondo il GDPR.",
+ "profile.deleteTitle": "Eliminare l'account?",
+ "profile.emailUnverified": "Email non confermata",
+ "profile.export": "Esporta i miei dati",
+ "profile.goals": "Obiettivi e dieta",
+ "profile.language": "Lingua",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Esci",
+ "profile.memory": "Cosa sa {brand} di me",
+ "profile.memorySubtitle": "Vedi, correggi, metti in pausa o elimina ciò che la piattaforma ha imparato.",
+ "profile.modeLabel": "Modalità:",
+ "profile.resendVerification": "Reinvia email di conferma",
+ "profile.subscription": "Abbonamento",
+ "profile.title": "Profilo",
+ "profile.verificationSent": "Inviata! Controlla la casella.",
+ "recipe.avgRating": "Media {avg} su {count} valutazioni",
+ "recipe.cook": "Cucina ora",
+ "recipe.cost": "circa {amount}/porzione",
+ "recipe.iCookedThis": "L'ho cucinato",
+ "recipe.ingredients": "Ingredienti",
+ "recipe.notSafe": "Non adatto alle tue impostazioni alimentari",
+ "recipe.perPortion": "a porzione",
"recipe.portions_one": "1 porzione",
"recipe.portions_other": "{count} porzioni",
- "recipe.time": "{min} min",
- "recipe.perPortion": "a porzione",
- "recipe.ingredients": "Ingredienti",
+ "recipe.save": "Salva",
+ "recipe.saved": "Salvata",
"recipe.steps": "Preparazione",
- "recipe.cook": "Cucina ora",
- "recipe.notSafe": "Non adatto alle tue impostazioni alimentari",
"recipe.substitutions": "Sostituisci",
- "recipe.iCookedThis": "L'ho cucinato",
- "recipe.cost": "circa {amount}/porzione",
- "cooking.step": "Passo {current} di {total}",
- "cooking.timer": "Avvia timer",
- "cooking.timerRunning": "{time} rimasti",
- "cooking.finish": "Fatto – registra il pasto",
- "cooking.scale": "Porzioni",
- "cooking.keepAwake": "Lo schermo resta acceso mentre cucini",
- "cooked.title": "Com'è andata?",
- "cooked.portionsCooked": "Porzioni cucinate",
- "cooked.whoAte": "Chi ha mangiato?",
- "cooked.mealBoxes": "Porzioni nei porta pranzo",
- "cooked.deductPantry": "Scala gli ingredienti dalla dispensa",
- "cooked.rate": "Valuta",
- "shopping.title": "Lista della spesa",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analisi in corso …",
+ "scan.barcode": "Codice a barre",
+ "scan.expiry": "Data di scadenza",
+ "scan.failed": "Analisi non riuscita. Riprova o inserisci manualmente.",
+ "scan.freezer": "Congelatore",
+ "scan.fridge": "Frigo",
+ "scan.ingredients": "Ingredienti",
+ "scan.nutrition": "Etichetta nutrizionale",
+ "scan.pantry": "Dispensa",
+ "scan.plate": "Piatto",
+ "scan.quotaLeft_one": "1 scansione IA rimasta questo mese",
+ "scan.quotaLeft_other": "{count} scansioni IA rimaste questo mese",
+ "scan.receipt": "Scontrino",
+ "scan.review.addItem": "+ Aggiungi prodotto",
+ "scan.review.approveAll": "Salva nella dispensa",
+ "scan.review.bestBeforeNote": "Limite di qualità: l'alimento può essere buono anche dopo. Annusa e assaggia prima di buttare.",
+ "scan.review.dateKindBestBefore": "Preferibilmente entro",
+ "scan.review.dateKindUseBy": "Data di scadenza",
+ "scan.review.datePlaceholder": "AAAA-MM-GG (facoltativo)",
+ "scan.review.itemPlaceholder": "Prodotto",
+ "scan.review.quantityPlaceholder": "Quantità",
+ "scan.review.rejected": "Rimosso",
+ "scan.review.subtitle": "L'IA a volte è incerta: decidi tu. Modifica, elimina o aggiungi prima di salvare.",
+ "scan.review.title": "Controlla il risultato",
+ "scan.review.uncertain": "Incerto – controlla",
+ "scan.review.unitPlaceholder": "Unità (g, l, pz …)",
+ "scan.review.unknownItem": "Prodotto sconosciuto",
+ "scan.review.useByNote": "Limite di sicurezza: non consumare dopo questa data.",
+ "scan.subtitle": "Riempi la dispensa o registra un pasto con la fotocamera.",
+ "scan.takePhoto": "Scatta foto",
+ "scan.tips.light": "Evita buio e ombre",
+ "scan.tips.move": "Sposta i prodotti che si coprono a vicenda",
+ "scan.tips.overview": "Inizia con una foto d'insieme",
+ "scan.tips.shelf": "Fotografa ripiano per ripiano",
+ "scan.tips.title": "Come ottenere la migliore analisi",
+ "scan.title": "Scansiona",
"shopping.addPlaceholder": "Aggiungi prodotto …",
"shopping.complete": "Concludi la spesa",
+ "shopping.completedBody_one": "1 prodotto aggiunto alla dispensa.",
+ "shopping.completedBody_other": "{count} prodotti aggiunti alla dispensa.",
+ "shopping.completedTitle": "Fatto!",
"shopping.completeNote": "I prodotti spuntati vengono aggiunti alla dispensa.",
"shopping.empty": "La lista è vuota.",
"shopping.estimated": "circa {amount}",
"shopping.estimatedTotal": "Totale stimato: circa {amount}",
- "mealbox.title": "Porta pranzo",
- "mealbox.eatBy": "Consumare entro il {date}",
- "mealbox.portionsLeft_one": "1 porzione rimasta",
- "mealbox.portionsLeft_other": "{count} porzioni rimaste",
- "mealbox.eat": "Mangia ora",
- "mealbox.empty": "Nessun porta pranzo al momento. Quando cucini puoi salvare qui le porzioni.",
- "household.members": "Membri",
- "household.invite": "Invita con il codice: {code}",
- "household.shared": "Condiviso in famiglia: dispensa, lista della spesa, piano settimanale, porta pranzo e budget.",
- "household.private": "Privato per persona: obiettivi, allergie, dati sanitari e cronologia dei pasti.",
- "memory.title": "Cosa sa {brand} di me",
- "memory.subtitle": "Trasparenza totale. Correggi, metti in pausa o elimina: la memoria è tua.",
- "memory.paused": "In pausa",
- "memory.verify": "Corretto",
- "memory.pause": "Pausa",
- "memory.delete": "Elimina",
- "memory.deleteAll": "Elimina tutta la memoria",
- "memory.empty": "{brand} non ha ancora imparato nulla su di te.",
- "memory.origin.user_stated": "Ce l'hai detto tu",
- "memory.origin.observed": "Schema osservato",
- "memory.origin.ai_inferred": "Ipotesi dell'IA",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "Il sistema operativo del cibo per tutta la famiglia: dispensa illimitata, piano settimanale e condivisione.",
- "paywall.trialActive_one": "1 giorno di prova rimasto",
- "paywall.trialActive_other": "{days} giorni di prova rimasti",
- "paywall.household": "Household · fino a 3 persone",
- "paywall.family": "Family · fino a 6 persone",
- "paywall.large": "Large Household · fino a 12 persone",
- "paywall.perMonth": "{price}/mese",
- "paywall.fairUse": "Quota fair use di scansioni IA inclusa.",
- "paywall.restore": "Ripristina acquisti",
- "paywall.freeNote": "Gratis: 10 scansioni IA/mese, dispensa manuale, ricette salvate e registrazione semplice.",
- "profile.title": "Profilo",
- "profile.goals": "Obiettivi e dieta",
- "profile.consents": "Consensi e dati",
- "profile.memory": "Cosa sa {brand} di me",
- "profile.subscription": "Abbonamento",
- "profile.logout": "Esci",
- "profile.export": "Esporta i miei dati",
- "profile.deleteAccount": "Elimina account",
- "profile.language": "Lingua",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.emailUnverified": "Email non confermata",
- "profile.resendVerification": "Reinvia email di conferma",
- "profile.verificationSent": "Inviata! Controlla la casella.",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Ops",
- "common.undo": "Ripristina",
- "common.remove": "Rimuovi",
- "common.add": "Aggiungi",
- "common.on": "Attivato",
- "common.off": "Disattivato",
- "home.thisWeek": "Questa settimana",
- "home.wasteWeek": "Sprechi questa settimana",
- "home.useSoonHint": "Il termine minimo di conservazione riguarda la qualità: annusa, osserva e assaggia prima di buttare. La data di scadenza va invece rispettata.",
- "scan.review.itemPlaceholder": "Prodotto",
- "scan.review.quantityPlaceholder": "Quantità",
- "scan.review.unitPlaceholder": "Unità (g, l, pz …)",
- "scan.review.datePlaceholder": "AAAA-MM-GG (facoltativo)",
- "scan.review.dateKindBestBefore": "Preferibilmente entro",
- "scan.review.dateKindUseBy": "Data di scadenza",
- "scan.review.bestBeforeNote": "Limite di qualità: l'alimento può essere buono anche dopo. Annusa e assaggia prima di buttare.",
- "scan.review.useByNote": "Limite di sicurezza: non consumare dopo questa data.",
- "scan.review.addItem": "+ Aggiungi prodotto",
- "scan.review.unknownItem": "Prodotto sconosciuto",
- "barcode.aim": "Inquadra il codice a barre",
- "barcode.addPrompt": "Aggiungere alla dispensa?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Dati nutrizionali mancanti",
- "barcode.unknownTitle": "Prodotto sconosciuto",
- "barcode.unknownBody": "Questo prodotto non è ancora nel database. Fotografa il fronte e l'etichetta nutrizionale e lo aggiungeremo.",
- "barcode.photoPackage": "Fotografa la confezione",
- "barcode.needHousehold": "Prima ti serve una famiglia.",
- "barcode.noLocation": "Nessun luogo di conservazione trovato.",
- "barcode.cameraTitle": "Serve la fotocamera",
- "barcode.cameraBody": "{brand} ha bisogno della fotocamera per leggere i codici a barre.",
- "barcode.allowCamera": "Consenti fotocamera",
- "onboarding.goal.lose_weight": "Perdere peso",
- "onboarding.goal.build_muscle": "Aumentare la massa muscolare",
- "onboarding.goal.maintain_weight": "Mantenere il peso",
- "onboarding.goal.more_protein": "Mangiare più proteine",
- "onboarding.goal.less_waste": "Ridurre gli sprechi",
- "onboarding.goal.lower_cost": "Spendere meno per il cibo",
- "onboarding.goal.cook_more": "Cucinare di più a casa",
- "onboarding.diet.omnivore": "Onnivoro",
- "onboarding.diet.flexitarian": "Flexitariano",
- "onboarding.diet.pescatarian": "Pescetariano",
- "onboarding.diet.vegetarian": "Vegetariano",
- "onboarding.diet.vegan": "Vegano",
- "onboarding.allergen.gluten": "Glutine",
- "onboarding.allergen.milk": "Latte/lattosio",
- "onboarding.allergen.eggs": "Uova",
- "onboarding.allergen.tree_nuts": "Frutta a guscio",
- "onboarding.allergen.peanuts": "Arachidi",
- "onboarding.allergen.fish": "Pesce",
- "onboarding.allergen.crustaceans": "Crostacei",
- "onboarding.allergen.soy": "Soia",
- "onboarding.allergen.sesame": "Sesamo",
- "onboarding.bodyTitle": "Per obiettivi calorici personali (facoltativo)",
- "onboarding.weightPlaceholder": "Peso (kg)",
- "onboarding.heightPlaceholder": "Altezza (cm)",
- "onboarding.birthYearPlaceholder": "Anno di nascita",
- "onboarding.householdDefaultName": "Casa",
- "onboarding.modesCombine": "Le modalità si possono combinare: semplice ogni giorno, esatta quando vuoi.",
- "myday.mealType.breakfast": "Colazione",
- "myday.mealType.lunch": "Pranzo",
- "myday.mealType.dinner": "Cena",
- "myday.mealType.snack": "Spuntino",
- "myday.mealType.dessert": "Dolce",
- "myday.overRecommended": "Oltre il consigliato",
- "myday.todaysMeals": "Pasti di oggi",
- "myday.estimateRange": "{min}–{max} kcal, probabilmente {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g di proteine",
- "logmeal.mealTypeTitle": "Tipo di pasto",
- "logmeal.quickTitle": "Registrazione rapida",
- "logmeal.quickSubtitle": "Registra gli stessi valori nutrizionali dell'ultima volta.",
- "logmeal.manualTitle": "Manuale",
- "logmeal.whatPlaceholder": "Cosa hai mangiato?",
- "logmeal.proteinPlaceholder": "proteine (g)",
- "logmeal.validationTitle": "Dati mancanti",
- "logmeal.validationBody": "Per la registrazione manuale servono nome e calorie.",
- "logmeal.photoTip": "Suggerimento: fotografa il piatto in Scansiona e l'app stimerà per te; confermi sempre tu.",
- "shopping.section.frukt_gront": "Frutta e verdura",
"shopping.section.brod": "Pane",
- "shopping.section.mejeri": "Latticini",
- "shopping.section.kott_fagel": "Carne e pollame",
- "shopping.section.fisk": "Pesce",
"shopping.section.chark": "Salumi",
- "shopping.section.frys": "Surgelati",
- "shopping.section.skafferi": "Dispensa",
- "shopping.section.konserver": "Conserve",
- "shopping.section.kryddor_bak": "Spezie e preparati per dolci",
"shopping.section.dryck": "Bevande",
- "shopping.section.snacks": "Snack",
+ "shopping.section.fisk": "Pesce",
+ "shopping.section.frukt_gront": "Frutta e verdura",
+ "shopping.section.frys": "Surgelati",
"shopping.section.hygien_ovrigt": "Altro",
- "shopping.completedTitle": "Fatto!",
- "household.role.owner": "Proprietario",
- "household.role.adult": "Adulto",
- "household.role.member": "Membro",
- "household.role.child": "Bambino",
- "household.empty": "Non hai ancora una famiglia. Creane una nell'onboarding o unisciti con un codice.",
- "household.shareCode": "Condividi il codice con la famiglia per condividere dispensa, lista e piano.",
- "household.locations": "Luoghi di conservazione",
- "household.portionFactor": "×{factor} porzione",
- "mealbox.enjoyTitle": "Buon appetito!",
- "mealbox.enjoyBody": "La porzione è registrata in La mia giornata.",
- "mealbox.guidanceNote": "Il termine consigliato è indicativo: fidati di olfatto e gusto.",
- "paywall.soonTitle": "Presto!",
- "paywall.soonBody": "Gli acquisti si attivano tramite App Store/Google Play quando l'integrazione con gli store sarà attiva (fase 7). Il flusso backend è già pronto.",
- "paywall.popular": "Il più scelto",
- "paywall.choose": "Scegli",
- "recipe.saved": "Salvata",
- "recipe.save": "Salva",
- "recipe.avgRating": "Media {avg} su {count} valutazioni",
- "memory.verified": "Verificato",
- "memory.resume": "Riprendi",
- "memory.deleteAllTitle": "Eliminare tutta la memoria?",
- "memory.irreversible": "Questa operazione non può essere annullata.",
- "profile.consent.personalization": "Funzioni personali (memoria e profilo dei gusti)",
- "profile.consent.anonymized_improvement": "Miglioramento anonimo dell'IA",
- "profile.consent.image_training": "Le mie foto possono essere usate per l'addestramento",
- "profile.consent.health_integration": "Dati sanitari (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Posizione per suggerimenti in base al meteo",
- "profile.consent.push_notifications": "Notifiche push",
- "profile.modeLabel": "Modalità:",
- "profile.memorySubtitle": "Vedi, correggi, metti in pausa o elimina ciò che la piattaforma ha imparato.",
- "profile.consentsNote": "I consensi sono separati: le funzioni personali non richiedono mai il consenso all'addestramento.",
- "profile.aiScansUsed": "Scansioni IA: {used} / {total} questo mese",
- "profile.deleteTitle": "Eliminare l'account?",
- "profile.deleteBody": "Tutti i tuoi dati saranno eliminati definitivamente secondo il GDPR.",
- "cooking.timerDone": "Fatto!",
- "cooked.deductPantryNote": "Gli ingredienti vengono scalati dalla dispensa: prima quelli in scadenza.",
- "home.moreItems_one": "+ 1 altro …",
- "home.moreItems_other": "+ {count} altri …",
- "shopping.completedBody_one": "1 prodotto aggiunto alla dispensa.",
- "shopping.completedBody_other": "{count} prodotti aggiunti alla dispensa.",
- "profile.consent.product_analytics": "Analisi del prodotto"
+ "shopping.section.konserver": "Conserve",
+ "shopping.section.kott_fagel": "Carne e pollame",
+ "shopping.section.kryddor_bak": "Spezie e preparati per dolci",
+ "shopping.section.mejeri": "Latticini",
+ "shopping.section.skafferi": "Dispensa",
+ "shopping.section.snacks": "Snack",
+ "shopping.title": "Lista della spesa",
+ "tabs.home": "A casa",
+ "tabs.myDay": "La mia giornata",
+ "tabs.scan": "Scansiona",
+ "tabs.whatToEat": "Cosa mangiamo?",
+ "wte.coverage": "{pct}% in casa",
+ "wte.cravingPlaceholder": "Ho voglia di … (es. cremoso, asiatico, meno di 500 kcal)",
+ "wte.empty": "Ancora nessun suggerimento: aggiungi cibo alla dispensa o allenta i filtri.",
+ "wte.mealBoxFirst": "Cibo pronto in casa",
+ "wte.missing": "Manca: {items}",
+ "wte.refresh": "Nuovi suggerimenti",
+ "wte.subtitle": "In base a ciò che avete in casa, a cosa va consumato presto e ai vostri gusti.",
+ "wte.title": "Cosa mangiamo?",
+ "wte.whyTitle": "Perché questo suggerimento?"
}
diff --git a/apps/mobile/src/locales/nb/common.json b/apps/mobile/src/locales/nb/common.json
index 34bca76..88eeadc 100644
--- a/apps/mobile/src/locales/nb/common.json
+++ b/apps/mobile/src/locales/nb/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Laster …",
+ "auth.backToLogin": "Tilbake til innlogging",
+ "auth.displayName": "Hva skal vi kalle deg?",
+ "auth.email": "E-post",
+ "auth.forgotBody": "Skriv inn e-postadressen din, så sender vi en lenke hvis kontoen finnes.",
+ "auth.forgotLink": "Glemt passordet?",
+ "auth.forgotSentBody": "Hvis adressen har en konto, har vi sendt en lenke som gjelder i 30 minutter. Åpne den på denne enheten.",
+ "auth.forgotSentTitle": "Sjekk innboksen din",
+ "auth.forgotSubmit": "Send lenke",
+ "auth.forgotTitle": "Tilbakestill passord",
+ "auth.hasAccount": "Har du allerede en konto? Logg inn",
+ "auth.login": "Logg inn",
+ "auth.newPassword": "Nytt passord (minst 10 tegn)",
+ "auth.noAccount": "Ny her? Opprett en konto",
+ "auth.password": "Passord",
+ "auth.register": "Opprett konto",
+ "auth.resetBody": "Lenken gjelder i 30 minutter og kan bare brukes én gang. Alle enheter logges ut.",
+ "auth.resetDoneBody": "Passordet ditt er endret. Logg inn med det nye.",
+ "auth.resetDoneTitle": "Ferdig!",
+ "auth.resetSubmit": "Bytt passord",
+ "auth.resetTitle": "Velg et nytt passord",
+ "auth.resetTokenPlaceholder": "Lim inn koden fra e-posten",
+ "auth.trialNote": "7 dager full tilgang – uten kort.",
+ "auth.verifyDoneBody": "Takk! Kontoen din er verifisert.",
+ "auth.verifyDoneTitle": "E-post bekreftet",
+ "auth.verifyFailedBody": "Lenken er ugyldig eller utløpt. Be om en ny fra profilen.",
+ "auth.verifyFailedTitle": "Lenken fungerte ikke",
+ "barcode.addPrompt": "Legge til i matlageret?",
+ "barcode.aim": "Rett kameraet mot strekkoden",
+ "barcode.allowCamera": "Tillat kamera",
+ "barcode.cameraBody": "{brand} trenger kameraet for å skanne strekkoder.",
+ "barcode.cameraTitle": "Kameraet trengs",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Du trenger en husstand først.",
+ "barcode.noLocation": "Fant ingen oppbevaringssteder.",
+ "barcode.noNutrition": "Ingen næringsdata",
+ "barcode.photoPackage": "Ta bilde av pakken",
+ "barcode.unknownBody": "Produktet er ikke i databasen ennå. Ta bilde av forsiden og næringsdeklarasjonen, så legger vi det til.",
+ "barcode.unknownTitle": "Ukjent produkt",
+ "common.add": "Legg til",
+ "common.back": "Tilbake",
+ "common.cancel": "Avbryt",
+ "common.done": "Ferdig",
"common.error": "Noe gikk galt. Prøv igjen.",
+ "common.estimate": "Estimat",
+ "common.loading": "Laster …",
+ "common.next": "Neste",
+ "common.off": "Av",
+ "common.offline": "Frakoblet – viser sist hentede data",
+ "common.on": "På",
+ "common.oops": "Oi sann",
+ "common.remove": "Fjern",
"common.retry": "Prøv igjen",
"common.save": "Lagre",
- "common.cancel": "Avbryt",
- "common.next": "Neste",
- "common.back": "Tilbake",
- "common.done": "Ferdig",
"common.skip": "Hopp over",
- "common.offline": "Frakoblet – viser sist hentede data",
- "common.estimate": "Estimat",
- "tabs.whatToEat": "Hva skal vi spise?",
- "tabs.scan": "Skann",
- "tabs.myDay": "Min dag",
- "tabs.home": "Hjemme",
- "auth.login": "Logg inn",
- "auth.register": "Opprett konto",
- "auth.email": "E-post",
- "auth.password": "Passord",
- "auth.displayName": "Hva skal vi kalle deg?",
- "auth.noAccount": "Ny her? Opprett en konto",
- "auth.hasAccount": "Har du allerede en konto? Logg inn",
- "auth.trialNote": "7 dager full tilgang – uten kort.",
- "auth.forgotLink": "Glemt passordet?",
- "auth.forgotTitle": "Tilbakestill passord",
- "auth.forgotBody": "Skriv inn e-postadressen din, så sender vi en lenke hvis kontoen finnes.",
- "auth.forgotSubmit": "Send lenke",
- "auth.forgotSentTitle": "Sjekk innboksen din",
- "auth.forgotSentBody": "Hvis adressen har en konto, har vi sendt en lenke som gjelder i 30 minutter. Åpne den på denne enheten.",
- "auth.backToLogin": "Tilbake til innlogging",
- "auth.resetTitle": "Velg et nytt passord",
- "auth.resetBody": "Lenken gjelder i 30 minutter og kan bare brukes én gang. Alle enheter logges ut.",
- "auth.resetTokenPlaceholder": "Lim inn koden fra e-posten",
- "auth.newPassword": "Nytt passord (minst 10 tegn)",
- "auth.resetSubmit": "Bytt passord",
- "auth.resetDoneTitle": "Ferdig!",
- "auth.resetDoneBody": "Passordet ditt er endret. Logg inn med det nye.",
- "auth.verifyDoneTitle": "E-post bekreftet",
- "auth.verifyDoneBody": "Takk! Kontoen din er verifisert.",
- "auth.verifyFailedTitle": "Lenken fungerte ikke",
- "auth.verifyFailedBody": "Lenken er ugyldig eller utløpt. Be om en ny fra profilen.",
- "onboarding.title": "Fortell oss litt om deg",
- "onboarding.subtitle": "Alt er frivillig og kan endres når som helst. Jo mer du fyller ut, desto bedre forslag.",
- "onboarding.goal": "Hva er ditt viktigste mål?",
- "onboarding.diet": "Hvordan spiser du?",
+ "common.undo": "Angre",
+ "cooked.deductPantry": "Trekk ingredienser fra lageret",
+ "cooked.deductPantryNote": "Ingrediensene trekkes fra matlageret – det som går ut først, brukes først.",
+ "cooked.mealBoxes": "Porsjoner til matbokser",
+ "cooked.portionsCooked": "Porsjoner laget",
+ "cooked.rate": "Vurder",
+ "cooked.title": "Hvordan gikk det?",
+ "cooked.whoAte": "Hvem spiste?",
+ "cooking.finish": "Ferdig – loggfør måltidet",
+ "cooking.keepAwake": "Skjermen holdes våken mens du lager mat",
+ "cooking.scale": "Porsjoner",
+ "cooking.step": "Steg {current} av {total}",
+ "cooking.timer": "Start timer",
+ "cooking.timerDone": "Ferdig!",
+ "cooking.timerRunning": "{time} igjen",
+ "home.budget": "Matbudsjett",
+ "home.emptyInventory": "Lageret er tomt. Skann kjøleskapet eller legg til varer manuelt.",
+ "home.expired": "Utløpt",
+ "home.expiresIn_one": "1 dag igjen",
+ "home.expiresIn_other": "{days} dager igjen",
+ "home.expiresToday": "Går ut i dag",
+ "home.household": "Husstand",
+ "home.inventory": "Matlager",
+ "home.mealBoxes": "Matbokser",
+ "home.moreItems_one": "+ 1 til …",
+ "home.moreItems_other": "+ {count} til …",
+ "home.pastBestBefore": "Best før er passert – lukt og smak først",
+ "home.shopping": "Handleliste",
+ "home.thisWeek": "Denne uken",
+ "home.title": "Hjemme",
+ "home.useSoon": "Bruk snart",
+ "home.useSoonHint": "Best før handler om kvalitet – lukt, se og smak før du kaster. Siste forbruksdag skal derimot respekteres.",
+ "home.waste": "Matsvinn",
+ "home.wasteWeek": "Matsvinn denne uken",
+ "household.empty": "Du har ingen husstand ennå. Opprett en i onboarding eller bli med via kode.",
+ "household.invite": "Inviter med kode: {code}",
+ "household.locations": "Oppbevaringssteder",
+ "household.members": "Medlemmer",
+ "household.portionFactor": "×{factor} porsjon",
+ "household.private": "Privat per person: mål, allergier, helsedata og måltidshistorikk.",
+ "household.role.adult": "Voksen",
+ "household.role.child": "Barn",
+ "household.role.member": "Medlem",
+ "household.role.owner": "Eier",
+ "household.shareCode": "Del koden med familien, så deler dere matlager, liste og plan.",
+ "household.shared": "Deles i husstanden: matlager, handleliste, ukeplan, matbokser og budsjett.",
+ "logmeal.manualTitle": "Manuelt",
+ "logmeal.mealTypeTitle": "Måltidstype",
+ "logmeal.photoTip": "Tips: ta bilde av tallerkenen under Skann, så anslår appen for deg – du bekrefter alltid.",
+ "logmeal.proteinPlaceholder": "protein (g)",
+ "logmeal.quickSubtitle": "Logger de samme næringsverdiene som sist.",
+ "logmeal.quickTitle": "Rask gjenlogging",
+ "logmeal.validationBody": "Navn og kalorier trengs for manuell logging.",
+ "logmeal.validationTitle": "Fyll ut",
+ "logmeal.whatPlaceholder": "Hva spiste du?",
+ "mealbox.eat": "Spis nå",
+ "mealbox.eatBy": "Spis innen {date}",
+ "mealbox.empty": "Ingen matbokser akkurat nå. Når du lager mat, kan du lagre porsjoner her.",
+ "mealbox.enjoyBody": "Porsjonen er logget i Min dag.",
+ "mealbox.enjoyTitle": "Vel bekomme!",
+ "mealbox.guidanceNote": "Anbefalt frist er veiledende – stol på lukt og smak.",
+ "mealbox.portionsLeft_one": "1 porsjon igjen",
+ "mealbox.portionsLeft_other": "{count} porsjoner igjen",
+ "mealbox.title": "Matbokser",
+ "memory.delete": "Slett",
+ "memory.deleteAll": "Slett alt minne",
+ "memory.deleteAllTitle": "Slette alt minne?",
+ "memory.empty": "{brand} har ikke lært noe om deg ennå.",
+ "memory.irreversible": "Dette kan ikke angres.",
+ "memory.origin.ai_inferred": "AI-antakelse",
+ "memory.origin.observed": "Observert mønster",
+ "memory.origin.user_stated": "Du har fortalt det",
+ "memory.pause": "Pause",
+ "memory.paused": "På pause",
+ "memory.resume": "Gjenoppta",
+ "memory.subtitle": "Full innsikt. Rett feil, sett på pause eller slett – du eier minnet ditt.",
+ "memory.title": "Hva {brand} vet om meg",
+ "memory.verified": "Bekreftet",
+ "memory.verify": "Stemmer",
+ "myday.calories": "Kalorier",
+ "myday.carbs": "Karbohydrater",
+ "myday.estimateNote": "Verdier med ~ er estimater du kan justere.",
+ "myday.estimateRange": "{min}–{max} kcal, trolig {kcal}",
+ "myday.fat": "Fett",
+ "myday.fiber": "Fiber",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
+ "myday.logMeal": "Loggfør måltid",
+ "myday.mealType.breakfast": "Frokost",
+ "myday.mealType.dessert": "Dessert",
+ "myday.mealType.dinner": "Middag",
+ "myday.mealType.lunch": "Lunsj",
+ "myday.mealType.snack": "Mellommåltid",
+ "myday.noMeals": "Ingen måltider loggført i dag.",
+ "myday.over": "{kcal} kcal over målet",
+ "myday.overRecommended": "Over anbefalt",
+ "myday.protein": "Protein",
+ "myday.remaining": "{kcal} kcal igjen",
+ "myday.salt": "Salt",
+ "myday.targetsNote": "Målene er veiledning, ikke medisinske råd.",
+ "myday.title": "Min dag",
+ "myday.todaysMeals": "Dagens måltider",
+ "onboarding.allergen.crustaceans": "Skalldyr",
+ "onboarding.allergen.eggs": "Egg",
+ "onboarding.allergen.fish": "Fisk",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Melk/laktose",
+ "onboarding.allergen.peanuts": "Peanøtter",
+ "onboarding.allergen.sesame": "Sesam",
+ "onboarding.allergen.soy": "Soya",
+ "onboarding.allergen.tree_nuts": "Nøtter",
"onboarding.allergies": "Allergier og intoleranser",
"onboarding.allergyNote": "Allergifiltrering er alltid streng – retter med dine allergener vises aldri.",
+ "onboarding.birthYearPlaceholder": "Fødselsår",
+ "onboarding.bodyTitle": "For personlige kalorimål (valgfritt)",
+ "onboarding.diet": "Hvordan spiser du?",
+ "onboarding.diet.flexitarian": "Fleksitarianer",
+ "onboarding.diet.omnivore": "Alteter",
+ "onboarding.diet.pescatarian": "Pescetarianer",
+ "onboarding.diet.vegan": "Veganer",
+ "onboarding.diet.vegetarian": "Vegetarianer",
+ "onboarding.goal": "Hva er ditt viktigste mål?",
+ "onboarding.goal.build_muscle": "Bygge muskler",
+ "onboarding.goal.cook_more": "Lage mer mat hjemme",
+ "onboarding.goal.less_waste": "Redusere matsvinn",
+ "onboarding.goal.lose_weight": "Gå ned i vekt",
+ "onboarding.goal.lower_cost": "Bruke mindre på mat",
+ "onboarding.goal.maintain_weight": "Holde vekten",
+ "onboarding.goal.more_protein": "Spise mer protein",
+ "onboarding.heightPlaceholder": "Høyde (cm)",
"onboarding.household": "Husstanden din",
"onboarding.householdCreate": "Opprett husstand",
+ "onboarding.householdDefaultName": "Hjemme",
"onboarding.householdJoin": "Bli med via kode",
"onboarding.householdName": "Husstandens navn",
"onboarding.inviteCode": "Invitasjonskode",
"onboarding.mode": "Hvor nøyaktig vil du være?",
- "onboarding.modeSimple": "Enkel modus",
- "onboarding.modeSimpleDesc": "Ta bilde av maten, godta estimater, minimalt styr.",
"onboarding.modeExact": "Nøyaktig modus",
"onboarding.modeExactDesc": "Vei maten, angi gram, full kontroll på tallene.",
+ "onboarding.modesCombine": "Modusene kan kombineres – enkelt til hverdags, nøyaktig når du vil.",
+ "onboarding.modeSimple": "Enkel modus",
+ "onboarding.modeSimpleDesc": "Ta bilde av maten, godta estimater, minimalt styr.",
"onboarding.notMedical": "{brand} gir veiledning – ikke medisinske råd.",
- "wte.title": "Hva skal vi spise?",
- "wte.subtitle": "Basert på hva dere har hjemme, hva som snart bør brukes, og hva dere liker.",
- "wte.cravingPlaceholder": "Jeg har lyst på … (f.eks. kremet, asiatisk, under 500 kcal)",
- "wte.mealBoxFirst": "Ferdig mat hjemme",
- "wte.whyTitle": "Hvorfor dette forslaget?",
- "wte.coverage": "{pct} % hjemme",
- "wte.missing": "Mangler: {items}",
- "wte.empty": "Ingen forslag ennå – legg inn litt mat på lageret eller løsne filtrene.",
- "wte.refresh": "Nye forslag",
- "scan.title": "Skann",
- "scan.subtitle": "Fyll matlageret eller loggfør et måltid med kameraet.",
- "scan.fridge": "Kjøleskap",
- "scan.freezer": "Fryser",
- "scan.pantry": "Spiskammer",
- "scan.ingredients": "Ingredienser",
- "scan.plate": "Tallerken",
- "scan.receipt": "Kvittering",
- "scan.barcode": "Strekkode",
- "scan.expiry": "Best før-dato",
- "scan.nutrition": "Næringsdeklarasjon",
- "scan.takePhoto": "Ta bilde",
- "scan.tips.title": "Slik blir analysen best",
- "scan.tips.overview": "Start med et oversiktsbilde",
- "scan.tips.shelf": "Fotografer hylle for hylle",
- "scan.tips.light": "Unngå mørke og skygger",
- "scan.tips.move": "Flytt varer som skjuler hverandre",
- "scan.analyzing": "Analyserer …",
- "scan.quotaLeft_one": "1 AI-skanning igjen denne måneden",
- "scan.quotaLeft_other": "{count} AI-skanninger igjen denne måneden",
- "scan.review.title": "Gå gjennom resultatet",
- "scan.review.subtitle": "AI-en er noen ganger usikker – du bestemmer. Endre, fjern eller legg til før du lagrer.",
- "scan.review.uncertain": "Usikker – sjekk",
- "scan.review.approveAll": "Lagre på lageret",
- "scan.review.rejected": "Fjernet",
- "scan.failed": "Analysen mislyktes. Prøv igjen eller registrer manuelt.",
- "myday.title": "Min dag",
- "myday.calories": "Kalorier",
- "myday.protein": "Protein",
- "myday.carbs": "Karbohydrater",
- "myday.fat": "Fett",
- "myday.fiber": "Fiber",
- "myday.salt": "Salt",
- "myday.remaining": "{kcal} kcal igjen",
- "myday.over": "{kcal} kcal over målet",
- "myday.logMeal": "Loggfør måltid",
- "myday.noMeals": "Ingen måltider loggført i dag.",
- "myday.estimateNote": "Verdier med ~ er estimater du kan justere.",
- "myday.targetsNote": "Målene er veiledning, ikke medisinske råd.",
- "home.title": "Hjemme",
- "home.inventory": "Matlager",
- "home.useSoon": "Bruk snart",
- "home.mealBoxes": "Matbokser",
- "home.shopping": "Handleliste",
- "home.budget": "Matbudsjett",
- "home.household": "Husstand",
- "home.waste": "Matsvinn",
- "home.emptyInventory": "Lageret er tomt. Skann kjøleskapet eller legg til varer manuelt.",
- "home.expiresIn_one": "1 dag igjen",
- "home.expiresIn_other": "{days} dager igjen",
- "home.expiresToday": "Går ut i dag",
- "home.expired": "Utløpt",
- "home.pastBestBefore": "Best før er passert – lukt og smak først",
+ "onboarding.stepBSubtitle": "Tilpass profilen din for bedre forslag.",
+ "onboarding.stepBTitle": "Fortsett oppsett",
+ "onboarding.stepCSubtitle": "Valgfritt – brukes til personlige kalorimål.",
+ "onboarding.stepCTitle": "Din helseprofil",
+ "onboarding.subtitle": "Alt er frivillig og kan endres når som helst. Jo mer du fyller ut, desto bedre forslag.",
+ "onboarding.title": "Fortell oss litt om deg",
+ "onboarding.weightPlaceholder": "Vekt (kg)",
+ "paywall.choose": "Velg",
+ "paywall.fairUse": "Fair use-kvote for AI-skanninger inkludert.",
+ "paywall.family": "Family · opptil 6 personer",
+ "paywall.freeNote": "Gratis: 10 AI-skanninger/mnd., manuelt lager, lagrede oppskrifter og enkel loggføring.",
+ "paywall.household": "Household · opptil 3 personer",
+ "paywall.large": "Large Household · opptil 12 personer",
+ "paywall.perMonth": "{price}/mnd.",
+ "paywall.popular": "Mest populær",
+ "paywall.restore": "Gjenopprett kjøp",
+ "paywall.soonBody": "Kjøp aktiveres via App Store/Google Play når butikkintegrasjonen slås på (fase 7). Backend-flyten er allerede klar.",
+ "paywall.soonTitle": "Snart!",
+ "paywall.subtitle": "Hele husstandens mat-OS: ubegrenset lager, ukeplan og deling.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "1 dag igjen av prøveperioden",
+ "paywall.trialActive_other": "{days} dager igjen av prøveperioden",
+ "profile.aiScansUsed": "AI-skanninger: {used} / {total} denne måneden",
+ "profile.consent.anonymized_improvement": "Anonymisert forbedring av AI-en",
+ "profile.consent.health_integration": "Helsedata (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Bildene mine kan brukes til trening",
+ "profile.consent.location_weather": "Posisjon for værbaserte forslag",
+ "profile.consent.personalization": "Personlige funksjoner (minne & smaksprofil)",
+ "profile.consent.product_analytics": "Produktanalyse",
+ "profile.consent.push_notifications": "Push-varsler",
+ "profile.consents": "Samtykker & data",
+ "profile.consentsNote": "Samtykkene er separate – personlige funksjoner krever aldri treningssamtykke.",
+ "profile.deleteAccount": "Slett konto",
+ "profile.deleteBody": "Alle dataene dine slettes permanent i henhold til GDPR.",
+ "profile.deleteTitle": "Slette kontoen?",
+ "profile.emailUnverified": "E-postadressen er ikke bekreftet",
+ "profile.export": "Eksporter dataene mine",
+ "profile.goals": "Mål & kosthold",
+ "profile.language": "Språk",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Logg ut",
+ "profile.memory": "Hva {brand} vet om meg",
+ "profile.memorySubtitle": "Se, rett, sett på pause eller slett det plattformen har lært.",
+ "profile.modeLabel": "Modus:",
+ "profile.resendVerification": "Send bekreftelses-e-post på nytt",
+ "profile.subscription": "Abonnement",
+ "profile.title": "Profil",
+ "profile.verificationSent": "Sendt! Sjekk innboksen.",
+ "recipe.avgRating": "Snitt {avg} av {count} vurderinger",
+ "recipe.cook": "Lag mat nå",
+ "recipe.cost": "ca. {amount}/porsjon",
+ "recipe.iCookedThis": "Jeg har laget denne",
+ "recipe.ingredients": "Ingredienser",
+ "recipe.notSafe": "Passer ikke kostinnstillingene dine",
+ "recipe.perPortion": "per porsjon",
"recipe.portions_one": "1 porsjon",
"recipe.portions_other": "{count} porsjoner",
- "recipe.time": "{min} min",
- "recipe.perPortion": "per porsjon",
- "recipe.ingredients": "Ingredienser",
+ "recipe.save": "Lagre",
+ "recipe.saved": "Lagret",
"recipe.steps": "Slik gjør du",
- "recipe.cook": "Lag mat nå",
- "recipe.notSafe": "Passer ikke kostinnstillingene dine",
"recipe.substitutions": "Bytt ut",
- "recipe.iCookedThis": "Jeg har laget denne",
- "recipe.cost": "ca. {amount}/porsjon",
- "cooking.step": "Steg {current} av {total}",
- "cooking.timer": "Start timer",
- "cooking.timerRunning": "{time} igjen",
- "cooking.finish": "Ferdig – loggfør måltidet",
- "cooking.scale": "Porsjoner",
- "cooking.keepAwake": "Skjermen holdes våken mens du lager mat",
- "cooked.title": "Hvordan gikk det?",
- "cooked.portionsCooked": "Porsjoner laget",
- "cooked.whoAte": "Hvem spiste?",
- "cooked.mealBoxes": "Porsjoner til matbokser",
- "cooked.deductPantry": "Trekk ingredienser fra lageret",
- "cooked.rate": "Vurder",
- "shopping.title": "Handleliste",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analyserer …",
+ "scan.barcode": "Strekkode",
+ "scan.expiry": "Best før-dato",
+ "scan.failed": "Analysen mislyktes. Prøv igjen eller registrer manuelt.",
+ "scan.freezer": "Fryser",
+ "scan.fridge": "Kjøleskap",
+ "scan.ingredients": "Ingredienser",
+ "scan.nutrition": "Næringsdeklarasjon",
+ "scan.pantry": "Spiskammer",
+ "scan.plate": "Tallerken",
+ "scan.quotaLeft_one": "1 AI-skanning igjen denne måneden",
+ "scan.quotaLeft_other": "{count} AI-skanninger igjen denne måneden",
+ "scan.receipt": "Kvittering",
+ "scan.review.addItem": "+ Legg til vare",
+ "scan.review.approveAll": "Lagre på lageret",
+ "scan.review.bestBeforeNote": "Kvalitetsdato – varen kan være god lenger. Lukt og smak før du kaster.",
+ "scan.review.dateKindBestBefore": "Best før",
+ "scan.review.dateKindUseBy": "Siste forbruksdag",
+ "scan.review.datePlaceholder": "ÅÅÅÅ-MM-DD (valgfritt)",
+ "scan.review.itemPlaceholder": "Vare",
+ "scan.review.quantityPlaceholder": "Mengde",
+ "scan.review.rejected": "Fjernet",
+ "scan.review.subtitle": "AI-en er noen ganger usikker – du bestemmer. Endre, fjern eller legg til før du lagrer.",
+ "scan.review.title": "Gå gjennom resultatet",
+ "scan.review.uncertain": "Usikker – sjekk",
+ "scan.review.unitPlaceholder": "Enhet (g, l, stk. …)",
+ "scan.review.unknownItem": "Ukjent vare",
+ "scan.review.useByNote": "Sikkerhetsdato – ikke spis etter denne datoen.",
+ "scan.subtitle": "Fyll matlageret eller loggfør et måltid med kameraet.",
+ "scan.takePhoto": "Ta bilde",
+ "scan.tips.light": "Unngå mørke og skygger",
+ "scan.tips.move": "Flytt varer som skjuler hverandre",
+ "scan.tips.overview": "Start med et oversiktsbilde",
+ "scan.tips.shelf": "Fotografer hylle for hylle",
+ "scan.tips.title": "Slik blir analysen best",
+ "scan.title": "Skann",
"shopping.addPlaceholder": "Legg til vare …",
"shopping.complete": "Avslutt handleturen",
+ "shopping.completedBody_one": "1 vare ble lagt inn i matlageret.",
+ "shopping.completedBody_other": "{count} varer ble lagt inn i matlageret.",
+ "shopping.completedTitle": "Ferdig!",
"shopping.completeNote": "Avkryssede varer legges i matlageret.",
"shopping.empty": "Listen er tom.",
"shopping.estimated": "ca. {amount}",
"shopping.estimatedTotal": "Anslått totalt: ca. {amount}",
- "mealbox.title": "Matbokser",
- "mealbox.eatBy": "Spis innen {date}",
- "mealbox.portionsLeft_one": "1 porsjon igjen",
- "mealbox.portionsLeft_other": "{count} porsjoner igjen",
- "mealbox.eat": "Spis nå",
- "mealbox.empty": "Ingen matbokser akkurat nå. Når du lager mat, kan du lagre porsjoner her.",
- "household.members": "Medlemmer",
- "household.invite": "Inviter med kode: {code}",
- "household.shared": "Deles i husstanden: matlager, handleliste, ukeplan, matbokser og budsjett.",
- "household.private": "Privat per person: mål, allergier, helsedata og måltidshistorikk.",
- "memory.title": "Hva {brand} vet om meg",
- "memory.subtitle": "Full innsikt. Rett feil, sett på pause eller slett – du eier minnet ditt.",
- "memory.paused": "På pause",
- "memory.verify": "Stemmer",
- "memory.pause": "Pause",
- "memory.delete": "Slett",
- "memory.deleteAll": "Slett alt minne",
- "memory.empty": "{brand} har ikke lært noe om deg ennå.",
- "memory.origin.user_stated": "Du har fortalt det",
- "memory.origin.observed": "Observert mønster",
- "memory.origin.ai_inferred": "AI-antakelse",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "Hele husstandens mat-OS: ubegrenset lager, ukeplan og deling.",
- "paywall.trialActive_one": "1 dag igjen av prøveperioden",
- "paywall.trialActive_other": "{days} dager igjen av prøveperioden",
- "paywall.household": "Household · opptil 3 personer",
- "paywall.family": "Family · opptil 6 personer",
- "paywall.large": "Large Household · opptil 12 personer",
- "paywall.perMonth": "{price}/mnd.",
- "paywall.fairUse": "Fair use-kvote for AI-skanninger inkludert.",
- "paywall.restore": "Gjenopprett kjøp",
- "paywall.freeNote": "Gratis: 10 AI-skanninger/mnd., manuelt lager, lagrede oppskrifter og enkel loggføring.",
- "profile.title": "Profil",
- "profile.goals": "Mål & kosthold",
- "profile.consents": "Samtykker & data",
- "profile.memory": "Hva {brand} vet om meg",
- "profile.subscription": "Abonnement",
- "profile.logout": "Logg ut",
- "profile.export": "Eksporter dataene mine",
- "profile.deleteAccount": "Slett konto",
- "profile.language": "Språk",
- "profile.emailUnverified": "E-postadressen er ikke bekreftet",
- "profile.resendVerification": "Send bekreftelses-e-post på nytt",
- "profile.verificationSent": "Sendt! Sjekk innboksen.",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Oi sann",
- "common.undo": "Angre",
- "common.remove": "Fjern",
- "common.add": "Legg til",
- "common.on": "På",
- "common.off": "Av",
- "home.thisWeek": "Denne uken",
- "home.wasteWeek": "Matsvinn denne uken",
- "home.useSoonHint": "Best før handler om kvalitet – lukt, se og smak før du kaster. Siste forbruksdag skal derimot respekteres.",
- "scan.review.itemPlaceholder": "Vare",
- "scan.review.quantityPlaceholder": "Mengde",
- "scan.review.unitPlaceholder": "Enhet (g, l, stk. …)",
- "scan.review.datePlaceholder": "ÅÅÅÅ-MM-DD (valgfritt)",
- "scan.review.dateKindBestBefore": "Best før",
- "scan.review.dateKindUseBy": "Siste forbruksdag",
- "scan.review.bestBeforeNote": "Kvalitetsdato – varen kan være god lenger. Lukt og smak før du kaster.",
- "scan.review.useByNote": "Sikkerhetsdato – ikke spis etter denne datoen.",
- "scan.review.addItem": "+ Legg til vare",
- "scan.review.unknownItem": "Ukjent vare",
- "barcode.aim": "Rett kameraet mot strekkoden",
- "barcode.addPrompt": "Legge til i matlageret?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Ingen næringsdata",
- "barcode.unknownTitle": "Ukjent produkt",
- "barcode.unknownBody": "Produktet er ikke i databasen ennå. Ta bilde av forsiden og næringsdeklarasjonen, så legger vi det til.",
- "barcode.photoPackage": "Ta bilde av pakken",
- "barcode.needHousehold": "Du trenger en husstand først.",
- "barcode.noLocation": "Fant ingen oppbevaringssteder.",
- "barcode.cameraTitle": "Kameraet trengs",
- "barcode.cameraBody": "{brand} trenger kameraet for å skanne strekkoder.",
- "barcode.allowCamera": "Tillat kamera",
- "onboarding.goal.lose_weight": "Gå ned i vekt",
- "onboarding.goal.build_muscle": "Bygge muskler",
- "onboarding.goal.maintain_weight": "Holde vekten",
- "onboarding.goal.more_protein": "Spise mer protein",
- "onboarding.goal.less_waste": "Redusere matsvinn",
- "onboarding.goal.lower_cost": "Bruke mindre på mat",
- "onboarding.goal.cook_more": "Lage mer mat hjemme",
- "onboarding.diet.omnivore": "Alteter",
- "onboarding.diet.flexitarian": "Fleksitarianer",
- "onboarding.diet.pescatarian": "Pescetarianer",
- "onboarding.diet.vegetarian": "Vegetarianer",
- "onboarding.diet.vegan": "Veganer",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Melk/laktose",
- "onboarding.allergen.eggs": "Egg",
- "onboarding.allergen.tree_nuts": "Nøtter",
- "onboarding.allergen.peanuts": "Peanøtter",
- "onboarding.allergen.fish": "Fisk",
- "onboarding.allergen.crustaceans": "Skalldyr",
- "onboarding.allergen.soy": "Soya",
- "onboarding.allergen.sesame": "Sesam",
- "onboarding.bodyTitle": "For personlige kalorimål (valgfritt)",
- "onboarding.weightPlaceholder": "Vekt (kg)",
- "onboarding.heightPlaceholder": "Høyde (cm)",
- "onboarding.birthYearPlaceholder": "Fødselsår",
- "onboarding.householdDefaultName": "Hjemme",
- "onboarding.modesCombine": "Modusene kan kombineres – enkelt til hverdags, nøyaktig når du vil.",
- "myday.mealType.breakfast": "Frokost",
- "myday.mealType.lunch": "Lunsj",
- "myday.mealType.dinner": "Middag",
- "myday.mealType.snack": "Mellommåltid",
- "myday.mealType.dessert": "Dessert",
- "myday.overRecommended": "Over anbefalt",
- "myday.todaysMeals": "Dagens måltider",
- "myday.estimateRange": "{min}–{max} kcal, trolig {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
- "logmeal.mealTypeTitle": "Måltidstype",
- "logmeal.quickTitle": "Rask gjenlogging",
- "logmeal.quickSubtitle": "Logger de samme næringsverdiene som sist.",
- "logmeal.manualTitle": "Manuelt",
- "logmeal.whatPlaceholder": "Hva spiste du?",
- "logmeal.proteinPlaceholder": "protein (g)",
- "logmeal.validationTitle": "Fyll ut",
- "logmeal.validationBody": "Navn og kalorier trengs for manuell logging.",
- "logmeal.photoTip": "Tips: ta bilde av tallerkenen under Skann, så anslår appen for deg – du bekrefter alltid.",
- "shopping.section.frukt_gront": "Frukt & grønt",
"shopping.section.brod": "Brød",
- "shopping.section.mejeri": "Meieri",
- "shopping.section.kott_fagel": "Kjøtt & fjærkre",
- "shopping.section.fisk": "Fisk",
"shopping.section.chark": "Pålegg",
- "shopping.section.frys": "Frys",
- "shopping.section.skafferi": "Tørrvarer",
- "shopping.section.konserver": "Hermetikk",
- "shopping.section.kryddor_bak": "Krydder & baking",
"shopping.section.dryck": "Drikke",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Fisk",
+ "shopping.section.frukt_gront": "Frukt & grønt",
+ "shopping.section.frys": "Frys",
"shopping.section.hygien_ovrigt": "Annet",
- "shopping.completedTitle": "Ferdig!",
- "household.role.owner": "Eier",
- "household.role.adult": "Voksen",
- "household.role.member": "Medlem",
- "household.role.child": "Barn",
- "household.empty": "Du har ingen husstand ennå. Opprett en i onboarding eller bli med via kode.",
- "household.shareCode": "Del koden med familien, så deler dere matlager, liste og plan.",
- "household.locations": "Oppbevaringssteder",
- "household.portionFactor": "×{factor} porsjon",
- "mealbox.enjoyTitle": "Vel bekomme!",
- "mealbox.enjoyBody": "Porsjonen er logget i Min dag.",
- "mealbox.guidanceNote": "Anbefalt frist er veiledende – stol på lukt og smak.",
- "paywall.soonTitle": "Snart!",
- "paywall.soonBody": "Kjøp aktiveres via App Store/Google Play når butikkintegrasjonen slås på (fase 7). Backend-flyten er allerede klar.",
- "paywall.popular": "Mest populær",
- "paywall.choose": "Velg",
- "recipe.saved": "Lagret",
- "recipe.save": "Lagre",
- "recipe.avgRating": "Snitt {avg} av {count} vurderinger",
- "memory.verified": "Bekreftet",
- "memory.resume": "Gjenoppta",
- "memory.deleteAllTitle": "Slette alt minne?",
- "memory.irreversible": "Dette kan ikke angres.",
- "profile.consent.personalization": "Personlige funksjoner (minne & smaksprofil)",
- "profile.consent.anonymized_improvement": "Anonymisert forbedring av AI-en",
- "profile.consent.image_training": "Bildene mine kan brukes til trening",
- "profile.consent.health_integration": "Helsedata (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Posisjon for værbaserte forslag",
- "profile.consent.push_notifications": "Push-varsler",
- "profile.modeLabel": "Modus:",
- "profile.memorySubtitle": "Se, rett, sett på pause eller slett det plattformen har lært.",
- "profile.consentsNote": "Samtykkene er separate – personlige funksjoner krever aldri treningssamtykke.",
- "profile.aiScansUsed": "AI-skanninger: {used} / {total} denne måneden",
- "profile.deleteTitle": "Slette kontoen?",
- "profile.deleteBody": "Alle dataene dine slettes permanent i henhold til GDPR.",
- "cooking.timerDone": "Ferdig!",
- "cooked.deductPantryNote": "Ingrediensene trekkes fra matlageret – det som går ut først, brukes først.",
- "home.moreItems_one": "+ 1 til …",
- "home.moreItems_other": "+ {count} til …",
- "shopping.completedBody_one": "1 vare ble lagt inn i matlageret.",
- "shopping.completedBody_other": "{count} varer ble lagt inn i matlageret.",
- "profile.consent.product_analytics": "Produktanalyse"
+ "shopping.section.konserver": "Hermetikk",
+ "shopping.section.kott_fagel": "Kjøtt & fjærkre",
+ "shopping.section.kryddor_bak": "Krydder & baking",
+ "shopping.section.mejeri": "Meieri",
+ "shopping.section.skafferi": "Tørrvarer",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Handleliste",
+ "tabs.home": "Hjemme",
+ "tabs.myDay": "Min dag",
+ "tabs.scan": "Skann",
+ "tabs.whatToEat": "Hva skal vi spise?",
+ "wte.coverage": "{pct} % hjemme",
+ "wte.cravingPlaceholder": "Jeg har lyst på … (f.eks. kremet, asiatisk, under 500 kcal)",
+ "wte.empty": "Ingen forslag ennå – legg inn litt mat på lageret eller løsne filtrene.",
+ "wte.mealBoxFirst": "Ferdig mat hjemme",
+ "wte.missing": "Mangler: {items}",
+ "wte.refresh": "Nye forslag",
+ "wte.subtitle": "Basert på hva dere har hjemme, hva som snart bør brukes, og hva dere liker.",
+ "wte.title": "Hva skal vi spise?",
+ "wte.whyTitle": "Hvorfor dette forslaget?"
}
diff --git a/apps/mobile/src/locales/nl/common.json b/apps/mobile/src/locales/nl/common.json
index df186da..0e4ded1 100644
--- a/apps/mobile/src/locales/nl/common.json
+++ b/apps/mobile/src/locales/nl/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Laden …",
+ "auth.backToLogin": "Terug naar inloggen",
+ "auth.displayName": "Hoe mogen we je noemen?",
+ "auth.email": "E-mail",
+ "auth.forgotBody": "Vul je e-mailadres in, dan sturen we een link als het account bestaat.",
+ "auth.forgotLink": "Wachtwoord vergeten?",
+ "auth.forgotSentBody": "Als het adres een account heeft, hebben we een link gestuurd die 30 minuten geldig is. Open hem op dit apparaat.",
+ "auth.forgotSentTitle": "Check je inbox",
+ "auth.forgotSubmit": "Link versturen",
+ "auth.forgotTitle": "Wachtwoord opnieuw instellen",
+ "auth.hasAccount": "Al een account? Log in",
+ "auth.login": "Inloggen",
+ "auth.newPassword": "Nieuw wachtwoord (minimaal 10 tekens)",
+ "auth.noAccount": "Nieuw hier? Maak een account",
+ "auth.password": "Wachtwoord",
+ "auth.register": "Account aanmaken",
+ "auth.resetBody": "De link is 30 minuten geldig en eenmalig te gebruiken. Alle apparaten worden uitgelogd.",
+ "auth.resetDoneBody": "Je wachtwoord is gewijzigd. Log in met het nieuwe wachtwoord.",
+ "auth.resetDoneTitle": "Klaar!",
+ "auth.resetSubmit": "Wachtwoord wijzigen",
+ "auth.resetTitle": "Kies een nieuw wachtwoord",
+ "auth.resetTokenPlaceholder": "Plak de code uit de e-mail",
+ "auth.trialNote": "7 dagen volledige toegang – zonder kaart.",
+ "auth.verifyDoneBody": "Bedankt! Je account is geverifieerd.",
+ "auth.verifyDoneTitle": "E-mail bevestigd",
+ "auth.verifyFailedBody": "De link is ongeldig of verlopen. Vraag een nieuwe aan via je profiel.",
+ "auth.verifyFailedTitle": "De link werkte niet",
+ "barcode.addPrompt": "Toevoegen aan de voorraad?",
+ "barcode.aim": "Richt de camera op de streepjescode",
+ "barcode.allowCamera": "Camera toestaan",
+ "barcode.cameraBody": "{brand} heeft de camera nodig om streepjescodes te scannen.",
+ "barcode.cameraTitle": "Camera nodig",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Je hebt eerst een huishouden nodig.",
+ "barcode.noLocation": "Geen bewaarplek gevonden.",
+ "barcode.noNutrition": "Geen voedingswaarden",
+ "barcode.photoPackage": "Fotografeer de verpakking",
+ "barcode.unknownBody": "Dit product staat nog niet in de database. Fotografeer de voorkant en het voedingsetiket, dan voegen we het toe.",
+ "barcode.unknownTitle": "Onbekend product",
+ "common.add": "Toevoegen",
+ "common.back": "Terug",
+ "common.cancel": "Annuleren",
+ "common.done": "Klaar",
"common.error": "Er ging iets mis. Probeer opnieuw.",
+ "common.estimate": "Schatting",
+ "common.loading": "Laden …",
+ "common.next": "Volgende",
+ "common.off": "Uit",
+ "common.offline": "Offline – laatst opgehaalde gegevens",
+ "common.on": "Aan",
+ "common.oops": "Oeps",
+ "common.remove": "Verwijderen",
"common.retry": "Opnieuw proberen",
"common.save": "Opslaan",
- "common.cancel": "Annuleren",
- "common.next": "Volgende",
- "common.back": "Terug",
- "common.done": "Klaar",
"common.skip": "Overslaan",
- "common.offline": "Offline – laatst opgehaalde gegevens",
- "common.estimate": "Schatting",
- "tabs.whatToEat": "Wat eten we?",
- "tabs.scan": "Scannen",
- "tabs.myDay": "Mijn dag",
- "tabs.home": "Thuis",
- "auth.login": "Inloggen",
- "auth.register": "Account aanmaken",
- "auth.email": "E-mail",
- "auth.password": "Wachtwoord",
- "auth.displayName": "Hoe mogen we je noemen?",
- "auth.noAccount": "Nieuw hier? Maak een account",
- "auth.hasAccount": "Al een account? Log in",
- "auth.trialNote": "7 dagen volledige toegang – zonder kaart.",
- "auth.forgotLink": "Wachtwoord vergeten?",
- "auth.forgotTitle": "Wachtwoord opnieuw instellen",
- "auth.forgotBody": "Vul je e-mailadres in, dan sturen we een link als het account bestaat.",
- "auth.forgotSubmit": "Link versturen",
- "auth.forgotSentTitle": "Check je inbox",
- "auth.forgotSentBody": "Als het adres een account heeft, hebben we een link gestuurd die 30 minuten geldig is. Open hem op dit apparaat.",
- "auth.backToLogin": "Terug naar inloggen",
- "auth.resetTitle": "Kies een nieuw wachtwoord",
- "auth.resetBody": "De link is 30 minuten geldig en eenmalig te gebruiken. Alle apparaten worden uitgelogd.",
- "auth.resetTokenPlaceholder": "Plak de code uit de e-mail",
- "auth.newPassword": "Nieuw wachtwoord (minimaal 10 tekens)",
- "auth.resetSubmit": "Wachtwoord wijzigen",
- "auth.resetDoneTitle": "Klaar!",
- "auth.resetDoneBody": "Je wachtwoord is gewijzigd. Log in met het nieuwe wachtwoord.",
- "auth.verifyDoneTitle": "E-mail bevestigd",
- "auth.verifyDoneBody": "Bedankt! Je account is geverifieerd.",
- "auth.verifyFailedTitle": "De link werkte niet",
- "auth.verifyFailedBody": "De link is ongeldig of verlopen. Vraag een nieuwe aan via je profiel.",
- "onboarding.title": "Vertel ons iets over jezelf",
- "onboarding.subtitle": "Alles is optioneel en altijd aan te passen. Hoe meer je invult, hoe beter de suggesties.",
- "onboarding.goal": "Wat is je belangrijkste doel?",
- "onboarding.diet": "Hoe eet je?",
+ "common.undo": "Herstel",
+ "cooked.deductPantry": "Ingrediënten van voorraad afboeken",
+ "cooked.deductPantryNote": "Ingrediënten worden van de voorraad afgeboekt – wat het eerst afloopt, gaat eerst.",
+ "cooked.mealBoxes": "Porties voor meal-prep",
+ "cooked.portionsCooked": "Gekookte porties",
+ "cooked.rate": "Beoordelen",
+ "cooked.title": "Hoe ging het?",
+ "cooked.whoAte": "Wie hebben er gegeten?",
+ "cooking.finish": "Klaar – maaltijd registreren",
+ "cooking.keepAwake": "Het scherm blijft aan tijdens het koken",
+ "cooking.scale": "Porties",
+ "cooking.step": "Stap {current} van {total}",
+ "cooking.timer": "Timer starten",
+ "cooking.timerDone": "Klaar!",
+ "cooking.timerRunning": "{time} over",
+ "home.budget": "Voedselbudget",
+ "home.emptyInventory": "De voorraad is leeg. Scan de koelkast of voeg handmatig toe.",
+ "home.expired": "Verlopen",
+ "home.expiresIn_one": "Nog 1 dag",
+ "home.expiresIn_other": "Nog {days} dagen",
+ "home.expiresToday": "Verloopt vandaag",
+ "home.household": "Huishouden",
+ "home.inventory": "Voorraad",
+ "home.mealBoxes": "Meal-prep bakjes",
+ "home.moreItems_one": "+ nog 1 …",
+ "home.moreItems_other": "+ nog {count} …",
+ "home.pastBestBefore": "THT verstreken – eerst ruiken en proeven",
+ "home.shopping": "Boodschappenlijst",
+ "home.thisWeek": "Deze week",
+ "home.title": "Thuis",
+ "home.useSoon": "Snel gebruiken",
+ "home.useSoonHint": "THT gaat over kwaliteit – ruik, kijk en proef voordat je iets weggooit. De TGT-datum (te gebruiken tot) moet je wél respecteren.",
+ "home.waste": "Voedselverspilling",
+ "home.wasteWeek": "Verspilling deze week",
+ "household.empty": "Je hebt nog geen huishouden. Maak er een aan in de onboarding of doe mee met een code.",
+ "household.invite": "Nodig uit met code: {code}",
+ "household.locations": "Bewaarplekken",
+ "household.members": "Leden",
+ "household.portionFactor": "×{factor} portie",
+ "household.private": "Privé per persoon: doelen, allergieën, gezondheidsgegevens en maaltijdgeschiedenis.",
+ "household.role.adult": "Volwassene",
+ "household.role.child": "Kind",
+ "household.role.member": "Lid",
+ "household.role.owner": "Eigenaar",
+ "household.shareCode": "Deel de code met je gezin om voorraad, lijst en planning te delen.",
+ "household.shared": "Gedeeld in het huishouden: voorraad, boodschappenlijst, weekplanning, bakjes en budget.",
+ "logmeal.manualTitle": "Handmatig",
+ "logmeal.mealTypeTitle": "Maaltijdtype",
+ "logmeal.photoTip": "Tip: fotografeer je bord onder Scannen en de app schat het voor je – jij bevestigt altijd.",
+ "logmeal.proteinPlaceholder": "eiwit (g)",
+ "logmeal.quickSubtitle": "Logt dezelfde voedingswaarden als de vorige keer.",
+ "logmeal.quickTitle": "Snel opnieuw loggen",
+ "logmeal.validationBody": "Naam en calorieën zijn nodig voor handmatig loggen.",
+ "logmeal.validationTitle": "Vul in",
+ "logmeal.whatPlaceholder": "Wat heb je gegeten?",
+ "mealbox.eat": "Nu eten",
+ "mealbox.eatBy": "Eten vóór {date}",
+ "mealbox.empty": "Momenteel geen bakjes. Tijdens het koken kun je hier porties bewaren.",
+ "mealbox.enjoyBody": "De portie is gelogd in Mijn dag.",
+ "mealbox.enjoyTitle": "Eet smakelijk!",
+ "mealbox.guidanceNote": "De aanbevolen termijn is een richtlijn – vertrouw op geur en smaak.",
+ "mealbox.portionsLeft_one": "Nog 1 portie",
+ "mealbox.portionsLeft_other": "Nog {count} porties",
+ "mealbox.title": "Meal-prep bakjes",
+ "memory.delete": "Verwijderen",
+ "memory.deleteAll": "Volledig geheugen wissen",
+ "memory.deleteAllTitle": "Alle geheugen wissen?",
+ "memory.empty": "{brand} heeft nog niets over je geleerd.",
+ "memory.irreversible": "Dit kan niet ongedaan worden gemaakt.",
+ "memory.origin.ai_inferred": "AI-aanname",
+ "memory.origin.observed": "Waargenomen patroon",
+ "memory.origin.user_stated": "Zelf verteld",
+ "memory.pause": "Pauzeren",
+ "memory.paused": "Gepauzeerd",
+ "memory.resume": "Hervatten",
+ "memory.subtitle": "Volledige transparantie. Corrigeer, pauzeer of verwijder – jouw geheugen is van jou.",
+ "memory.title": "Wat {brand} over mij weet",
+ "memory.verified": "Geverifieerd",
+ "memory.verify": "Klopt",
+ "myday.calories": "Calorieën",
+ "myday.carbs": "Koolhydraten",
+ "myday.estimateNote": "Waarden met ~ zijn schattingen die je kunt aanpassen.",
+ "myday.estimateRange": "{min}–{max} kcal, waarschijnlijk {kcal}",
+ "myday.fat": "Vetten",
+ "myday.fiber": "Vezels",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g eiwit",
+ "myday.logMeal": "Maaltijd registreren",
+ "myday.mealType.breakfast": "Ontbijt",
+ "myday.mealType.dessert": "Toetje",
+ "myday.mealType.dinner": "Avondeten",
+ "myday.mealType.lunch": "Lunch",
+ "myday.mealType.snack": "Tussendoortje",
+ "myday.noMeals": "Vandaag nog geen maaltijden geregistreerd.",
+ "myday.over": "{kcal} kcal boven je doel",
+ "myday.overRecommended": "Boven aanbevolen",
+ "myday.protein": "Eiwitten",
+ "myday.remaining": "{kcal} kcal over",
+ "myday.salt": "Zout",
+ "myday.targetsNote": "Doelen zijn richtlijnen, geen medisch advies.",
+ "myday.title": "Mijn dag",
+ "myday.todaysMeals": "Maaltijden van vandaag",
+ "onboarding.allergen.crustaceans": "Schaaldieren",
+ "onboarding.allergen.eggs": "Eieren",
+ "onboarding.allergen.fish": "Vis",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Melk/lactose",
+ "onboarding.allergen.peanuts": "Pinda's",
+ "onboarding.allergen.sesame": "Sesam",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Noten",
"onboarding.allergies": "Allergieën en intoleranties",
"onboarding.allergyNote": "Het allergiefilter is altijd strikt – gerechten met jouw allergenen worden nooit getoond.",
+ "onboarding.birthYearPlaceholder": "Geboortejaar",
+ "onboarding.bodyTitle": "Voor persoonlijke caloriedoelen (optioneel)",
+ "onboarding.diet": "Hoe eet je?",
+ "onboarding.diet.flexitarian": "Flexitariër",
+ "onboarding.diet.omnivore": "Alleseter",
+ "onboarding.diet.pescatarian": "Pescotariër",
+ "onboarding.diet.vegan": "Veganist",
+ "onboarding.diet.vegetarian": "Vegetariër",
+ "onboarding.goal": "Wat is je belangrijkste doel?",
+ "onboarding.goal.build_muscle": "Spieren opbouwen",
+ "onboarding.goal.cook_more": "Vaker thuis koken",
+ "onboarding.goal.less_waste": "Minder verspillen",
+ "onboarding.goal.lose_weight": "Afvallen",
+ "onboarding.goal.lower_cost": "Minder uitgeven aan eten",
+ "onboarding.goal.maintain_weight": "Op gewicht blijven",
+ "onboarding.goal.more_protein": "Meer eiwitten eten",
+ "onboarding.heightPlaceholder": "Lengte (cm)",
"onboarding.household": "Jouw huishouden",
"onboarding.householdCreate": "Huishouden aanmaken",
+ "onboarding.householdDefaultName": "Thuis",
"onboarding.householdJoin": "Deelnemen met code",
"onboarding.householdName": "Naam van het huishouden",
"onboarding.inviteCode": "Uitnodigingscode",
"onboarding.mode": "Hoe precies wil je het?",
- "onboarding.modeSimple": "Simpele modus",
- "onboarding.modeSimpleDesc": "Fotografeer je eten, accepteer schattingen, minimaal gedoe.",
"onboarding.modeExact": "Exacte modus",
"onboarding.modeExactDesc": "Weeg je eten, voer grammen in, volledige controle over de cijfers.",
+ "onboarding.modesCombine": "De standen zijn te combineren – simpel in het dagelijks leven, exact wanneer je wilt.",
+ "onboarding.modeSimple": "Simpele modus",
+ "onboarding.modeSimpleDesc": "Fotografeer je eten, accepteer schattingen, minimaal gedoe.",
"onboarding.notMedical": "{brand} geeft richtlijnen – geen medisch advies.",
- "wte.title": "Wat eten we?",
- "wte.subtitle": "Op basis van wat jullie in huis hebben, wat snel op moet en wat jullie lekker vinden.",
- "wte.cravingPlaceholder": "Ik heb zin in … (bijv. romig, Aziatisch, onder 500 kcal)",
- "wte.mealBoxFirst": "Kant-en-klaar eten in huis",
- "wte.whyTitle": "Waarom deze suggestie?",
- "wte.coverage": "{pct}% in huis",
- "wte.missing": "Ontbreekt: {items}",
- "wte.empty": "Nog geen suggesties – vul de voorraad aan of versoepel de filters.",
- "wte.refresh": "Nieuwe suggesties",
- "scan.title": "Scannen",
- "scan.subtitle": "Vul je voorraad aan of registreer een maaltijd met de camera.",
- "scan.fridge": "Koelkast",
- "scan.freezer": "Vriezer",
- "scan.pantry": "Voorraadkast",
- "scan.ingredients": "Ingrediënten",
- "scan.plate": "Bord",
- "scan.receipt": "Kassabon",
- "scan.barcode": "Barcode",
- "scan.expiry": "THT-datum",
- "scan.nutrition": "Voedingswaarde-etiket",
- "scan.takePhoto": "Foto maken",
- "scan.tips.title": "Zo lukt de analyse het best",
- "scan.tips.overview": "Begin met een overzichtsfoto",
- "scan.tips.shelf": "Fotografeer plank voor plank",
- "scan.tips.light": "Vermijd donker en schaduw",
- "scan.tips.move": "Verplaats producten die elkaar bedekken",
- "scan.analyzing": "Analyseren …",
- "scan.quotaLeft_one": "1 AI-scan over deze maand",
- "scan.quotaLeft_other": "{count} AI-scans over deze maand",
- "scan.review.title": "Controleer het resultaat",
- "scan.review.subtitle": "De AI twijfelt soms – jij beslist. Pas aan, verwijder of vul aan vóór het opslaan.",
- "scan.review.uncertain": "Onzeker – controleer",
- "scan.review.approveAll": "Opslaan in voorraad",
- "scan.review.rejected": "Verwijderd",
- "scan.failed": "De analyse is mislukt. Probeer opnieuw of voer handmatig in.",
- "myday.title": "Mijn dag",
- "myday.calories": "Calorieën",
- "myday.protein": "Eiwitten",
- "myday.carbs": "Koolhydraten",
- "myday.fat": "Vetten",
- "myday.fiber": "Vezels",
- "myday.salt": "Zout",
- "myday.remaining": "{kcal} kcal over",
- "myday.over": "{kcal} kcal boven je doel",
- "myday.logMeal": "Maaltijd registreren",
- "myday.noMeals": "Vandaag nog geen maaltijden geregistreerd.",
- "myday.estimateNote": "Waarden met ~ zijn schattingen die je kunt aanpassen.",
- "myday.targetsNote": "Doelen zijn richtlijnen, geen medisch advies.",
- "home.title": "Thuis",
- "home.inventory": "Voorraad",
- "home.useSoon": "Snel gebruiken",
- "home.mealBoxes": "Meal-prep bakjes",
- "home.shopping": "Boodschappenlijst",
- "home.budget": "Voedselbudget",
- "home.household": "Huishouden",
- "home.waste": "Voedselverspilling",
- "home.emptyInventory": "De voorraad is leeg. Scan de koelkast of voeg handmatig toe.",
- "home.expiresIn_one": "Nog 1 dag",
- "home.expiresIn_other": "Nog {days} dagen",
- "home.expiresToday": "Verloopt vandaag",
- "home.expired": "Verlopen",
- "home.pastBestBefore": "THT verstreken – eerst ruiken en proeven",
+ "onboarding.stepBSubtitle": "Pas je profiel aan voor betere suggesties.",
+ "onboarding.stepBTitle": "Doorgaan met instellen",
+ "onboarding.stepCSubtitle": "Optioneel – gebruikt voor persoonlijke calorie-doelen.",
+ "onboarding.stepCTitle": "Je gezondheidsprofiel",
+ "onboarding.subtitle": "Alles is optioneel en altijd aan te passen. Hoe meer je invult, hoe beter de suggesties.",
+ "onboarding.title": "Vertel ons iets over jezelf",
+ "onboarding.weightPlaceholder": "Gewicht (kg)",
+ "paywall.choose": "Kies",
+ "paywall.fairUse": "Fair-use quotum voor AI-scans inbegrepen.",
+ "paywall.family": "Family · tot 6 personen",
+ "paywall.freeNote": "Gratis: 10 AI-scans/maand, handmatige voorraad, opgeslagen recepten en eenvoudig registreren.",
+ "paywall.household": "Household · tot 3 personen",
+ "paywall.large": "Large Household · tot 12 personen",
+ "paywall.perMonth": "{price}/maand",
+ "paywall.popular": "Populairst",
+ "paywall.restore": "Aankopen herstellen",
+ "paywall.soonBody": "Aankopen lopen via de App Store/Google Play zodra de winkelintegratie aanstaat (fase 7). De backend is al klaar.",
+ "paywall.soonTitle": "Binnenkort!",
+ "paywall.subtitle": "Het voedsel-OS van het hele huishouden: onbeperkte voorraad, weekplanning en delen.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "Nog 1 dag proefperiode",
+ "paywall.trialActive_other": "Nog {days} dagen proefperiode",
+ "profile.aiScansUsed": "AI-scans: {used} / {total} deze maand",
+ "profile.consent.anonymized_improvement": "Geanonimiseerde verbetering van de AI",
+ "profile.consent.health_integration": "Gezondheidsgegevens (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Mijn foto's mogen voor training worden gebruikt",
+ "profile.consent.location_weather": "Locatie voor weersuggesties",
+ "profile.consent.personalization": "Persoonlijke functies (geheugen & smaakprofiel)",
+ "profile.consent.product_analytics": "Productanalyse",
+ "profile.consent.push_notifications": "Pushmeldingen",
+ "profile.consents": "Toestemmingen & gegevens",
+ "profile.consentsNote": "Toestemmingen zijn gescheiden – persoonlijke functies vereisen nooit trainingstoestemming.",
+ "profile.deleteAccount": "Account verwijderen",
+ "profile.deleteBody": "Al je gegevens worden permanent verwijderd volgens de AVG.",
+ "profile.deleteTitle": "Account verwijderen?",
+ "profile.emailUnverified": "E-mailadres niet bevestigd",
+ "profile.export": "Mijn gegevens exporteren",
+ "profile.goals": "Doelen & voeding",
+ "profile.language": "Taal",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Uitloggen",
+ "profile.memory": "Wat {brand} over mij weet",
+ "profile.memorySubtitle": "Bekijk, corrigeer, pauzeer of wis wat het platform heeft geleerd.",
+ "profile.modeLabel": "Modus:",
+ "profile.resendVerification": "Bevestigingsmail opnieuw sturen",
+ "profile.subscription": "Abonnement",
+ "profile.title": "Profiel",
+ "profile.verificationSent": "Verstuurd! Check je inbox.",
+ "recipe.avgRating": "Gemiddeld {avg} uit {count} beoordelingen",
+ "recipe.cook": "Nu koken",
+ "recipe.cost": "ca. {amount}/portie",
+ "recipe.iCookedThis": "Dit heb ik gekookt",
+ "recipe.ingredients": "Ingrediënten",
+ "recipe.notSafe": "Past niet bij je voedingsinstellingen",
+ "recipe.perPortion": "per portie",
"recipe.portions_one": "1 portie",
"recipe.portions_other": "{count} porties",
- "recipe.time": "{min} min",
- "recipe.perPortion": "per portie",
- "recipe.ingredients": "Ingrediënten",
+ "recipe.save": "Opslaan",
+ "recipe.saved": "Opgeslagen",
"recipe.steps": "Bereiding",
- "recipe.cook": "Nu koken",
- "recipe.notSafe": "Past niet bij je voedingsinstellingen",
"recipe.substitutions": "Vervangen",
- "recipe.iCookedThis": "Dit heb ik gekookt",
- "recipe.cost": "ca. {amount}/portie",
- "cooking.step": "Stap {current} van {total}",
- "cooking.timer": "Timer starten",
- "cooking.timerRunning": "{time} over",
- "cooking.finish": "Klaar – maaltijd registreren",
- "cooking.scale": "Porties",
- "cooking.keepAwake": "Het scherm blijft aan tijdens het koken",
- "cooked.title": "Hoe ging het?",
- "cooked.portionsCooked": "Gekookte porties",
- "cooked.whoAte": "Wie hebben er gegeten?",
- "cooked.mealBoxes": "Porties voor meal-prep",
- "cooked.deductPantry": "Ingrediënten van voorraad afboeken",
- "cooked.rate": "Beoordelen",
- "shopping.title": "Boodschappenlijst",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analyseren …",
+ "scan.barcode": "Barcode",
+ "scan.expiry": "THT-datum",
+ "scan.failed": "De analyse is mislukt. Probeer opnieuw of voer handmatig in.",
+ "scan.freezer": "Vriezer",
+ "scan.fridge": "Koelkast",
+ "scan.ingredients": "Ingrediënten",
+ "scan.nutrition": "Voedingswaarde-etiket",
+ "scan.pantry": "Voorraadkast",
+ "scan.plate": "Bord",
+ "scan.quotaLeft_one": "1 AI-scan over deze maand",
+ "scan.quotaLeft_other": "{count} AI-scans over deze maand",
+ "scan.receipt": "Kassabon",
+ "scan.review.addItem": "+ Product toevoegen",
+ "scan.review.approveAll": "Opslaan in voorraad",
+ "scan.review.bestBeforeNote": "Kwaliteitsdatum – vaak nog prima daarna. Ruik en proef voordat je weggooit.",
+ "scan.review.dateKindBestBefore": "THT (ten minste houdbaar tot)",
+ "scan.review.dateKindUseBy": "TGT (te gebruiken tot)",
+ "scan.review.datePlaceholder": "JJJJ-MM-DD (optioneel)",
+ "scan.review.itemPlaceholder": "Product",
+ "scan.review.quantityPlaceholder": "Hoeveelheid",
+ "scan.review.rejected": "Verwijderd",
+ "scan.review.subtitle": "De AI twijfelt soms – jij beslist. Pas aan, verwijder of vul aan vóór het opslaan.",
+ "scan.review.title": "Controleer het resultaat",
+ "scan.review.uncertain": "Onzeker – controleer",
+ "scan.review.unitPlaceholder": "Eenheid (g, l, st. …)",
+ "scan.review.unknownItem": "Onbekend product",
+ "scan.review.useByNote": "Veiligheidsdatum – niet meer eten na deze datum.",
+ "scan.subtitle": "Vul je voorraad aan of registreer een maaltijd met de camera.",
+ "scan.takePhoto": "Foto maken",
+ "scan.tips.light": "Vermijd donker en schaduw",
+ "scan.tips.move": "Verplaats producten die elkaar bedekken",
+ "scan.tips.overview": "Begin met een overzichtsfoto",
+ "scan.tips.shelf": "Fotografeer plank voor plank",
+ "scan.tips.title": "Zo lukt de analyse het best",
+ "scan.title": "Scannen",
"shopping.addPlaceholder": "Product toevoegen …",
"shopping.complete": "Boodschappen afronden",
+ "shopping.completedBody_one": "1 product is aan de voorraad toegevoegd.",
+ "shopping.completedBody_other": "{count} producten zijn aan de voorraad toegevoegd.",
+ "shopping.completedTitle": "Klaar!",
"shopping.completeNote": "Afgevinkte producten gaan naar de voorraad.",
"shopping.empty": "De lijst is leeg.",
"shopping.estimated": "ca. {amount}",
"shopping.estimatedTotal": "Geschat totaal: ca. {amount}",
- "mealbox.title": "Meal-prep bakjes",
- "mealbox.eatBy": "Eten vóór {date}",
- "mealbox.portionsLeft_one": "Nog 1 portie",
- "mealbox.portionsLeft_other": "Nog {count} porties",
- "mealbox.eat": "Nu eten",
- "mealbox.empty": "Momenteel geen bakjes. Tijdens het koken kun je hier porties bewaren.",
- "household.members": "Leden",
- "household.invite": "Nodig uit met code: {code}",
- "household.shared": "Gedeeld in het huishouden: voorraad, boodschappenlijst, weekplanning, bakjes en budget.",
- "household.private": "Privé per persoon: doelen, allergieën, gezondheidsgegevens en maaltijdgeschiedenis.",
- "memory.title": "Wat {brand} over mij weet",
- "memory.subtitle": "Volledige transparantie. Corrigeer, pauzeer of verwijder – jouw geheugen is van jou.",
- "memory.paused": "Gepauzeerd",
- "memory.verify": "Klopt",
- "memory.pause": "Pauzeren",
- "memory.delete": "Verwijderen",
- "memory.deleteAll": "Volledig geheugen wissen",
- "memory.empty": "{brand} heeft nog niets over je geleerd.",
- "memory.origin.user_stated": "Zelf verteld",
- "memory.origin.observed": "Waargenomen patroon",
- "memory.origin.ai_inferred": "AI-aanname",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "Het voedsel-OS van het hele huishouden: onbeperkte voorraad, weekplanning en delen.",
- "paywall.trialActive_one": "Nog 1 dag proefperiode",
- "paywall.trialActive_other": "Nog {days} dagen proefperiode",
- "paywall.household": "Household · tot 3 personen",
- "paywall.family": "Family · tot 6 personen",
- "paywall.large": "Large Household · tot 12 personen",
- "paywall.perMonth": "{price}/maand",
- "paywall.fairUse": "Fair-use quotum voor AI-scans inbegrepen.",
- "paywall.restore": "Aankopen herstellen",
- "paywall.freeNote": "Gratis: 10 AI-scans/maand, handmatige voorraad, opgeslagen recepten en eenvoudig registreren.",
- "profile.title": "Profiel",
- "profile.goals": "Doelen & voeding",
- "profile.consents": "Toestemmingen & gegevens",
- "profile.memory": "Wat {brand} over mij weet",
- "profile.subscription": "Abonnement",
- "profile.logout": "Uitloggen",
- "profile.export": "Mijn gegevens exporteren",
- "profile.deleteAccount": "Account verwijderen",
- "profile.language": "Taal",
- "profile.emailUnverified": "E-mailadres niet bevestigd",
- "profile.resendVerification": "Bevestigingsmail opnieuw sturen",
- "profile.verificationSent": "Verstuurd! Check je inbox.",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Oeps",
- "common.undo": "Herstel",
- "common.remove": "Verwijderen",
- "common.add": "Toevoegen",
- "common.on": "Aan",
- "common.off": "Uit",
- "home.thisWeek": "Deze week",
- "home.wasteWeek": "Verspilling deze week",
- "home.useSoonHint": "THT gaat over kwaliteit – ruik, kijk en proef voordat je iets weggooit. De TGT-datum (te gebruiken tot) moet je wél respecteren.",
- "scan.review.itemPlaceholder": "Product",
- "scan.review.quantityPlaceholder": "Hoeveelheid",
- "scan.review.unitPlaceholder": "Eenheid (g, l, st. …)",
- "scan.review.datePlaceholder": "JJJJ-MM-DD (optioneel)",
- "scan.review.dateKindBestBefore": "THT (ten minste houdbaar tot)",
- "scan.review.dateKindUseBy": "TGT (te gebruiken tot)",
- "scan.review.bestBeforeNote": "Kwaliteitsdatum – vaak nog prima daarna. Ruik en proef voordat je weggooit.",
- "scan.review.useByNote": "Veiligheidsdatum – niet meer eten na deze datum.",
- "scan.review.addItem": "+ Product toevoegen",
- "scan.review.unknownItem": "Onbekend product",
- "barcode.aim": "Richt de camera op de streepjescode",
- "barcode.addPrompt": "Toevoegen aan de voorraad?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Geen voedingswaarden",
- "barcode.unknownTitle": "Onbekend product",
- "barcode.unknownBody": "Dit product staat nog niet in de database. Fotografeer de voorkant en het voedingsetiket, dan voegen we het toe.",
- "barcode.photoPackage": "Fotografeer de verpakking",
- "barcode.needHousehold": "Je hebt eerst een huishouden nodig.",
- "barcode.noLocation": "Geen bewaarplek gevonden.",
- "barcode.cameraTitle": "Camera nodig",
- "barcode.cameraBody": "{brand} heeft de camera nodig om streepjescodes te scannen.",
- "barcode.allowCamera": "Camera toestaan",
- "onboarding.goal.lose_weight": "Afvallen",
- "onboarding.goal.build_muscle": "Spieren opbouwen",
- "onboarding.goal.maintain_weight": "Op gewicht blijven",
- "onboarding.goal.more_protein": "Meer eiwitten eten",
- "onboarding.goal.less_waste": "Minder verspillen",
- "onboarding.goal.lower_cost": "Minder uitgeven aan eten",
- "onboarding.goal.cook_more": "Vaker thuis koken",
- "onboarding.diet.omnivore": "Alleseter",
- "onboarding.diet.flexitarian": "Flexitariër",
- "onboarding.diet.pescatarian": "Pescotariër",
- "onboarding.diet.vegetarian": "Vegetariër",
- "onboarding.diet.vegan": "Veganist",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Melk/lactose",
- "onboarding.allergen.eggs": "Eieren",
- "onboarding.allergen.tree_nuts": "Noten",
- "onboarding.allergen.peanuts": "Pinda's",
- "onboarding.allergen.fish": "Vis",
- "onboarding.allergen.crustaceans": "Schaaldieren",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sesam",
- "onboarding.bodyTitle": "Voor persoonlijke caloriedoelen (optioneel)",
- "onboarding.weightPlaceholder": "Gewicht (kg)",
- "onboarding.heightPlaceholder": "Lengte (cm)",
- "onboarding.birthYearPlaceholder": "Geboortejaar",
- "onboarding.householdDefaultName": "Thuis",
- "onboarding.modesCombine": "De standen zijn te combineren – simpel in het dagelijks leven, exact wanneer je wilt.",
- "myday.mealType.breakfast": "Ontbijt",
- "myday.mealType.lunch": "Lunch",
- "myday.mealType.dinner": "Avondeten",
- "myday.mealType.snack": "Tussendoortje",
- "myday.mealType.dessert": "Toetje",
- "myday.overRecommended": "Boven aanbevolen",
- "myday.todaysMeals": "Maaltijden van vandaag",
- "myday.estimateRange": "{min}–{max} kcal, waarschijnlijk {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g eiwit",
- "logmeal.mealTypeTitle": "Maaltijdtype",
- "logmeal.quickTitle": "Snel opnieuw loggen",
- "logmeal.quickSubtitle": "Logt dezelfde voedingswaarden als de vorige keer.",
- "logmeal.manualTitle": "Handmatig",
- "logmeal.whatPlaceholder": "Wat heb je gegeten?",
- "logmeal.proteinPlaceholder": "eiwit (g)",
- "logmeal.validationTitle": "Vul in",
- "logmeal.validationBody": "Naam en calorieën zijn nodig voor handmatig loggen.",
- "logmeal.photoTip": "Tip: fotografeer je bord onder Scannen en de app schat het voor je – jij bevestigt altijd.",
- "shopping.section.frukt_gront": "Groente & fruit",
"shopping.section.brod": "Brood",
- "shopping.section.mejeri": "Zuivel",
- "shopping.section.kott_fagel": "Vlees & gevogelte",
- "shopping.section.fisk": "Vis",
"shopping.section.chark": "Vleeswaren",
- "shopping.section.frys": "Diepvries",
- "shopping.section.skafferi": "Voorraadkast",
- "shopping.section.konserver": "Conserven",
- "shopping.section.kryddor_bak": "Kruiden & bakken",
"shopping.section.dryck": "Dranken",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Vis",
+ "shopping.section.frukt_gront": "Groente & fruit",
+ "shopping.section.frys": "Diepvries",
"shopping.section.hygien_ovrigt": "Overig",
- "shopping.completedTitle": "Klaar!",
- "household.role.owner": "Eigenaar",
- "household.role.adult": "Volwassene",
- "household.role.member": "Lid",
- "household.role.child": "Kind",
- "household.empty": "Je hebt nog geen huishouden. Maak er een aan in de onboarding of doe mee met een code.",
- "household.shareCode": "Deel de code met je gezin om voorraad, lijst en planning te delen.",
- "household.locations": "Bewaarplekken",
- "household.portionFactor": "×{factor} portie",
- "mealbox.enjoyTitle": "Eet smakelijk!",
- "mealbox.enjoyBody": "De portie is gelogd in Mijn dag.",
- "mealbox.guidanceNote": "De aanbevolen termijn is een richtlijn – vertrouw op geur en smaak.",
- "paywall.soonTitle": "Binnenkort!",
- "paywall.soonBody": "Aankopen lopen via de App Store/Google Play zodra de winkelintegratie aanstaat (fase 7). De backend is al klaar.",
- "paywall.popular": "Populairst",
- "paywall.choose": "Kies",
- "recipe.saved": "Opgeslagen",
- "recipe.save": "Opslaan",
- "recipe.avgRating": "Gemiddeld {avg} uit {count} beoordelingen",
- "memory.verified": "Geverifieerd",
- "memory.resume": "Hervatten",
- "memory.deleteAllTitle": "Alle geheugen wissen?",
- "memory.irreversible": "Dit kan niet ongedaan worden gemaakt.",
- "profile.consent.personalization": "Persoonlijke functies (geheugen & smaakprofiel)",
- "profile.consent.anonymized_improvement": "Geanonimiseerde verbetering van de AI",
- "profile.consent.image_training": "Mijn foto's mogen voor training worden gebruikt",
- "profile.consent.health_integration": "Gezondheidsgegevens (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Locatie voor weersuggesties",
- "profile.consent.push_notifications": "Pushmeldingen",
- "profile.modeLabel": "Modus:",
- "profile.memorySubtitle": "Bekijk, corrigeer, pauzeer of wis wat het platform heeft geleerd.",
- "profile.consentsNote": "Toestemmingen zijn gescheiden – persoonlijke functies vereisen nooit trainingstoestemming.",
- "profile.aiScansUsed": "AI-scans: {used} / {total} deze maand",
- "profile.deleteTitle": "Account verwijderen?",
- "profile.deleteBody": "Al je gegevens worden permanent verwijderd volgens de AVG.",
- "cooking.timerDone": "Klaar!",
- "cooked.deductPantryNote": "Ingrediënten worden van de voorraad afgeboekt – wat het eerst afloopt, gaat eerst.",
- "home.moreItems_one": "+ nog 1 …",
- "home.moreItems_other": "+ nog {count} …",
- "shopping.completedBody_one": "1 product is aan de voorraad toegevoegd.",
- "shopping.completedBody_other": "{count} producten zijn aan de voorraad toegevoegd.",
- "profile.consent.product_analytics": "Productanalyse"
+ "shopping.section.konserver": "Conserven",
+ "shopping.section.kott_fagel": "Vlees & gevogelte",
+ "shopping.section.kryddor_bak": "Kruiden & bakken",
+ "shopping.section.mejeri": "Zuivel",
+ "shopping.section.skafferi": "Voorraadkast",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Boodschappenlijst",
+ "tabs.home": "Thuis",
+ "tabs.myDay": "Mijn dag",
+ "tabs.scan": "Scannen",
+ "tabs.whatToEat": "Wat eten we?",
+ "wte.coverage": "{pct}% in huis",
+ "wte.cravingPlaceholder": "Ik heb zin in … (bijv. romig, Aziatisch, onder 500 kcal)",
+ "wte.empty": "Nog geen suggesties – vul de voorraad aan of versoepel de filters.",
+ "wte.mealBoxFirst": "Kant-en-klaar eten in huis",
+ "wte.missing": "Ontbreekt: {items}",
+ "wte.refresh": "Nieuwe suggesties",
+ "wte.subtitle": "Op basis van wat jullie in huis hebben, wat snel op moet en wat jullie lekker vinden.",
+ "wte.title": "Wat eten we?",
+ "wte.whyTitle": "Waarom deze suggestie?"
}
diff --git a/apps/mobile/src/locales/pl/common.json b/apps/mobile/src/locales/pl/common.json
index dfe7517..f991f4c 100644
--- a/apps/mobile/src/locales/pl/common.json
+++ b/apps/mobile/src/locales/pl/common.json
@@ -1,353 +1,357 @@
{
- "common.loading": "Ładowanie …",
+ "auth.backToLogin": "Wróć do logowania",
+ "auth.displayName": "Jak mamy się do Ciebie zwracać?",
+ "auth.email": "E-mail",
+ "auth.forgotBody": "Podaj swój e-mail, a wyślemy link, jeśli konto istnieje.",
+ "auth.forgotLink": "Nie pamiętasz hasła?",
+ "auth.forgotSentBody": "Jeśli adres ma konto, wysłaliśmy link ważny 30 minut. Otwórz go na tym urządzeniu.",
+ "auth.forgotSentTitle": "Sprawdź skrzynkę",
+ "auth.forgotSubmit": "Wyślij link",
+ "auth.forgotTitle": "Zresetuj hasło",
+ "auth.hasAccount": "Masz już konto? Zaloguj się",
+ "auth.login": "Zaloguj się",
+ "auth.newPassword": "Nowe hasło (min. 10 znaków)",
+ "auth.noAccount": "Nowy tutaj? Utwórz konto",
+ "auth.password": "Hasło",
+ "auth.register": "Utwórz konto",
+ "auth.resetBody": "Link jest ważny 30 minut i można go użyć tylko raz. Wszystkie urządzenia zostaną wylogowane.",
+ "auth.resetDoneBody": "Hasło zostało zmienione. Zaloguj się nowym hasłem.",
+ "auth.resetDoneTitle": "Gotowe!",
+ "auth.resetSubmit": "Zmień hasło",
+ "auth.resetTitle": "Wybierz nowe hasło",
+ "auth.resetTokenPlaceholder": "Wklej kod z e-maila",
+ "auth.trialNote": "7 dni pełnego dostępu – bez karty.",
+ "auth.verifyDoneBody": "Dziękujemy! Twoje konto jest zweryfikowane.",
+ "auth.verifyDoneTitle": "E-mail potwierdzony",
+ "auth.verifyFailedBody": "Link jest nieprawidłowy lub wygasł. Poproś o nowy w profilu.",
+ "auth.verifyFailedTitle": "Link nie zadziałał",
+ "barcode.addPrompt": "Dodać do spiżarni?",
+ "barcode.aim": "Skieruj aparat na kod kreskowy",
+ "barcode.allowCamera": "Zezwól na aparat",
+ "barcode.cameraBody": "{brand} potrzebuje aparatu do skanowania kodów kreskowych.",
+ "barcode.cameraTitle": "Potrzebny aparat",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Najpierw potrzebujesz gospodarstwa.",
+ "barcode.noLocation": "Nie znaleziono miejsca przechowywania.",
+ "barcode.noNutrition": "Brak danych żywieniowych",
+ "barcode.photoPackage": "Sfotografuj opakowanie",
+ "barcode.unknownBody": "Tego produktu nie ma jeszcze w bazie. Sfotografuj przód i etykietę wartości odżywczych, a my go dodamy.",
+ "barcode.unknownTitle": "Nieznany produkt",
+ "common.add": "Dodaj",
+ "common.back": "Wstecz",
+ "common.cancel": "Anuluj",
+ "common.done": "Gotowe",
"common.error": "Coś poszło nie tak. Spróbuj ponownie.",
+ "common.estimate": "Szacunek",
+ "common.loading": "Ładowanie …",
+ "common.next": "Dalej",
+ "common.off": "Wył.",
+ "common.offline": "Offline – ostatnio pobrane dane",
+ "common.on": "Wł.",
+ "common.oops": "Ups",
+ "common.remove": "Usuń",
"common.retry": "Spróbuj ponownie",
"common.save": "Zapisz",
- "common.cancel": "Anuluj",
- "common.next": "Dalej",
- "common.back": "Wstecz",
- "common.done": "Gotowe",
"common.skip": "Pomiń",
- "common.offline": "Offline – ostatnio pobrane dane",
- "common.estimate": "Szacunek",
- "tabs.whatToEat": "Co jemy?",
- "tabs.scan": "Skanuj",
- "tabs.myDay": "Mój dzień",
- "tabs.home": "W domu",
- "auth.login": "Zaloguj się",
- "auth.register": "Utwórz konto",
- "auth.email": "E-mail",
- "auth.password": "Hasło",
- "auth.displayName": "Jak mamy się do Ciebie zwracać?",
- "auth.noAccount": "Nowy tutaj? Utwórz konto",
- "auth.hasAccount": "Masz już konto? Zaloguj się",
- "auth.trialNote": "7 dni pełnego dostępu – bez karty.",
- "auth.forgotLink": "Nie pamiętasz hasła?",
- "auth.forgotTitle": "Zresetuj hasło",
- "auth.forgotBody": "Podaj swój e-mail, a wyślemy link, jeśli konto istnieje.",
- "auth.forgotSubmit": "Wyślij link",
- "auth.forgotSentTitle": "Sprawdź skrzynkę",
- "auth.forgotSentBody": "Jeśli adres ma konto, wysłaliśmy link ważny 30 minut. Otwórz go na tym urządzeniu.",
- "auth.backToLogin": "Wróć do logowania",
- "auth.resetTitle": "Wybierz nowe hasło",
- "auth.resetBody": "Link jest ważny 30 minut i można go użyć tylko raz. Wszystkie urządzenia zostaną wylogowane.",
- "auth.resetTokenPlaceholder": "Wklej kod z e-maila",
- "auth.newPassword": "Nowe hasło (min. 10 znaków)",
- "auth.resetSubmit": "Zmień hasło",
- "auth.resetDoneTitle": "Gotowe!",
- "auth.resetDoneBody": "Hasło zostało zmienione. Zaloguj się nowym hasłem.",
- "auth.verifyDoneTitle": "E-mail potwierdzony",
- "auth.verifyDoneBody": "Dziękujemy! Twoje konto jest zweryfikowane.",
- "auth.verifyFailedTitle": "Link nie zadziałał",
- "auth.verifyFailedBody": "Link jest nieprawidłowy lub wygasł. Poproś o nowy w profilu.",
- "onboarding.title": "Opowiedz nam coś o sobie",
- "onboarding.subtitle": "Wszystko jest opcjonalne i można to zmienić w każdej chwili. Im więcej uzupełnisz, tym lepsze propozycje.",
- "onboarding.goal": "Jaki jest Twój główny cel?",
- "onboarding.diet": "Jak się odżywiasz?",
+ "common.undo": "Cofnij",
+ "cooked.deductPantry": "Odejmij składniki ze spiżarni",
+ "cooked.deductPantryNote": "Składniki są odejmowane ze spiżarni – najpierw te z najkrótszym terminem.",
+ "cooked.mealBoxes": "Porcje do pojemników",
+ "cooked.portionsCooked": "Ugotowane porcje",
+ "cooked.rate": "Oceń",
+ "cooked.title": "Jak poszło?",
+ "cooked.whoAte": "Kto jadł?",
+ "cooking.finish": "Gotowe – zarejestruj posiłek",
+ "cooking.keepAwake": "Ekran pozostaje włączony podczas gotowania",
+ "cooking.scale": "Porcje",
+ "cooking.step": "Krok {current} z {total}",
+ "cooking.timer": "Uruchom minutnik",
+ "cooking.timerDone": "Gotowe!",
+ "cooking.timerRunning": "Pozostało {time}",
+ "home.budget": "Budżet na jedzenie",
+ "home.emptyInventory": "Spiżarnia jest pusta. Zeskanuj lodówkę albo dodaj produkty ręcznie.",
+ "home.expired": "Przeterminowane",
+ "home.expiresIn_few": "Zostały {days} dni",
+ "home.expiresIn_many": "Zostało {days} dni",
+ "home.expiresIn_one": "Został 1 dzień",
+ "home.expiresIn_other": "Zostało {days} dnia",
+ "home.expiresToday": "Kończy się dziś",
+ "home.household": "Gospodarstwo",
+ "home.inventory": "Spiżarnia",
+ "home.mealBoxes": "Pojemniki z jedzeniem",
+ "home.moreItems_few": "+ jeszcze {count} …",
+ "home.moreItems_many": "+ jeszcze {count} …",
+ "home.moreItems_one": "+ jeszcze 1 …",
+ "home.moreItems_other": "+ jeszcze {count} …",
+ "home.pastBestBefore": "Po terminie przydatności – najpierw powąchaj i spróbuj",
+ "home.shopping": "Lista zakupów",
+ "home.thisWeek": "W tym tygodniu",
+ "home.title": "W domu",
+ "home.useSoon": "Zużyj wkrótce",
+ "home.useSoonHint": "„Najlepiej spożyć przed” dotyczy jakości – powąchaj, obejrzyj i spróbuj, zanim wyrzucisz. Terminu „należy spożyć do” należy natomiast przestrzegać.",
+ "home.waste": "Marnowanie żywności",
+ "home.wasteWeek": "Marnowanie w tym tygodniu",
+ "household.empty": "Nie masz jeszcze gospodarstwa. Utwórz je podczas konfiguracji lub dołącz kodem.",
+ "household.invite": "Zaproś kodem: {code}",
+ "household.locations": "Miejsca przechowywania",
+ "household.members": "Członkowie",
+ "household.portionFactor": "×{factor} porcji",
+ "household.private": "Prywatne dla każdej osoby: cele, alergie, dane zdrowotne i historia posiłków.",
+ "household.role.adult": "Dorosły",
+ "household.role.child": "Dziecko",
+ "household.role.member": "Członek",
+ "household.role.owner": "Właściciel",
+ "household.shareCode": "Udostępnij kod rodzinie, aby dzielić spiżarnię, listę i plan.",
+ "household.shared": "Wspólne w gospodarstwie: spiżarnia, lista zakupów, plan tygodnia, pojemniki i budżet.",
+ "logmeal.manualTitle": "Ręcznie",
+ "logmeal.mealTypeTitle": "Rodzaj posiłku",
+ "logmeal.photoTip": "Wskazówka: sfotografuj talerz w zakładce Skanuj, a aplikacja oszacuje za Ciebie – zawsze potwierdzasz.",
+ "logmeal.proteinPlaceholder": "białko (g)",
+ "logmeal.quickSubtitle": "Zapisuje te same wartości odżywcze co ostatnio.",
+ "logmeal.quickTitle": "Szybkie ponowne dodanie",
+ "logmeal.validationBody": "Do ręcznego dodania potrzebne są nazwa i kalorie.",
+ "logmeal.validationTitle": "Uzupełnij",
+ "logmeal.whatPlaceholder": "Co zjadłeś/aś?",
+ "mealbox.eat": "Zjedz teraz",
+ "mealbox.eatBy": "Zjedz do {date}",
+ "mealbox.empty": "Brak pojemników. Gotując, możesz zapisać tu porcje.",
+ "mealbox.enjoyBody": "Porcja została zapisana w Mój dzień.",
+ "mealbox.enjoyTitle": "Smacznego!",
+ "mealbox.guidanceNote": "Zalecany termin to wskazówka – zaufaj węchowi i smakowi.",
+ "mealbox.portionsLeft_few": "Zostały {count} porcje",
+ "mealbox.portionsLeft_many": "Zostało {count} porcji",
+ "mealbox.portionsLeft_one": "Została 1 porcja",
+ "mealbox.portionsLeft_other": "Zostało {count} porcji",
+ "mealbox.title": "Pojemniki z jedzeniem",
+ "memory.delete": "Usuń",
+ "memory.deleteAll": "Usuń całą pamięć",
+ "memory.deleteAllTitle": "Usunąć całą pamięć?",
+ "memory.empty": "{brand} jeszcze niczego się o Tobie nie nauczył.",
+ "memory.irreversible": "Tego nie można cofnąć.",
+ "memory.origin.ai_inferred": "Przypuszczenie AI",
+ "memory.origin.observed": "Zaobserwowany wzorzec",
+ "memory.origin.user_stated": "Sam(a) powiedziałeś/-aś",
+ "memory.pause": "Wstrzymaj",
+ "memory.paused": "Wstrzymane",
+ "memory.resume": "Wznów",
+ "memory.subtitle": "Pełna przejrzystość. Poprawiaj, wstrzymuj lub usuwaj – Twoja pamięć należy do Ciebie.",
+ "memory.title": "Co {brand} o mnie wie",
+ "memory.verified": "Zweryfikowane",
+ "memory.verify": "Zgadza się",
+ "myday.calories": "Kalorie",
+ "myday.carbs": "Węglowodany",
+ "myday.estimateNote": "Wartości z ~ to szacunki, które możesz poprawić.",
+ "myday.estimateRange": "{min}–{max} kcal, prawdopodobnie {kcal}",
+ "myday.fat": "Tłuszcze",
+ "myday.fiber": "Błonnik",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g białka",
+ "myday.logMeal": "Zarejestruj posiłek",
+ "myday.mealType.breakfast": "Śniadanie",
+ "myday.mealType.dessert": "Deser",
+ "myday.mealType.dinner": "Kolacja",
+ "myday.mealType.lunch": "Obiad",
+ "myday.mealType.snack": "Przekąska",
+ "myday.noMeals": "Dziś nie zarejestrowano posiłków.",
+ "myday.over": "{kcal} kcal ponad cel",
+ "myday.overRecommended": "Powyżej zaleceń",
+ "myday.protein": "Białko",
+ "myday.remaining": "Pozostało {kcal} kcal",
+ "myday.salt": "Sól",
+ "myday.targetsNote": "Cele to wskazówki, nie porada medyczna.",
+ "myday.title": "Mój dzień",
+ "myday.todaysMeals": "Dzisiejsze posiłki",
+ "onboarding.allergen.crustaceans": "Skorupiaki",
+ "onboarding.allergen.eggs": "Jaja",
+ "onboarding.allergen.fish": "Ryby",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Mleko/laktoza",
+ "onboarding.allergen.peanuts": "Orzeszki ziemne",
+ "onboarding.allergen.sesame": "Sezam",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Orzechy",
"onboarding.allergies": "Alergie i nietolerancje",
"onboarding.allergyNote": "Filtr alergii jest zawsze rygorystyczny – dania z Twoimi alergenami nigdy się nie pojawią.",
+ "onboarding.birthYearPlaceholder": "Rok urodzenia",
+ "onboarding.bodyTitle": "Dla osobistych celów kalorycznych (opcjonalnie)",
+ "onboarding.diet": "Jak się odżywiasz?",
+ "onboarding.diet.flexitarian": "Fleksitarianin",
+ "onboarding.diet.omnivore": "Wszystkożerca",
+ "onboarding.diet.pescatarian": "Peskatarianin",
+ "onboarding.diet.vegan": "Weganin",
+ "onboarding.diet.vegetarian": "Wegetarianin",
+ "onboarding.goal": "Jaki jest Twój główny cel?",
+ "onboarding.goal.build_muscle": "Zbudować mięśnie",
+ "onboarding.goal.cook_more": "Częściej gotować w domu",
+ "onboarding.goal.less_waste": "Mniej marnować",
+ "onboarding.goal.lose_weight": "Schudnąć",
+ "onboarding.goal.lower_cost": "Wydawać mniej na jedzenie",
+ "onboarding.goal.maintain_weight": "Utrzymać wagę",
+ "onboarding.goal.more_protein": "Jeść więcej białka",
+ "onboarding.heightPlaceholder": "Wzrost (cm)",
"onboarding.household": "Twoje gospodarstwo",
"onboarding.householdCreate": "Utwórz gospodarstwo",
+ "onboarding.householdDefaultName": "Dom",
"onboarding.householdJoin": "Dołącz kodem",
"onboarding.householdName": "Nazwa gospodarstwa",
"onboarding.inviteCode": "Kod zaproszenia",
"onboarding.mode": "Jak dokładnie chcesz to robić?",
- "onboarding.modeSimple": "Tryb prosty",
- "onboarding.modeSimpleDesc": "Fotografuj jedzenie, akceptuj szacunki, minimum zachodu.",
"onboarding.modeExact": "Tryb dokładny",
"onboarding.modeExactDesc": "Waż jedzenie, wpisuj gramy, pełna kontrola nad liczbami.",
+ "onboarding.modesCombine": "Tryby można łączyć – na co dzień prosto, dokładnie, gdy chcesz.",
+ "onboarding.modeSimple": "Tryb prosty",
+ "onboarding.modeSimpleDesc": "Fotografuj jedzenie, akceptuj szacunki, minimum zachodu.",
"onboarding.notMedical": "{brand} to wskazówki – nie porada medyczna.",
- "wte.title": "Co jemy?",
- "wte.subtitle": "Na podstawie tego, co macie w domu, co trzeba wkrótce zużyć i co lubicie.",
- "wte.cravingPlaceholder": "Mam ochotę na … (np. kremowe, azjatyckie, poniżej 500 kcal)",
- "wte.mealBoxFirst": "Gotowe jedzenie w domu",
- "wte.whyTitle": "Dlaczego ta propozycja?",
- "wte.coverage": "{pct}% w domu",
- "wte.missing": "Brakuje: {items}",
- "wte.empty": "Brak propozycji – dodaj jedzenie do spiżarni albo poluzuj filtry.",
- "wte.refresh": "Nowe propozycje",
- "scan.title": "Skanuj",
- "scan.subtitle": "Uzupełnij spiżarnię lub zarejestruj posiłek aparatem.",
- "scan.fridge": "Lodówka",
- "scan.freezer": "Zamrażarka",
- "scan.pantry": "Spiżarnia",
- "scan.ingredients": "Składniki",
- "scan.plate": "Talerz",
- "scan.receipt": "Paragon",
- "scan.barcode": "Kod kreskowy",
- "scan.expiry": "Data przydatności",
- "scan.nutrition": "Etykieta wartości odżywczych",
- "scan.takePhoto": "Zrób zdjęcie",
- "scan.tips.title": "Jak uzyskać najlepszą analizę",
- "scan.tips.overview": "Zacznij od zdjęcia ogólnego",
- "scan.tips.shelf": "Fotografuj półka po półce",
- "scan.tips.light": "Unikaj ciemności i cieni",
- "scan.tips.move": "Rozsuń zasłaniające się produkty",
- "scan.analyzing": "Analizowanie …",
- "scan.quotaLeft_one": "Został 1 skan AI w tym miesiącu",
- "scan.quotaLeft_few": "Zostały {count} skany AI w tym miesiącu",
- "scan.quotaLeft_many": "Zostało {count} skanów AI w tym miesiącu",
- "scan.quotaLeft_other": "Zostało {count} skanu AI w tym miesiącu",
- "scan.review.title": "Sprawdź wynik",
- "scan.review.subtitle": "AI czasem się waha – Ty decydujesz. Popraw, usuń lub dodaj przed zapisaniem.",
- "scan.review.uncertain": "Niepewne – sprawdź",
- "scan.review.approveAll": "Zapisz do spiżarni",
- "scan.review.rejected": "Usunięto",
- "scan.failed": "Analiza się nie powiodła. Spróbuj ponownie lub dodaj ręcznie.",
- "myday.title": "Mój dzień",
- "myday.calories": "Kalorie",
- "myday.protein": "Białko",
- "myday.carbs": "Węglowodany",
- "myday.fat": "Tłuszcze",
- "myday.fiber": "Błonnik",
- "myday.salt": "Sól",
- "myday.remaining": "Pozostało {kcal} kcal",
- "myday.over": "{kcal} kcal ponad cel",
- "myday.logMeal": "Zarejestruj posiłek",
- "myday.noMeals": "Dziś nie zarejestrowano posiłków.",
- "myday.estimateNote": "Wartości z ~ to szacunki, które możesz poprawić.",
- "myday.targetsNote": "Cele to wskazówki, nie porada medyczna.",
- "home.title": "W domu",
- "home.inventory": "Spiżarnia",
- "home.useSoon": "Zużyj wkrótce",
- "home.mealBoxes": "Pojemniki z jedzeniem",
- "home.shopping": "Lista zakupów",
- "home.budget": "Budżet na jedzenie",
- "home.household": "Gospodarstwo",
- "home.waste": "Marnowanie żywności",
- "home.emptyInventory": "Spiżarnia jest pusta. Zeskanuj lodówkę albo dodaj produkty ręcznie.",
- "home.expiresIn_one": "Został 1 dzień",
- "home.expiresIn_few": "Zostały {days} dni",
- "home.expiresIn_many": "Zostało {days} dni",
- "home.expiresIn_other": "Zostało {days} dnia",
- "home.expiresToday": "Kończy się dziś",
- "home.expired": "Przeterminowane",
- "home.pastBestBefore": "Po terminie przydatności – najpierw powąchaj i spróbuj",
- "recipe.portions_one": "1 porcja",
+ "onboarding.stepBSubtitle": "Dostosuj swój profil, aby uzyskać lepsze sugestie.",
+ "onboarding.stepBTitle": "Kontynuuj konfigurację",
+ "onboarding.stepCSubtitle": "Opcjonalne – używane do osobistych celów kalorycznych.",
+ "onboarding.stepCTitle": "Twój profil zdrowia",
+ "onboarding.subtitle": "Wszystko jest opcjonalne i można to zmienić w każdej chwili. Im więcej uzupełnisz, tym lepsze propozycje.",
+ "onboarding.title": "Opowiedz nam coś o sobie",
+ "onboarding.weightPlaceholder": "Waga (kg)",
+ "paywall.choose": "Wybierz",
+ "paywall.fairUse": "Limit fair use skanów AI w cenie.",
+ "paywall.family": "Family · do 6 osób",
+ "paywall.freeNote": "Za darmo: 10 skanów AI/mies., ręczna spiżarnia, zapisane przepisy i proste rejestrowanie.",
+ "paywall.household": "Household · do 3 osób",
+ "paywall.large": "Large Household · do 12 osób",
+ "paywall.perMonth": "{price}/mies.",
+ "paywall.popular": "Najpopularniejszy",
+ "paywall.restore": "Przywróć zakupy",
+ "paywall.soonBody": "Zakupy będą aktywowane przez App Store/Google Play po włączeniu integracji ze sklepami (faza 7). Backend jest już gotowy.",
+ "paywall.soonTitle": "Wkrótce!",
+ "paywall.subtitle": "System operacyjny jedzenia dla całego gospodarstwa: nielimitowana spiżarnia, plan tygodnia i udostępnianie.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_few": "Zostały {days} dni okresu próbnego",
+ "paywall.trialActive_many": "Zostało {days} dni okresu próbnego",
+ "paywall.trialActive_one": "Został 1 dzień okresu próbnego",
+ "paywall.trialActive_other": "Zostało {days} dnia okresu próbnego",
+ "profile.aiScansUsed": "Skany AI: {used} / {total} w tym miesiącu",
+ "profile.consent.anonymized_improvement": "Anonimowe ulepszanie AI",
+ "profile.consent.health_integration": "Dane zdrowotne (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Moje zdjęcia mogą służyć do trenowania",
+ "profile.consent.location_weather": "Lokalizacja dla propozycji zależnych od pogody",
+ "profile.consent.personalization": "Funkcje osobiste (pamięć i profil smaku)",
+ "profile.consent.product_analytics": "Analiza produktu",
+ "profile.consent.push_notifications": "Powiadomienia push",
+ "profile.consents": "Zgody i dane",
+ "profile.consentsNote": "Zgody są rozdzielne – funkcje osobiste nigdy nie wymagają zgody na trenowanie.",
+ "profile.deleteAccount": "Usuń konto",
+ "profile.deleteBody": "Wszystkie Twoje dane zostaną trwale usunięte zgodnie z RODO.",
+ "profile.deleteTitle": "Usunąć konto?",
+ "profile.emailUnverified": "Adres e-mail niepotwierdzony",
+ "profile.export": "Eksportuj moje dane",
+ "profile.goals": "Cele i dieta",
+ "profile.language": "Język",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Wyloguj się",
+ "profile.memory": "Co {brand} o mnie wie",
+ "profile.memorySubtitle": "Zobacz, popraw, wstrzymaj lub usuń to, czego nauczyła się platforma.",
+ "profile.modeLabel": "Tryb:",
+ "profile.resendVerification": "Wyślij ponownie e-mail potwierdzający",
+ "profile.subscription": "Subskrypcja",
+ "profile.title": "Profil",
+ "profile.verificationSent": "Wysłano! Sprawdź skrzynkę.",
+ "recipe.avgRating": "Średnia {avg} z {count} ocen",
+ "recipe.cook": "Gotuj teraz",
+ "recipe.cost": "ok. {amount}/porcja",
+ "recipe.iCookedThis": "Ugotowałem/-am to",
+ "recipe.ingredients": "Składniki",
+ "recipe.notSafe": "Nie pasuje do Twoich ustawień żywieniowych",
+ "recipe.perPortion": "na porcję",
"recipe.portions_few": "{count} porcje",
"recipe.portions_many": "{count} porcji",
+ "recipe.portions_one": "1 porcja",
"recipe.portions_other": "{count} porcji",
- "recipe.time": "{min} min",
- "recipe.perPortion": "na porcję",
- "recipe.ingredients": "Składniki",
+ "recipe.save": "Zapisz",
+ "recipe.saved": "Zapisany",
"recipe.steps": "Przygotowanie",
- "recipe.cook": "Gotuj teraz",
- "recipe.notSafe": "Nie pasuje do Twoich ustawień żywieniowych",
"recipe.substitutions": "Zamień",
- "recipe.iCookedThis": "Ugotowałem/-am to",
- "recipe.cost": "ok. {amount}/porcja",
- "cooking.step": "Krok {current} z {total}",
- "cooking.timer": "Uruchom minutnik",
- "cooking.timerRunning": "Pozostało {time}",
- "cooking.finish": "Gotowe – zarejestruj posiłek",
- "cooking.scale": "Porcje",
- "cooking.keepAwake": "Ekran pozostaje włączony podczas gotowania",
- "cooked.title": "Jak poszło?",
- "cooked.portionsCooked": "Ugotowane porcje",
- "cooked.whoAte": "Kto jadł?",
- "cooked.mealBoxes": "Porcje do pojemników",
- "cooked.deductPantry": "Odejmij składniki ze spiżarni",
- "cooked.rate": "Oceń",
- "shopping.title": "Lista zakupów",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analizowanie …",
+ "scan.barcode": "Kod kreskowy",
+ "scan.expiry": "Data przydatności",
+ "scan.failed": "Analiza się nie powiodła. Spróbuj ponownie lub dodaj ręcznie.",
+ "scan.freezer": "Zamrażarka",
+ "scan.fridge": "Lodówka",
+ "scan.ingredients": "Składniki",
+ "scan.nutrition": "Etykieta wartości odżywczych",
+ "scan.pantry": "Spiżarnia",
+ "scan.plate": "Talerz",
+ "scan.quotaLeft_few": "Zostały {count} skany AI w tym miesiącu",
+ "scan.quotaLeft_many": "Zostało {count} skanów AI w tym miesiącu",
+ "scan.quotaLeft_one": "Został 1 skan AI w tym miesiącu",
+ "scan.quotaLeft_other": "Zostało {count} skanu AI w tym miesiącu",
+ "scan.receipt": "Paragon",
+ "scan.review.addItem": "+ Dodaj produkt",
+ "scan.review.approveAll": "Zapisz do spiżarni",
+ "scan.review.bestBeforeNote": "Data jakości – produkt często jest dobry dłużej. Powąchaj i spróbuj, zanim wyrzucisz.",
+ "scan.review.dateKindBestBefore": "Najlepiej spożyć przed",
+ "scan.review.dateKindUseBy": "Należy spożyć do",
+ "scan.review.datePlaceholder": "RRRR-MM-DD (opcjonalnie)",
+ "scan.review.itemPlaceholder": "Produkt",
+ "scan.review.quantityPlaceholder": "Ilość",
+ "scan.review.rejected": "Usunięto",
+ "scan.review.subtitle": "AI czasem się waha – Ty decydujesz. Popraw, usuń lub dodaj przed zapisaniem.",
+ "scan.review.title": "Sprawdź wynik",
+ "scan.review.uncertain": "Niepewne – sprawdź",
+ "scan.review.unitPlaceholder": "Jednostka (g, l, szt. …)",
+ "scan.review.unknownItem": "Nieznany produkt",
+ "scan.review.useByNote": "Data bezpieczeństwa – nie jedz po tej dacie.",
+ "scan.subtitle": "Uzupełnij spiżarnię lub zarejestruj posiłek aparatem.",
+ "scan.takePhoto": "Zrób zdjęcie",
+ "scan.tips.light": "Unikaj ciemności i cieni",
+ "scan.tips.move": "Rozsuń zasłaniające się produkty",
+ "scan.tips.overview": "Zacznij od zdjęcia ogólnego",
+ "scan.tips.shelf": "Fotografuj półka po półce",
+ "scan.tips.title": "Jak uzyskać najlepszą analizę",
+ "scan.title": "Skanuj",
"shopping.addPlaceholder": "Dodaj produkt …",
"shopping.complete": "Zakończ zakupy",
+ "shopping.completedBody_few": "{count} produkty trafiły do spiżarni.",
+ "shopping.completedBody_many": "{count} produktów trafiło do spiżarni.",
+ "shopping.completedBody_one": "1 produkt trafił do spiżarni.",
+ "shopping.completedBody_other": "{count} produktu trafiło do spiżarni.",
+ "shopping.completedTitle": "Gotowe!",
"shopping.completeNote": "Odhaczone produkty trafiają do spiżarni.",
"shopping.empty": "Lista jest pusta.",
"shopping.estimated": "ok. {amount}",
"shopping.estimatedTotal": "Szacowana suma: ok. {amount}",
- "mealbox.title": "Pojemniki z jedzeniem",
- "mealbox.eatBy": "Zjedz do {date}",
- "mealbox.portionsLeft_one": "Została 1 porcja",
- "mealbox.portionsLeft_few": "Zostały {count} porcje",
- "mealbox.portionsLeft_many": "Zostało {count} porcji",
- "mealbox.portionsLeft_other": "Zostało {count} porcji",
- "mealbox.eat": "Zjedz teraz",
- "mealbox.empty": "Brak pojemników. Gotując, możesz zapisać tu porcje.",
- "household.members": "Członkowie",
- "household.invite": "Zaproś kodem: {code}",
- "household.shared": "Wspólne w gospodarstwie: spiżarnia, lista zakupów, plan tygodnia, pojemniki i budżet.",
- "household.private": "Prywatne dla każdej osoby: cele, alergie, dane zdrowotne i historia posiłków.",
- "memory.title": "Co {brand} o mnie wie",
- "memory.subtitle": "Pełna przejrzystość. Poprawiaj, wstrzymuj lub usuwaj – Twoja pamięć należy do Ciebie.",
- "memory.paused": "Wstrzymane",
- "memory.verify": "Zgadza się",
- "memory.pause": "Wstrzymaj",
- "memory.delete": "Usuń",
- "memory.deleteAll": "Usuń całą pamięć",
- "memory.empty": "{brand} jeszcze niczego się o Tobie nie nauczył.",
- "memory.origin.user_stated": "Sam(a) powiedziałeś/-aś",
- "memory.origin.observed": "Zaobserwowany wzorzec",
- "memory.origin.ai_inferred": "Przypuszczenie AI",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "System operacyjny jedzenia dla całego gospodarstwa: nielimitowana spiżarnia, plan tygodnia i udostępnianie.",
- "paywall.trialActive_one": "Został 1 dzień okresu próbnego",
- "paywall.trialActive_few": "Zostały {days} dni okresu próbnego",
- "paywall.trialActive_many": "Zostało {days} dni okresu próbnego",
- "paywall.trialActive_other": "Zostało {days} dnia okresu próbnego",
- "paywall.household": "Household · do 3 osób",
- "paywall.family": "Family · do 6 osób",
- "paywall.large": "Large Household · do 12 osób",
- "paywall.perMonth": "{price}/mies.",
- "paywall.fairUse": "Limit fair use skanów AI w cenie.",
- "paywall.restore": "Przywróć zakupy",
- "paywall.freeNote": "Za darmo: 10 skanów AI/mies., ręczna spiżarnia, zapisane przepisy i proste rejestrowanie.",
- "profile.title": "Profil",
- "profile.goals": "Cele i dieta",
- "profile.consents": "Zgody i dane",
- "profile.memory": "Co {brand} o mnie wie",
- "profile.subscription": "Subskrypcja",
- "profile.logout": "Wyloguj się",
- "profile.export": "Eksportuj moje dane",
- "profile.deleteAccount": "Usuń konto",
- "profile.language": "Język",
- "profile.emailUnverified": "Adres e-mail niepotwierdzony",
- "profile.resendVerification": "Wyślij ponownie e-mail potwierdzający",
- "profile.verificationSent": "Wysłano! Sprawdź skrzynkę.",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Ups",
- "common.undo": "Cofnij",
- "common.remove": "Usuń",
- "common.add": "Dodaj",
- "common.on": "Wł.",
- "common.off": "Wył.",
- "home.thisWeek": "W tym tygodniu",
- "home.wasteWeek": "Marnowanie w tym tygodniu",
- "home.useSoonHint": "„Najlepiej spożyć przed” dotyczy jakości – powąchaj, obejrzyj i spróbuj, zanim wyrzucisz. Terminu „należy spożyć do” należy natomiast przestrzegać.",
- "scan.review.itemPlaceholder": "Produkt",
- "scan.review.quantityPlaceholder": "Ilość",
- "scan.review.unitPlaceholder": "Jednostka (g, l, szt. …)",
- "scan.review.datePlaceholder": "RRRR-MM-DD (opcjonalnie)",
- "scan.review.dateKindBestBefore": "Najlepiej spożyć przed",
- "scan.review.dateKindUseBy": "Należy spożyć do",
- "scan.review.bestBeforeNote": "Data jakości – produkt często jest dobry dłużej. Powąchaj i spróbuj, zanim wyrzucisz.",
- "scan.review.useByNote": "Data bezpieczeństwa – nie jedz po tej dacie.",
- "scan.review.addItem": "+ Dodaj produkt",
- "scan.review.unknownItem": "Nieznany produkt",
- "barcode.aim": "Skieruj aparat na kod kreskowy",
- "barcode.addPrompt": "Dodać do spiżarni?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Brak danych żywieniowych",
- "barcode.unknownTitle": "Nieznany produkt",
- "barcode.unknownBody": "Tego produktu nie ma jeszcze w bazie. Sfotografuj przód i etykietę wartości odżywczych, a my go dodamy.",
- "barcode.photoPackage": "Sfotografuj opakowanie",
- "barcode.needHousehold": "Najpierw potrzebujesz gospodarstwa.",
- "barcode.noLocation": "Nie znaleziono miejsca przechowywania.",
- "barcode.cameraTitle": "Potrzebny aparat",
- "barcode.cameraBody": "{brand} potrzebuje aparatu do skanowania kodów kreskowych.",
- "barcode.allowCamera": "Zezwól na aparat",
- "onboarding.goal.lose_weight": "Schudnąć",
- "onboarding.goal.build_muscle": "Zbudować mięśnie",
- "onboarding.goal.maintain_weight": "Utrzymać wagę",
- "onboarding.goal.more_protein": "Jeść więcej białka",
- "onboarding.goal.less_waste": "Mniej marnować",
- "onboarding.goal.lower_cost": "Wydawać mniej na jedzenie",
- "onboarding.goal.cook_more": "Częściej gotować w domu",
- "onboarding.diet.omnivore": "Wszystkożerca",
- "onboarding.diet.flexitarian": "Fleksitarianin",
- "onboarding.diet.pescatarian": "Peskatarianin",
- "onboarding.diet.vegetarian": "Wegetarianin",
- "onboarding.diet.vegan": "Weganin",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Mleko/laktoza",
- "onboarding.allergen.eggs": "Jaja",
- "onboarding.allergen.tree_nuts": "Orzechy",
- "onboarding.allergen.peanuts": "Orzeszki ziemne",
- "onboarding.allergen.fish": "Ryby",
- "onboarding.allergen.crustaceans": "Skorupiaki",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sezam",
- "onboarding.bodyTitle": "Dla osobistych celów kalorycznych (opcjonalnie)",
- "onboarding.weightPlaceholder": "Waga (kg)",
- "onboarding.heightPlaceholder": "Wzrost (cm)",
- "onboarding.birthYearPlaceholder": "Rok urodzenia",
- "onboarding.householdDefaultName": "Dom",
- "onboarding.modesCombine": "Tryby można łączyć – na co dzień prosto, dokładnie, gdy chcesz.",
- "myday.mealType.breakfast": "Śniadanie",
- "myday.mealType.lunch": "Obiad",
- "myday.mealType.dinner": "Kolacja",
- "myday.mealType.snack": "Przekąska",
- "myday.mealType.dessert": "Deser",
- "myday.overRecommended": "Powyżej zaleceń",
- "myday.todaysMeals": "Dzisiejsze posiłki",
- "myday.estimateRange": "{min}–{max} kcal, prawdopodobnie {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g białka",
- "logmeal.mealTypeTitle": "Rodzaj posiłku",
- "logmeal.quickTitle": "Szybkie ponowne dodanie",
- "logmeal.quickSubtitle": "Zapisuje te same wartości odżywcze co ostatnio.",
- "logmeal.manualTitle": "Ręcznie",
- "logmeal.whatPlaceholder": "Co zjadłeś/aś?",
- "logmeal.proteinPlaceholder": "białko (g)",
- "logmeal.validationTitle": "Uzupełnij",
- "logmeal.validationBody": "Do ręcznego dodania potrzebne są nazwa i kalorie.",
- "logmeal.photoTip": "Wskazówka: sfotografuj talerz w zakładce Skanuj, a aplikacja oszacuje za Ciebie – zawsze potwierdzasz.",
- "shopping.section.frukt_gront": "Owoce i warzywa",
"shopping.section.brod": "Pieczywo",
- "shopping.section.mejeri": "Nabiał",
- "shopping.section.kott_fagel": "Mięso i drób",
- "shopping.section.fisk": "Ryby",
"shopping.section.chark": "Wędliny",
- "shopping.section.frys": "Mrożonki",
- "shopping.section.skafferi": "Spiżarnia",
- "shopping.section.konserver": "Konserwy",
- "shopping.section.kryddor_bak": "Przyprawy i pieczenie",
"shopping.section.dryck": "Napoje",
- "shopping.section.snacks": "Przekąski",
+ "shopping.section.fisk": "Ryby",
+ "shopping.section.frukt_gront": "Owoce i warzywa",
+ "shopping.section.frys": "Mrożonki",
"shopping.section.hygien_ovrigt": "Inne",
- "shopping.completedTitle": "Gotowe!",
- "household.role.owner": "Właściciel",
- "household.role.adult": "Dorosły",
- "household.role.member": "Członek",
- "household.role.child": "Dziecko",
- "household.empty": "Nie masz jeszcze gospodarstwa. Utwórz je podczas konfiguracji lub dołącz kodem.",
- "household.shareCode": "Udostępnij kod rodzinie, aby dzielić spiżarnię, listę i plan.",
- "household.locations": "Miejsca przechowywania",
- "household.portionFactor": "×{factor} porcji",
- "mealbox.enjoyTitle": "Smacznego!",
- "mealbox.enjoyBody": "Porcja została zapisana w Mój dzień.",
- "mealbox.guidanceNote": "Zalecany termin to wskazówka – zaufaj węchowi i smakowi.",
- "paywall.soonTitle": "Wkrótce!",
- "paywall.soonBody": "Zakupy będą aktywowane przez App Store/Google Play po włączeniu integracji ze sklepami (faza 7). Backend jest już gotowy.",
- "paywall.popular": "Najpopularniejszy",
- "paywall.choose": "Wybierz",
- "recipe.saved": "Zapisany",
- "recipe.save": "Zapisz",
- "recipe.avgRating": "Średnia {avg} z {count} ocen",
- "memory.verified": "Zweryfikowane",
- "memory.resume": "Wznów",
- "memory.deleteAllTitle": "Usunąć całą pamięć?",
- "memory.irreversible": "Tego nie można cofnąć.",
- "profile.consent.personalization": "Funkcje osobiste (pamięć i profil smaku)",
- "profile.consent.anonymized_improvement": "Anonimowe ulepszanie AI",
- "profile.consent.image_training": "Moje zdjęcia mogą służyć do trenowania",
- "profile.consent.health_integration": "Dane zdrowotne (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Lokalizacja dla propozycji zależnych od pogody",
- "profile.consent.push_notifications": "Powiadomienia push",
- "profile.modeLabel": "Tryb:",
- "profile.memorySubtitle": "Zobacz, popraw, wstrzymaj lub usuń to, czego nauczyła się platforma.",
- "profile.consentsNote": "Zgody są rozdzielne – funkcje osobiste nigdy nie wymagają zgody na trenowanie.",
- "profile.aiScansUsed": "Skany AI: {used} / {total} w tym miesiącu",
- "profile.deleteTitle": "Usunąć konto?",
- "profile.deleteBody": "Wszystkie Twoje dane zostaną trwale usunięte zgodnie z RODO.",
- "cooking.timerDone": "Gotowe!",
- "cooked.deductPantryNote": "Składniki są odejmowane ze spiżarni – najpierw te z najkrótszym terminem.",
- "home.moreItems_one": "+ jeszcze 1 …",
- "home.moreItems_few": "+ jeszcze {count} …",
- "home.moreItems_many": "+ jeszcze {count} …",
- "home.moreItems_other": "+ jeszcze {count} …",
- "shopping.completedBody_one": "1 produkt trafił do spiżarni.",
- "shopping.completedBody_few": "{count} produkty trafiły do spiżarni.",
- "shopping.completedBody_many": "{count} produktów trafiło do spiżarni.",
- "shopping.completedBody_other": "{count} produktu trafiło do spiżarni.",
- "profile.consent.product_analytics": "Analiza produktu"
+ "shopping.section.konserver": "Konserwy",
+ "shopping.section.kott_fagel": "Mięso i drób",
+ "shopping.section.kryddor_bak": "Przyprawy i pieczenie",
+ "shopping.section.mejeri": "Nabiał",
+ "shopping.section.skafferi": "Spiżarnia",
+ "shopping.section.snacks": "Przekąski",
+ "shopping.title": "Lista zakupów",
+ "tabs.home": "W domu",
+ "tabs.myDay": "Mój dzień",
+ "tabs.scan": "Skanuj",
+ "tabs.whatToEat": "Co jemy?",
+ "wte.coverage": "{pct}% w domu",
+ "wte.cravingPlaceholder": "Mam ochotę na … (np. kremowe, azjatyckie, poniżej 500 kcal)",
+ "wte.empty": "Brak propozycji – dodaj jedzenie do spiżarni albo poluzuj filtry.",
+ "wte.mealBoxFirst": "Gotowe jedzenie w domu",
+ "wte.missing": "Brakuje: {items}",
+ "wte.refresh": "Nowe propozycje",
+ "wte.subtitle": "Na podstawie tego, co macie w domu, co trzeba wkrótce zużyć i co lubicie.",
+ "wte.title": "Co jemy?",
+ "wte.whyTitle": "Dlaczego ta propozycja?"
}
diff --git a/apps/mobile/src/locales/pt/common.json b/apps/mobile/src/locales/pt/common.json
index 3b7092b..df58767 100644
--- a/apps/mobile/src/locales/pt/common.json
+++ b/apps/mobile/src/locales/pt/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "A carregar …",
+ "auth.backToLogin": "Voltar ao início de sessão",
+ "auth.displayName": "Como o devemos tratar?",
+ "auth.email": "E-mail",
+ "auth.forgotBody": "Introduza o seu e-mail e enviaremos um link se a conta existir.",
+ "auth.forgotLink": "Esqueceu-se da palavra-passe?",
+ "auth.forgotSentBody": "Se o endereço tiver uma conta, enviámos um link válido por 30 minutos. Abra-o neste dispositivo.",
+ "auth.forgotSentTitle": "Verifique a sua caixa de entrada",
+ "auth.forgotSubmit": "Enviar link",
+ "auth.forgotTitle": "Repor palavra-passe",
+ "auth.hasAccount": "Já tem conta? Inicie sessão",
+ "auth.login": "Iniciar sessão",
+ "auth.newPassword": "Nova palavra-passe (mín. 10 caracteres)",
+ "auth.noAccount": "Novo por aqui? Crie uma conta",
+ "auth.password": "Palavra-passe",
+ "auth.register": "Criar conta",
+ "auth.resetBody": "O link é válido por 30 minutos e de uso único. Todos os dispositivos serão desligados.",
+ "auth.resetDoneBody": "A palavra-passe foi alterada. Inicie sessão com a nova.",
+ "auth.resetDoneTitle": "Concluído!",
+ "auth.resetSubmit": "Alterar palavra-passe",
+ "auth.resetTitle": "Escolha uma nova palavra-passe",
+ "auth.resetTokenPlaceholder": "Cole o código do e-mail",
+ "auth.trialNote": "7 dias de acesso completo – sem cartão.",
+ "auth.verifyDoneBody": "Obrigado! A sua conta está verificada.",
+ "auth.verifyDoneTitle": "E-mail confirmado",
+ "auth.verifyFailedBody": "O link é inválido ou expirou. Peça um novo no perfil.",
+ "auth.verifyFailedTitle": "O link não funcionou",
+ "barcode.addPrompt": "Adicionar à despensa?",
+ "barcode.aim": "Aponte a câmara para o código de barras",
+ "barcode.allowCamera": "Permitir câmara",
+ "barcode.cameraBody": "O {brand} precisa da câmara para ler códigos de barras.",
+ "barcode.cameraTitle": "É precisa a câmara",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Primeiro precisa de um agregado.",
+ "barcode.noLocation": "Nenhum local de armazenamento encontrado.",
+ "barcode.noNutrition": "Sem dados nutricionais",
+ "barcode.photoPackage": "Fotografar a embalagem",
+ "barcode.unknownBody": "Este produto ainda não está na base de dados. Fotografe a frente e o rótulo nutricional e nós adicionamo-lo.",
+ "barcode.unknownTitle": "Produto desconhecido",
+ "common.add": "Adicionar",
+ "common.back": "Voltar",
+ "common.cancel": "Cancelar",
+ "common.done": "Concluído",
"common.error": "Algo correu mal. Tente novamente.",
+ "common.estimate": "Estimativa",
+ "common.loading": "A carregar …",
+ "common.next": "Seguinte",
+ "common.off": "Desativado",
+ "common.offline": "Offline – a mostrar os últimos dados",
+ "common.on": "Ativado",
+ "common.oops": "Ops",
+ "common.remove": "Remover",
"common.retry": "Tentar novamente",
"common.save": "Guardar",
- "common.cancel": "Cancelar",
- "common.next": "Seguinte",
- "common.back": "Voltar",
- "common.done": "Concluído",
"common.skip": "Ignorar",
- "common.offline": "Offline – a mostrar os últimos dados",
- "common.estimate": "Estimativa",
- "tabs.whatToEat": "O que vamos comer?",
- "tabs.scan": "Digitalizar",
- "tabs.myDay": "O meu dia",
- "tabs.home": "Em casa",
- "auth.login": "Iniciar sessão",
- "auth.register": "Criar conta",
- "auth.email": "E-mail",
- "auth.password": "Palavra-passe",
- "auth.displayName": "Como o devemos tratar?",
- "auth.noAccount": "Novo por aqui? Crie uma conta",
- "auth.hasAccount": "Já tem conta? Inicie sessão",
- "auth.trialNote": "7 dias de acesso completo – sem cartão.",
- "auth.forgotLink": "Esqueceu-se da palavra-passe?",
- "auth.forgotTitle": "Repor palavra-passe",
- "auth.forgotBody": "Introduza o seu e-mail e enviaremos um link se a conta existir.",
- "auth.forgotSubmit": "Enviar link",
- "auth.forgotSentTitle": "Verifique a sua caixa de entrada",
- "auth.forgotSentBody": "Se o endereço tiver uma conta, enviámos um link válido por 30 minutos. Abra-o neste dispositivo.",
- "auth.backToLogin": "Voltar ao início de sessão",
- "auth.resetTitle": "Escolha uma nova palavra-passe",
- "auth.resetBody": "O link é válido por 30 minutos e de uso único. Todos os dispositivos serão desligados.",
- "auth.resetTokenPlaceholder": "Cole o código do e-mail",
- "auth.newPassword": "Nova palavra-passe (mín. 10 caracteres)",
- "auth.resetSubmit": "Alterar palavra-passe",
- "auth.resetDoneTitle": "Concluído!",
- "auth.resetDoneBody": "A palavra-passe foi alterada. Inicie sessão com a nova.",
- "auth.verifyDoneTitle": "E-mail confirmado",
- "auth.verifyDoneBody": "Obrigado! A sua conta está verificada.",
- "auth.verifyFailedTitle": "O link não funcionou",
- "auth.verifyFailedBody": "O link é inválido ou expirou. Peça um novo no perfil.",
- "onboarding.title": "Fale-nos um pouco de si",
- "onboarding.subtitle": "Tudo é opcional e pode ser alterado a qualquer momento. Quanto mais preencher, melhores as sugestões.",
- "onboarding.goal": "Qual é o seu objetivo principal?",
- "onboarding.diet": "Como come?",
+ "common.undo": "Desfazer",
+ "cooked.deductPantry": "Descontar ingredientes da despensa",
+ "cooked.deductPantryNote": "Os ingredientes são descontados da despensa: primeiro os que expiram antes.",
+ "cooked.mealBoxes": "Doses para marmitas",
+ "cooked.portionsCooked": "Doses cozinhadas",
+ "cooked.rate": "Avaliar",
+ "cooked.title": "Como correu?",
+ "cooked.whoAte": "Quem comeu?",
+ "cooking.finish": "Concluído – registar a refeição",
+ "cooking.keepAwake": "O ecrã fica ligado enquanto cozinha",
+ "cooking.scale": "Doses",
+ "cooking.step": "Passo {current} de {total}",
+ "cooking.timer": "Iniciar temporizador",
+ "cooking.timerDone": "Pronto!",
+ "cooking.timerRunning": "Faltam {time}",
+ "home.budget": "Orçamento alimentar",
+ "home.emptyInventory": "A despensa está vazia. Digitalize o frigorífico ou adicione manualmente.",
+ "home.expired": "Expirado",
+ "home.expiresIn_one": "Falta 1 dia",
+ "home.expiresIn_other": "Faltam {days} dias",
+ "home.expiresToday": "Expira hoje",
+ "home.household": "Agregado",
+ "home.inventory": "Despensa",
+ "home.mealBoxes": "Marmitas",
+ "home.moreItems_one": "+ mais 1 …",
+ "home.moreItems_other": "+ mais {count} …",
+ "home.pastBestBefore": "Validade ultrapassada – cheire e prove primeiro",
+ "home.shopping": "Lista de compras",
+ "home.thisWeek": "Esta semana",
+ "home.title": "Em casa",
+ "home.useSoon": "Usar em breve",
+ "home.useSoonHint": "„A consumir de preferência antes de” é sobre qualidade: cheire, observe e prove antes de deitar fora. Já a data-limite de consumo deve ser respeitada.",
+ "home.waste": "Desperdício",
+ "home.wasteWeek": "Desperdício esta semana",
+ "household.empty": "Ainda não tem um agregado. Crie um na configuração inicial ou junte-se com um código.",
+ "household.invite": "Convide com o código: {code}",
+ "household.locations": "Locais de armazenamento",
+ "household.members": "Membros",
+ "household.portionFactor": "×{factor} dose",
+ "household.private": "Privado por pessoa: objetivos, alergias, dados de saúde e histórico de refeições.",
+ "household.role.adult": "Adulto",
+ "household.role.child": "Criança",
+ "household.role.member": "Membro",
+ "household.role.owner": "Proprietário",
+ "household.shareCode": "Partilhe o código com a família para partilhar despensa, lista e plano.",
+ "household.shared": "Partilhado no agregado: despensa, lista de compras, plano semanal, marmitas e orçamento.",
+ "logmeal.manualTitle": "Manual",
+ "logmeal.mealTypeTitle": "Tipo de refeição",
+ "logmeal.photoTip": "Dica: fotografe o prato em Digitalizar e a app estima por si – você confirma sempre.",
+ "logmeal.proteinPlaceholder": "proteína (g)",
+ "logmeal.quickSubtitle": "Regista os mesmos valores nutricionais da última vez.",
+ "logmeal.quickTitle": "Registo rápido",
+ "logmeal.validationBody": "Nome e calorias são necessários para o registo manual.",
+ "logmeal.validationTitle": "Preencha",
+ "logmeal.whatPlaceholder": "O que comeu?",
+ "mealbox.eat": "Comer agora",
+ "mealbox.eatBy": "Comer até {date}",
+ "mealbox.empty": "Sem marmitas de momento. Ao cozinhar, pode guardar doses aqui.",
+ "mealbox.enjoyBody": "A dose foi registada em O meu dia.",
+ "mealbox.enjoyTitle": "Bom apetite!",
+ "mealbox.guidanceNote": "O prazo recomendado é indicativo: confie no cheiro e no sabor.",
+ "mealbox.portionsLeft_one": "Falta 1 dose",
+ "mealbox.portionsLeft_other": "Faltam {count} doses",
+ "mealbox.title": "Marmitas",
+ "memory.delete": "Apagar",
+ "memory.deleteAll": "Apagar toda a memória",
+ "memory.deleteAllTitle": "Apagar toda a memória?",
+ "memory.empty": "O {brand} ainda não aprendeu nada sobre si.",
+ "memory.irreversible": "Isto não pode ser anulado.",
+ "memory.origin.ai_inferred": "Suposição da IA",
+ "memory.origin.observed": "Padrão observado",
+ "memory.origin.user_stated": "Disse-nos você",
+ "memory.pause": "Pausar",
+ "memory.paused": "Em pausa",
+ "memory.resume": "Retomar",
+ "memory.subtitle": "Transparência total. Corrija, pause ou apague – a memória é sua.",
+ "memory.title": "O que o {brand} sabe sobre mim",
+ "memory.verified": "Verificado",
+ "memory.verify": "Correto",
+ "myday.calories": "Calorias",
+ "myday.carbs": "Hidratos",
+ "myday.estimateNote": "Valores com ~ são estimativas que pode ajustar.",
+ "myday.estimateRange": "{min}–{max} kcal, provavelmente {kcal}",
+ "myday.fat": "Gorduras",
+ "myday.fiber": "Fibras",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g de proteína",
+ "myday.logMeal": "Registar refeição",
+ "myday.mealType.breakfast": "Pequeno-almoço",
+ "myday.mealType.dessert": "Sobremesa",
+ "myday.mealType.dinner": "Jantar",
+ "myday.mealType.lunch": "Almoço",
+ "myday.mealType.snack": "Lanche",
+ "myday.noMeals": "Sem refeições registadas hoje.",
+ "myday.over": "{kcal} kcal acima do objetivo",
+ "myday.overRecommended": "Acima do recomendado",
+ "myday.protein": "Proteínas",
+ "myday.remaining": "Faltam {kcal} kcal",
+ "myday.salt": "Sal",
+ "myday.targetsNote": "Os objetivos são orientações, não aconselhamento médico.",
+ "myday.title": "O meu dia",
+ "myday.todaysMeals": "Refeições de hoje",
+ "onboarding.allergen.crustaceans": "Crustáceos",
+ "onboarding.allergen.eggs": "Ovos",
+ "onboarding.allergen.fish": "Peixe",
+ "onboarding.allergen.gluten": "Glúten",
+ "onboarding.allergen.milk": "Leite/lactose",
+ "onboarding.allergen.peanuts": "Amendoins",
+ "onboarding.allergen.sesame": "Sésamo",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Frutos de casca rija",
"onboarding.allergies": "Alergias e intolerâncias",
"onboarding.allergyNote": "O filtro de alergias é sempre rigoroso – pratos com os seus alergénios nunca são mostrados.",
+ "onboarding.birthYearPlaceholder": "Ano de nascimento",
+ "onboarding.bodyTitle": "Para objetivos calóricos pessoais (opcional)",
+ "onboarding.diet": "Como come?",
+ "onboarding.diet.flexitarian": "Flexitariano",
+ "onboarding.diet.omnivore": "Omnívoro",
+ "onboarding.diet.pescatarian": "Pescetariano",
+ "onboarding.diet.vegan": "Vegano",
+ "onboarding.diet.vegetarian": "Vegetariano",
+ "onboarding.goal": "Qual é o seu objetivo principal?",
+ "onboarding.goal.build_muscle": "Ganhar músculo",
+ "onboarding.goal.cook_more": "Cozinhar mais em casa",
+ "onboarding.goal.less_waste": "Reduzir o desperdício",
+ "onboarding.goal.lose_weight": "Perder peso",
+ "onboarding.goal.lower_cost": "Gastar menos em comida",
+ "onboarding.goal.maintain_weight": "Manter o peso",
+ "onboarding.goal.more_protein": "Comer mais proteína",
+ "onboarding.heightPlaceholder": "Altura (cm)",
"onboarding.household": "O seu agregado",
"onboarding.householdCreate": "Criar agregado",
+ "onboarding.householdDefaultName": "Casa",
"onboarding.householdJoin": "Aderir com código",
"onboarding.householdName": "Nome do agregado",
"onboarding.inviteCode": "Código de convite",
"onboarding.mode": "Que nível de precisão quer?",
- "onboarding.modeSimple": "Modo simples",
- "onboarding.modeSimpleDesc": "Fotografe a comida, aceite estimativas, zero complicações.",
"onboarding.modeExact": "Modo exato",
"onboarding.modeExactDesc": "Pese a comida, introduza gramas, controlo total dos números.",
+ "onboarding.modesCombine": "Os modos podem combinar-se: simples no dia a dia, exato quando quiser.",
+ "onboarding.modeSimple": "Modo simples",
+ "onboarding.modeSimpleDesc": "Fotografe a comida, aceite estimativas, zero complicações.",
"onboarding.notMedical": "{brand} dá orientações – não aconselhamento médico.",
- "wte.title": "O que vamos comer?",
- "wte.subtitle": "Com base no que têm em casa, no que deve ser usado em breve e no que gostam.",
- "wte.cravingPlaceholder": "Apetece-me … (ex.: cremoso, asiático, menos de 500 kcal)",
- "wte.mealBoxFirst": "Comida pronta em casa",
- "wte.whyTitle": "Porquê esta sugestão?",
- "wte.coverage": "{pct}% em casa",
- "wte.missing": "Falta: {items}",
- "wte.empty": "Ainda sem sugestões – adicione comida à despensa ou alivie os filtros.",
- "wte.refresh": "Novas sugestões",
- "scan.title": "Digitalizar",
- "scan.subtitle": "Abasteça a despensa ou registe uma refeição com a câmara.",
- "scan.fridge": "Frigorífico",
- "scan.freezer": "Congelador",
- "scan.pantry": "Despensa",
- "scan.ingredients": "Ingredientes",
- "scan.plate": "Prato",
- "scan.receipt": "Talão",
- "scan.barcode": "Código de barras",
- "scan.expiry": "Data de validade",
- "scan.nutrition": "Rótulo nutricional",
- "scan.takePhoto": "Tirar foto",
- "scan.tips.title": "Como obter a melhor análise",
- "scan.tips.overview": "Comece com uma foto geral",
- "scan.tips.shelf": "Fotografe prateleira a prateleira",
- "scan.tips.light": "Evite escuridão e sombras",
- "scan.tips.move": "Afaste produtos que se tapam",
- "scan.analyzing": "A analisar …",
- "scan.quotaLeft_one": "1 análise de IA restante este mês",
- "scan.quotaLeft_other": "{count} análises de IA restantes este mês",
- "scan.review.title": "Reveja o resultado",
- "scan.review.subtitle": "A IA às vezes hesita – você decide. Edite, remova ou acrescente antes de guardar.",
- "scan.review.uncertain": "Incerto – verifique",
- "scan.review.approveAll": "Guardar na despensa",
- "scan.review.rejected": "Removido",
- "scan.failed": "A análise falhou. Tente novamente ou adicione manualmente.",
- "myday.title": "O meu dia",
- "myday.calories": "Calorias",
- "myday.protein": "Proteínas",
- "myday.carbs": "Hidratos",
- "myday.fat": "Gorduras",
- "myday.fiber": "Fibras",
- "myday.salt": "Sal",
- "myday.remaining": "Faltam {kcal} kcal",
- "myday.over": "{kcal} kcal acima do objetivo",
- "myday.logMeal": "Registar refeição",
- "myday.noMeals": "Sem refeições registadas hoje.",
- "myday.estimateNote": "Valores com ~ são estimativas que pode ajustar.",
- "myday.targetsNote": "Os objetivos são orientações, não aconselhamento médico.",
- "home.title": "Em casa",
- "home.inventory": "Despensa",
- "home.useSoon": "Usar em breve",
- "home.mealBoxes": "Marmitas",
- "home.shopping": "Lista de compras",
- "home.budget": "Orçamento alimentar",
- "home.household": "Agregado",
- "home.waste": "Desperdício",
- "home.emptyInventory": "A despensa está vazia. Digitalize o frigorífico ou adicione manualmente.",
- "home.expiresIn_one": "Falta 1 dia",
- "home.expiresIn_other": "Faltam {days} dias",
- "home.expiresToday": "Expira hoje",
- "home.expired": "Expirado",
- "home.pastBestBefore": "Validade ultrapassada – cheire e prove primeiro",
+ "onboarding.stepBSubtitle": "Personaliza o teu perfil para melhores sugestões.",
+ "onboarding.stepBTitle": "Continuar configuração",
+ "onboarding.stepCSubtitle": "Opcional – usado para objetivos calóricos pessoais.",
+ "onboarding.stepCTitle": "O teu perfil de saúde",
+ "onboarding.subtitle": "Tudo é opcional e pode ser alterado a qualquer momento. Quanto mais preencher, melhores as sugestões.",
+ "onboarding.title": "Fale-nos um pouco de si",
+ "onboarding.weightPlaceholder": "Peso (kg)",
+ "paywall.choose": "Escolher",
+ "paywall.fairUse": "Quota de utilização justa de análises de IA incluída.",
+ "paywall.family": "Family · até 6 pessoas",
+ "paywall.freeNote": "Grátis: 10 análises de IA/mês, despensa manual, receitas guardadas e registo simples.",
+ "paywall.household": "Household · até 3 pessoas",
+ "paywall.large": "Large Household · até 12 pessoas",
+ "paywall.perMonth": "{price}/mês",
+ "paywall.popular": "Mais popular",
+ "paywall.restore": "Restaurar compras",
+ "paywall.soonBody": "As compras ativam-se via App Store/Google Play quando a integração com as lojas for ligada (fase 7). O fluxo de backend já está pronto.",
+ "paywall.soonTitle": "Em breve!",
+ "paywall.subtitle": "O sistema operativo alimentar de todo o agregado: despensa ilimitada, plano semanal e partilha.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "Falta 1 dia de período experimental",
+ "paywall.trialActive_other": "Faltam {days} dias de período experimental",
+ "profile.aiScansUsed": "Digitalizações de IA: {used} / {total} este mês",
+ "profile.consent.anonymized_improvement": "Melhoria anonimizada da IA",
+ "profile.consent.health_integration": "Dados de saúde (Apple Health / Health Connect)",
+ "profile.consent.image_training": "As minhas fotos podem ser usadas para treino",
+ "profile.consent.location_weather": "Localização para sugestões conforme o tempo",
+ "profile.consent.personalization": "Funções pessoais (memória e perfil de gosto)",
+ "profile.consent.product_analytics": "Análise de produto",
+ "profile.consent.push_notifications": "Notificações push",
+ "profile.consents": "Consentimentos e dados",
+ "profile.consentsNote": "Os consentimentos são separados: as funções pessoais nunca exigem consentimento de treino.",
+ "profile.deleteAccount": "Eliminar conta",
+ "profile.deleteBody": "Todos os seus dados são apagados permanentemente conforme o RGPD.",
+ "profile.deleteTitle": "Apagar a conta?",
+ "profile.emailUnverified": "Endereço de e-mail não confirmado",
+ "profile.export": "Exportar os meus dados",
+ "profile.goals": "Objetivos e alimentação",
+ "profile.language": "Idioma",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Terminar sessão",
+ "profile.memory": "O que o {brand} sabe sobre mim",
+ "profile.memorySubtitle": "Veja, corrija, pause ou apague o que a plataforma aprendeu.",
+ "profile.modeLabel": "Modo:",
+ "profile.resendVerification": "Reenviar e-mail de confirmação",
+ "profile.subscription": "Subscrição",
+ "profile.title": "Perfil",
+ "profile.verificationSent": "Enviado! Verifique a caixa de entrada.",
+ "recipe.avgRating": "Média {avg} em {count} avaliações",
+ "recipe.cook": "Cozinhar agora",
+ "recipe.cost": "aprox. {amount}/dose",
+ "recipe.iCookedThis": "Cozinhei isto",
+ "recipe.ingredients": "Ingredientes",
+ "recipe.notSafe": "Não se adequa às suas definições alimentares",
+ "recipe.perPortion": "por dose",
"recipe.portions_one": "1 dose",
"recipe.portions_other": "{count} doses",
- "recipe.time": "{min} min",
- "recipe.perPortion": "por dose",
- "recipe.ingredients": "Ingredientes",
+ "recipe.save": "Guardar",
+ "recipe.saved": "Guardada",
"recipe.steps": "Preparação",
- "recipe.cook": "Cozinhar agora",
- "recipe.notSafe": "Não se adequa às suas definições alimentares",
"recipe.substitutions": "Substituir",
- "recipe.iCookedThis": "Cozinhei isto",
- "recipe.cost": "aprox. {amount}/dose",
- "cooking.step": "Passo {current} de {total}",
- "cooking.timer": "Iniciar temporizador",
- "cooking.timerRunning": "Faltam {time}",
- "cooking.finish": "Concluído – registar a refeição",
- "cooking.scale": "Doses",
- "cooking.keepAwake": "O ecrã fica ligado enquanto cozinha",
- "cooked.title": "Como correu?",
- "cooked.portionsCooked": "Doses cozinhadas",
- "cooked.whoAte": "Quem comeu?",
- "cooked.mealBoxes": "Doses para marmitas",
- "cooked.deductPantry": "Descontar ingredientes da despensa",
- "cooked.rate": "Avaliar",
- "shopping.title": "Lista de compras",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "A analisar …",
+ "scan.barcode": "Código de barras",
+ "scan.expiry": "Data de validade",
+ "scan.failed": "A análise falhou. Tente novamente ou adicione manualmente.",
+ "scan.freezer": "Congelador",
+ "scan.fridge": "Frigorífico",
+ "scan.ingredients": "Ingredientes",
+ "scan.nutrition": "Rótulo nutricional",
+ "scan.pantry": "Despensa",
+ "scan.plate": "Prato",
+ "scan.quotaLeft_one": "1 análise de IA restante este mês",
+ "scan.quotaLeft_other": "{count} análises de IA restantes este mês",
+ "scan.receipt": "Talão",
+ "scan.review.addItem": "+ Adicionar produto",
+ "scan.review.approveAll": "Guardar na despensa",
+ "scan.review.bestBeforeNote": "Data de qualidade: o alimento pode estar bom depois dela. Cheire e prove antes de deitar fora.",
+ "scan.review.dateKindBestBefore": "Preferencialmente antes de",
+ "scan.review.dateKindUseBy": "Data-limite de consumo",
+ "scan.review.datePlaceholder": "AAAA-MM-DD (opcional)",
+ "scan.review.itemPlaceholder": "Produto",
+ "scan.review.quantityPlaceholder": "Quantidade",
+ "scan.review.rejected": "Removido",
+ "scan.review.subtitle": "A IA às vezes hesita – você decide. Edite, remova ou acrescente antes de guardar.",
+ "scan.review.title": "Reveja o resultado",
+ "scan.review.uncertain": "Incerto – verifique",
+ "scan.review.unitPlaceholder": "Unidade (g, l, un. …)",
+ "scan.review.unknownItem": "Produto desconhecido",
+ "scan.review.useByNote": "Data de segurança: não coma depois desta data.",
+ "scan.subtitle": "Abasteça a despensa ou registe uma refeição com a câmara.",
+ "scan.takePhoto": "Tirar foto",
+ "scan.tips.light": "Evite escuridão e sombras",
+ "scan.tips.move": "Afaste produtos que se tapam",
+ "scan.tips.overview": "Comece com uma foto geral",
+ "scan.tips.shelf": "Fotografe prateleira a prateleira",
+ "scan.tips.title": "Como obter a melhor análise",
+ "scan.title": "Digitalizar",
"shopping.addPlaceholder": "Adicionar artigo …",
"shopping.complete": "Terminar as compras",
+ "shopping.completedBody_one": "1 produto foi adicionado à despensa.",
+ "shopping.completedBody_other": "{count} produtos foram adicionados à despensa.",
+ "shopping.completedTitle": "Feito!",
"shopping.completeNote": "Os artigos marcados vão para a despensa.",
"shopping.empty": "A lista está vazia.",
"shopping.estimated": "aprox. {amount}",
"shopping.estimatedTotal": "Total estimado: aprox. {amount}",
- "mealbox.title": "Marmitas",
- "mealbox.eatBy": "Comer até {date}",
- "mealbox.portionsLeft_one": "Falta 1 dose",
- "mealbox.portionsLeft_other": "Faltam {count} doses",
- "mealbox.eat": "Comer agora",
- "mealbox.empty": "Sem marmitas de momento. Ao cozinhar, pode guardar doses aqui.",
- "household.members": "Membros",
- "household.invite": "Convide com o código: {code}",
- "household.shared": "Partilhado no agregado: despensa, lista de compras, plano semanal, marmitas e orçamento.",
- "household.private": "Privado por pessoa: objetivos, alergias, dados de saúde e histórico de refeições.",
- "memory.title": "O que o {brand} sabe sobre mim",
- "memory.subtitle": "Transparência total. Corrija, pause ou apague – a memória é sua.",
- "memory.paused": "Em pausa",
- "memory.verify": "Correto",
- "memory.pause": "Pausar",
- "memory.delete": "Apagar",
- "memory.deleteAll": "Apagar toda a memória",
- "memory.empty": "O {brand} ainda não aprendeu nada sobre si.",
- "memory.origin.user_stated": "Disse-nos você",
- "memory.origin.observed": "Padrão observado",
- "memory.origin.ai_inferred": "Suposição da IA",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "O sistema operativo alimentar de todo o agregado: despensa ilimitada, plano semanal e partilha.",
- "paywall.trialActive_one": "Falta 1 dia de período experimental",
- "paywall.trialActive_other": "Faltam {days} dias de período experimental",
- "paywall.household": "Household · até 3 pessoas",
- "paywall.family": "Family · até 6 pessoas",
- "paywall.large": "Large Household · até 12 pessoas",
- "paywall.perMonth": "{price}/mês",
- "paywall.fairUse": "Quota de utilização justa de análises de IA incluída.",
- "paywall.restore": "Restaurar compras",
- "paywall.freeNote": "Grátis: 10 análises de IA/mês, despensa manual, receitas guardadas e registo simples.",
- "profile.title": "Perfil",
- "profile.goals": "Objetivos e alimentação",
- "profile.consents": "Consentimentos e dados",
- "profile.memory": "O que o {brand} sabe sobre mim",
- "profile.subscription": "Subscrição",
- "profile.logout": "Terminar sessão",
- "profile.export": "Exportar os meus dados",
- "profile.deleteAccount": "Eliminar conta",
- "profile.language": "Idioma",
- "profile.emailUnverified": "Endereço de e-mail não confirmado",
- "profile.resendVerification": "Reenviar e-mail de confirmação",
- "profile.verificationSent": "Enviado! Verifique a caixa de entrada.",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Ops",
- "common.undo": "Desfazer",
- "common.remove": "Remover",
- "common.add": "Adicionar",
- "common.on": "Ativado",
- "common.off": "Desativado",
- "home.thisWeek": "Esta semana",
- "home.wasteWeek": "Desperdício esta semana",
- "home.useSoonHint": "„A consumir de preferência antes de” é sobre qualidade: cheire, observe e prove antes de deitar fora. Já a data-limite de consumo deve ser respeitada.",
- "scan.review.itemPlaceholder": "Produto",
- "scan.review.quantityPlaceholder": "Quantidade",
- "scan.review.unitPlaceholder": "Unidade (g, l, un. …)",
- "scan.review.datePlaceholder": "AAAA-MM-DD (opcional)",
- "scan.review.dateKindBestBefore": "Preferencialmente antes de",
- "scan.review.dateKindUseBy": "Data-limite de consumo",
- "scan.review.bestBeforeNote": "Data de qualidade: o alimento pode estar bom depois dela. Cheire e prove antes de deitar fora.",
- "scan.review.useByNote": "Data de segurança: não coma depois desta data.",
- "scan.review.addItem": "+ Adicionar produto",
- "scan.review.unknownItem": "Produto desconhecido",
- "barcode.aim": "Aponte a câmara para o código de barras",
- "barcode.addPrompt": "Adicionar à despensa?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Sem dados nutricionais",
- "barcode.unknownTitle": "Produto desconhecido",
- "barcode.unknownBody": "Este produto ainda não está na base de dados. Fotografe a frente e o rótulo nutricional e nós adicionamo-lo.",
- "barcode.photoPackage": "Fotografar a embalagem",
- "barcode.needHousehold": "Primeiro precisa de um agregado.",
- "barcode.noLocation": "Nenhum local de armazenamento encontrado.",
- "barcode.cameraTitle": "É precisa a câmara",
- "barcode.cameraBody": "O {brand} precisa da câmara para ler códigos de barras.",
- "barcode.allowCamera": "Permitir câmara",
- "onboarding.goal.lose_weight": "Perder peso",
- "onboarding.goal.build_muscle": "Ganhar músculo",
- "onboarding.goal.maintain_weight": "Manter o peso",
- "onboarding.goal.more_protein": "Comer mais proteína",
- "onboarding.goal.less_waste": "Reduzir o desperdício",
- "onboarding.goal.lower_cost": "Gastar menos em comida",
- "onboarding.goal.cook_more": "Cozinhar mais em casa",
- "onboarding.diet.omnivore": "Omnívoro",
- "onboarding.diet.flexitarian": "Flexitariano",
- "onboarding.diet.pescatarian": "Pescetariano",
- "onboarding.diet.vegetarian": "Vegetariano",
- "onboarding.diet.vegan": "Vegano",
- "onboarding.allergen.gluten": "Glúten",
- "onboarding.allergen.milk": "Leite/lactose",
- "onboarding.allergen.eggs": "Ovos",
- "onboarding.allergen.tree_nuts": "Frutos de casca rija",
- "onboarding.allergen.peanuts": "Amendoins",
- "onboarding.allergen.fish": "Peixe",
- "onboarding.allergen.crustaceans": "Crustáceos",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sésamo",
- "onboarding.bodyTitle": "Para objetivos calóricos pessoais (opcional)",
- "onboarding.weightPlaceholder": "Peso (kg)",
- "onboarding.heightPlaceholder": "Altura (cm)",
- "onboarding.birthYearPlaceholder": "Ano de nascimento",
- "onboarding.householdDefaultName": "Casa",
- "onboarding.modesCombine": "Os modos podem combinar-se: simples no dia a dia, exato quando quiser.",
- "myday.mealType.breakfast": "Pequeno-almoço",
- "myday.mealType.lunch": "Almoço",
- "myday.mealType.dinner": "Jantar",
- "myday.mealType.snack": "Lanche",
- "myday.mealType.dessert": "Sobremesa",
- "myday.overRecommended": "Acima do recomendado",
- "myday.todaysMeals": "Refeições de hoje",
- "myday.estimateRange": "{min}–{max} kcal, provavelmente {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g de proteína",
- "logmeal.mealTypeTitle": "Tipo de refeição",
- "logmeal.quickTitle": "Registo rápido",
- "logmeal.quickSubtitle": "Regista os mesmos valores nutricionais da última vez.",
- "logmeal.manualTitle": "Manual",
- "logmeal.whatPlaceholder": "O que comeu?",
- "logmeal.proteinPlaceholder": "proteína (g)",
- "logmeal.validationTitle": "Preencha",
- "logmeal.validationBody": "Nome e calorias são necessários para o registo manual.",
- "logmeal.photoTip": "Dica: fotografe o prato em Digitalizar e a app estima por si – você confirma sempre.",
- "shopping.section.frukt_gront": "Fruta e legumes",
"shopping.section.brod": "Pão",
- "shopping.section.mejeri": "Laticínios",
- "shopping.section.kott_fagel": "Carne e aves",
- "shopping.section.fisk": "Peixe",
"shopping.section.chark": "Charcutaria",
- "shopping.section.frys": "Congelados",
- "shopping.section.skafferi": "Despensa",
- "shopping.section.konserver": "Conservas",
- "shopping.section.kryddor_bak": "Especiarias e pastelaria",
"shopping.section.dryck": "Bebidas",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Peixe",
+ "shopping.section.frukt_gront": "Fruta e legumes",
+ "shopping.section.frys": "Congelados",
"shopping.section.hygien_ovrigt": "Outros",
- "shopping.completedTitle": "Feito!",
- "household.role.owner": "Proprietário",
- "household.role.adult": "Adulto",
- "household.role.member": "Membro",
- "household.role.child": "Criança",
- "household.empty": "Ainda não tem um agregado. Crie um na configuração inicial ou junte-se com um código.",
- "household.shareCode": "Partilhe o código com a família para partilhar despensa, lista e plano.",
- "household.locations": "Locais de armazenamento",
- "household.portionFactor": "×{factor} dose",
- "mealbox.enjoyTitle": "Bom apetite!",
- "mealbox.enjoyBody": "A dose foi registada em O meu dia.",
- "mealbox.guidanceNote": "O prazo recomendado é indicativo: confie no cheiro e no sabor.",
- "paywall.soonTitle": "Em breve!",
- "paywall.soonBody": "As compras ativam-se via App Store/Google Play quando a integração com as lojas for ligada (fase 7). O fluxo de backend já está pronto.",
- "paywall.popular": "Mais popular",
- "paywall.choose": "Escolher",
- "recipe.saved": "Guardada",
- "recipe.save": "Guardar",
- "recipe.avgRating": "Média {avg} em {count} avaliações",
- "memory.verified": "Verificado",
- "memory.resume": "Retomar",
- "memory.deleteAllTitle": "Apagar toda a memória?",
- "memory.irreversible": "Isto não pode ser anulado.",
- "profile.consent.personalization": "Funções pessoais (memória e perfil de gosto)",
- "profile.consent.anonymized_improvement": "Melhoria anonimizada da IA",
- "profile.consent.image_training": "As minhas fotos podem ser usadas para treino",
- "profile.consent.health_integration": "Dados de saúde (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Localização para sugestões conforme o tempo",
- "profile.consent.push_notifications": "Notificações push",
- "profile.modeLabel": "Modo:",
- "profile.memorySubtitle": "Veja, corrija, pause ou apague o que a plataforma aprendeu.",
- "profile.consentsNote": "Os consentimentos são separados: as funções pessoais nunca exigem consentimento de treino.",
- "profile.aiScansUsed": "Digitalizações de IA: {used} / {total} este mês",
- "profile.deleteTitle": "Apagar a conta?",
- "profile.deleteBody": "Todos os seus dados são apagados permanentemente conforme o RGPD.",
- "cooking.timerDone": "Pronto!",
- "cooked.deductPantryNote": "Os ingredientes são descontados da despensa: primeiro os que expiram antes.",
- "home.moreItems_one": "+ mais 1 …",
- "home.moreItems_other": "+ mais {count} …",
- "shopping.completedBody_one": "1 produto foi adicionado à despensa.",
- "shopping.completedBody_other": "{count} produtos foram adicionados à despensa.",
- "profile.consent.product_analytics": "Análise de produto"
+ "shopping.section.konserver": "Conservas",
+ "shopping.section.kott_fagel": "Carne e aves",
+ "shopping.section.kryddor_bak": "Especiarias e pastelaria",
+ "shopping.section.mejeri": "Laticínios",
+ "shopping.section.skafferi": "Despensa",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Lista de compras",
+ "tabs.home": "Em casa",
+ "tabs.myDay": "O meu dia",
+ "tabs.scan": "Digitalizar",
+ "tabs.whatToEat": "O que vamos comer?",
+ "wte.coverage": "{pct}% em casa",
+ "wte.cravingPlaceholder": "Apetece-me … (ex.: cremoso, asiático, menos de 500 kcal)",
+ "wte.empty": "Ainda sem sugestões – adicione comida à despensa ou alivie os filtros.",
+ "wte.mealBoxFirst": "Comida pronta em casa",
+ "wte.missing": "Falta: {items}",
+ "wte.refresh": "Novas sugestões",
+ "wte.subtitle": "Com base no que têm em casa, no que deve ser usado em breve e no que gostam.",
+ "wte.title": "O que vamos comer?",
+ "wte.whyTitle": "Porquê esta sugestão?"
}
diff --git a/apps/mobile/src/locales/sv/common.json b/apps/mobile/src/locales/sv/common.json
index 5ecfad8..1f5a514 100644
--- a/apps/mobile/src/locales/sv/common.json
+++ b/apps/mobile/src/locales/sv/common.json
@@ -1,339 +1,343 @@
{
- "common.loading": "Laddar …",
+ "auth.backToLogin": "Tillbaka till inloggning",
+ "auth.displayName": "Vad ska vi kalla dig?",
+ "auth.email": "E-post",
+ "auth.forgotBody": "Ange din e-postadress så skickar vi en återställningslänk om kontot finns.",
+ "auth.forgotLink": "Glömt lösenordet?",
+ "auth.forgotSentBody": "Om adressen har ett konto har vi skickat en länk som gäller i 30 minuter. Öppna den på den här enheten.",
+ "auth.forgotSentTitle": "Kolla din inkorg",
+ "auth.forgotSubmit": "Skicka länk",
+ "auth.forgotTitle": "Återställ lösenord",
+ "auth.hasAccount": "Har du redan ett konto? Logga in",
+ "auth.login": "Logga in",
+ "auth.newPassword": "Nytt lösenord (minst 10 tecken)",
+ "auth.noAccount": "Ny här? Skapa konto",
+ "auth.password": "Lösenord",
+ "auth.register": "Skapa konto",
+ "auth.resetBody": "Länken gäller i 30 minuter och kan bara användas en gång. Alla enheter loggas ut när lösenordet byts.",
+ "auth.resetDoneBody": "Ditt lösenord är bytt. Logga in med det nya lösenordet.",
+ "auth.resetDoneTitle": "Klart!",
+ "auth.resetSubmit": "Byt lösenord",
+ "auth.resetTitle": "Välj nytt lösenord",
+ "auth.resetTokenPlaceholder": "Klistra in koden från mejlet",
+ "auth.trialNote": "7 dagars full tillgång – inget kort behövs.",
+ "auth.verifyDoneBody": "Tack! Ditt konto är nu verifierat.",
+ "auth.verifyDoneTitle": "E-postadressen är bekräftad",
+ "auth.verifyFailedBody": "Länken är ogiltig eller har gått ut. Begär en ny från profilen.",
+ "auth.verifyFailedTitle": "Länken fungerade inte",
+ "barcode.addPrompt": "Lägga till i lagret?",
+ "barcode.aim": "Rikta kameran mot streckkoden",
+ "barcode.allowCamera": "Tillåt kamera",
+ "barcode.cameraBody": "För att skanna streckkoder behöver {brand} kameran.",
+ "barcode.cameraTitle": "Kameran behövs",
+ "barcode.kcalPer100": "{kcal} kcal/100 g",
+ "barcode.needHousehold": "Du behöver ett hushåll först.",
+ "barcode.noLocation": "Ingen förvaringsplats hittades.",
+ "barcode.noNutrition": "Näringsdata saknas",
+ "barcode.photoPackage": "Fota förpackningen",
+ "barcode.unknownBody": "Produkten finns inte i databasen ännu. Fota framsidan och näringsdeklarationen så lägger vi till den.",
+ "barcode.unknownTitle": "Okänd produkt",
+ "common.add": "Lägg till",
+ "common.back": "Tillbaka",
+ "common.cancel": "Avbryt",
+ "common.done": "Klar",
"common.error": "Något gick fel. Försök igen.",
+ "common.estimate": "Uppskattning",
+ "common.loading": "Laddar …",
+ "common.next": "Nästa",
+ "common.off": "Av",
+ "common.offline": "Offline – visar senast hämtade data",
+ "common.on": "På",
+ "common.oops": "Hoppsan",
+ "common.remove": "Ta bort",
"common.retry": "Försök igen",
"common.save": "Spara",
- "common.cancel": "Avbryt",
- "common.next": "Nästa",
- "common.back": "Tillbaka",
- "common.done": "Klar",
"common.skip": "Hoppa över",
- "common.offline": "Offline – visar senast hämtade data",
- "common.estimate": "Uppskattning",
- "tabs.whatToEat": "Vad ska vi äta?",
- "tabs.scan": "Skanna",
- "tabs.myDay": "Min dag",
- "tabs.home": "Hemma",
- "auth.login": "Logga in",
- "auth.register": "Skapa konto",
- "auth.email": "E-post",
- "auth.password": "Lösenord",
- "auth.displayName": "Vad ska vi kalla dig?",
- "auth.noAccount": "Ny här? Skapa konto",
- "auth.hasAccount": "Har du redan ett konto? Logga in",
- "auth.trialNote": "7 dagars full tillgång – inget kort behövs.",
- "onboarding.title": "Berätta lite om dig",
- "onboarding.subtitle": "Allt är frivilligt och kan ändras när som helst. Ju mer du fyller i, desto bättre förslag.",
- "onboarding.goal": "Vad är ditt främsta mål?",
- "onboarding.diet": "Hur äter du?",
+ "common.undo": "Ångra",
+ "cooked.deductPantry": "Dra ingredienser från lagret",
+ "cooked.deductPantryNote": "Ingredienserna dras från lagret enligt först-utgången-först.",
+ "cooked.mealBoxes": "Portioner till matlådor",
+ "cooked.portionsCooked": "Portioner lagade",
+ "cooked.rate": "Betygsätt",
+ "cooked.title": "Hur gick det?",
+ "cooked.whoAte": "Vilka åt?",
+ "cooking.finish": "Klart – logga måltiden",
+ "cooking.keepAwake": "Skärmen hålls vaken medan du lagar",
+ "cooking.scale": "Portioner",
+ "cooking.step": "Steg {current} av {total}",
+ "cooking.timer": "Starta timer",
+ "cooking.timerDone": "Klart!",
+ "cooking.timerRunning": "{time} kvar",
+ "home.budget": "Matbudget",
+ "home.emptyInventory": "Lagret är tomt. Skanna kylen eller lägg till varor manuellt.",
+ "home.expired": "Utgången",
+ "home.expiresIn_one": "1 dag kvar",
+ "home.expiresIn_other": "{days} dagar kvar",
+ "home.expiresToday": "Går ut i dag",
+ "home.household": "Hushåll",
+ "home.inventory": "Matlager",
+ "home.mealBoxes": "Matlådor",
+ "home.moreItems_one": "+ 1 till …",
+ "home.moreItems_other": "+ {count} till …",
+ "home.pastBestBefore": "Passerat bäst före – lukta och smaka",
+ "home.shopping": "Inköpslista",
+ "home.thisWeek": "Denna vecka",
+ "home.title": "Hemma",
+ "home.useSoon": "Använd snart",
+ "home.useSoonHint": "Bäst före handlar om kvalitet – lukta, titta och smaka innan du slänger. Sista förbrukningsdag ska däremot respekteras.",
+ "home.waste": "Matsvinn",
+ "home.wasteWeek": "Matsvinn denna vecka",
+ "household.empty": "Du har inget hushåll ännu. Skapa ett i onboardingen eller gå med via kod.",
+ "household.invite": "Bjud in med kod: {code}",
+ "household.locations": "Förvaringsplatser",
+ "household.members": "Medlemmar",
+ "household.portionFactor": "×{factor} portion",
+ "household.private": "Privat per person: mål, allergier, hälsodata och måltidshistorik.",
+ "household.role.adult": "Vuxen",
+ "household.role.child": "Barn",
+ "household.role.member": "Medlem",
+ "household.role.owner": "Ägare",
+ "household.shareCode": "Dela koden med familjen så delar ni lager, lista och plan.",
+ "household.shared": "Delas i hushållet: matlager, inköpslista, veckoplan, matlådor och budget.",
+ "logmeal.manualTitle": "Manuellt",
+ "logmeal.mealTypeTitle": "Måltidstyp",
+ "logmeal.photoTip": "Tips: fota tallriken under Skanna så uppskattar appen åt dig – du bekräftar alltid.",
+ "logmeal.proteinPlaceholder": "protein (g)",
+ "logmeal.quickSubtitle": "Loggar samma näringsvärden som förra gången.",
+ "logmeal.quickTitle": "Snabb återloggning",
+ "logmeal.validationBody": "Namn och kalorier behövs för manuell loggning.",
+ "logmeal.validationTitle": "Fyll i",
+ "logmeal.whatPlaceholder": "Vad åt du?",
+ "mealbox.eat": "Ät nu",
+ "mealbox.eatBy": "Ät senast {date}",
+ "mealbox.empty": "Inga matlådor just nu. När du lagar mat kan du spara portioner här.",
+ "mealbox.enjoyBody": "Portionen är loggad i Min dag.",
+ "mealbox.enjoyTitle": "Smaklig måltid!",
+ "mealbox.guidanceNote": "Rekommenderad användningstid är vägledning – lita på lukt och smak.",
+ "mealbox.portionsLeft_one": "1 portion kvar",
+ "mealbox.portionsLeft_other": "{count} portioner kvar",
+ "mealbox.title": "Matlådor",
+ "memory.delete": "Radera",
+ "memory.deleteAll": "Radera allt minne",
+ "memory.deleteAllTitle": "Radera allt minne?",
+ "memory.empty": "{brand} har inte lärt sig något om dig ännu.",
+ "memory.irreversible": "Detta går inte att ångra.",
+ "memory.origin.ai_inferred": "AI-antagande",
+ "memory.origin.observed": "Observerat mönster",
+ "memory.origin.user_stated": "Du har berättat",
+ "memory.pause": "Pausa",
+ "memory.paused": "Pausad",
+ "memory.resume": "Återuppta",
+ "memory.subtitle": "Full insyn. Rätta det som är fel, pausa eller radera – du äger ditt minne.",
+ "memory.title": "Vad {brand} vet om mig",
+ "memory.verified": "Verifierad",
+ "memory.verify": "Stämmer",
+ "myday.calories": "Kalorier",
+ "myday.carbs": "Kolhydrater",
+ "myday.estimateNote": "Värden med ~ är uppskattningar som du kan justera.",
+ "myday.estimateRange": "{min}–{max} kcal, troligen {kcal}",
+ "myday.fat": "Fett",
+ "myday.fiber": "Fibrer",
+ "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
+ "myday.logMeal": "Logga måltid",
+ "myday.mealType.breakfast": "Frukost",
+ "myday.mealType.dessert": "Efterrätt",
+ "myday.mealType.dinner": "Middag",
+ "myday.mealType.lunch": "Lunch",
+ "myday.mealType.snack": "Mellanmål",
+ "myday.noMeals": "Inga måltider loggade i dag.",
+ "myday.over": "{kcal} kcal över målet",
+ "myday.overRecommended": "Över rekommenderat",
+ "myday.protein": "Protein",
+ "myday.remaining": "{kcal} kcal kvar",
+ "myday.salt": "Salt",
+ "myday.targetsNote": "Målen är vägledning, inte medicinsk rådgivning.",
+ "myday.title": "Min dag",
+ "myday.todaysMeals": "Dagens måltider",
+ "onboarding.allergen.crustaceans": "Skaldjur",
+ "onboarding.allergen.eggs": "Ägg",
+ "onboarding.allergen.fish": "Fisk",
+ "onboarding.allergen.gluten": "Gluten",
+ "onboarding.allergen.milk": "Mjölk/laktos",
+ "onboarding.allergen.peanuts": "Jordnötter",
+ "onboarding.allergen.sesame": "Sesam",
+ "onboarding.allergen.soy": "Soja",
+ "onboarding.allergen.tree_nuts": "Nötter",
"onboarding.allergies": "Allergier och intoleranser",
"onboarding.allergyNote": "Allergifiltrering är alltid strikt – rätter med dina allergener visas aldrig.",
+ "onboarding.birthYearPlaceholder": "Födelseår",
+ "onboarding.bodyTitle": "För personliga kalorimål (frivilligt)",
+ "onboarding.diet": "Hur äter du?",
+ "onboarding.diet.flexitarian": "Flexitarian",
+ "onboarding.diet.omnivore": "Allätare",
+ "onboarding.diet.pescatarian": "Pescetarian",
+ "onboarding.diet.vegan": "Vegan",
+ "onboarding.diet.vegetarian": "Vegetarian",
+ "onboarding.goal": "Vad är ditt främsta mål?",
+ "onboarding.goal.build_muscle": "Bygga muskler",
+ "onboarding.goal.cook_more": "Laga mer hemma",
+ "onboarding.goal.less_waste": "Minska matsvinn",
+ "onboarding.goal.lose_weight": "Gå ner i vikt",
+ "onboarding.goal.lower_cost": "Sänka matkostnaden",
+ "onboarding.goal.maintain_weight": "Behålla vikten",
+ "onboarding.goal.more_protein": "Äta mer protein",
+ "onboarding.heightPlaceholder": "Längd (cm)",
"onboarding.household": "Ditt hushåll",
"onboarding.householdCreate": "Skapa hushåll",
+ "onboarding.householdDefaultName": "Hemma",
"onboarding.householdJoin": "Gå med via kod",
"onboarding.householdName": "Hushållets namn",
"onboarding.inviteCode": "Inbjudningskod",
"onboarding.mode": "Hur noggrann vill du vara?",
- "onboarding.modeSimple": "Enkelt läge",
- "onboarding.modeSimpleDesc": "Fota maten, acceptera uppskattningar, minimalt pyssel.",
"onboarding.modeExact": "Exakt läge",
"onboarding.modeExactDesc": "Väg mat, ange gram, full kontroll på siffrorna.",
+ "onboarding.modesCombine": "Lägena kan kombineras – enkelt till vardags, exakt när du vill.",
+ "onboarding.modeSimple": "Enkelt läge",
+ "onboarding.modeSimpleDesc": "Fota maten, acceptera uppskattningar, minimalt pyssel.",
"onboarding.notMedical": "{brand} ger vägledning – inte medicinsk rådgivning.",
- "wte.title": "Vad ska vi äta?",
- "wte.subtitle": "Utifrån vad ni har hemma, vad som bör användas och vad ni gillar.",
- "wte.cravingPlaceholder": "Jag är sugen på … (t.ex. krämigt, asiatiskt, under 500 kcal)",
- "wte.mealBoxFirst": "Färdig mat hemma",
- "wte.whyTitle": "Varför detta förslag?",
- "wte.coverage": "{pct} % hemma",
- "wte.missing": "Saknas: {items}",
- "wte.empty": "Inga förslag ännu – lägg in lite mat i lagret eller lätta på filtren.",
- "wte.refresh": "Nya förslag",
- "scan.title": "Skanna",
- "scan.subtitle": "Fyll på matlagret eller logga en måltid med kameran.",
- "scan.fridge": "Kyl",
- "scan.freezer": "Frys",
- "scan.pantry": "Skafferi",
- "scan.ingredients": "Ingredienser",
- "scan.plate": "Tallrik",
- "scan.receipt": "Kvitto",
+ "onboarding.stepBSubtitle": "Anpassa din profil för bättre förslag.",
+ "onboarding.stepBTitle": "Fortsätt konfiguration",
+ "onboarding.stepCSubtitle": "Valfritt – används för personliga kalorimål.",
+ "onboarding.stepCTitle": "Din hälsoprofil",
+ "onboarding.subtitle": "Allt är frivilligt och kan ändras när som helst. Ju mer du fyller i, desto bättre förslag.",
+ "onboarding.title": "Berätta lite om dig",
+ "onboarding.weightPlaceholder": "Vikt (kg)",
+ "paywall.choose": "Välj",
+ "paywall.fairUse": "Fair use-kvot för AI-skanningar ingår.",
+ "paywall.family": "Family · upp till 6 personer",
+ "paywall.freeNote": "Gratis: 10 AI-skanningar/mån, manuellt lager, sparade recept och enkel loggning.",
+ "paywall.household": "Household · upp till 3 personer",
+ "paywall.large": "Large Household · upp till 12 personer",
+ "paywall.perMonth": "{price}/mån",
+ "paywall.popular": "Populärast",
+ "paywall.restore": "Återställ köp",
+ "paywall.soonBody": "Köp aktiveras via App Store/Google Play när butiksintegrationen slås på (fas 7). Backend-flödet är redan klart.",
+ "paywall.soonTitle": "Snart!",
+ "paywall.subtitle": "Hela hushållets mat-OS: obegränsat lager, veckoplan och delning.",
+ "paywall.title": "{brand} Premium",
+ "paywall.trialActive_one": "1 dag kvar av din provperiod",
+ "paywall.trialActive_other": "{days} dagar kvar av din provperiod",
+ "profile.aiScansUsed": "AI-skanningar: {used} / {total} denna månad",
+ "profile.consent.anonymized_improvement": "Anonymiserad förbättring av AI:n",
+ "profile.consent.health_integration": "Hälsodata (Apple Health / Health Connect)",
+ "profile.consent.image_training": "Mina bilder får användas för träning",
+ "profile.consent.location_weather": "Plats för väderbaserade förslag",
+ "profile.consent.personalization": "Personliga funktioner (minne & smakprofil)",
+ "profile.consent.product_analytics": "Produktanalys",
+ "profile.consent.push_notifications": "Push-notiser",
+ "profile.consents": "Samtycken & data",
+ "profile.consentsNote": "Samtyckena är separata – personlig funktion kräver aldrig träningssamtycke.",
+ "profile.deleteAccount": "Radera konto",
+ "profile.deleteBody": "All din data raderas permanent enligt GDPR.",
+ "profile.deleteTitle": "Radera kontot?",
+ "profile.emailUnverified": "E-postadressen är inte bekräftad",
+ "profile.export": "Exportera min data",
+ "profile.goals": "Mål & kost",
+ "profile.language": "Språk",
+ "profile.language.da": "Dansk",
+ "profile.language.de": "Deutsch",
+ "profile.language.en": "English",
+ "profile.language.es": "Español",
+ "profile.language.fi": "Suomi",
+ "profile.language.fr": "Français",
+ "profile.language.it": "Italiano",
+ "profile.language.nb": "Norsk",
+ "profile.language.nl": "Nederlands",
+ "profile.language.pl": "Polski",
+ "profile.language.pt": "Português",
+ "profile.language.sv": "Svenska",
+ "profile.logout": "Logga ut",
+ "profile.memory": "Vad {brand} vet om mig",
+ "profile.memorySubtitle": "Se, rätta, pausa eller radera det plattformen lärt sig.",
+ "profile.modeLabel": "Läge:",
+ "profile.resendVerification": "Skicka bekräftelsemejl igen",
+ "profile.subscription": "Prenumeration",
+ "profile.title": "Profil",
+ "profile.verificationSent": "Skickat! Kolla din inkorg.",
+ "recipe.avgRating": "Snitt {avg} av {count} betyg",
+ "recipe.cook": "Laga nu",
+ "recipe.cost": "ca {amount}/portion",
+ "recipe.iCookedThis": "Jag lagade detta",
+ "recipe.ingredients": "Ingredienser",
+ "recipe.notSafe": "Passar inte dina kostinställningar",
+ "recipe.perPortion": "per portion",
+ "recipe.portions_one": "1 portion",
+ "recipe.portions_other": "{count} portioner",
+ "recipe.save": "Spara",
+ "recipe.saved": "Sparad",
+ "recipe.steps": "Gör så här",
+ "recipe.substitutions": "Byt ut",
+ "recipe.time": "{min} min",
+ "scan.analyzing": "Analyserar …",
"scan.barcode": "Streckkod",
"scan.expiry": "Bäst före-datum",
+ "scan.failed": "Analysen misslyckades. Försök igen eller registrera manuellt.",
+ "scan.freezer": "Frys",
+ "scan.fridge": "Kyl",
+ "scan.ingredients": "Ingredienser",
"scan.nutrition": "Näringsdeklaration",
+ "scan.pantry": "Skafferi",
+ "scan.plate": "Tallrik",
+ "scan.quotaLeft_one": "1 AI-skanning kvar denna månad",
+ "scan.quotaLeft_other": "{count} AI-skanningar kvar denna månad",
+ "scan.receipt": "Kvitto",
+ "scan.review.addItem": "+ Lägg till vara",
+ "scan.review.approveAll": "Spara till lagret",
+ "scan.review.bestBeforeNote": "Kvalitetsgräns – varan kan vara god längre. Lukta och smaka innan du slänger.",
+ "scan.review.dateKindBestBefore": "Bäst före",
+ "scan.review.dateKindUseBy": "Sista förbrukningsdag",
+ "scan.review.datePlaceholder": "ÅÅÅÅ-MM-DD (valfritt)",
+ "scan.review.itemPlaceholder": "Vara",
+ "scan.review.quantityPlaceholder": "Mängd",
+ "scan.review.rejected": "Borttagen",
+ "scan.review.subtitle": "AI:n är osäker ibland – du bestämmer. Ändra, ta bort eller lägg till innan du sparar.",
+ "scan.review.title": "Granska resultatet",
+ "scan.review.uncertain": "Osäker – kontrollera",
+ "scan.review.unitPlaceholder": "Enhet (g, l, st …)",
+ "scan.review.unknownItem": "Okänd vara",
+ "scan.review.useByNote": "Säkerhetsgräns – ät inte efter detta datum.",
+ "scan.subtitle": "Fyll på matlagret eller logga en måltid med kameran.",
"scan.takePhoto": "Ta bild",
- "scan.tips.title": "Så blir analysen bäst",
- "scan.tips.overview": "Ta en översiktsbild först",
- "scan.tips.shelf": "Fota gärna hylla för hylla",
"scan.tips.light": "Undvik mörker och skugga",
"scan.tips.move": "Flytta varor som skymmer varandra",
- "scan.analyzing": "Analyserar …",
- "scan.review.title": "Granska resultatet",
- "scan.review.subtitle": "AI:n är osäker ibland – du bestämmer. Ändra, ta bort eller lägg till innan du sparar.",
- "scan.review.uncertain": "Osäker – kontrollera",
- "scan.review.approveAll": "Spara till lagret",
- "scan.review.rejected": "Borttagen",
- "scan.failed": "Analysen misslyckades. Försök igen eller registrera manuellt.",
- "myday.title": "Min dag",
- "myday.calories": "Kalorier",
- "myday.protein": "Protein",
- "myday.carbs": "Kolhydrater",
- "myday.fat": "Fett",
- "myday.fiber": "Fibrer",
- "myday.salt": "Salt",
- "myday.remaining": "{kcal} kcal kvar",
- "myday.over": "{kcal} kcal över målet",
- "myday.logMeal": "Logga måltid",
- "myday.noMeals": "Inga måltider loggade i dag.",
- "myday.estimateNote": "Värden med ~ är uppskattningar som du kan justera.",
- "myday.targetsNote": "Målen är vägledning, inte medicinsk rådgivning.",
- "home.title": "Hemma",
- "home.inventory": "Matlager",
- "home.useSoon": "Använd snart",
- "home.mealBoxes": "Matlådor",
- "home.shopping": "Inköpslista",
- "home.budget": "Matbudget",
- "home.household": "Hushåll",
- "home.waste": "Matsvinn",
- "home.emptyInventory": "Lagret är tomt. Skanna kylen eller lägg till varor manuellt.",
- "home.expiresToday": "Går ut i dag",
- "home.expired": "Utgången",
- "home.pastBestBefore": "Passerat bäst före – lukta och smaka",
- "recipe.time": "{min} min",
- "recipe.perPortion": "per portion",
- "recipe.ingredients": "Ingredienser",
- "recipe.steps": "Gör så här",
- "recipe.cook": "Laga nu",
- "recipe.notSafe": "Passar inte dina kostinställningar",
- "recipe.substitutions": "Byt ut",
- "recipe.iCookedThis": "Jag lagade detta",
- "recipe.cost": "ca {amount}/portion",
- "cooking.step": "Steg {current} av {total}",
- "cooking.timer": "Starta timer",
- "cooking.timerRunning": "{time} kvar",
- "cooking.finish": "Klart – logga måltiden",
- "cooking.scale": "Portioner",
- "cooking.keepAwake": "Skärmen hålls vaken medan du lagar",
- "cooked.title": "Hur gick det?",
- "cooked.portionsCooked": "Portioner lagade",
- "cooked.whoAte": "Vilka åt?",
- "cooked.mealBoxes": "Portioner till matlådor",
- "cooked.deductPantry": "Dra ingredienser från lagret",
- "cooked.rate": "Betygsätt",
- "shopping.title": "Inköpslista",
+ "scan.tips.overview": "Ta en översiktsbild först",
+ "scan.tips.shelf": "Fota gärna hylla för hylla",
+ "scan.tips.title": "Så blir analysen bäst",
+ "scan.title": "Skanna",
"shopping.addPlaceholder": "Lägg till vara …",
"shopping.complete": "Avsluta köprundan",
+ "shopping.completedBody_one": "1 vara lades in i matlagret.",
+ "shopping.completedBody_other": "{count} varor lades in i matlagret.",
+ "shopping.completedTitle": "Klart!",
"shopping.completeNote": "Bockade varor läggs in i matlagret.",
"shopping.empty": "Listan är tom.",
"shopping.estimated": "ca {amount}",
"shopping.estimatedTotal": "Uppskattad totalsumma: ca {amount}",
- "mealbox.title": "Matlådor",
- "mealbox.eatBy": "Ät senast {date}",
- "mealbox.eat": "Ät nu",
- "mealbox.empty": "Inga matlådor just nu. När du lagar mat kan du spara portioner här.",
- "household.members": "Medlemmar",
- "household.invite": "Bjud in med kod: {code}",
- "household.shared": "Delas i hushållet: matlager, inköpslista, veckoplan, matlådor och budget.",
- "household.private": "Privat per person: mål, allergier, hälsodata och måltidshistorik.",
- "memory.title": "Vad {brand} vet om mig",
- "memory.subtitle": "Full insyn. Rätta det som är fel, pausa eller radera – du äger ditt minne.",
- "memory.paused": "Pausad",
- "memory.verify": "Stämmer",
- "memory.pause": "Pausa",
- "memory.delete": "Radera",
- "memory.deleteAll": "Radera allt minne",
- "memory.empty": "{brand} har inte lärt sig något om dig ännu.",
- "memory.origin.user_stated": "Du har berättat",
- "memory.origin.observed": "Observerat mönster",
- "memory.origin.ai_inferred": "AI-antagande",
- "paywall.title": "{brand} Premium",
- "paywall.subtitle": "Hela hushållets mat-OS: obegränsat lager, veckoplan och delning.",
- "paywall.household": "Household · upp till 3 personer",
- "paywall.family": "Family · upp till 6 personer",
- "paywall.large": "Large Household · upp till 12 personer",
- "paywall.perMonth": "{price}/mån",
- "paywall.fairUse": "Fair use-kvot för AI-skanningar ingår.",
- "paywall.restore": "Återställ köp",
- "paywall.freeNote": "Gratis: 10 AI-skanningar/mån, manuellt lager, sparade recept och enkel loggning.",
- "profile.title": "Profil",
- "profile.goals": "Mål & kost",
- "profile.consents": "Samtycken & data",
- "profile.memory": "Vad {brand} vet om mig",
- "profile.subscription": "Prenumeration",
- "profile.logout": "Logga ut",
- "profile.export": "Exportera min data",
- "profile.deleteAccount": "Radera konto",
- "home.expiresIn_one": "1 dag kvar",
- "home.expiresIn_other": "{days} dagar kvar",
- "scan.quotaLeft_one": "1 AI-skanning kvar denna månad",
- "scan.quotaLeft_other": "{count} AI-skanningar kvar denna månad",
- "mealbox.portionsLeft_one": "1 portion kvar",
- "mealbox.portionsLeft_other": "{count} portioner kvar",
- "recipe.portions_one": "1 portion",
- "recipe.portions_other": "{count} portioner",
- "paywall.trialActive_one": "1 dag kvar av din provperiod",
- "paywall.trialActive_other": "{days} dagar kvar av din provperiod",
- "profile.language": "Språk",
- "profile.language.sv": "Svenska",
- "profile.language.en": "English",
- "auth.forgotLink": "Glömt lösenordet?",
- "auth.forgotTitle": "Återställ lösenord",
- "auth.forgotBody": "Ange din e-postadress så skickar vi en återställningslänk om kontot finns.",
- "auth.forgotSubmit": "Skicka länk",
- "auth.forgotSentTitle": "Kolla din inkorg",
- "auth.forgotSentBody": "Om adressen har ett konto har vi skickat en länk som gäller i 30 minuter. Öppna den på den här enheten.",
- "auth.backToLogin": "Tillbaka till inloggning",
- "auth.resetTitle": "Välj nytt lösenord",
- "auth.resetBody": "Länken gäller i 30 minuter och kan bara användas en gång. Alla enheter loggas ut när lösenordet byts.",
- "auth.resetTokenPlaceholder": "Klistra in koden från mejlet",
- "auth.newPassword": "Nytt lösenord (minst 10 tecken)",
- "auth.resetSubmit": "Byt lösenord",
- "auth.resetDoneTitle": "Klart!",
- "auth.resetDoneBody": "Ditt lösenord är bytt. Logga in med det nya lösenordet.",
- "auth.verifyDoneTitle": "E-postadressen är bekräftad",
- "auth.verifyDoneBody": "Tack! Ditt konto är nu verifierat.",
- "auth.verifyFailedTitle": "Länken fungerade inte",
- "auth.verifyFailedBody": "Länken är ogiltig eller har gått ut. Begär en ny från profilen.",
- "profile.emailUnverified": "E-postadressen är inte bekräftad",
- "profile.resendVerification": "Skicka bekräftelsemejl igen",
- "profile.verificationSent": "Skickat! Kolla din inkorg.",
- "profile.language.es": "Español",
- "profile.language.it": "Italiano",
- "profile.language.de": "Deutsch",
- "profile.language.fr": "Français",
- "profile.language.da": "Dansk",
- "profile.language.nb": "Norsk",
- "profile.language.fi": "Suomi",
- "profile.language.nl": "Nederlands",
- "profile.language.pl": "Polski",
- "profile.language.pt": "Português",
- "common.oops": "Hoppsan",
- "common.undo": "Ångra",
- "common.remove": "Ta bort",
- "common.add": "Lägg till",
- "common.on": "På",
- "common.off": "Av",
- "home.thisWeek": "Denna vecka",
- "home.wasteWeek": "Matsvinn denna vecka",
- "home.useSoonHint": "Bäst före handlar om kvalitet – lukta, titta och smaka innan du slänger. Sista förbrukningsdag ska däremot respekteras.",
- "scan.review.itemPlaceholder": "Vara",
- "scan.review.quantityPlaceholder": "Mängd",
- "scan.review.unitPlaceholder": "Enhet (g, l, st …)",
- "scan.review.datePlaceholder": "ÅÅÅÅ-MM-DD (valfritt)",
- "scan.review.dateKindBestBefore": "Bäst före",
- "scan.review.dateKindUseBy": "Sista förbrukningsdag",
- "scan.review.bestBeforeNote": "Kvalitetsgräns – varan kan vara god längre. Lukta och smaka innan du slänger.",
- "scan.review.useByNote": "Säkerhetsgräns – ät inte efter detta datum.",
- "scan.review.addItem": "+ Lägg till vara",
- "scan.review.unknownItem": "Okänd vara",
- "barcode.aim": "Rikta kameran mot streckkoden",
- "barcode.addPrompt": "Lägga till i lagret?",
- "barcode.kcalPer100": "{kcal} kcal/100 g",
- "barcode.noNutrition": "Näringsdata saknas",
- "barcode.unknownTitle": "Okänd produkt",
- "barcode.unknownBody": "Produkten finns inte i databasen ännu. Fota framsidan och näringsdeklarationen så lägger vi till den.",
- "barcode.photoPackage": "Fota förpackningen",
- "barcode.needHousehold": "Du behöver ett hushåll först.",
- "barcode.noLocation": "Ingen förvaringsplats hittades.",
- "barcode.cameraTitle": "Kameran behövs",
- "barcode.cameraBody": "För att skanna streckkoder behöver {brand} kameran.",
- "barcode.allowCamera": "Tillåt kamera",
- "onboarding.goal.lose_weight": "Gå ner i vikt",
- "onboarding.goal.build_muscle": "Bygga muskler",
- "onboarding.goal.maintain_weight": "Behålla vikten",
- "onboarding.goal.more_protein": "Äta mer protein",
- "onboarding.goal.less_waste": "Minska matsvinn",
- "onboarding.goal.lower_cost": "Sänka matkostnaden",
- "onboarding.goal.cook_more": "Laga mer hemma",
- "onboarding.diet.omnivore": "Allätare",
- "onboarding.diet.flexitarian": "Flexitarian",
- "onboarding.diet.pescatarian": "Pescetarian",
- "onboarding.diet.vegetarian": "Vegetarian",
- "onboarding.diet.vegan": "Vegan",
- "onboarding.allergen.gluten": "Gluten",
- "onboarding.allergen.milk": "Mjölk/laktos",
- "onboarding.allergen.eggs": "Ägg",
- "onboarding.allergen.tree_nuts": "Nötter",
- "onboarding.allergen.peanuts": "Jordnötter",
- "onboarding.allergen.fish": "Fisk",
- "onboarding.allergen.crustaceans": "Skaldjur",
- "onboarding.allergen.soy": "Soja",
- "onboarding.allergen.sesame": "Sesam",
- "onboarding.bodyTitle": "För personliga kalorimål (frivilligt)",
- "onboarding.weightPlaceholder": "Vikt (kg)",
- "onboarding.heightPlaceholder": "Längd (cm)",
- "onboarding.birthYearPlaceholder": "Födelseår",
- "onboarding.householdDefaultName": "Hemma",
- "onboarding.modesCombine": "Lägena kan kombineras – enkelt till vardags, exakt när du vill.",
- "myday.mealType.breakfast": "Frukost",
- "myday.mealType.lunch": "Lunch",
- "myday.mealType.dinner": "Middag",
- "myday.mealType.snack": "Mellanmål",
- "myday.mealType.dessert": "Efterrätt",
- "myday.overRecommended": "Över rekommenderat",
- "myday.todaysMeals": "Dagens måltider",
- "myday.estimateRange": "{min}–{max} kcal, troligen {kcal}",
- "myday.kcalProtein": "{kcal} kcal · {protein} g protein",
- "logmeal.mealTypeTitle": "Måltidstyp",
- "logmeal.quickTitle": "Snabb återloggning",
- "logmeal.quickSubtitle": "Loggar samma näringsvärden som förra gången.",
- "logmeal.manualTitle": "Manuellt",
- "logmeal.whatPlaceholder": "Vad åt du?",
- "logmeal.proteinPlaceholder": "protein (g)",
- "logmeal.validationTitle": "Fyll i",
- "logmeal.validationBody": "Namn och kalorier behövs för manuell loggning.",
- "logmeal.photoTip": "Tips: fota tallriken under Skanna så uppskattar appen åt dig – du bekräftar alltid.",
- "shopping.section.frukt_gront": "Frukt & grönt",
"shopping.section.brod": "Bröd",
- "shopping.section.mejeri": "Mejeri",
- "shopping.section.kott_fagel": "Kött & fågel",
- "shopping.section.fisk": "Fisk",
"shopping.section.chark": "Chark",
- "shopping.section.frys": "Frys",
- "shopping.section.skafferi": "Skafferi",
- "shopping.section.konserver": "Konserver",
- "shopping.section.kryddor_bak": "Kryddor & bakning",
"shopping.section.dryck": "Dryck",
- "shopping.section.snacks": "Snacks",
+ "shopping.section.fisk": "Fisk",
+ "shopping.section.frukt_gront": "Frukt & grönt",
+ "shopping.section.frys": "Frys",
"shopping.section.hygien_ovrigt": "Övrigt",
- "shopping.completedTitle": "Klart!",
- "household.role.owner": "Ägare",
- "household.role.adult": "Vuxen",
- "household.role.member": "Medlem",
- "household.role.child": "Barn",
- "household.empty": "Du har inget hushåll ännu. Skapa ett i onboardingen eller gå med via kod.",
- "household.shareCode": "Dela koden med familjen så delar ni lager, lista och plan.",
- "household.locations": "Förvaringsplatser",
- "household.portionFactor": "×{factor} portion",
- "mealbox.enjoyTitle": "Smaklig måltid!",
- "mealbox.enjoyBody": "Portionen är loggad i Min dag.",
- "mealbox.guidanceNote": "Rekommenderad användningstid är vägledning – lita på lukt och smak.",
- "paywall.soonTitle": "Snart!",
- "paywall.soonBody": "Köp aktiveras via App Store/Google Play när butiksintegrationen slås på (fas 7). Backend-flödet är redan klart.",
- "paywall.popular": "Populärast",
- "paywall.choose": "Välj",
- "recipe.saved": "Sparad",
- "recipe.save": "Spara",
- "recipe.avgRating": "Snitt {avg} av {count} betyg",
- "memory.verified": "Verifierad",
- "memory.resume": "Återuppta",
- "memory.deleteAllTitle": "Radera allt minne?",
- "memory.irreversible": "Detta går inte att ångra.",
- "profile.consent.personalization": "Personliga funktioner (minne & smakprofil)",
- "profile.consent.anonymized_improvement": "Anonymiserad förbättring av AI:n",
- "profile.consent.image_training": "Mina bilder får användas för träning",
- "profile.consent.health_integration": "Hälsodata (Apple Health / Health Connect)",
- "profile.consent.location_weather": "Plats för väderbaserade förslag",
- "profile.consent.push_notifications": "Push-notiser",
- "profile.modeLabel": "Läge:",
- "profile.memorySubtitle": "Se, rätta, pausa eller radera det plattformen lärt sig.",
- "profile.consentsNote": "Samtyckena är separata – personlig funktion kräver aldrig träningssamtycke.",
- "profile.aiScansUsed": "AI-skanningar: {used} / {total} denna månad",
- "profile.deleteTitle": "Radera kontot?",
- "profile.deleteBody": "All din data raderas permanent enligt GDPR.",
- "cooking.timerDone": "Klart!",
- "cooked.deductPantryNote": "Ingredienserna dras från lagret enligt först-utgången-först.",
- "home.moreItems_one": "+ 1 till …",
- "home.moreItems_other": "+ {count} till …",
- "shopping.completedBody_one": "1 vara lades in i matlagret.",
- "shopping.completedBody_other": "{count} varor lades in i matlagret.",
- "profile.consent.product_analytics": "Produktanalys"
+ "shopping.section.konserver": "Konserver",
+ "shopping.section.kott_fagel": "Kött & fågel",
+ "shopping.section.kryddor_bak": "Kryddor & bakning",
+ "shopping.section.mejeri": "Mejeri",
+ "shopping.section.skafferi": "Skafferi",
+ "shopping.section.snacks": "Snacks",
+ "shopping.title": "Inköpslista",
+ "tabs.home": "Hemma",
+ "tabs.myDay": "Min dag",
+ "tabs.scan": "Skanna",
+ "tabs.whatToEat": "Vad ska vi äta?",
+ "wte.coverage": "{pct} % hemma",
+ "wte.cravingPlaceholder": "Jag är sugen på … (t.ex. krämigt, asiatiskt, under 500 kcal)",
+ "wte.empty": "Inga förslag ännu – lägg in lite mat i lagret eller lätta på filtren.",
+ "wte.mealBoxFirst": "Färdig mat hemma",
+ "wte.missing": "Saknas: {items}",
+ "wte.refresh": "Nya förslag",
+ "wte.subtitle": "Utifrån vad ni har hemma, vad som bör användas och vad ni gillar.",
+ "wte.title": "Vad ska vi äta?",
+ "wte.whyTitle": "Varför detta förslag?"
}
diff --git a/infrastructure/migrations/0004_progressive_onboarding.sql b/infrastructure/migrations/0004_progressive_onboarding.sql
new file mode 100644
index 0000000..82458e2
--- /dev/null
+++ b/infrastructure/migrations/0004_progressive_onboarding.sql
@@ -0,0 +1,8 @@
+-- FAS 1b: Progressive onboarding (3-layer flow)
+-- Step A = immediate value, Step B = after first value, Step C = contextual/completed
+ALTER TABLE "users" ADD COLUMN "onboarding_step" text NOT NULL DEFAULT 'a';
+
+-- Add feature flag for progressive onboarding rollout
+INSERT INTO "feature_flags" ("key", "enabled", "rollout_percent", "description_sv")
+VALUES ('progressive_onboarding', false, 0, 'Progressiv onboarding: 3-stegs flow (FAS 1b)')
+ON CONFLICT ("key") DO NOTHING;
diff --git a/packages/database/src/schema/users.ts b/packages/database/src/schema/users.ts
index ad9629a..91c3af6 100644
--- a/packages/database/src/schema/users.ts
+++ b/packages/database/src/schema/users.ts
@@ -39,6 +39,8 @@ export const users = pgTable(
locale: text("locale").notNull().default("sv-SE"),
precisionMode: precisionModeEnum("precision_mode").notNull().default("simple"),
onboardingCompleted: boolean("onboarding_completed").notNull().default(false),
+ /** Progressive onboarding step: a=immediate value, b=after first value, c=completed (spec FAS 1b). */
+ onboardingStep: text("onboarding_step").notNull().default("a"),
deletedAt: timestamp("deleted_at", { withTimezone: true }),
createdAt: createdAt(),
updatedAt: updatedAt(),
diff --git a/packages/feature-flags/src/index.ts b/packages/feature-flags/src/index.ts
index 8d5f9ed..d109953 100644
--- a/packages/feature-flags/src/index.ts
+++ b/packages/feature-flags/src/index.ts
@@ -19,6 +19,7 @@ export const KNOWN_FLAGS = {
FOOD_MEMORIES: "food_memories",
VOICE_INPUT: "voice_input",
AI_RERANK: "ai_rerank",
+ PROGRESSIVE_ONBOARDING: "progressive_onboarding",
} as const;
export type KnownFlagKey = (typeof KNOWN_FLAGS)[keyof typeof KNOWN_FLAGS];
diff --git a/packages/shared-types/src/entities.ts b/packages/shared-types/src/entities.ts
index b1d73ca..696cc5f 100644
--- a/packages/shared-types/src/entities.ts
+++ b/packages/shared-types/src/entities.ts
@@ -83,6 +83,7 @@ export interface User {
locale: string;
precisionMode: PrecisionMode;
onboardingCompleted: boolean;
+ onboardingStep: "a" | "b" | "c";
createdAt: string;
updatedAt: string;
}
diff --git a/packages/validation/src/profile.ts b/packages/validation/src/profile.ts
index c61aaea..2818fa8 100644
--- a/packages/validation/src/profile.ts
+++ b/packages/validation/src/profile.ts
@@ -70,3 +70,20 @@ export const onboardingInputSchema = z.object({
.default({ kind: "skip" }),
});
export type OnboardingInput = z.infer;
+
+/** Progressive onboarding Step A – minimal info for immediate value (FAS 1b). */
+export const quickStartInputSchema = z.object({
+ primaryGoal: z.enum(GOAL_TYPES).optional(),
+ precisionMode: z.enum(PRECISION_MODES).default("simple"),
+});
+export type QuickStartInput = z.infer;
+
+/** Progressive onboarding status response (FAS 1b). */
+export const onboardingStatusSchema = z.object({
+ step: z.enum(["a", "b", "c"]),
+ onboardingCompleted: z.boolean(),
+ hasHousehold: z.boolean(),
+ hasHealthProfile: z.boolean(),
+ hasPreferences: z.boolean(),
+});
+export type OnboardingStatus = z.infer;