diff --git a/src/app/calculators/courberemous/en.json b/src/app/calculators/courberemous/en.json
index f965d3e9f8bb00e3af5dcfccf7a3a94404f632f6..c238adfb5a991db7374b0e71fceb2536c7484eaa 100644
--- a/src/app/calculators/courberemous/en.json
+++ b/src/app/calculators/courberemous/en.json
@@ -53,7 +53,7 @@
     "TARGET_Hsc": "Critical head (m)",
     "TARGET_B": "Surface width (m)",
     "TARGET_P": "Wetted perimeter (m)",
-    "TARGET_S": "Wetted area (m2)",
+    "TARGET_S": "Wet surface (m2)",
     "TARGET_R": "Hydraulic radius (m)",
     "TARGET_V": "Average speed (m/s)",
     "TARGET_Fr": "Froude number",
diff --git a/src/app/calculators/jet/en.json b/src/app/calculators/jet/en.json
index c8342e3234a4c8cc17d99573b2d28cf8fbe24b88..32cc2afed438f0b92db9d7ca8f9ee3e5f3507068 100644
--- a/src/app/calculators/jet/en.json
+++ b/src/app/calculators/jet/en.json
@@ -9,7 +9,7 @@
     "ZF": "Bottom elevation",
     "H": "Fall height",
     "Y": "Depth",
-    "YH": "Depth/height ration",
+    "YH": "Depth/height ratio",
     "t": "Flight time",
     "Vx": "Horizontal speed at impact",
     "Vz": "Vertical speed at impact",
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 92462013f634e7ec6f954d77d07203e3369794f6..b662a5000d25250ee124089a9a93d715453b9ad5 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -433,6 +433,8 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
                     this.setForm(this.formulaireService.getFormulaireFromId(uid));
                     this.resultsComponent.formulaire = this._formulaire;
                     this._calculatorNameComponent.model = this._formulaire;
+                    // reload localisation in all cases (it does not eat bread)
+                    this.formulaireService.updateFormulaireLocalisation(this._formulaire);
                     // call Form init hook
                     this._formulaire.onCalculatorInit();
                     break;
diff --git a/src/app/formulaire/elements/formulaire-element.ts b/src/app/formulaire/elements/formulaire-element.ts
index 79a4899ea702d5c7f964ca0b5124d242bf4290c9..579b62648b34a662d8edba307d86920a98ff32d3 100644
--- a/src/app/formulaire/elements/formulaire-element.ts
+++ b/src/app/formulaire/elements/formulaire-element.ts
@@ -1,8 +1,7 @@
 import { FormulaireNode } from "./formulaire-node";
-import { StringMap } from "../../stringmap";
-import { I18nService } from "../../services/internationalisation.service";
 import { ServiceFactory } from "../../services/service-factory";
 import { FormulaireDefinition } from "../definition/form-definition";
+import { FormulaireService } from "../../services/formulaire.service";
 
 /**
  * élément (enfant) du formulaire : fieldset, input, container, ...
@@ -18,7 +17,7 @@ export abstract class FormulaireElement extends FormulaireNode {
      */
     protected _label: string;
 
