From 5959f66387ecc31bfa493a0fbc061615622e0c6a Mon Sep 17 00:00:00 2001 From: Till JS Date: Mon, 27 Apr 2026 00:12:18 +0200 Subject: [PATCH] =?UTF-8?q?i18n(wardrobe):=20translate=20all=205=20locales?= =?UTF-8?q?=20=E2=80=94=2036=20strings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds wardrobe namespace (de/en/es/fr/it) covering ListView, GridView, OutfitsView, DetailGarmentView, DetailOutfitView, GarmentForm, OutfitComposer, GarmentTryOnButton, TryOnButton, TryOnModelPicker, CategoryTabs, GarmentCard, OutfitCard, plus the /wardrobe/compose route. Categories/occasions/seasons routed through dynamic `wardrobe.categories.{key}` lookups so constants.ts keeps the order-tuples without leaking DE labels into UI. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../web/src/lib/i18n/locales/wardrobe/de.json | 257 ++++++++++++++++++ .../web/src/lib/i18n/locales/wardrobe/en.json | 257 ++++++++++++++++++ .../web/src/lib/i18n/locales/wardrobe/es.json | 257 ++++++++++++++++++ .../web/src/lib/i18n/locales/wardrobe/fr.json | 257 ++++++++++++++++++ .../web/src/lib/i18n/locales/wardrobe/it.json | 257 ++++++++++++++++++ .../src/lib/modules/wardrobe/ListView.svelte | 34 ++- .../wardrobe/components/CategoryTabs.svelte | 7 +- .../wardrobe/components/GarmentCard.svelte | 8 +- .../wardrobe/components/GarmentForm.svelte | 48 ++-- .../components/GarmentTryOnButton.svelte | 56 ++-- .../wardrobe/components/OutfitCard.svelte | 19 +- .../wardrobe/components/OutfitComposer.svelte | 89 +++--- .../wardrobe/components/TryOnButton.svelte | 49 ++-- .../components/TryOnModelPicker.svelte | 29 +- .../wardrobe/views/DetailGarmentView.svelte | 87 ++++-- .../wardrobe/views/DetailOutfitView.svelte | 65 +++-- .../modules/wardrobe/views/GridView.svelte | 30 +- .../modules/wardrobe/views/OutfitsView.svelte | 23 +- .../compose/[[outfitId]]/+page.svelte | 17 +- scripts/i18n-hardcoded-baseline.json | 17 +- scripts/i18n-missing-baseline.json | 88 +++--- 21 files changed, 1677 insertions(+), 274 deletions(-) create mode 100644 apps/mana/apps/web/src/lib/i18n/locales/wardrobe/de.json create mode 100644 apps/mana/apps/web/src/lib/i18n/locales/wardrobe/en.json create mode 100644 apps/mana/apps/web/src/lib/i18n/locales/wardrobe/es.json create mode 100644 apps/mana/apps/web/src/lib/i18n/locales/wardrobe/fr.json create mode 100644 apps/mana/apps/web/src/lib/i18n/locales/wardrobe/it.json diff --git a/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/de.json b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/de.json new file mode 100644 index 000000000..0f12cf6da --- /dev/null +++ b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/de.json @@ -0,0 +1,257 @@ +{ + "categories": { + "all": "Alle", + "top": "Oberteile", + "bottom": "Hosen", + "dress": "Kleider", + "outerwear": "Jacken", + "shoes": "Schuhe", + "bag": "Taschen", + "accessory": "Accessoires", + "glasses": "Brillen", + "jewelry": "Schmuck", + "hat": "Kopfbedeckung", + "other": "Sonstiges" + }, + "categories_singular": { + "top": "Oberteil", + "bottom": "Hose", + "dress": "Kleid", + "outerwear": "Jacke", + "shoes": "Schuh", + "bag": "Tasche", + "accessory": "Accessoire", + "glasses": "Brille", + "jewelry": "Schmuck", + "hat": "Kopfbedeckung", + "other": "Item" + }, + "occasions": { + "casual": "Casual", + "work": "Arbeit", + "formal": "Festlich", + "workout": "Sport", + "date": "Date", + "travel": "Reise", + "event": "Event", + "sleep": "Schlafanzug", + "other": "Sonstiges" + }, + "seasons": { + "spring": "Frühling", + "summer": "Sommer", + "autumn": "Herbst", + "winter": "Winter" + }, + "piece_singular": "Stück", + "piece_plural": "Stücke", + "upload_failed": "Upload fehlgeschlagen", + "list_view": { + "aria_tabs": "Ansicht wechseln", + "tab_garments": "Kleidung", + "tab_outfits": "Outfits", + "face_saved_title": "Gesichtsbild gespeichert", + "face_saved_hint": "Perfekt — als nächstes lädst du unten dein erstes Kleidungsstück hoch.", + "dismiss": "Schließen", + "face_prompt_title": "Lade ein Gesichtsbild hoch", + "face_prompt_desc": "Wir brauchen dich auf Bild, damit Try-On Kleidung an dir visualisieren kann. Das Bild bleibt lokal und wird nur für deine eigenen Generierungen genutzt.", + "face_uploading_label": "Wird hochgeladen…", + "face_upload_label": "Gesichtsbild hochladen", + "face_upload_hint": "Kopf + Schulter, möglichst neutrale Beleuchtung", + "face_uploading_chip": "Lade…" + }, + "grid_view": { + "upload_label_all": "Kleidungsstück hochladen", + "upload_label_for_category": "{category} hochladen", + "upload_hint": "Foto frontal, heller Hintergrund — bessere Try-On-Ergebnisse", + "empty_title": "Noch nichts im Schrank.", + "empty_hint": "Zieh ein Foto in die Zone oben — oder klick sie an, um eins auszuwählen.", + "no_entries_under": "Keine Einträge unter {category}.", + "space_footer": "Dieser Schrank gehört zu {name} — Uploads landen nur hier, nicht in deinem persönlichen Schrank." + }, + "outfits_view": { + "title": "Outfits", + "count_singular": "Zusammenstellung", + "count_plural": "Zusammenstellungen", + "action_new": "Neues Outfit", + "empty_title": "Noch keine Outfits.", + "empty_no_garments": "Füge zuerst ein paar Kleidungsstücke im Tab \"Kleidung\" hinzu — danach lassen sie sich hier zu Outfits kombinieren.", + "empty_with_garments": "Kombiniere deine Kleidungsstücke zu Looks, die du dann mit KI an dir selbst anprobieren kannst.", + "action_compose_first": "Erstes Outfit komponieren" + }, + "detail_garment": { + "loading": "Lädt…", + "not_found_title": "Nicht gefunden.", + "not_found_desc": "Das Kleidungsstück wurde gelöscht oder gehört zu einem anderen Space.", + "action_enlarge": "Foto vergrößern", + "action_edit": "Bearbeiten", + "label_brand": "Marke", + "label_color": "Farbe", + "label_size": "Größe", + "label_material": "Material", + "label_price": "Preis", + "label_wear_count": "Getragen", + "wear_count_value": "{count}×", + "last_worn_suffix": " · zuletzt {date}", + "action_comic": "Als Comic-Character", + "action_comic_title": "Aus diesem Kleidungsstück einen Comic-Character generieren", + "action_marking": "Gespeichert…", + "action_mark_worn": "Heute getragen", + "action_unarchive": "Wieder aktiv setzen", + "action_archive": "Archivieren", + "action_delete": "Löschen", + "section_try_ons": "Anproben · {count}", + "section_outfits": "In Outfits · {count}", + "no_try_on_yet": "Noch keine Anprobe", + "action_open_picture": "In Picture öffnen", + "confirm_delete": "\"{name}\" wirklich löschen?" + }, + "detail_outfit": { + "back": "Zurück zum Kleiderschrank", + "breadcrumb": "Kleiderschrank · Outfits", + "loading": "Lädt…", + "not_found_title": "Outfit nicht gefunden.", + "not_found_desc": "Gelöscht oder in einem anderen Space.", + "try_on_preview_alt": "Try-On Vorschau", + "no_garments": "Keine Kleidungsstücke", + "action_comic": "Als Comic-Character", + "action_comic_title": "Aus diesem Outfit einen Comic-Character generieren", + "try_on_history": "Try-On Verlauf", + "action_unfavorite": "Favorit entfernen", + "action_favorite": "Als Favorit markieren", + "action_edit": "Bearbeiten", + "label_visibility": "Sichtbarkeit", + "section_composition": "Zusammenstellung", + "composition_missing": "Referenzierte Kleidungsstücke wurden entfernt oder gehören zu einem anderen Space.", + "action_unarchive": "Wieder aktiv", + "action_archive": "Archivieren", + "action_delete": "Löschen", + "confirm_delete": "Outfit \"{name}\" wirklich löschen?" + }, + "garment_form": { + "err_name_required": "Name darf nicht leer sein", + "err_save_failed": "Speichern fehlgeschlagen", + "label_name": "Name", + "placeholder_name": "z.B. Blau-weiß gestreiftes Hemd", + "label_category": "Kategorie", + "label_brand": "Marke", + "placeholder_brand": "z.B. Uniqlo", + "label_color": "Farbe", + "placeholder_color": "z.B. navy", + "label_size": "Größe", + "placeholder_size": "z.B. M oder 42", + "label_material": "Material", + "placeholder_material": "z.B. Baumwolle", + "label_tags": "Tags", + "tags_hint": "(komma-getrennt)", + "placeholder_tags": "formal, sommer, lieblingsstück", + "label_price": "Preis", + "aria_currency": "Währung", + "label_notes": "Notizen", + "placeholder_notes": "Anlass, Tragevorschriften, …", + "action_saving": "Speichere…", + "action_save": "Speichern", + "action_cancel": "Abbrechen" + }, + "composer": { + "err_name_required": "Gib dem Outfit einen Namen.", + "err_no_garments": "Wähle mindestens ein Kleidungsstück aus.", + "err_save_failed": "Speichern fehlgeschlagen", + "section_library": "Kleiderschrank", + "available_singular": "{count} Stück verfügbar", + "available_plural": "{count} Stücke verfügbar", + "empty_title": "Nichts zum Kombinieren.", + "empty_hint_prefix": "Lade zuerst ein paar Kleidungsstücke im Tab", + "tab_garments_link": "Kleidung", + "empty_hint_suffix": "hoch.", + "label_name": "Name", + "placeholder_name": "z.B. Bürooutfit Juni", + "label_description": "Beschreibung", + "placeholder_description": "Für welchen Anlass? Besonderheiten?", + "label_occasion": "Anlass", + "no_occasion": "— kein Anlass —", + "label_seasons": "Jahreszeit", + "label_tags": "Tags", + "tags_hint": "(komma-getrennt)", + "placeholder_tags": "minimal, layering, meeting", + "section_composition": "Zusammenstellung", + "composition_count_singular": "· {count} Stück", + "composition_count_plural": "· {count} Stücke", + "composition_empty": "Klicke links auf Kleidungsstücke, um sie dem Outfit hinzuzufügen.", + "action_remove": "Aus Outfit entfernen", + "action_saving": "Speichere…", + "action_save_edit": "Änderungen speichern", + "action_save_new": "Outfit anlegen", + "action_cancel": "Abbrechen" + }, + "try_on_garment": { + "err_failed": "Try-On fehlgeschlagen", + "err_upload": "Upload fehlgeschlagen", + "no_photo": "Lade erst ein Foto hoch, um dieses Stück an dir zu visualisieren.", + "refs_title": "Für Solo-Try-On brauchen wir dich auf Bild.", + "refs_accessory": "Ein Gesichtsbild reicht — das Stück wird darauf montiert.", + "refs_full": "Ein Gesichts- und ein Ganzkörperbild. Beide werden nur für deine eigenen Generierungen genutzt.", + "upload_face": "Gesichtsbild hochladen", + "upload_body": "Ganzkörperbild hochladen", + "face_hint": "Kopf + Schulter, möglichst neutrale Beleuchtung", + "body_hint": "Stehend, freier Hintergrund, gut erkennbare Haltung", + "refs_more_prefix": "Weitere Referenzen oder AI-Opt-ins pro Bild:", + "refs_link": "Meine Bilder", + "rendering": "Rendere…", + "cta": "An mir anprobieren", + "credits": "{count} Credits", + "accessory_hint": "Accessoire-Modus — nur das Gesicht wird gerendert (spart Credits).", + "space_hint_prefix": "Try-On nutzt deine Referenzbilder aus diesem Space", + "space_hint_suffix": ", nicht aus Persönlich.", + "result_label": "Ergebnis", + "try_on_alt": "Try-On", + "result_hint_prefix": "Gefunden in der", + "picture_gallery_link": "Picture-Galerie", + "result_hint_suffix": "als normale Generierung." + }, + "try_on_outfit": { + "err_failed": "Try-On fehlgeschlagen", + "err_upload": "Upload fehlgeschlagen", + "refs_title": "Für Try-On brauchen wir dich auf Bild.", + "refs_accessory": "Ein Gesichtsbild reicht — der Rest bleibt wie auf deinem Foto.", + "refs_full": "Ein Gesichts- und ein Ganzkörperbild. Beide werden nur für deine eigenen Generierungen genutzt.", + "upload_face": "Gesichtsbild hochladen", + "upload_body": "Ganzkörperbild hochladen", + "face_hint": "Kopf + Schulter, möglichst neutrale Beleuchtung", + "body_hint": "Stehend, freier Hintergrund, gut erkennbare Haltung", + "refs_more_prefix": "Weitere Referenzen oder AI-Opt-ins pro Bild:", + "refs_link": "Meine Bilder", + "rendering": "Rendere…", + "cta": "Anprobieren", + "credits": "{count} Credits", + "accessory_hint": "Accessoire-Modus — nur das Gesicht wird gerendert (spart Credits).", + "many_garments_hint": "Mit {count} Kleidungsstücken ist der Referenz-Slot knapp — ältere Items werden evtl. nicht mitgezogen.", + "space_hint_prefix": "Try-On nutzt deine Referenzbilder aus diesem Space", + "space_hint_suffix": ", nicht aus Persönlich.", + "family_hint": "Kinder-Outfits werden trotzdem auf dein Gesicht gerendert.", + "empty_garments": "Füge mindestens ein {category} hinzu, um Try-On zu aktivieren." + }, + "model_picker": { + "legend": "Modell", + "option_openai_label": "OpenAI", + "option_openai_hint": "GPT-image · Standard", + "option_pro_label": "Nano Banana Pro", + "option_pro_hint": "Google · hohe Konsistenz", + "option_flash_label": "Nano Banana 2", + "option_flash_hint": "Google · neuestes · günstig" + }, + "garment_card": { + "wear_count_title": "{count}× getragen" + }, + "outfit_card": { + "try_on_badge": "Try-On", + "try_on_preview_title": "Try-On Vorschau", + "empty": "Leer", + "favorite": "Favorit" + }, + "compose": { + "title_edit": "Outfit bearbeiten", + "title_new": "Neues Outfit", + "back": "Zurück" + } +} diff --git a/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/en.json b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/en.json new file mode 100644 index 000000000..2efe25bd5 --- /dev/null +++ b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/en.json @@ -0,0 +1,257 @@ +{ + "categories": { + "all": "All", + "top": "Tops", + "bottom": "Bottoms", + "dress": "Dresses", + "outerwear": "Jackets", + "shoes": "Shoes", + "bag": "Bags", + "accessory": "Accessories", + "glasses": "Glasses", + "jewelry": "Jewelry", + "hat": "Hats", + "other": "Other" + }, + "categories_singular": { + "top": "Top", + "bottom": "Bottom", + "dress": "Dress", + "outerwear": "Jacket", + "shoes": "Shoe", + "bag": "Bag", + "accessory": "Accessory", + "glasses": "Glasses", + "jewelry": "Jewelry", + "hat": "Hat", + "other": "Item" + }, + "occasions": { + "casual": "Casual", + "work": "Work", + "formal": "Formal", + "workout": "Workout", + "date": "Date", + "travel": "Travel", + "event": "Event", + "sleep": "Sleepwear", + "other": "Other" + }, + "seasons": { + "spring": "Spring", + "summer": "Summer", + "autumn": "Autumn", + "winter": "Winter" + }, + "piece_singular": "piece", + "piece_plural": "pieces", + "upload_failed": "Upload failed", + "list_view": { + "aria_tabs": "Switch view", + "tab_garments": "Clothing", + "tab_outfits": "Outfits", + "face_saved_title": "Face photo saved", + "face_saved_hint": "Perfect — next, upload your first piece of clothing below.", + "dismiss": "Close", + "face_prompt_title": "Upload a face photo", + "face_prompt_desc": "We need you in a photo so Try-On can visualize clothing on you. The image stays local and is only used for your own generations.", + "face_uploading_label": "Uploading…", + "face_upload_label": "Upload face photo", + "face_upload_hint": "Head + shoulders, neutral lighting if possible", + "face_uploading_chip": "Loading…" + }, + "grid_view": { + "upload_label_all": "Upload garment", + "upload_label_for_category": "Upload {category}", + "upload_hint": "Front-on photo, bright background — better Try-On results", + "empty_title": "Nothing in the wardrobe yet.", + "empty_hint": "Drag a photo into the zone above — or click it to pick one.", + "no_entries_under": "No items under {category}.", + "space_footer": "This wardrobe belongs to {name} — uploads only land here, not in your personal wardrobe." + }, + "outfits_view": { + "title": "Outfits", + "count_singular": "outfit", + "count_plural": "outfits", + "action_new": "New outfit", + "empty_title": "No outfits yet.", + "empty_no_garments": "First add a few pieces of clothing in the \"Clothing\" tab — then you can combine them into outfits here.", + "empty_with_garments": "Combine your clothing pieces into looks that you can then try on yourself with AI.", + "action_compose_first": "Compose first outfit" + }, + "detail_garment": { + "loading": "Loading…", + "not_found_title": "Not found.", + "not_found_desc": "The garment was deleted or belongs to another space.", + "action_enlarge": "Enlarge photo", + "action_edit": "Edit", + "label_brand": "Brand", + "label_color": "Color", + "label_size": "Size", + "label_material": "Material", + "label_price": "Price", + "label_wear_count": "Worn", + "wear_count_value": "{count}×", + "last_worn_suffix": " · last on {date}", + "action_comic": "As comic character", + "action_comic_title": "Generate a comic character from this garment", + "action_marking": "Saving…", + "action_mark_worn": "Worn today", + "action_unarchive": "Set active again", + "action_archive": "Archive", + "action_delete": "Delete", + "section_try_ons": "Try-Ons · {count}", + "section_outfits": "In outfits · {count}", + "no_try_on_yet": "No try-on yet", + "action_open_picture": "Open in Picture", + "confirm_delete": "Really delete \"{name}\"?" + }, + "detail_outfit": { + "back": "Back to wardrobe", + "breadcrumb": "Wardrobe · Outfits", + "loading": "Loading…", + "not_found_title": "Outfit not found.", + "not_found_desc": "Deleted or in another space.", + "try_on_preview_alt": "Try-On preview", + "no_garments": "No garments", + "action_comic": "As comic character", + "action_comic_title": "Generate a comic character from this outfit", + "try_on_history": "Try-On history", + "action_unfavorite": "Remove favorite", + "action_favorite": "Mark as favorite", + "action_edit": "Edit", + "label_visibility": "Visibility", + "section_composition": "Composition", + "composition_missing": "Referenced garments were removed or belong to another space.", + "action_unarchive": "Set active", + "action_archive": "Archive", + "action_delete": "Delete", + "confirm_delete": "Really delete outfit \"{name}\"?" + }, + "garment_form": { + "err_name_required": "Name cannot be empty", + "err_save_failed": "Save failed", + "label_name": "Name", + "placeholder_name": "e.g. Blue and white striped shirt", + "label_category": "Category", + "label_brand": "Brand", + "placeholder_brand": "e.g. Uniqlo", + "label_color": "Color", + "placeholder_color": "e.g. navy", + "label_size": "Size", + "placeholder_size": "e.g. M or 42", + "label_material": "Material", + "placeholder_material": "e.g. cotton", + "label_tags": "Tags", + "tags_hint": "(comma-separated)", + "placeholder_tags": "formal, summer, favorite", + "label_price": "Price", + "aria_currency": "Currency", + "label_notes": "Notes", + "placeholder_notes": "Occasion, care instructions, …", + "action_saving": "Saving…", + "action_save": "Save", + "action_cancel": "Cancel" + }, + "composer": { + "err_name_required": "Give the outfit a name.", + "err_no_garments": "Pick at least one garment.", + "err_save_failed": "Save failed", + "section_library": "Wardrobe", + "available_singular": "{count} piece available", + "available_plural": "{count} pieces available", + "empty_title": "Nothing to combine.", + "empty_hint_prefix": "First upload a few garments in the", + "tab_garments_link": "Clothing", + "empty_hint_suffix": "tab.", + "label_name": "Name", + "placeholder_name": "e.g. Office outfit June", + "label_description": "Description", + "placeholder_description": "For what occasion? Anything special?", + "label_occasion": "Occasion", + "no_occasion": "— no occasion —", + "label_seasons": "Season", + "label_tags": "Tags", + "tags_hint": "(comma-separated)", + "placeholder_tags": "minimal, layering, meeting", + "section_composition": "Composition", + "composition_count_singular": "· {count} piece", + "composition_count_plural": "· {count} pieces", + "composition_empty": "Click garments on the left to add them to the outfit.", + "action_remove": "Remove from outfit", + "action_saving": "Saving…", + "action_save_edit": "Save changes", + "action_save_new": "Create outfit", + "action_cancel": "Cancel" + }, + "try_on_garment": { + "err_failed": "Try-On failed", + "err_upload": "Upload failed", + "no_photo": "Upload a photo first to visualize this piece on yourself.", + "refs_title": "We need you in a photo for solo try-on.", + "refs_accessory": "A face photo is enough — the piece is mounted onto it.", + "refs_full": "A face and a full-body photo. Both are only used for your own generations.", + "upload_face": "Upload face photo", + "upload_body": "Upload full-body photo", + "face_hint": "Head + shoulders, neutral lighting if possible", + "body_hint": "Standing, free background, posture clearly visible", + "refs_more_prefix": "More references or per-image AI opt-ins:", + "refs_link": "My Images", + "rendering": "Rendering…", + "cta": "Try on me", + "credits": "{count} credits", + "accessory_hint": "Accessory mode — only the face is rendered (saves credits).", + "space_hint_prefix": "Try-On uses your reference images from this space", + "space_hint_suffix": ", not from Personal.", + "result_label": "Result", + "try_on_alt": "Try-On", + "result_hint_prefix": "Found in the", + "picture_gallery_link": "Picture gallery", + "result_hint_suffix": "as a regular generation." + }, + "try_on_outfit": { + "err_failed": "Try-On failed", + "err_upload": "Upload failed", + "refs_title": "We need you in a photo for try-on.", + "refs_accessory": "A face photo is enough — the rest stays as in your photo.", + "refs_full": "A face and a full-body photo. Both are only used for your own generations.", + "upload_face": "Upload face photo", + "upload_body": "Upload full-body photo", + "face_hint": "Head + shoulders, neutral lighting if possible", + "body_hint": "Standing, free background, posture clearly visible", + "refs_more_prefix": "More references or per-image AI opt-ins:", + "refs_link": "My Images", + "rendering": "Rendering…", + "cta": "Try on", + "credits": "{count} credits", + "accessory_hint": "Accessory mode — only the face is rendered (saves credits).", + "many_garments_hint": "With {count} garments the reference slot is tight — older items may not be carried over.", + "space_hint_prefix": "Try-On uses your reference images from this space", + "space_hint_suffix": ", not from Personal.", + "family_hint": "Kids' outfits are still rendered onto your face.", + "empty_garments": "Add at least one {category} to enable Try-On." + }, + "model_picker": { + "legend": "Model", + "option_openai_label": "OpenAI", + "option_openai_hint": "GPT-image · Standard", + "option_pro_label": "Nano Banana Pro", + "option_pro_hint": "Google · high consistency", + "option_flash_label": "Nano Banana 2", + "option_flash_hint": "Google · newest · cheap" + }, + "garment_card": { + "wear_count_title": "Worn {count}×" + }, + "outfit_card": { + "try_on_badge": "Try-On", + "try_on_preview_title": "Try-On preview", + "empty": "Empty", + "favorite": "Favorite" + }, + "compose": { + "title_edit": "Edit outfit", + "title_new": "New outfit", + "back": "Back" + } +} diff --git a/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/es.json b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/es.json new file mode 100644 index 000000000..f056f3595 --- /dev/null +++ b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/es.json @@ -0,0 +1,257 @@ +{ + "categories": { + "all": "Todos", + "top": "Tops", + "bottom": "Pantalones", + "dress": "Vestidos", + "outerwear": "Chaquetas", + "shoes": "Zapatos", + "bag": "Bolsos", + "accessory": "Accesorios", + "glasses": "Gafas", + "jewelry": "Joyería", + "hat": "Sombreros", + "other": "Otros" + }, + "categories_singular": { + "top": "Top", + "bottom": "Pantalón", + "dress": "Vestido", + "outerwear": "Chaqueta", + "shoes": "Zapato", + "bag": "Bolso", + "accessory": "Accesorio", + "glasses": "Gafas", + "jewelry": "Joya", + "hat": "Sombrero", + "other": "Item" + }, + "occasions": { + "casual": "Casual", + "work": "Trabajo", + "formal": "Formal", + "workout": "Deporte", + "date": "Cita", + "travel": "Viaje", + "event": "Evento", + "sleep": "Pijama", + "other": "Otros" + }, + "seasons": { + "spring": "Primavera", + "summer": "Verano", + "autumn": "Otoño", + "winter": "Invierno" + }, + "piece_singular": "pieza", + "piece_plural": "piezas", + "upload_failed": "Error al subir", + "list_view": { + "aria_tabs": "Cambiar vista", + "tab_garments": "Ropa", + "tab_outfits": "Outfits", + "face_saved_title": "Foto de cara guardada", + "face_saved_hint": "Perfecto — ahora sube tu primera prenda abajo.", + "dismiss": "Cerrar", + "face_prompt_title": "Sube una foto de tu cara", + "face_prompt_desc": "Te necesitamos en una foto para que Try-On pueda visualizar la ropa en ti. La imagen se queda local y solo se usa para tus propias generaciones.", + "face_uploading_label": "Subiendo…", + "face_upload_label": "Subir foto de cara", + "face_upload_hint": "Cabeza + hombros, iluminación neutra a poder ser", + "face_uploading_chip": "Cargando…" + }, + "grid_view": { + "upload_label_all": "Subir prenda", + "upload_label_for_category": "Subir {category}", + "upload_hint": "Foto frontal, fondo claro — mejores resultados de Try-On", + "empty_title": "Aún no hay nada en el armario.", + "empty_hint": "Arrastra una foto a la zona de arriba — o haz clic para elegir una.", + "no_entries_under": "No hay entradas en {category}.", + "space_footer": "Este armario pertenece a {name} — los archivos subidos solo aterrizan aquí, no en tu armario personal." + }, + "outfits_view": { + "title": "Outfits", + "count_singular": "combinación", + "count_plural": "combinaciones", + "action_new": "Nuevo outfit", + "empty_title": "Aún no hay outfits.", + "empty_no_garments": "Primero añade unas prendas en la pestaña \"Ropa\" — luego podrás combinarlas en outfits aquí.", + "empty_with_garments": "Combina tus prendas en looks que luego puedes probarte con IA.", + "action_compose_first": "Crear primer outfit" + }, + "detail_garment": { + "loading": "Cargando…", + "not_found_title": "No encontrado.", + "not_found_desc": "La prenda fue eliminada o pertenece a otro espacio.", + "action_enlarge": "Ampliar foto", + "action_edit": "Editar", + "label_brand": "Marca", + "label_color": "Color", + "label_size": "Talla", + "label_material": "Material", + "label_price": "Precio", + "label_wear_count": "Usado", + "wear_count_value": "{count}×", + "last_worn_suffix": " · última vez {date}", + "action_comic": "Como personaje cómic", + "action_comic_title": "Generar un personaje cómic a partir de esta prenda", + "action_marking": "Guardando…", + "action_mark_worn": "Usado hoy", + "action_unarchive": "Reactivar", + "action_archive": "Archivar", + "action_delete": "Eliminar", + "section_try_ons": "Pruebas · {count}", + "section_outfits": "En outfits · {count}", + "no_try_on_yet": "Aún sin prueba", + "action_open_picture": "Abrir en Picture", + "confirm_delete": "¿Eliminar realmente \"{name}\"?" + }, + "detail_outfit": { + "back": "Volver al armario", + "breadcrumb": "Armario · Outfits", + "loading": "Cargando…", + "not_found_title": "Outfit no encontrado.", + "not_found_desc": "Eliminado o en otro espacio.", + "try_on_preview_alt": "Vista previa Try-On", + "no_garments": "Sin prendas", + "action_comic": "Como personaje cómic", + "action_comic_title": "Generar un personaje cómic a partir de este outfit", + "try_on_history": "Historial Try-On", + "action_unfavorite": "Quitar favorito", + "action_favorite": "Marcar como favorito", + "action_edit": "Editar", + "label_visibility": "Visibilidad", + "section_composition": "Composición", + "composition_missing": "Las prendas referenciadas fueron eliminadas o pertenecen a otro espacio.", + "action_unarchive": "Reactivar", + "action_archive": "Archivar", + "action_delete": "Eliminar", + "confirm_delete": "¿Eliminar realmente el outfit \"{name}\"?" + }, + "garment_form": { + "err_name_required": "El nombre no puede estar vacío", + "err_save_failed": "Error al guardar", + "label_name": "Nombre", + "placeholder_name": "p. ej. Camisa rayas azul y blanco", + "label_category": "Categoría", + "label_brand": "Marca", + "placeholder_brand": "p. ej. Uniqlo", + "label_color": "Color", + "placeholder_color": "p. ej. azul marino", + "label_size": "Talla", + "placeholder_size": "p. ej. M o 42", + "label_material": "Material", + "placeholder_material": "p. ej. algodón", + "label_tags": "Etiquetas", + "tags_hint": "(separadas por comas)", + "placeholder_tags": "formal, verano, favorita", + "label_price": "Precio", + "aria_currency": "Moneda", + "label_notes": "Notas", + "placeholder_notes": "Ocasión, instrucciones de cuidado, …", + "action_saving": "Guardando…", + "action_save": "Guardar", + "action_cancel": "Cancelar" + }, + "composer": { + "err_name_required": "Dale un nombre al outfit.", + "err_no_garments": "Elige al menos una prenda.", + "err_save_failed": "Error al guardar", + "section_library": "Armario", + "available_singular": "{count} pieza disponible", + "available_plural": "{count} piezas disponibles", + "empty_title": "Nada que combinar.", + "empty_hint_prefix": "Primero sube unas prendas en la pestaña", + "tab_garments_link": "Ropa", + "empty_hint_suffix": ".", + "label_name": "Nombre", + "placeholder_name": "p. ej. Outfit oficina junio", + "label_description": "Descripción", + "placeholder_description": "¿Para qué ocasión? ¿Algo especial?", + "label_occasion": "Ocasión", + "no_occasion": "— sin ocasión —", + "label_seasons": "Temporada", + "label_tags": "Etiquetas", + "tags_hint": "(separadas por comas)", + "placeholder_tags": "minimal, capas, reunión", + "section_composition": "Composición", + "composition_count_singular": "· {count} pieza", + "composition_count_plural": "· {count} piezas", + "composition_empty": "Haz clic en las prendas a la izquierda para añadirlas al outfit.", + "action_remove": "Quitar del outfit", + "action_saving": "Guardando…", + "action_save_edit": "Guardar cambios", + "action_save_new": "Crear outfit", + "action_cancel": "Cancelar" + }, + "try_on_garment": { + "err_failed": "Error en Try-On", + "err_upload": "Error al subir", + "no_photo": "Sube primero una foto para visualizar esta prenda en ti.", + "refs_title": "Para Try-On en solitario te necesitamos en una foto.", + "refs_accessory": "Una foto de cara basta — la prenda se monta sobre ella.", + "refs_full": "Una foto de cara y otra de cuerpo entero. Ambas solo se usan para tus propias generaciones.", + "upload_face": "Subir foto de cara", + "upload_body": "Subir foto de cuerpo entero", + "face_hint": "Cabeza + hombros, iluminación neutra a poder ser", + "body_hint": "De pie, fondo libre, postura claramente visible", + "refs_more_prefix": "Más referencias u opt-ins de IA por imagen:", + "refs_link": "Mis imágenes", + "rendering": "Renderizando…", + "cta": "Probarme", + "credits": "{count} créditos", + "accessory_hint": "Modo accesorio — solo se renderiza la cara (ahorra créditos).", + "space_hint_prefix": "Try-On usa tus imágenes de referencia de este espacio", + "space_hint_suffix": ", no del Personal.", + "result_label": "Resultado", + "try_on_alt": "Try-On", + "result_hint_prefix": "Encontrado en la", + "picture_gallery_link": "Galería Picture", + "result_hint_suffix": "como una generación normal." + }, + "try_on_outfit": { + "err_failed": "Error en Try-On", + "err_upload": "Error al subir", + "refs_title": "Para Try-On te necesitamos en una foto.", + "refs_accessory": "Una foto de cara basta — el resto se queda como en tu foto.", + "refs_full": "Una foto de cara y otra de cuerpo entero. Ambas solo se usan para tus propias generaciones.", + "upload_face": "Subir foto de cara", + "upload_body": "Subir foto de cuerpo entero", + "face_hint": "Cabeza + hombros, iluminación neutra a poder ser", + "body_hint": "De pie, fondo libre, postura claramente visible", + "refs_more_prefix": "Más referencias u opt-ins de IA por imagen:", + "refs_link": "Mis imágenes", + "rendering": "Renderizando…", + "cta": "Probar", + "credits": "{count} créditos", + "accessory_hint": "Modo accesorio — solo se renderiza la cara (ahorra créditos).", + "many_garments_hint": "Con {count} prendas el slot de referencias está justo — los items más antiguos pueden no entrar.", + "space_hint_prefix": "Try-On usa tus imágenes de referencia de este espacio", + "space_hint_suffix": ", no del Personal.", + "family_hint": "Los outfits de niños se renderizan igualmente en tu cara.", + "empty_garments": "Añade al menos un {category} para activar Try-On." + }, + "model_picker": { + "legend": "Modelo", + "option_openai_label": "OpenAI", + "option_openai_hint": "GPT-image · Estándar", + "option_pro_label": "Nano Banana Pro", + "option_pro_hint": "Google · alta consistencia", + "option_flash_label": "Nano Banana 2", + "option_flash_hint": "Google · más nuevo · barato" + }, + "garment_card": { + "wear_count_title": "Usado {count}×" + }, + "outfit_card": { + "try_on_badge": "Try-On", + "try_on_preview_title": "Vista previa Try-On", + "empty": "Vacío", + "favorite": "Favorito" + }, + "compose": { + "title_edit": "Editar outfit", + "title_new": "Nuevo outfit", + "back": "Volver" + } +} diff --git a/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/fr.json b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/fr.json new file mode 100644 index 000000000..e78a7a6cb --- /dev/null +++ b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/fr.json @@ -0,0 +1,257 @@ +{ + "categories": { + "all": "Tous", + "top": "Hauts", + "bottom": "Pantalons", + "dress": "Robes", + "outerwear": "Vestes", + "shoes": "Chaussures", + "bag": "Sacs", + "accessory": "Accessoires", + "glasses": "Lunettes", + "jewelry": "Bijoux", + "hat": "Chapeaux", + "other": "Autres" + }, + "categories_singular": { + "top": "Haut", + "bottom": "Pantalon", + "dress": "Robe", + "outerwear": "Veste", + "shoes": "Chaussure", + "bag": "Sac", + "accessory": "Accessoire", + "glasses": "Lunettes", + "jewelry": "Bijou", + "hat": "Chapeau", + "other": "Article" + }, + "occasions": { + "casual": "Décontracté", + "work": "Travail", + "formal": "Habillé", + "workout": "Sport", + "date": "Rendez-vous", + "travel": "Voyage", + "event": "Événement", + "sleep": "Pyjama", + "other": "Autre" + }, + "seasons": { + "spring": "Printemps", + "summer": "Été", + "autumn": "Automne", + "winter": "Hiver" + }, + "piece_singular": "pièce", + "piece_plural": "pièces", + "upload_failed": "Échec de l'envoi", + "list_view": { + "aria_tabs": "Changer de vue", + "tab_garments": "Vêtements", + "tab_outfits": "Tenues", + "face_saved_title": "Photo de visage enregistrée", + "face_saved_hint": "Parfait — ensuite, charge ton premier vêtement ci-dessous.", + "dismiss": "Fermer", + "face_prompt_title": "Charge une photo de ton visage", + "face_prompt_desc": "Nous avons besoin de toi en photo pour que Try-On puisse visualiser les vêtements sur toi. L'image reste locale et n'est utilisée que pour tes propres générations.", + "face_uploading_label": "Envoi…", + "face_upload_label": "Charger photo de visage", + "face_upload_hint": "Tête + épaules, éclairage neutre si possible", + "face_uploading_chip": "Chargement…" + }, + "grid_view": { + "upload_label_all": "Charger un vêtement", + "upload_label_for_category": "Charger {category}", + "upload_hint": "Photo de face, fond clair — meilleurs résultats Try-On", + "empty_title": "Encore rien dans la garde-robe.", + "empty_hint": "Glisse une photo dans la zone ci-dessus — ou clique dessus pour en choisir une.", + "no_entries_under": "Aucune entrée sous {category}.", + "space_footer": "Cette garde-robe appartient à {name} — les fichiers chargés n'atterrissent qu'ici, pas dans ta garde-robe personnelle." + }, + "outfits_view": { + "title": "Tenues", + "count_singular": "composition", + "count_plural": "compositions", + "action_new": "Nouvelle tenue", + "empty_title": "Encore aucune tenue.", + "empty_no_garments": "Ajoute d'abord quelques vêtements dans l'onglet \"Vêtements\" — ensuite tu pourras les combiner en tenues ici.", + "empty_with_garments": "Combine tes vêtements en looks que tu pourras ensuite essayer sur toi avec l'IA.", + "action_compose_first": "Composer la première tenue" + }, + "detail_garment": { + "loading": "Chargement…", + "not_found_title": "Introuvable.", + "not_found_desc": "Le vêtement a été supprimé ou appartient à un autre espace.", + "action_enlarge": "Agrandir la photo", + "action_edit": "Modifier", + "label_brand": "Marque", + "label_color": "Couleur", + "label_size": "Taille", + "label_material": "Matière", + "label_price": "Prix", + "label_wear_count": "Porté", + "wear_count_value": "{count}×", + "last_worn_suffix": " · dernière fois {date}", + "action_comic": "Comme personnage BD", + "action_comic_title": "Générer un personnage BD à partir de ce vêtement", + "action_marking": "Enregistrement…", + "action_mark_worn": "Porté aujourd'hui", + "action_unarchive": "Réactiver", + "action_archive": "Archiver", + "action_delete": "Supprimer", + "section_try_ons": "Essayages · {count}", + "section_outfits": "Dans des tenues · {count}", + "no_try_on_yet": "Pas encore d'essayage", + "action_open_picture": "Ouvrir dans Picture", + "confirm_delete": "Vraiment supprimer \"{name}\" ?" + }, + "detail_outfit": { + "back": "Retour à la garde-robe", + "breadcrumb": "Garde-robe · Tenues", + "loading": "Chargement…", + "not_found_title": "Tenue introuvable.", + "not_found_desc": "Supprimée ou dans un autre espace.", + "try_on_preview_alt": "Aperçu Try-On", + "no_garments": "Aucun vêtement", + "action_comic": "Comme personnage BD", + "action_comic_title": "Générer un personnage BD à partir de cette tenue", + "try_on_history": "Historique Try-On", + "action_unfavorite": "Retirer des favoris", + "action_favorite": "Marquer comme favori", + "action_edit": "Modifier", + "label_visibility": "Visibilité", + "section_composition": "Composition", + "composition_missing": "Les vêtements référencés ont été supprimés ou appartiennent à un autre espace.", + "action_unarchive": "Réactiver", + "action_archive": "Archiver", + "action_delete": "Supprimer", + "confirm_delete": "Vraiment supprimer la tenue \"{name}\" ?" + }, + "garment_form": { + "err_name_required": "Le nom ne peut pas être vide", + "err_save_failed": "Échec de l'enregistrement", + "label_name": "Nom", + "placeholder_name": "p. ex. Chemise rayée bleu et blanc", + "label_category": "Catégorie", + "label_brand": "Marque", + "placeholder_brand": "p. ex. Uniqlo", + "label_color": "Couleur", + "placeholder_color": "p. ex. marine", + "label_size": "Taille", + "placeholder_size": "p. ex. M ou 42", + "label_material": "Matière", + "placeholder_material": "p. ex. coton", + "label_tags": "Étiquettes", + "tags_hint": "(séparées par virgules)", + "placeholder_tags": "habillé, été, préférée", + "label_price": "Prix", + "aria_currency": "Devise", + "label_notes": "Notes", + "placeholder_notes": "Occasion, instructions d'entretien, …", + "action_saving": "Enregistrement…", + "action_save": "Enregistrer", + "action_cancel": "Annuler" + }, + "composer": { + "err_name_required": "Donne un nom à la tenue.", + "err_no_garments": "Choisis au moins un vêtement.", + "err_save_failed": "Échec de l'enregistrement", + "section_library": "Garde-robe", + "available_singular": "{count} pièce disponible", + "available_plural": "{count} pièces disponibles", + "empty_title": "Rien à combiner.", + "empty_hint_prefix": "Charge d'abord quelques vêtements dans l'onglet", + "tab_garments_link": "Vêtements", + "empty_hint_suffix": ".", + "label_name": "Nom", + "placeholder_name": "p. ex. Tenue bureau juin", + "label_description": "Description", + "placeholder_description": "Pour quelle occasion ? Particularités ?", + "label_occasion": "Occasion", + "no_occasion": "— sans occasion —", + "label_seasons": "Saison", + "label_tags": "Étiquettes", + "tags_hint": "(séparées par virgules)", + "placeholder_tags": "minimal, layering, réunion", + "section_composition": "Composition", + "composition_count_singular": "· {count} pièce", + "composition_count_plural": "· {count} pièces", + "composition_empty": "Clique sur les vêtements à gauche pour les ajouter à la tenue.", + "action_remove": "Retirer de la tenue", + "action_saving": "Enregistrement…", + "action_save_edit": "Enregistrer les modifications", + "action_save_new": "Créer la tenue", + "action_cancel": "Annuler" + }, + "try_on_garment": { + "err_failed": "Échec Try-On", + "err_upload": "Échec de l'envoi", + "no_photo": "Charge d'abord une photo pour visualiser cette pièce sur toi.", + "refs_title": "Pour Try-On solo, nous avons besoin de toi en photo.", + "refs_accessory": "Une photo de visage suffit — la pièce y est montée.", + "refs_full": "Une photo de visage et une photo en pied. Les deux ne sont utilisées que pour tes propres générations.", + "upload_face": "Charger photo de visage", + "upload_body": "Charger photo en pied", + "face_hint": "Tête + épaules, éclairage neutre si possible", + "body_hint": "Debout, fond libre, posture clairement visible", + "refs_more_prefix": "Plus de références ou opt-ins IA par image :", + "refs_link": "Mes images", + "rendering": "Rendu…", + "cta": "Essayer sur moi", + "credits": "{count} crédits", + "accessory_hint": "Mode accessoire — seul le visage est rendu (économise des crédits).", + "space_hint_prefix": "Try-On utilise tes images de référence de cet espace", + "space_hint_suffix": ", pas de Personnel.", + "result_label": "Résultat", + "try_on_alt": "Try-On", + "result_hint_prefix": "Trouvé dans la", + "picture_gallery_link": "galerie Picture", + "result_hint_suffix": "comme une génération normale." + }, + "try_on_outfit": { + "err_failed": "Échec Try-On", + "err_upload": "Échec de l'envoi", + "refs_title": "Pour Try-On, nous avons besoin de toi en photo.", + "refs_accessory": "Une photo de visage suffit — le reste reste comme sur ta photo.", + "refs_full": "Une photo de visage et une photo en pied. Les deux ne sont utilisées que pour tes propres générations.", + "upload_face": "Charger photo de visage", + "upload_body": "Charger photo en pied", + "face_hint": "Tête + épaules, éclairage neutre si possible", + "body_hint": "Debout, fond libre, posture clairement visible", + "refs_more_prefix": "Plus de références ou opt-ins IA par image :", + "refs_link": "Mes images", + "rendering": "Rendu…", + "cta": "Essayer", + "credits": "{count} crédits", + "accessory_hint": "Mode accessoire — seul le visage est rendu (économise des crédits).", + "many_garments_hint": "Avec {count} vêtements, le slot de référence est juste — les items plus anciens peuvent ne pas être inclus.", + "space_hint_prefix": "Try-On utilise tes images de référence de cet espace", + "space_hint_suffix": ", pas de Personnel.", + "family_hint": "Les tenues d'enfants sont quand même rendues sur ton visage.", + "empty_garments": "Ajoute au moins un {category} pour activer Try-On." + }, + "model_picker": { + "legend": "Modèle", + "option_openai_label": "OpenAI", + "option_openai_hint": "GPT-image · Standard", + "option_pro_label": "Nano Banana Pro", + "option_pro_hint": "Google · forte cohérence", + "option_flash_label": "Nano Banana 2", + "option_flash_hint": "Google · le plus récent · pas cher" + }, + "garment_card": { + "wear_count_title": "Porté {count}×" + }, + "outfit_card": { + "try_on_badge": "Try-On", + "try_on_preview_title": "Aperçu Try-On", + "empty": "Vide", + "favorite": "Favori" + }, + "compose": { + "title_edit": "Modifier la tenue", + "title_new": "Nouvelle tenue", + "back": "Retour" + } +} diff --git a/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/it.json b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/it.json new file mode 100644 index 000000000..9b82610f0 --- /dev/null +++ b/apps/mana/apps/web/src/lib/i18n/locales/wardrobe/it.json @@ -0,0 +1,257 @@ +{ + "categories": { + "all": "Tutti", + "top": "Top", + "bottom": "Pantaloni", + "dress": "Vestiti", + "outerwear": "Giacche", + "shoes": "Scarpe", + "bag": "Borse", + "accessory": "Accessori", + "glasses": "Occhiali", + "jewelry": "Gioielli", + "hat": "Cappelli", + "other": "Altro" + }, + "categories_singular": { + "top": "Top", + "bottom": "Pantaloni", + "dress": "Vestito", + "outerwear": "Giacca", + "shoes": "Scarpa", + "bag": "Borsa", + "accessory": "Accessorio", + "glasses": "Occhiali", + "jewelry": "Gioiello", + "hat": "Cappello", + "other": "Articolo" + }, + "occasions": { + "casual": "Casual", + "work": "Lavoro", + "formal": "Elegante", + "workout": "Sport", + "date": "Appuntamento", + "travel": "Viaggio", + "event": "Evento", + "sleep": "Pigiama", + "other": "Altro" + }, + "seasons": { + "spring": "Primavera", + "summer": "Estate", + "autumn": "Autunno", + "winter": "Inverno" + }, + "piece_singular": "pezzo", + "piece_plural": "pezzi", + "upload_failed": "Caricamento fallito", + "list_view": { + "aria_tabs": "Cambia vista", + "tab_garments": "Abbigliamento", + "tab_outfits": "Outfit", + "face_saved_title": "Foto del viso salvata", + "face_saved_hint": "Perfetto — ora carica il tuo primo capo qui sotto.", + "dismiss": "Chiudi", + "face_prompt_title": "Carica una foto del viso", + "face_prompt_desc": "Abbiamo bisogno di te in una foto perché Try-On possa visualizzare gli abiti su di te. L'immagine resta locale e viene usata solo per le tue generazioni.", + "face_uploading_label": "Caricamento…", + "face_upload_label": "Carica foto del viso", + "face_upload_hint": "Testa + spalle, illuminazione neutra se possibile", + "face_uploading_chip": "Carico…" + }, + "grid_view": { + "upload_label_all": "Carica capo", + "upload_label_for_category": "Carica {category}", + "upload_hint": "Foto frontale, sfondo chiaro — risultati Try-On migliori", + "empty_title": "Ancora nulla nell'armadio.", + "empty_hint": "Trascina una foto nella zona sopra — o cliccala per sceglierne una.", + "no_entries_under": "Nessuna voce sotto {category}.", + "space_footer": "Questo armadio appartiene a {name} — i caricamenti finiscono solo qui, non nel tuo armadio personale." + }, + "outfits_view": { + "title": "Outfit", + "count_singular": "composizione", + "count_plural": "composizioni", + "action_new": "Nuovo outfit", + "empty_title": "Ancora nessun outfit.", + "empty_no_garments": "Prima aggiungi qualche capo nella scheda \"Abbigliamento\" — poi potrai combinarli in outfit qui.", + "empty_with_garments": "Combina i tuoi capi in look che potrai poi provare su di te con l'IA.", + "action_compose_first": "Comporre il primo outfit" + }, + "detail_garment": { + "loading": "Caricamento…", + "not_found_title": "Non trovato.", + "not_found_desc": "Il capo è stato eliminato o appartiene a un altro spazio.", + "action_enlarge": "Ingrandisci foto", + "action_edit": "Modifica", + "label_brand": "Marca", + "label_color": "Colore", + "label_size": "Taglia", + "label_material": "Materiale", + "label_price": "Prezzo", + "label_wear_count": "Indossato", + "wear_count_value": "{count}×", + "last_worn_suffix": " · l'ultima volta {date}", + "action_comic": "Come personaggio comic", + "action_comic_title": "Genera un personaggio comic da questo capo", + "action_marking": "Salvataggio…", + "action_mark_worn": "Indossato oggi", + "action_unarchive": "Riattiva", + "action_archive": "Archivia", + "action_delete": "Elimina", + "section_try_ons": "Prove · {count}", + "section_outfits": "In outfit · {count}", + "no_try_on_yet": "Ancora nessuna prova", + "action_open_picture": "Apri in Picture", + "confirm_delete": "Eliminare davvero \"{name}\"?" + }, + "detail_outfit": { + "back": "Torna all'armadio", + "breadcrumb": "Armadio · Outfit", + "loading": "Caricamento…", + "not_found_title": "Outfit non trovato.", + "not_found_desc": "Eliminato o in un altro spazio.", + "try_on_preview_alt": "Anteprima Try-On", + "no_garments": "Nessun capo", + "action_comic": "Come personaggio comic", + "action_comic_title": "Genera un personaggio comic da questo outfit", + "try_on_history": "Cronologia Try-On", + "action_unfavorite": "Rimuovi preferito", + "action_favorite": "Segna come preferito", + "action_edit": "Modifica", + "label_visibility": "Visibilità", + "section_composition": "Composizione", + "composition_missing": "I capi referenziati sono stati rimossi o appartengono a un altro spazio.", + "action_unarchive": "Riattiva", + "action_archive": "Archivia", + "action_delete": "Elimina", + "confirm_delete": "Eliminare davvero l'outfit \"{name}\"?" + }, + "garment_form": { + "err_name_required": "Il nome non può essere vuoto", + "err_save_failed": "Salvataggio fallito", + "label_name": "Nome", + "placeholder_name": "es. Camicia a righe blu e bianca", + "label_category": "Categoria", + "label_brand": "Marca", + "placeholder_brand": "es. Uniqlo", + "label_color": "Colore", + "placeholder_color": "es. blu navy", + "label_size": "Taglia", + "placeholder_size": "es. M o 42", + "label_material": "Materiale", + "placeholder_material": "es. cotone", + "label_tags": "Tag", + "tags_hint": "(separati da virgola)", + "placeholder_tags": "elegante, estate, preferito", + "label_price": "Prezzo", + "aria_currency": "Valuta", + "label_notes": "Note", + "placeholder_notes": "Occasione, istruzioni di cura, …", + "action_saving": "Salvataggio…", + "action_save": "Salva", + "action_cancel": "Annulla" + }, + "composer": { + "err_name_required": "Dai un nome all'outfit.", + "err_no_garments": "Scegli almeno un capo.", + "err_save_failed": "Salvataggio fallito", + "section_library": "Armadio", + "available_singular": "{count} pezzo disponibile", + "available_plural": "{count} pezzi disponibili", + "empty_title": "Niente da combinare.", + "empty_hint_prefix": "Prima carica qualche capo nella scheda", + "tab_garments_link": "Abbigliamento", + "empty_hint_suffix": ".", + "label_name": "Nome", + "placeholder_name": "es. Outfit ufficio giugno", + "label_description": "Descrizione", + "placeholder_description": "Per quale occasione? Particolarità?", + "label_occasion": "Occasione", + "no_occasion": "— nessuna occasione —", + "label_seasons": "Stagione", + "label_tags": "Tag", + "tags_hint": "(separati da virgola)", + "placeholder_tags": "minimal, layering, riunione", + "section_composition": "Composizione", + "composition_count_singular": "· {count} pezzo", + "composition_count_plural": "· {count} pezzi", + "composition_empty": "Clicca i capi a sinistra per aggiungerli all'outfit.", + "action_remove": "Rimuovi dall'outfit", + "action_saving": "Salvataggio…", + "action_save_edit": "Salva modifiche", + "action_save_new": "Crea outfit", + "action_cancel": "Annulla" + }, + "try_on_garment": { + "err_failed": "Try-On fallito", + "err_upload": "Caricamento fallito", + "no_photo": "Carica prima una foto per visualizzare questo capo su di te.", + "refs_title": "Per il Try-On in solitaria abbiamo bisogno di te in foto.", + "refs_accessory": "Una foto del viso basta — il capo viene montato sopra.", + "refs_full": "Una foto del viso e una a figura intera. Entrambe sono usate solo per le tue generazioni.", + "upload_face": "Carica foto del viso", + "upload_body": "Carica foto a figura intera", + "face_hint": "Testa + spalle, illuminazione neutra se possibile", + "body_hint": "In piedi, sfondo libero, postura ben visibile", + "refs_more_prefix": "Altri riferimenti o opt-in IA per immagine:", + "refs_link": "Le mie immagini", + "rendering": "Rendering…", + "cta": "Provami addosso", + "credits": "{count} crediti", + "accessory_hint": "Modalità accessorio — viene reso solo il viso (risparmia crediti).", + "space_hint_prefix": "Try-On usa le tue immagini di riferimento di questo spazio", + "space_hint_suffix": ", non da Personale.", + "result_label": "Risultato", + "try_on_alt": "Try-On", + "result_hint_prefix": "Trovato nella", + "picture_gallery_link": "galleria Picture", + "result_hint_suffix": "come una generazione normale." + }, + "try_on_outfit": { + "err_failed": "Try-On fallito", + "err_upload": "Caricamento fallito", + "refs_title": "Per il Try-On abbiamo bisogno di te in foto.", + "refs_accessory": "Una foto del viso basta — il resto resta come nella tua foto.", + "refs_full": "Una foto del viso e una a figura intera. Entrambe sono usate solo per le tue generazioni.", + "upload_face": "Carica foto del viso", + "upload_body": "Carica foto a figura intera", + "face_hint": "Testa + spalle, illuminazione neutra se possibile", + "body_hint": "In piedi, sfondo libero, postura ben visibile", + "refs_more_prefix": "Altri riferimenti o opt-in IA per immagine:", + "refs_link": "Le mie immagini", + "rendering": "Rendering…", + "cta": "Prova", + "credits": "{count} crediti", + "accessory_hint": "Modalità accessorio — viene reso solo il viso (risparmia crediti).", + "many_garments_hint": "Con {count} capi lo slot di riferimento è stretto — gli articoli più vecchi potrebbero non essere inclusi.", + "space_hint_prefix": "Try-On usa le tue immagini di riferimento di questo spazio", + "space_hint_suffix": ", non da Personale.", + "family_hint": "Gli outfit dei bambini vengono comunque resi sul tuo viso.", + "empty_garments": "Aggiungi almeno un {category} per attivare Try-On." + }, + "model_picker": { + "legend": "Modello", + "option_openai_label": "OpenAI", + "option_openai_hint": "GPT-image · Standard", + "option_pro_label": "Nano Banana Pro", + "option_pro_hint": "Google · alta coerenza", + "option_flash_label": "Nano Banana 2", + "option_flash_hint": "Google · ultimo · economico" + }, + "garment_card": { + "wear_count_title": "Indossato {count}×" + }, + "outfit_card": { + "try_on_badge": "Try-On", + "try_on_preview_title": "Anteprima Try-On", + "empty": "Vuoto", + "favorite": "Preferito" + }, + "compose": { + "title_edit": "Modifica outfit", + "title_new": "Nuovo outfit", + "back": "Indietro" + } +} diff --git a/apps/mana/apps/web/src/lib/modules/wardrobe/ListView.svelte b/apps/mana/apps/web/src/lib/modules/wardrobe/ListView.svelte index 7bb982dba..b30490d9c 100644 --- a/apps/mana/apps/web/src/lib/modules/wardrobe/ListView.svelte +++ b/apps/mana/apps/web/src/lib/modules/wardrobe/ListView.svelte @@ -13,6 +13,7 @@ -->
-
{:else}
-

