This commit is contained in:
2026-08-17 21:20:45 +02:00
parent 321f11e817
commit 6fcdc74843
157 changed files with 2895 additions and 7544 deletions
+37 -28
View File
@@ -78,7 +78,7 @@ export const en: MessageDict = {
"auth.login.failed": "Login failed",
"auth.login.passwordNotSet": "This account still needs a password. Open your invite link, or ask an admin to re-issue one.",
"auth.login.setPasswordFirstTitle": "Set password first:",
"auth.login.setPasswordFirstBody": "use the invite link from your email. If the link went to an old address (email drift), ask a company admin to re-issue a set-password invite to {email}.",
"auth.login.setPasswordFirstBody": "use the invite link from your email. If you need a new link, ask a company admin to re-issue a set-password link to {email}.",
"auth.login.yourEmail": "your email",
"auth.login.platformAdminsReissue": "Platform admins can re-issue from",
"auth.login.adminUsersLink": "Admin → Users",
@@ -144,9 +144,9 @@ export const en: MessageDict = {
"auth.invite.acceptFailed": "Could not accept invite",
"auth.invite.setPasswordFailed": "Could not set password",
"auth.invite.expired": "This invite is invalid or expired. Ask your company admin to send a new invite, then open the new link (or paste the new token below).",
"auth.invite.setPasswordExpired": "This set-password link is invalid or expired. Ask a company or platform admin to re-issue it, then open the new link (or paste the new token below).",
"auth.invite.setPasswordExpired": "This set-password link is invalid or expired. Ask a company admin to re-issue a set-password link to this email, then open the new link (or paste the new token below).",
"auth.invite.emailMismatchDefault": "You're signed in as a different email than this invite.",
"auth.invite.expiredFooter": "Expired link? Ask an admin to re-issue — there is no self-serve resend API. Platform admins:",
"auth.invite.expiredFooter": "Expired link? Ask a company admin to re-issue — there is no self-serve resend API.",
"auth.invite.adminUsersLink": "Admin → Users",
"auth.invite.doneTitle": "You're on the team",
"auth.invite.doneSetPasswordTitle": "Password saved",
@@ -163,7 +163,7 @@ export const en: MessageDict = {
"auth.invite.switchAccountTitle": "Switch account:",
"auth.invite.switchAccountBody": "sign out, then finish this form with the invited email{emailSuffix}.",
"auth.invite.reissueTitle": "Re-issue path:",
"auth.invite.reissueBody": "if your real login email changed (email drift), ask a company admin to revoke this invite and send a new one to the email you use to sign in. Platform admins can also re-issue set-password links from Admin → Users.",
"auth.invite.reissueBody": "ask a company admin to re-issue a set-password link to this email, or to revoke this invite and send a new one to the email you use to sign in.",
"locale.switcher": "Interface language",
"locale.menu": "Choose interface language",
"locale.label": "Dashboard language",
@@ -296,7 +296,7 @@ export const en: MessageDict = {
"settings.table.lastUsed": "Last Used",
"dashboard.demoSandbox": "Demo sandbox",
"dashboard.demoEmptyTitle": "Demo sandbox is empty",
"dashboard.demoEmptyHint": "Demo sandbox is empty — switch to A1 or connect a feed to see real catalog stats.",
"dashboard.demoEmptyHint": "Demo sandbox is empty — connect a feed to see catalog stats.",
"dashboard.overviewTitle": "Overview",
"dashboard.quickLinks": "Quick links",
"dashboard.whatsNew": "What's new",
@@ -339,7 +339,7 @@ export const en: MessageDict = {
"dashboard.workflow.exportMap": "Map then export",
"dashboard.workflowHint": "Catalog in → enrich / process → export or push to stores. Jump to the next step for {name}.",
"dashboard.overviewHint": "Live totals for {name}",
"dashboard.demoEmptyMessage": "Switch to A1 (or another seeded company) in the header, or connect a feed here to populate this sandbox.",
"dashboard.demoEmptyMessage": "Connect a feed here to populate this sandbox, or switch to another company in the header.",
"dashboard.emptyTitle": "Bring a catalog in",
"dashboard.emptyMessage": "Catalog in → enrich / process → export or push to stores. Start with Getting started below (or connect a feed / upload a CSV).",
"dashboard.connectFeedAnyway": "Connect feed anyway",
@@ -391,28 +391,28 @@ export const en: MessageDict = {
"activation.focus.sync": "Next: Sync a sample after mappings are saved. Use Sync on a mapped feed — avoid syncing unmapped sources.",
"activation.focus.dismiss": "Dismiss hint",
"activation.dismiss": "Dismiss checklist",
"hypercare.report.title": "Cutover hypercare",
"hypercare.report.message": "See missing or wrong data after migration? Report it so we can fix your workspace.",
"hypercare.report.title": "Need help after the move?",
"hypercare.report.message": "See missing or wrong data after the move? Report it so we can fix your workspace.",
"hypercare.report.cta": "Report missing or wrong data",
"hypercare.report.dismiss": "Dismiss",
"hypercare.report.adminTriage": "Open hypercare queue",
"etl.gaps.title": "What did not migrate",
"etl.gaps.message": "These areas were intentionally left empty or partial after the Descrybe platform cutover. Nothing is broken — recreate or reconnect as needed.",
"etl.gaps.title": "What still needs setup",
"etl.gaps.message": "Some items weren't copied when we moved your workspace. Nothing is broken — recreate or reconnect as needed.",
"etl.gaps.dismiss": "Dismiss",
"etl.gaps.apiKeys.title": "API keys",
"etl.gaps.apiKeys.body": "Legacy API key secrets were not migrated. Create a new key to restore API access — the secret is shown only once.",
"etl.gaps.apiKeys.body": "Previous API keys weren't copied. Create a new key to restore API access — the secret is shown only once.",
"etl.gaps.apiKeys.cta": "Open API keys",
"etl.gaps.blobs.title": "File contents (blobs)",
"etl.gaps.blobs.body": "Upload records may exist as metadata only. File bytes were not copied — re-upload CSVs or resync object storage if you need the originals.",
"etl.gaps.blobs.countHint": "{count} file records are metadata-only (bytes were not migrated).",
"etl.gaps.blobs.title": "Uploaded files",
"etl.gaps.blobs.body": "File names may appear even when the file itself wasn't copied. Re-upload CSVs if you need the originals.",
"etl.gaps.blobs.countHint": "{count} files are listed without their contents (they weren't copied).",
"etl.gaps.blobs.cta": "Open Files",
"etl.gaps.jobs.title": "Processing history",
"etl.gaps.jobs.body": "Legacy job and task history was not backfilled for cutover. New jobs you start here will appear normally.",
"etl.gaps.jobs.emptyHint": "Optional jobs domain was not run — empty history is expected.",
"etl.gaps.jobs.migratedHint": "{count} jobs were tagged migrated from an optional backfill.",
"etl.gaps.jobs.body": "Earlier job history wasn't imported. New jobs you start here will appear normally.",
"etl.gaps.jobs.emptyHint": "Processing history wasn't imported — an empty list is expected.",
"etl.gaps.jobs.migratedHint": "{count} jobs were imported from the previous workspace.",
"etl.gaps.jobs.cta": "Open Processing",
"etl.gaps.woo.title": "Store credentials",
"etl.gaps.woo.body": "WooCommerce and Shopify secrets may need to be re-entered after cutoverthat is a reconnect step, not a broken sync.",
"etl.gaps.woo.body": "WooCommerce and Shopify passwords may need to be re-entered after the move — reconnect your store; sync is not broken.",
"etl.gaps.woo.cta": "Open Stores",
"etl.gaps.settings.title": "Company settings",
"etl.gaps.settings.body": "Only language and merge-products settings were imported. Re-check other company preferences in Settings.",
@@ -479,9 +479,9 @@ export const en: MessageDict = {
"errors.readOnly": "The system is in read-only mode. Changes are temporarily disabled.",
"errors.companyAdminDenied": "Only company admins can {action}. Ask a company admin for help.",
"errors.companyAdminDenied.actionDefault": "do this",
"docs.tryIt.memberCannotCreate": "Only company admins can create API keys. Legacy keys were not migrated — paste a key below, or ask an admin to create a new one.",
"docs.tryIt.noKeysLegacyAdmin": "Legacy API keys were not migrated. Create a new key via Use my API key or Settings → API keys — the secret is shown only once.",
"docs.tryIt.noKeysLegacyMember": "No API keys listed. Legacy keys were not migrated — ask a company admin to create one, or paste a dk_ key.",
"docs.tryIt.memberCannotCreate": "Only company admins can create API keys. Keys from the previous platform were not migrated — paste a key below, or ask an admin to create a new one.",
"docs.tryIt.noKeysLegacyAdmin": "API keys from the previous platform were not migrated. Create a new key via Use my API key or Settings → API keys — the secret is shown only once.",
"docs.tryIt.noKeysLegacyMember": "No API keys listed. Keys from the previous platform were not migrated — ask a company admin to create one, or paste a dk_ key.",
"errors.couldNotUpdateLanguage": "Could not update language",
"toast.support.replyTitle": "Support reply",
"toast.support.replyBody": "Staff replied to your support ticket.",
@@ -3729,6 +3729,7 @@ export const en: MessageDict = {
"processing.receipt.cancelledDesc": "The just-started job was cancelled.",
"processing.receipt.cancelFailed": "Could not cancel processing job",
"unsubscribe.title": "Unsubscribe",
"unsubscribe.useEmailLink": "Use the unsubscribe link in the email we sent you. Opening this page without that link cannot change your email preferences.",
"unsubscribe.me": "Unsubscribe me",
"unsubscribe.invalidLink": "Invalid link",
"unsubscribe.failedShort": "Unsubscribe failed",
@@ -4445,23 +4446,23 @@ export const en: MessageDict = {
"categories.promptSection.navHeading": "Sections",
"categories.promptSection.navHint": "Edit one part of the enhance reply at a time.",
"categories.promptSection.title": "Title",
"categories.promptSection.titleHelp": "Instructions for the product title (JSON name).",
"categories.promptSection.titleHelp": "Instructions for the product title.",
"categories.promptSection.titleFormulaNote": "Title formula slots (type + brand + model) are appended automatically when set on this category.",
"categories.promptSection.description": "Description",
"categories.promptSection.descriptionHelp": "Instructions for the HTML product body (JSON description - not SEO meta).",
"categories.promptSection.descriptionHelp": "Instructions for the HTML product body (not SEO meta).",
"categories.promptSection.descriptionFormulaNote": "Description formula sections are appended at render time when configured.",
"categories.promptSection.meta": "Meta",
"categories.promptSection.metaHelp": "Instructions for SEO meta_title and meta_description (plain text).",
"categories.promptSection.metaHelp": "Instructions for the SEO title and description (plain text).",
"categories.promptSection.metaFormulaNote": "SEO meta formulas from the description template are appended when present.",
"categories.promptSection.attributes": "Attributes",
"categories.promptSection.attributesHelp": "Instructions for the attrs object (allowlisted keys).",
"categories.promptSection.attributesHelp": "Instructions for product attributes (allowed keys only).",
"categories.promptSection.attributesFormulaNote": "Allowed attribute keys and title-formula attr slots are appended at render time.",
"categories.promptSection.schemaHeading": "One-shot JSON",
"categories.promptSection.schemaHelp": "Enhance returns a single JSON object. This section owns the keys below.",
"categories.promptSection.contentLabel": "Section instructions",
"categories.promptSection.contentPlaceholder": "Role guidance and placeholders for this section...",
"categories.promptSection.preambleToggle": "Shared intro (all sections)",
"categories.promptSection.preambleHelp": "Shown once above the section markers. Keep the JSON schema reminder so the model replies correctly.",
"categories.promptSection.preambleHelp": "Shown once above the section markers. Keep language and evidence reminders so the model replies correctly.",
"categories.promptSection.clearLanguage": "Clear language override",
"categories.promptSection.unstructuredHint": "This prompt is not sectioned yet. Content is shown under Description - edit the sections you need and save to store the standard Title / Description / Meta / Attributes layout.",
"categories.promptSection.categorizeNote": "Categorize (taxonomy pick) is a separate pipeline step - not part of this enhance prompt.",
@@ -4792,6 +4793,10 @@ export const en: MessageDict = {
"seo.terms.description": "Terms for using Descrybe — feed import, catalog enrichment, AI-assisted content, exports, and WooCommerce sync for your business.",
"seo.features.title": "Features — Feeds, enrichment, and export | Descrybe",
"seo.features.description": "See how Descrybe imports supplier feeds, maps fields to your taxonomy, enriches product data, and ships catalogs via export feeds, WooCommerce, or API.",
"seo.contactSales.title": "Contact sales | Descrybe",
"seo.contactSales.description": "Tell us about your catalog and capacity needs — we will prepare a custom plan you can pay online.",
"seo.unsubscribe.title": "Unsubscribe | Descrybe",
"seo.unsubscribe.description": "Stop marketing emails from Descrybe using the unsubscribe link in the message we sent you.",
"pricing.page.eyebrow": "Pricing",
"pricing.page.title": "Simple plans for growing catalogs",
"pricing.page.lead": "Start free with feed mapping and basic cleanup. Upgrade when you need AI titles and descriptions, more products, export feeds, or WooCommerce sync — Starter through Enterprise.",
@@ -4799,6 +4804,8 @@ export const en: MessageDict = {
"pricing.page.subscribedMid": "or compare plans in",
"pricing.page.plansLink": "Plans",
"pricing.page.subscribedAfter": ".",
"pricing.page.guestSubscribedBefore": "Already subscribed?",
"pricing.page.guestSubscribedAfter": "to manage billing and compare plans.",
"legal.lastUpdated": "Last updated: {date}",
"legal.backHome": "← Back to Home",
"legal.emailLabel": "Email:",
@@ -5130,7 +5137,7 @@ export const en: MessageDict = {
"brand.uploadLogo": "Upload logo",
"brand.clear": "Clear",
"brand.field.logoUrl": "Logo URL",
"brand.placeholder.logoUrl": "https://… or uploaded /api/brand/logo/files/…",
"brand.placeholder.logoUrl": "https://…",
"brand.logoAlt": "Brand logo preview",
"brand.tipsTitle": "Formula / preview tips",
"brand.saving": "Saving…",
@@ -5291,6 +5298,8 @@ export const en: MessageDict = {
"pricing.section.publicBefore": "Public plans: Free, Starter, Plus, Growth, Business, Scale, and Enterprise. Create a Free account, then upgrade under",
"pricing.section.publicOr": "or",
"pricing.section.publicAfter": "via Stripe Checkout. Enterprise remains sales-led.",
"pricing.section.guestPublicBefore": "Public plans: Free, Starter, Plus, Growth, Business, Scale, and Enterprise. Create a Free account, then",
"pricing.section.guestPublicAfter": "to upgrade via Stripe Checkout. Enterprise remains sales-led.",
"pricing.section.plansLink": "Plans",
"pricing.section.billingLink": "Billing",
"pricing.section.capabilitiesTitle": "What every plan is built for",
@@ -5359,7 +5368,7 @@ export const en: MessageDict = {
"pricing.calc.enterpriseTitle": "Sounds like Enterprise",
"pricing.calc.enterpriseBody": "Your feeds or catalog size exceed self-serve caps. Talk to sales for unlimited capacity and a managed AI grant or BYOK.",
"pricing.calc.ctaPlan": "Choose {name}",
"pricing.calc.disclaimer": "Estimates use list prices and ~2 credits per AI product enhance. Checkout prices come from Stripe. A1 and other client deals stay admin-only.",
"pricing.calc.disclaimer": "Estimates use list prices and ~2 credits per AI product enhance. Checkout prices come from Stripe. Custom client deals stay admin-only.",
"pricing.card.mostPopular": "Most Popular",
"pricing.card.custom": "Custom",
"pricing.card.forever": "forever",