-    private intlService: I18nService;
+    private formulaireService: FormulaireService;
 
     public static removePrefix(s: string, prefix: string): string {
         if (s.startsWith(prefix)) {
@@ -30,7 +29,7 @@ export abstract class FormulaireElement extends FormulaireNode {
     constructor(parent: FormulaireNode) {
         super(parent);
         this._isDisplayed = true;
-        this.intlService = ServiceFactory.i18nService;
+        this.formulaireService = ServiceFactory.formulaireService;
     }
 
     get isDisplayed(): boolean {
@@ -71,11 +70,8 @@ export abstract class FormulaireElement extends FormulaireNode {
      * @param loc calculator-specific localised messages map
      * @param key Element label key
      */
-    public updateLocalisation(key?: string) {
-        if (!key) {
-            key = this._confId;
-        }
-        this._label = this.intlService.localizeText(key);
+    public updateLocalisation() {
+        this._label = this.formulaireService.localizeText(this._confId, this.parentForm.currentNub.calcType);
         for (const f of this.getKids()) {
             f.updateLocalisation();
         }
diff --git a/src/app/formulaire/elements/select-field.ts b/src/app/formulaire/elements/select-field.ts
index 4f7196cf6b8b8ab4d78cca767a28c99e36913ea5..0884f25641cb3a37472be53baa6f0d928a7453fe 100644
--- a/src/app/formulaire/elements/select-field.ts
+++ b/src/app/formulaire/elements/select-field.ts
@@ -10,7 +10,6 @@ import {
 
 import { Field } from "./field";
 import { SelectEntry } from "./select-entry";
-import { StringMap } from "../../stringmap";
 import { FormulaireNode } from "./formulaire-node";
 import { FormulaireDefinition } from "../definition/form-definition";
 import { ServiceFactory } from "../../services/service-factory";
@@ -113,10 +112,29 @@ export class SelectField extends Field {
     public updateLocalisation() {
         super.updateLocalisation();
         for (const e of this._entries) {
-            // some Select fields already have a translated label at this time; translate others
-            if (e.label === undefined) {
+            if (this.source === "solveur_targetted_result") {
+                // @WARNING clodo hack for Solveur
+                // 1. calculated param
+                const nub: Nub = (this.parentForm as FormulaireDefinition).currentNub;
+                const ntc = (nub as Solveur).nubToCalculate;
+                if (e.value !== undefined && ntc !== undefined) {
+                    if (e.value === "" && ntc.calculatedParam !== undefined) {
+                        const varName = ServiceFactory.formulaireService.expandVariableName(ntc.calcType, ntc.calculatedParam.symbol);
+                        e.label = `${varName} (${ntc.calculatedParam.symbol})`;
+                    } else {
+                        // 2. extra results
+                        const varName = ServiceFactory.formulaireService.expandVariableName(ntc.calcType, e.value);
+                        e.label = `${varName} (${e.value})`;
+                    }
+                }
+            } else {
+                // general case
                 const aId = e.id.split("_");
-                e.label = ServiceFactory.i18nService.localizeText(`${aId[1].toUpperCase()}_${aId[2]}`);
+                const trad = ServiceFactory.formulaireService.localizeText(
+                    `${aId[1].toUpperCase()}_${aId[2]}`,
+                    this.parentForm.currentNub.calcType
+                );
+                e.label = trad;
             }
         }
     }
@@ -155,25 +173,16 @@ export class SelectField extends Field {
 
             // driven by string[], not enum
             case "solveur_targetted_result":
+                // @WARNING for localisation, @see hack in this.updateLocalisation()
                 // 1. calculated param
                 const ntc = (nub as Solveur).nubToCalculate;
                 if (ntc !== undefined && ntc.calculatedParam !== undefined) { // some nubs have no calculatedParam, for ex. SectionParam
-                    const varName = ServiceFactory.formulaireService.expandVariableName(ntc.calcType, ntc.calculatedParam.symbol);
-                    this.addEntry(new SelectEntry(
-                        this._entriesBaseId + "none",
-                        "",
-                        `${varName} (${ntc.calculatedParam.symbol})`
-                    ));
+                    this.addEntry(new SelectEntry(this._entriesBaseId + "none", ""));
                 }
                 // 2. extra results
                 if (ntc !== undefined && ntc.resultsFamilies !== undefined) {
                     for (const er of Object.keys(ntc.resultsFamilies)) {
-                        const varName = ServiceFactory.formulaireService.expandVariableName(ntc.calcType, er);
-                        const e: SelectEntry = new SelectEntry(
-                            this._entriesBaseId + er,
-                            er,
-                            `${varName} (${er})`
-                        );
+                        const e: SelectEntry = new SelectEntry(this._entriesBaseId + er, er);
                         this.addEntry(e);
                     }
                 }
diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts
index 78c74c8a7e8545eccb75eb90242fb160a7782f0d..4a3e78aea4f5d6f9f0a75fe9499f87bd6635fc3f 100644
--- a/src/app/services/formulaire.service.ts
+++ b/src/app/services/formulaire.service.ts
@@ -99,6 +99,51 @@ export class FormulaireService extends Observable {
         return this.intlService.localizeText(`INFO_${sCalculator}_TITRE_COURT`);
     }
 
+    /**
+     * Forces update of all form strings in given Formulaire, with current language
+     */
+    public updateFormulaireLocalisation(f: FormulaireDefinition) {
+        const requiredLang = this.intlService.currentLanguage;
+        f.updateLocalisation(requiredLang);
+    }
+
+
+    /**
+     * Tente de trouver une traduction pour textKey dans les fichiers de langues
+     * spécifiques du module de calcul en cours, dans la langue en cours, puis
+     * dans la langue par défaut; si aucune traduction n'est trouvée, demande au
+     * service i18n de rechercher dans les fichiers de langues globaux
+     * @param textKey la clé du texte à traduire
+     */
+    public localizeText(textKey: string, ct: CalculatorType): string {
+        const calcType = /* this.currentForm?.currentNub?.calcType || */ ct;
+        if (calcType !== undefined) {
+            // throw new Error("FormulaireService.localizeText(): cannot find CalculatorType for current form's Nub");
+            let langCache = this.i18nService.languageCache;
+            if (langCache && langCache[calcType]) {
+                langCache = langCache[calcType]; // …for target Nub type
+            }
+            // try current language
+            if (
+                langCache
+                && langCache[this.intlService.currentLanguage]
+                && langCache[this.intlService.currentLanguage][textKey] !== undefined
+            ) {
+                return langCache[this.intlService.currentLanguage][textKey];
+
+            } else if ( // try calculator type specific translation, but for default language
+                langCache
+                && langCache[this.appSetupService.fallbackLanguage]
+                && langCache[this.appSetupService.fallbackLanguage][textKey] !== undefined
+            ) {
+                return langCache[this.appSetupService.fallbackLanguage][textKey];
+
+            }
+        }
+        // fallback to global (not calculator type specific) translation system
+        return this.i18nService.localizeText(textKey);
+    }
+
     /**
      * Returns variable name from symbol
      * @param calcType
@@ -115,7 +160,7 @@ export class FormulaireService extends Observable {
             langCache = langCache[this.intlService.currentLanguage]; // … for current language
         }
         if (langCache && langCache[symbol] !== undefined) {
-            s = this.intlService.localizeText(symbol, langCache);
+            s = this.localizeText(symbol, calcType);
         } else {
             // is symbol of the form ouvrages[i]… ?
             const re = /([A-Z,a-z]+)\[(\d+)\]\.(.+)/;
@@ -169,7 +214,7 @@ export class FormulaireService extends Observable {
             } else {
                 const unitKey = "UNIT_" + symbolBase;
                 if (langCache && langCache[unitKey] !== undefined) {
-                    unit = this.intlService.localizeText(unitKey, langCache);
+                    unit = this.localizeText(unitKey, calcType);
                 }
             }
         }
@@ -295,8 +340,7 @@ export class FormulaireService extends Observable {
         const f: FormulaireDefinition = this.newFormulaire(ct);
         this._formulaires.push(f);
         // Charge la configuration dépendamment du type
-        const prom: Promise<any> = this.loadConfig(ct);
-        return prom.then(s => {
+        return this.loadConfig(ct).then(s => {
             f.preparseConfig(s);
 
             // Associe le Nub fourni (chargement de session / duplication de module), sinon en crée un nouveau
diff --git a/src/app/services/internationalisation.service.ts b/src/app/services/internationalisation.service.ts
index 26d2cecce0c2e8490055f851a0df7d184916838e..ed8011d094735b5d8f5ab59d9b27163c1bdd91ac 100644
--- a/src/app/services/internationalisation.service.ts
+++ b/src/app/services/internationalisation.service.ts
@@ -79,7 +79,6 @@ export class I18nService extends Observable implements Observer {
             this._Messages = undefined;
             // reload all messages: global lang files, plus lang files for all calculators !
             const that = this;
-            console.log("> promise.all !");
             const promisesList: Promise<any>[] = [];
             for (const ct in CalculatorType) {
                 const calcType = Number(ct);
@@ -88,7 +87,6 @@ export class I18nService extends Observable implements Observer {
                 }
             }
             Promise.all(promisesList).then(() => {
-                console.log(">> get global messages !");
                 this.httpGetMessages(code).then((res: any) => {
                     that._Messages = res;
                     // propagate language change to all application
@@ -174,16 +172,15 @@ export class I18nService extends Observable implements Observer {
      *
      * @param textKey id du texte (ex: "ERROR_PARAM_NULL")
      */
-    public localizeText(textKey: string, msg?: StringMap) {
-        const messages = msg || this._Messages;
-        if (! messages) {
+    public localizeText(textKey: string) {
+        if (! this._Messages) {
             return `*** messages not loaded: ${this._currentLanguage} ***`;
         }
-        if (messages[textKey] !== undefined) {
-            return decodeHtml(messages[textKey]);
+        if (this._Messages[textKey] !== undefined) {
+            return decodeHtml(this._Messages[textKey]);
         } else {
             // try general message
-            if (msg !== undefined && this._Messages["INFO_LIB_" + textKey.toUpperCase()] !== undefined) {
+            if (this._Messages !== undefined && this._Messages["INFO_LIB_" + textKey.toUpperCase()] !== undefined) {
                 return decodeHtml(this._Messages["INFO_LIB_" + textKey.toUpperCase()]);
             }
             if (!isDevMode()) {