fix(ui): wave 2 from critique re-run — AA contrast, unified PageHeader, checkout confirm
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m46s

Nav: teams/settings/services back out of the nav until product-ready (user
decision); teams page was already half-finished (UUID member display is a
backend limitation).

Payment: explicit confirmation dialog (plan, amount, billing period, Stripe
note) before any redirect; ?plan= URL now pre-opens the dialog instead of
triggering a silent checkout.

Contrast AA sweep (71 replacements): functional micro-labels raised to
>=60-65% opacity and >=10px across sidebar, header, pricing, landing;
decorative all-caps 'interface' label removed.

Design unification: new PageHeader component (accent pill + serif
base/accent title) applied to settings, services, reviews, teams; pricing
header returned to the editorial voice (serif + accent pill); dead
GlossaryCard deleted.

i18n residuals: suggestion chips, 'Standard' provider label, notification
close, model-combobox strings extracted (+broken bg-surface/border-border-
subtle tokens fixed); ~45 new keys EN+FR; 13 dead keys removed; zero
missing keys verified.

Reviews: icon-only row actions now carry visible text; 'Approve all' is
two-step armed-confirm.

Accelerators: Ctrl/Cmd+Enter submits; arrow-key navigation in the language
combobox; recent-jobs history cap 8->20 with per-job download; source=target
config rejected; empty 'Master Quality' badge removed.

Cookie consent: reopenable via footer link, emoji replaced with drawn icon.

Verified: build exit 0, vitest 9/9, eslint 64 errors = previous level,
0 missing i18n keys.
This commit is contained in:
2026-08-30 22:02:35 +02:00
parent 50047ea8a2
commit 111f3cb69d
41 changed files with 470 additions and 280 deletions

View File

@@ -1,4 +1,8 @@
{
"common.loading": "Loading...",
"common.backToHome": "Back to home"
"common.backToHome": "Back to home",
"common.browse": "Browse",
"common.noModels": "No models retrieved",
"common.noModelMatch": "No model matches your search",
"common.closeNotification": "Close notification"
}

View File

@@ -3,5 +3,6 @@
"cookieConsent.description": "We use essential cookies so the app works (session, security, language). With your permission, we also use optional cookies to measure traffic and improve the product.",
"cookieConsent.acceptAll": "Accept all",
"cookieConsent.essentialOnly": "Essential only",
"cookieConsent.learnMore": "Learn more"
"cookieConsent.learnMore": "Learn more",
"cookieConsent.reopen": "Cookie preferences"
}

View File

@@ -220,5 +220,11 @@
"glossaries.card.use": "Use",
"glossaries.createFirst": "Create my first glossary",
"glossaries.noResults": "No results for “{query}”",
"glossaries.card.terms": "terms"
"glossaries.card.terms": "terms",
"glossaries.suggestion.formal": "Formal tone",
"glossaries.suggestion.proprietary": "Proper nouns",
"glossaries.suggestion.numbers": "Numbers",
"glossaries.suggestion.placeholders": "Placeholders",
"glossaries.suggestion.technical": "Technical terms",
"glossaries.suggestion.concise": "Concise style"
}

View File

@@ -152,5 +152,13 @@
"pricing.enterprise.subject": "Enterprise plan enquiry",
"pricing.toast.close": "Close",
"pricing.header.titleBase": "A plan for",
"pricing.header.titleAccent": "every need"
"pricing.header.titleAccent": "every need",
"pricing.confirm.title": "Confirm your subscription",
"pricing.confirm.subtitle": "You will be redirected to our secure payment provider.",
"pricing.confirm.month": "month",
"pricing.confirm.year": "year",
"pricing.confirm.monthlyEquivalent": "Billed yearly — {price} € / month equivalent.",
"pricing.confirm.secureNote": "You can cancel anytime from your profile. Payment is processed by Stripe; your card details never touch our servers.",
"pricing.confirm.cancel": "Cancel",
"pricing.confirm.cta": "Continue to payment"
}

View File

@@ -3,5 +3,6 @@
"providerSelector.noLlm": "No AI model configured.",
"providerSelector.costOne": "Cost: 1 credit per page",
"providerSelector.costFive": "Cost: 5 credits per page (Premium factor)",
"providerSelector.unlockContextual": "Unlock premium contextual translation for your entire documents."
"providerSelector.unlockContextual": "Unlock premium contextual translation for your entire documents.",
"providerSelector.standard": "Standard"
}

View File

@@ -28,5 +28,11 @@
"reviews.error.title": "Error",
"reviews.error.load": "Loading failed",
"reviews.error.update": "Could not update",
"reviews.error.download": "Download failed (HTTP {status})"
"reviews.error.download": "Download failed (HTTP {status})",
"reviews.pill": "Quality control",
"reviews.titleBase": "Translation",
"reviews.titleAccent": "review",
"reviews.approveAllConfirm": "Confirm ({count})",
"reviews.action.approveShort": "OK",
"reviews.action.resetShort": "Re-review"
}

View File