Lade ein Gesichtsbild hoch

+

+ {$_('wardrobe.list_view.face_prompt_title')} +

- Wir brauchen dich auf Bild, damit Try-On Kleidung an dir visualisieren kann. Das Bild - bleibt lokal und wird nur für deine eigenen Generierungen genutzt. + {$_('wardrobe.list_view.face_prompt_desc')}

@@ -168,7 +172,7 @@ aria-live="polite" > - Lade… + {$_('wardrobe.list_view.face_uploading_chip')} {/if}
diff --git a/apps/mana/apps/web/src/lib/modules/wardrobe/components/CategoryTabs.svelte b/apps/mana/apps/web/src/lib/modules/wardrobe/components/CategoryTabs.svelte index 3a7e9e88a..128bc3d8c 100644 --- a/apps/mana/apps/web/src/lib/modules/wardrobe/components/CategoryTabs.svelte +++ b/apps/mana/apps/web/src/lib/modules/wardrobe/components/CategoryTabs.svelte @@ -5,7 +5,8 @@ category, so "Oberteile aktiv → Datei droppen → landet als top"). --> @@ -94,7 +95,7 @@
@@ -221,14 +223,14 @@
@@ -249,7 +251,7 @@ disabled={saving || !name.trim()} class="flex-1 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50" > - {saving ? 'Speichere…' : 'Speichern'} + {saving ? $_('wardrobe.garment_form.action_saving') : $_('wardrobe.garment_form.action_save')} {#if onCancel} {/if}
diff --git a/apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentTryOnButton.svelte b/apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentTryOnButton.svelte index 28c9181ab..86e55eb9f 100644 --- a/apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentTryOnButton.svelte +++ b/apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentTryOnButton.svelte @@ -11,6 +11,7 @@ outfit's try-on history. --> @@ -140,21 +137,24 @@

- Kleiderschrank + {$_('wardrobe.composer.section_library')}

- {garments.length} - {garments.length === 1 ? 'Stück' : 'Stücke'} verfügbar + {garments.length === 1 + ? $_('wardrobe.composer.available_singular', { values: { count: garments.length } }) + : $_('wardrobe.composer.available_plural', { values: { count: garments.length } })}
{#if garments.length === 0}
-

Nichts zum Kombinieren.

+

{$_('wardrobe.composer.empty_title')}

- Lade zuerst ein paar Kleidungsstücke im Tab - Kleidung - hoch. + {$_('wardrobe.composer.empty_hint_prefix')} + {$_('wardrobe.composer.tab_garments_link')} + {$_('wardrobe.composer.empty_hint_suffix')}

{:else} @@ -166,7 +166,7 @@ {#if list.length > 0}

- {CATEGORY_LABELS[category]} + {$_('wardrobe.categories.' + category)} · {list.length}

@@ -216,7 +216,7 @@
- Jahreszeit + {$_('wardrobe.composer.label_seasons')}
- {#each Object.entries(SEASON_LABELS) as [season, label]} - {@const s = season as OutfitSeason} + {#each SEASON_KEYS as s} {@const on = selectedSeasons.includes(s)} {/each}
@@ -283,14 +284,15 @@
@@ -299,10 +301,15 @@

- Zusammenstellung + {$_('wardrobe.composer.section_composition')} - · {selectedGarments.length} - {selectedGarments.length === 1 ? 'Stück' : 'Stücke'} + {selectedGarments.length === 1 + ? $_('wardrobe.composer.composition_count_singular', { + values: { count: selectedGarments.length }, + }) + : $_('wardrobe.composer.composition_count_plural', { + values: { count: selectedGarments.length }, + })}

@@ -310,7 +317,7 @@

- Klicke links auf Kleidungsstücke, um sie dem Outfit hinzuzufügen. + {$_('wardrobe.composer.composition_empty')}

{:else}
@@ -331,8 +338,8 @@ {#if onCancel} {/if}
diff --git a/apps/mana/apps/web/src/lib/modules/wardrobe/components/TryOnButton.svelte b/apps/mana/apps/web/src/lib/modules/wardrobe/components/TryOnButton.svelte index 7dbf47802..776958723 100644 --- a/apps/mana/apps/web/src/lib/modules/wardrobe/components/TryOnButton.svelte +++ b/apps/mana/apps/web/src/lib/modules/wardrobe/components/TryOnButton.svelte @@ -5,6 +5,7 @@ loading (request in flight). -->
- Modell + {$_('wardrobe.model_picker.legend')}
{#each OPTIONS as opt (opt.id)}