diff --git a/README.md b/README.md
index 295763ab75d4f206964294826dbae347485cb5e9..4fbfddf36734a719915870eb200e3a4764d78162 100644
--- a/README.md
+++ b/README.md
@@ -87,6 +87,13 @@ Build with a custom config file:
 CONFIG_PATH='config.customName.json' npm run build
 ```
 
+### Theme checker
+
+The [Hubl theme manager](https://cdn.startinblox.com/hubl/theme/) is very handy for customer to easily customize the main colors they want to use.
+But developers should verify that their development use those colors to fit the customer wishes. The theme checker make this task easier :
+just add `"themeChecker": true` to the config.json to display the color picker tool in the header bar. Changing the color will set them on the
+whole app so that you can verify that your development take them into account correctly.
+
 ## Mandatory modules
 
 By default, a Hubl includes only individual chat modules.
diff --git a/src/dependencies.pug b/src/dependencies.pug
index 4783e38144276916e3830f2f9f7fdaacef826dbd..589c5a7ccd91a875604b11d8a99da1d9ee417810 100644
--- a/src/dependencies.pug
+++ b/src/dependencies.pug
@@ -10,6 +10,10 @@ script(type="module" src="https://cdn.skypack.dev/@startinblox/router@0.11" defe
 script(type="module" src="https://cdn.skypack.dev/@startinblox/component-notifications@0.9" defer)
 //- script(type="module" src="/lib/sib-notifications/index.js" defer)
 
+if themeChecker
+    script(src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js")
+    link(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css')
+
 if endpoints.get
   if endpoints.get.events && endpoints.get.typeevents
       script(type="module" src="https://cdn.skypack.dev/@startinblox/component-event@1.4" defer)
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 85aca9def505a1d2c85491bcd76e2119d7e83802..f0d7cd32bc24fc7a34f0066c18e3f9dc1fa12a28 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -27,7 +27,7 @@
     "jobBoard": "Offres de mission",
     "profileDirectory": "Annuaire des membres",
     "projects": "Projets",
-    "circles": "Circles",
+    "circles": "Cercles",
     "messages": "Messages",
     "search": "Rechercher..."
   },
diff --git a/src/scripts/theme-checker.js b/src/scripts/theme-checker.js
new file mode 100644
index 0000000000000000000000000000000000000000..b6f2d67dffaa9a0e1bf62bf20e724e6fc63532c0
--- /dev/null
+++ b/src/scripts/theme-checker.js
@@ -0,0 +1,97 @@
+document.addEventListener("DOMContentLoaded", () => {
+
+    if( !document.querySelector('.input-color') ) return
+    const params = new URLSearchParams(window.location.search);
+    const currentPrimary = getComputedStyle(document.documentElement).getPropertyValue('--color-primary')
+    const defaultPrimary = params.has('p') ? "#" + params.get('p') : currentPrimary ? currentPrimary.trim() : "#FF0055";
+    document.documentElement.style.setProperty('--color-primary', defaultPrimary);
+    const cP = Pickr.create({
+        el: '.input-color#color-primary',
+        theme: 'nano',
+        default: defaultPrimary,
+        defaultRepresentation: 'HEX',
+        swatches: null,
+        components: {
+            hue: true,
+            preview: true,
+            palette: true,
+            interaction: {
+                input: true
+            }
+        }
+    });
+    cP.on('change', (color, evt) => {
+        document.documentElement.style.setProperty('--color-primary', color.toHEXA());
+        params.set('p', String(color.toHEXA()).substr(1));
+        cP.applyColor();
+    });
+    const currentSecondary = getComputedStyle(document.documentElement).getPropertyValue('--color-secondary')
+    const defaultSecondary = params.has('s') ? "#" + params.get('s') : currentSecondary ? currentSecondary.trim() : "#314560";
+    document.documentElement.style.setProperty('--color-secondary', defaultSecondary);
+    const cS = Pickr.create({
+        el: '.input-color#color-secondary',
+        theme: 'nano',
+        default: defaultSecondary,
+        defaultRepresentation: 'HEX',
+        swatches: null,
+        components: {
+            hue: true,
+            preview: true,
+            palette: true,
+            interaction: {
+                input: true
+            }
+        }
+    });
+    cS.on('change', (color, evt) => {
+        document.documentElement.style.setProperty('--color-secondary', color.toHEXA());
+        params.set('s', String(color.toHEXA()).substr(1));
+        cS.applyColor();
+    });
+    const currentComplementary = getComputedStyle(document.documentElement).getPropertyValue('--color-complementary')
+    const defaultComplementary = params.has('c') ? "#" + params.get('c') : currentComplementary ? currentComplementary.trim() : "#00E3B4";
+    document.documentElement.style.setProperty('--color-complementary', defaultComplementary);
+    const cC = Pickr.create({
+        el: '.input-color#color-complementary',
+        theme: 'nano',
+        default: defaultComplementary,
+        defaultRepresentation: 'HEX',
+        swatches: null,
+        components: {
+            hue: true,
+            preview: true,
+            palette: true,
+            interaction: {
+                input: true
+            }
+        }
+    });
+    cC.on('change', (color, evt) => {
+        document.documentElement.style.setProperty('--color-complementary', color.toHEXA());
+        params.set('c', String(color.toHEXA()).substr(1));
+        cC.applyColor();
+    });
+    const currentComplementaryDarken = getComputedStyle(document.documentElement).getPropertyValue('--color-complementary-darken')
+    const defaultComplementaryDarken = params.has('cd') ? "#" + params.get('cd') : currentComplementaryDarken ? currentComplementaryDarken.trim() : "#0068FF";
+    document.documentElement.style.setProperty('--color-complementary-darken', defaultComplementaryDarken);
+    const cCd = Pickr.create({
+        el: '.input-color#color-complementary-darken',
+        theme: 'nano',
+        default: defaultComplementaryDarken,
+        defaultRepresentation: 'HEX',
+        swatches: null,
+        components: {
+            hue: true,
+            preview: true,
+            palette: true,
+            interaction: {
+                input: true
+            }
+        }
+    });
+    cCd.on('change', (color, evt) => {
+        document.documentElement.style.setProperty('--color-complementary-darken', color.toHEXA());
+        params.set('cd', String(color.toHEXA()).substr(1));
+        cCd.applyColor();
+    });
+});
diff --git a/src/views/partials/header.pug b/src/views/partials/header.pug
index fdb4adfcd1e2cd1c3a668cf3c5d21e5b4740d0b7..eaf2c83b46a1dc9f904fd12402468f1987b1a4c3 100644
--- a/src/views/partials/header.pug
+++ b/src/views/partials/header.pug
@@ -2,7 +2,7 @@
 div
 
   solid-link(next='dashboard')
-    img.logo(src=`${clientLogo || '/images/logo.png'}`)
+    img.logo(src=`${clientLogo || '/images/logo.webp'}`)
 
 
   span.tag.reversed.text-semibold(data-trans='header.beta')
@@ -13,6 +13,15 @@ div
       bind-user
     )
 
+    if themeChecker
+      div.selector
+        each val, index in ['primary', 'secondary', 'complementary', 'complementary-darken']
+          label= 'Couleur ' + (index+1)
+            input.input-color(
+              id='color-'+val
+              type="text"
+            )
+
     details.segment.notLoggedIn
       summary.text-right
         solid-display.labelled-avatar(