@@ -11,5 +11,6 @@
"services.adminOnly.desc": "API keys, model selection, and provider activation are managed exclusively by the administrator in the admin panel. You never need to enter an API key.",
"services.fallback.google.label": "Google Translate",
"services.fallback.google.desc": "Fast translation, 130+ languages",
"services.pill": "Engines"
"services.pill": "Engines",
"services.titleAccent": "status"
}

View File

@@ -19,5 +19,6 @@
"settings.formats.powerpoint.name": "PowerPoint",
"settings.pill": "Configuration",
"settings.cache.confirm": "Confirm and reload",
"settings.cache.cancelClear": "Cancel"
"settings.cache.cancelClear": "Cancel",
"settings.titleAccent": "presets"
}

View File

@@ -22,5 +22,8 @@
"teams.invite": "Invite",
"teams.empty": "No workspace yet — create the first one above.",
"teams.error.title": "Error",
"teams.error.load": "Could not load"
"teams.error.load": "Could not load",
"teams.pill": "Collaboration",
"teams.titleBase": "Team",
"teams.titleAccent": "workspaces"
}

View File

@@ -49,12 +49,8 @@
"translate.glossary.targetWarningBut": "but your document targets",
"translate.glossary.targetWarningEnd": "Terms may not be relevant.",
"translate.header.processing": "Processing in progress",
"translate.header.aiActive": "AI analysis active",
"translate.header.aiActiveDesc": "Your layout is being preserved by our contextual engine.",
"translate.header.completed": "Completed",
"translate.header.completedTitle": "Translation completed",
"translate.header.proSpace": "Pro space",
"translate.header.translateDoc": "Translate a document",
"translate.header.translateDocDesc": "Preserve the original layout with our ultra-high-fidelity translation engine.",
"translate.upload.nativeFormat": "Native format",
"translate.fileType.word": "Word (.docx)",
@@ -68,12 +64,7 @@
"translate.contextEngineActive": "Contextual engine active",
"translate.phase1": "Phase 1: Initialisation",
"translate.phase2": "Phase 2: Contextual reconstruction",
"translate.stat.segments": "segments",
"translate.stat.precision": "precision",
"translate.stat.speedLabel": "speed",
"translate.stat.turbo": "Turbo",
"translate.stat.time": "time",
"translate.complete.masterQuality": "✓ Master quality",
"translate.download": "Download",
"translate.newTranslation": "+ New translation",
"translate.failedTitle": "Translation error",
@@ -81,10 +72,6 @@
"translate.uploadAnother": "Upload another file",
"translate.monitor": "AI monitor",
"translate.summary": "Summary",
"translate.cancelProcess": "⟳ Cancel the process",
"translate.layoutIntegrity": "Layout integrity",
"translate.secureHundred": "100% SECURE",
"translate.okHundred": "100% OK",
"translate.preserveLayout": "Preserve layout",
"translate.preserveLayoutDesc": "Preserve the layout",
"translate.textOnly": "Text only",

View File

@@ -1,4 +1,8 @@
{
"common.loading": "Chargement...",
"common.backToHome": "Retour à l'accueil"
"common.backToHome": "Retour à l'accueil",
"common.browse": "Parcourir",
"common.noModels": "Aucun modèle récupéré",
"common.noModelMatch": "Aucun modèle ne correspond",
"common.closeNotification": "Fermer la notification"
}

View File

@@ -3,5 +3,6 @@
"cookieConsent.description": "Nous utilisons des cookies strictement nécessaires au fonctionnement du service (session, sécurité, langue). Avec votre accord, nous pouvons aussi utiliser des cookies optionnels pour mesurer l'audience et améliorer le produit.",
"cookieConsent.acceptAll": "Tout accepter",
"cookieConsent.essentialOnly": "Nécessaires uniquement",
"cookieConsent.learnMore": "En savoir plus"
"cookieConsent.learnMore": "En savoir plus",
"cookieConsent.reopen": "Préférences cookies"
}

View File

@@ -220,5 +220,11 @@
"glossaries.card.use": "Utiliser",
"glossaries.createFirst": "Créer mon premier glossaire",
"glossaries.noResults": "Aucun résultat pour « {query} »",
"glossaries.card.terms": "termes"
"glossaries.card.terms": "termes",
"glossaries.suggestion.formal": "Ton formel",
"glossaries.suggestion.proprietary": "Noms propres",
"glossaries.suggestion.numbers": "Chiffres",
"glossaries.suggestion.placeholders": "Placeholders",
"glossaries.suggestion.technical": "Termes techniques",
"glossaries.suggestion.concise": "Style concis"
}

View File

@@ -152,5 +152,13 @@
"pricing.enterprise.subject": "Offre Enterprise",
"pricing.toast.close": "Fermer",
"pricing.header.titleBase": "Un forfait pour",
"pricing.header.titleAccent": "chaque besoin"
"pricing.header.titleAccent": "chaque besoin",
"pricing.confirm.title": "Confirmez votre abonnement",
"pricing.confirm.subtitle": "Vous serez redirigé vers notre prestataire de paiement sécurisé.",
"pricing.confirm.month": "mois",
"pricing.confirm.year": "an",
"pricing.confirm.monthlyEquivalent": "Facturation annuelle — soit {price} € / mois.",
"pricing.confirm.secureNote": "Résiliable à tout moment depuis votre profil. Paiement traité par Stripe ; vos données bancaires ne passent jamais par nos serveurs.",
"pricing.confirm.cancel": "Annuler",
"pricing.confirm.cta": "Continuer vers le paiement"
}

View File

@@ -3,5 +3,6 @@
"providerSelector.noLlm": "Aucun modèle IA configuré.",
"providerSelector.costOne": "Coût : 1 crédit par page",
"providerSelector.costFive": "Coût : 5 crédits par page (Facteur Premium)",
"providerSelector.unlockContextual": "Débloquez la traduction contextuelle haut de gamme pour vos documents entiers."
"providerSelector.unlockContextual": "Débloquez la traduction contextuelle haut de gamme pour vos documents entiers.",
"providerSelector.standard": "Standard"
}

View File

@@ -28,5 +28,11 @@
"reviews.error.title": "Erreur",
"reviews.error.load": "Erreur de chargement",
"reviews.error.update": "Mise à jour impossible",
"reviews.error.download": "Téléchargement échoué (HTTP {status})"
"reviews.error.download": "Téléchargement échoué (HTTP {status})",
"reviews.pill": "Contrôle qualité",
"reviews.titleBase": "Relecture de la",
"reviews.titleAccent": "traduction",
"reviews.approveAllConfirm": "Confirmer ({count})",
"reviews.action.approveShort": "OK",
"reviews.action.resetShort": "À relire"
}

View File

@@ -11,5 +11,6 @@
"services.adminOnly.desc": "Les clés API, la sélection de modèle et l'activation des fournisseurs sont gérées exclusivement par l'administrateur. Vous n'avez jamais besoin de saisir de clé API.",
"services.fallback.google.label": "Google Traduction",
"services.fallback.google.desc": "Traduction rapide, 130+ langues",
"services.pill": "Moteurs"
"services.pill": "Moteurs",
"services.titleAccent": "disponibles"
}

View File

@@ -19,5 +19,6 @@
"settings.formats.powerpoint.name": "PowerPoint",
"settings.pill": "Configuration",
"settings.cache.confirm": "Confirmer et recharger",
"settings.cache.cancelClear": "Annuler"
"settings.cache.cancelClear": "Annuler",
"settings.titleAccent": "préréglages"
}

View File

@@ -22,5 +22,8 @@
"teams.invite": "Inviter",
"teams.empty": "Aucun espace pour l'instant — créez le premier ci-dessus.",
"teams.error.title": "Erreur",
"teams.error.load": "Chargement impossible"
"teams.error.load": "Chargement impossible",
"teams.pill": "Collaboration",
"teams.titleBase": "Espaces de",
"teams.titleAccent": "travail"
}

View File

@@ -49,12 +49,8 @@
"translate.glossary.targetWarningBut": "mais votre document cible",
"translate.glossary.targetWarningEnd": "Les termes risquent de ne pas être pertinents.",
"translate.header.processing": "Traitement en cours",
"translate.header.aiActive": "Analyse IA active",
"translate.header.aiActiveDesc": "Votre mise en page est en cours de préservation par notre moteur contextuel.",
"translate.header.completed": "Complété",
"translate.header.completedTitle": "Traduction terminée",
"translate.header.proSpace": "Espace Pro",
"translate.header.translateDoc": "Traduire un document",
"translate.header.translateDocDesc": "Conservez la mise en page d'origine grâce au moteur de traduction ultra-haute fidélité.",
"translate.upload.nativeFormat": "Format natif",
"translate.fileType.word": "Word (.docx)",
@@ -68,12 +64,7 @@
"translate.contextEngineActive": "Moteur contextuel actif",
"translate.phase1": "Phase 1 : Initialisation",
"translate.phase2": "Phase 2 : Reconstruction contextuelle",
"translate.stat.segments": "segments",
"translate.stat.precision": "précision",
"translate.stat.speedLabel": "vitesse",
"translate.stat.turbo": "Turbo",
"translate.stat.time": "temps",
"translate.complete.masterQuality": "✓ Qualité Maître",
"translate.download": "Télécharger",
"translate.newTranslation": "+ Nouvelle traduction",
"translate.failedTitle": "Erreur lors de la traduction",
@@ -81,10 +72,6 @@
"translate.uploadAnother": "Téléverser un autre fichier",
"translate.monitor": "Moniteur IA",
"translate.summary": "Récapitulatif",
"translate.cancelProcess": "⟳ Annuler le processus",
"translate.layoutIntegrity": "Intégrité Layout",
"translate.secureHundred": "100% SÉCURISÉ",
"translate.okHundred": "100% OK",
"translate.preserveLayout": "Conserver la mise en page",
"translate.preserveLayoutDesc": "Conserver la mise en page",
"translate.textOnly": "Texte brut",