diff --git a/Gemfile b/Gemfile
index 23a59d1f081f6b71b09f51ac32f283a4b3b03f3f..e993e753d4c293833f0bceff8b4364393cff30eb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,6 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
 ruby '3.1.2'
 
 # Infrastructure
+gem 'activestorage-scaleway-service'#, path: '../activestorage-scaleway-service'
 gem 'angularjs-rails'
 gem 'aws-sdk-s3'
 gem 'bootsnap', '>= 1.4.4', require: false
@@ -20,7 +21,7 @@ gem 'delayed_job_web'
 gem 'devise'
 gem 'devise-i18n'
 gem 'enum_help'
-gem 'faceted_search'#, path: '../faceted_search'
+gem 'faceted_search'#, path: '../../noesya/faceted_search'
 gem 'front_matter_parser'
 gem 'gdpr'
 gem 'gitlab'
@@ -29,6 +30,7 @@ gem 'hash_dot'
 gem 'image_processing'
 gem 'jbuilder'
 gem 'jquery-rails'
+gem "jquery-ui-rails", "~> 6.0.1"
 gem 'kamifusen'#, path: '../kamifusen'
 gem 'kaminari'
 gem 'mini_magick'
@@ -38,6 +40,7 @@ gem 'omniauth-saml', '~> 2.0'
 gem 'pg', '~> 1.1'
 gem 'puma'
 gem 'rails', '~> 7.0'
+gem "rails-autocomplete", "~> 2.0"
 gem 'rails-i18n'
 gem 'roo', "~> 2.9"
 gem 'sanitize'
diff --git a/Gemfile.lock b/Gemfile.lock
index e53f34dfad3fc0b59a3029ac5872f0f19ee0665b..94e2488b8618dd9ff94d43b83f514bf665cd9d6b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -81,6 +81,7 @@ GEM
       activesupport (= 7.0.4)
       marcel (~> 1.0)
       mini_mime (>= 1.1.0)
+    activestorage-scaleway-service (1.0.0)
     activesupport (7.0.4)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 1.6, < 2)
@@ -243,6 +244,8 @@ GEM
       rails-dom-testing (>= 1, < 3)
       railties (>= 4.2.0)
       thor (>= 0.14, < 2.0)
+    jquery-ui-rails (6.0.1)
+      railties (>= 3.2.16)
     js_cookie_rails (2.2.0)
       railties (>= 3.1)
     json (2.6.2)
@@ -366,6 +369,8 @@ GEM
       activesupport (= 7.0.4)
       bundler (>= 1.15.0)
       railties (= 7.0.4)
+    rails-autocomplete (2.0.1)
+      rails (>= 4.0)
     rails-dom-testing (2.0.3)
       activesupport (>= 4.2.0)
       nokogiri (>= 1.6)
@@ -503,6 +508,7 @@ PLATFORMS
   x86_64-linux
 
 DEPENDENCIES
+  activestorage-scaleway-service
   angularjs-rails
   annotate
   aws-sdk-s3
@@ -532,6 +538,7 @@ DEPENDENCIES
   image_processing
   jbuilder
   jquery-rails
+  jquery-ui-rails (~> 6.0.1)
   kamifusen
   kaminari
   listen (~> 3.3)
@@ -543,6 +550,7 @@ DEPENDENCIES
   puma
   rack-mini-profiler (~> 2.0)
   rails (~> 7.0)
+  rails-autocomplete (~> 2.0)
   rails-i18n
   roo (~> 2.9)
   sanitize
diff --git a/README.md b/README.md
index 65ddbf222ba6b135033dcaddd368318c9acc14ef..b09ced57fd6a3d73699716f2401b8342486c57be 100644
--- a/README.md
+++ b/README.md
@@ -4,16 +4,4 @@ Open Source University, la plateforme numérique en source ouverte des Universit
 
 [![Maintainability](https://api.codeclimate.com/v1/badges/beb68a199e248e3edc65/maintainability)](https://codeclimate.com/github/noesya/osuny/maintainability)
 
-## Setup
-
-- Lancer `bin/setup`
-- Paramétrer les variables d'environnement dans `config/application.yml`
-- Démarrer le serveur avec `rails app:start`
-
-## Appstack
-
-Pour mettre à jour :
-- remplacer les fichiers css (dark et light) dans vendor/assets/stylesheets
-- remplacer les fichiers js dans vendor/assets/javascripts/appstack
-- remplacer les fichiers fonts dans vendor/assets/fonts/appstack
-- dans les css, remplacer ":url" par ": url"
+[Documentation officielle sur developers.osuny.org](https://developers.osuny.org)
diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
index 034e848032092eaf8ef96eac731b6ed5961987f3..0000000000000000000000000000000000000000
--- a/SECURITY.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Security Policy
-
-## Supported Versions
-
-Use this section to tell people about which versions of your project are
-currently being supported with security updates.
-
-| Version | Supported          |
-| ------- | ------------------ |
-| 5.1.x   | :white_check_mark: |
-| 5.0.x   | :x:                |
-| 4.0.x   | :white_check_mark: |
-| < 4.0   | :x:                |
-
-## Reporting a Vulnerability
-
-Use this section to tell people how to report a vulnerability.
-
-Tell them where to go, how often they can expect to get an update on a
-reported vulnerability, what to expect if the vulnerability is accepted or
-declined, etc.
diff --git a/app/assets/fonts/Basier-Square/basiersquare-medium.woff b/app/assets/fonts/Basier-Square/basiersquare-medium.woff
new file mode 100755
index 0000000000000000000000000000000000000000..1fca3b5ad86765fa93bc2dc7bdc784a15a06f306
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-medium.woff differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-medium.woff2 b/app/assets/fonts/Basier-Square/basiersquare-medium.woff2
new file mode 100755
index 0000000000000000000000000000000000000000..7de63d7fda6a40143347481c8fd6cd12901e773a
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-medium.woff2 differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-semibold.woff b/app/assets/fonts/Basier-Square/basiersquare-semibold.woff
new file mode 100755
index 0000000000000000000000000000000000000000..0ddef095ff7f63abe723ac24456cfdb9f6cfb887
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-semibold.woff differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-semibold.woff2 b/app/assets/fonts/Basier-Square/basiersquare-semibold.woff2
new file mode 100755
index 0000000000000000000000000000000000000000..2d57f6eab291dbdd173c083093c1e1e42317c0a0
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-semibold.woff2 differ
diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js
index 20f2a4a00fdaa93d960d110a25eb866c6b758959..78287d1c61c91076bbcd78c89f0ef865eceebd42 100644
--- a/app/assets/javascripts/admin.js
+++ b/app/assets/javascripts/admin.js
@@ -14,8 +14,8 @@
 //= require cocoon
 //= require_self
 //= require_tree ./admin/commons
+//= require_tree ./application/plugins
 //= require_tree ./admin/plugins
 //= require ./admin/communication/init
-//= require ./admin/university/init
 
 window.osuny = {};
diff --git a/app/assets/javascripts/admin/commons/nav.js b/app/assets/javascripts/admin/commons/nav.js
new file mode 100644
index 0000000000000000000000000000000000000000..07f5e68468086d25baa873b203de5f5e3c9bf957
--- /dev/null
+++ b/app/assets/javascripts/admin/commons/nav.js
@@ -0,0 +1,13 @@
+var autoCollapseSidebar = function () {
+    'use strict';
+    var sidebar = document.querySelector('#sidebar[data-auto-collapsed]');
+    if (sidebar && window.innerWidth >= 992) {
+        sidebar.classList.add('collapsed');
+        sidebar.removeAttribute('data-auto-collapsed');
+    }
+};
+
+window.addEventListener('DOMContentLoaded', function () {
+    'use strict';
+    autoCollapseSidebar();
+});
diff --git a/app/assets/javascripts/admin/university/edit.js b/app/assets/javascripts/admin/commons/sso.js
similarity index 70%
rename from app/assets/javascripts/admin/university/edit.js
rename to app/assets/javascripts/admin/commons/sso.js
index f28aff7782236f888f513731d91113adc074696e..1009ce91052b4ba3754978f3e3ea4646ddbc212a 100644
--- a/app/assets/javascripts/admin/university/edit.js
+++ b/app/assets/javascripts/admin/commons/sso.js
@@ -1,7 +1,7 @@
-window.osuny.university.edit = {
+window.osuny.sso = {
     init: function () {
         'use strict';
-        this.hasSsoInput = document.querySelector('input[type="checkbox"][name="university[has_sso]"]');
+        this.hasSsoInput = document.querySelector('input[type="checkbox"][name$="[has_sso]"]');
         this.hasSsoInput.addEventListener('change', this.onHasSsoChange.bind(this));
         this.ssoFields = document.querySelectorAll('.sso-inputs');
         this.onHasSsoChange();
@@ -30,10 +30,7 @@ window.osuny.university.edit = {
 
 window.addEventListener('DOMContentLoaded', function () {
     'use strict';
-    if (document.body.classList.contains('universities-new')
-        || document.body.classList.contains('universities-create')
-        || document.body.classList.contains('universities-edit')
-        || document.body.classList.contains('universities-update')) {
-        window.osuny.university.edit.init();
+    if (document.querySelector('[name$="[has_sso]"]')) {
+        window.osuny.sso.init();
     }
 });
diff --git a/app/assets/javascripts/admin/plugins/notyf.js b/app/assets/javascripts/admin/plugins/notyf.js
index 68499577b5c1695a8ec1a79dc9659ebb2c3f0909..894daa6deb76e1f4cb4a2c07272dffe45b152222 100644
--- a/app/assets/javascripts/admin/plugins/notyf.js
+++ b/app/assets/javascripts/admin/plugins/notyf.js
@@ -1,31 +1,34 @@
 /*global Notyf */
-var notyfAlerts = document.getElementsByClassName('js-notyf-alert'),
-    notyfNotices = document.getElementsByClassName('js-notyf-notice'),
-    notyf = new Notyf();
+window.addEventListener('DOMContentLoaded', function () {
+    'use strict';
+    var notyfAlerts = document.getElementsByClassName('js-notyf-alert'),
+        notyfNotices = document.getElementsByClassName('js-notyf-notice'),
+        notyf = new Notyf();
 
-if (notyfAlerts.length > 0) {
-    notyf.open({
-        type: 'error',
-        position: {
-            x: 'center',
-            y: 'bottom'
-        },
-        message: notyfAlerts[0].innerText,
-        duration: 9000,
-        ripple: true,
-        dismissible: true
-    });
-}
-if (notyfNotices.length > 0) {
-    notyf.open({
-        type: 'success',
-        position: {
-            x: 'center',
-            y: 'bottom'
-        },
-        message: notyfNotices[0].innerText,
-        duration: 9000,
-        ripple: true,
-        dismissible: true
-    });
-}
+    if (notyfAlerts.length > 0) {
+        notyf.open({
+            type: 'error',
+            position: {
+                x: 'center',
+                y: 'bottom'
+            },
+            message: notyfAlerts[0].innerText,
+            duration: 9000,
+            ripple: true,
+            dismissible: true
+        });
+    }
+    if (notyfNotices.length > 0) {
+        notyf.open({
+            type: 'success',
+            position: {
+                x: 'center',
+                y: 'bottom'
+            },
+            message: notyfNotices[0].innerText,
+            duration: 9000,
+            ripple: true,
+            dismissible: true
+        });
+    }
+});
diff --git a/app/assets/javascripts/admin/university/init.js b/app/assets/javascripts/admin/university/init.js
deleted file mode 100644
index 1c33bd9eb5e950e7bc13965380783a4a7a10b073..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/admin/university/init.js
+++ /dev/null
@@ -1,4 +0,0 @@
-//= require_self
-//= require ./edit
-
-window.osuny.university = {};
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 66678c1d2bf190af84483be6bf38dfea2ef5e3c5..19545a0bccd3fa9908e5b35280ed224190b74b3e 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -7,7 +7,10 @@
 //= require jquery-cropper/dist/jquery-cropper
 //= require simple_form_password_with_hints
 //= require simple_form_bs5_file_input
+//= require summernote/summernote-bs5
 //= require gdpr/cookie_consent
+//= require autocomplete-rails
+//= require_tree ./application/plugins
 //= require_self
 
 window.osuny = {};
diff --git a/app/assets/javascripts/admin/plugins/summernote-paste.js b/app/assets/javascripts/application/plugins/summernote-paste.js
similarity index 100%
rename from app/assets/javascripts/admin/plugins/summernote-paste.js
rename to app/assets/javascripts/application/plugins/summernote-paste.js
diff --git a/app/assets/javascripts/admin/plugins/summernote.js b/app/assets/javascripts/application/plugins/summernote.js
similarity index 100%
rename from app/assets/javascripts/admin/plugins/summernote.js
rename to app/assets/javascripts/application/plugins/summernote.js
diff --git a/app/assets/javascripts/devise.js b/app/assets/javascripts/devise.js
new file mode 100644
index 0000000000000000000000000000000000000000..26efc2d665f4a7e902f56e9075c6baec61b83df2
--- /dev/null
+++ b/app/assets/javascripts/devise.js
@@ -0,0 +1,15 @@
+//= require activestorage
+//= require popper
+//= require bootstrap-sprockets
+//= require jquery3
+//= require jquery_ujs
+//= require notyf/notyf.min
+//= require simple_form_password_with_hints
+//= require simple_form_bs5_file_input
+//= require cropperjs/dist/cropper
+//= require jquery-cropper/dist/jquery-cropper
+//= require gdpr/cookie_consent
+//= require_self
+//= require_tree ./admin/plugins
+
+window.osuny = {};
diff --git a/app/assets/javascripts/extranet.js b/app/assets/javascripts/extranet.js
new file mode 100644
index 0000000000000000000000000000000000000000..ca7451c7833082a0749e90a3db42f26611bb8c36
--- /dev/null
+++ b/app/assets/javascripts/extranet.js
@@ -0,0 +1,16 @@
+//= require activestorage
+//= require popper
+//= require bootstrap-sprockets
+//= require jquery3
+//= require jquery-ui/widgets/autocomplete
+//= require jquery_ujs
+//= require cropperjs/dist/cropper
+//= require jquery-cropper/dist/jquery-cropper
+//= require simple_form_password_with_hints
+//= require simple_form_bs5_file_input
+//= require summernote/summernote-bs5
+//= require gdpr/cookie_consent
+//= require autocomplete-rails
+//= require_tree ./application/plugins
+//= require_tree ./extranet
+//= require_self
diff --git a/app/assets/javascripts/extranet/experiences.js b/app/assets/javascripts/extranet/experiences.js
new file mode 100644
index 0000000000000000000000000000000000000000..f00ced3d8d9560c7d5f1953a057c253fd798be18
--- /dev/null
+++ b/app/assets/javascripts/extranet/experiences.js
@@ -0,0 +1,18 @@
+/*global $ */
+$(function () {
+    'use strict';
+    var setAutocompleteTargetValue = function (targetId, value) {
+        var targetInput = document.querySelector(targetId);
+        if (targetInput) {
+            targetInput.value = value;
+        }
+    };
+
+    $('input.autocomplete')
+        .on('input', function ($event) {
+            setAutocompleteTargetValue($event.target.dataset.autocompleteTarget, '');
+        })
+        .on('railsAutocomplete.select', function ($event, data) {
+            setAutocompleteTargetValue($event.target.dataset.autocompleteTarget, data.item.id);
+        });
+});
diff --git a/app/assets/stylesheets/admin/appstack.sass b/app/assets/stylesheets/admin/appstack.sass
index f840f4a3c9fb55df1316d459568114c41148bd0c..8f70930f8f528c25fceb5695f2c1899b8dc8dcb1 100644
--- a/app/assets/stylesheets/admin/appstack.sass
+++ b/app/assets/stylesheets/admin/appstack.sass
@@ -7,16 +7,21 @@ main.content
             padding: .125rem
 
 .sidebar.collapsed + .footer.fixed
-    left: 0
-    transition: left .35s ease-in-out
+    left: 260px
+    @include media-breakpoint-up(lg)
+        left: 0
 
 .footer.fixed
     bottom: 0
-    left: 260px
+    left: 0
     padding: .5rem
     position: fixed
     right: 0
+    transition: left .35s ease-in-out
     z-index: 1
+    @include media-breakpoint-up(lg)
+        left: 260px
+
 
 .card-footer
     .pagination
@@ -24,3 +29,12 @@ main.content
 
 .alert
     padding: .95rem
+
+.sidebar[data-auto-collapsed]
+    @include media-breakpoint-up(lg)
+        margin-left: -260px
+        transition-duration: 0s
+
+.sidebar[data-auto-collapsed] + .footer.fixed
+    @include media-breakpoint-up(lg)
+        left: 0
diff --git a/app/assets/stylesheets/extranet.sass b/app/assets/stylesheets/extranet.sass
index 55f7e1025b411247dc6558838dc03e1660f39ba3..5dd30c32a9679e6d85a4a5584b5016529db154bd 100644
--- a/app/assets/stylesheets/extranet.sass
+++ b/app/assets/stylesheets/extranet.sass
@@ -1,17 +1,16 @@
-@import 'extranet/_default/abstracts/*'
-
-// IJBA Theme
-@import 'extranet/themes/IJBA/variables'
+@import 'extranet/_functions'
+@import 'extranet/_variables'
 
 // Vendors
 @import 'bootstrap'
 @import 'simple_form_password_with_hints'
 @import 'simple_form_bs5_file_input'
+@import 'summernote-bs5'
 @import 'gdpr/cookie_consent'
 @import 'cropperjs/dist/cropper'
+@import 'commons/summernote'
 
 // Default
-@import 'extranet/_default/base/*'
-@import 'extranet/_default/layouts/*'
-@import 'extranet/_default/components/*'
-@import 'extranet/_default/pages/*'
+@import 'extranet/bootstrap-icons'
+@import 'extranet/layout/*'
+@import 'extranet/pages/*'
diff --git a/app/assets/stylesheets/extranet/_default/abstracts/_functions.sass b/app/assets/stylesheets/extranet/_default/abstracts/_functions.sass
deleted file mode 100644
index dfad930d62f5dea9a4275ca321f9d0f6b3beb6c6..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/abstracts/_functions.sass
+++ /dev/null
@@ -1,7 +0,0 @@
-@function px2rem($size)
-    $remSize: $size / 16
-    @return #{$remSize}rem
-
-@function pxr2rem($size)
-    $remSize: $size / 16 / 2
-    @return #{$remSize}rem
diff --git a/app/assets/stylesheets/extranet/_default/base/_fonts.sass b/app/assets/stylesheets/extranet/_default/base/_fonts.sass
deleted file mode 100644
index 1ae9991f29db0e9c8d3afa131687a3f471b456a9..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/base/_fonts.sass
+++ /dev/null
@@ -1,14 +0,0 @@
-@font-face
-    font-display: swap
-    font-family: 'Basier Square'
-    font-style: normal
-    font-weight: 400
-    src: asset-url("Basier-Square/basiersquare-regular.woff2") format("woff2"), url("Basier-Square/basiersquare-regular.woff") format("woff")
-
-@font-face
-    font-display: swap
-    font-family: 'Basier Square'
-    font-style: normal
-    font-weight: 700
-    src: asset-url("Basier-Square/basiersquare-bold.woff2") format("woff2"), url("Basier-Square/basiersquare-bold.woff") format("woff")
-
diff --git a/app/assets/stylesheets/extranet/_default/base/_typography.sass b/app/assets/stylesheets/extranet/_default/base/_typography.sass
deleted file mode 100644
index d3ba1250a0653c92085d5977c92b04fac4515e7e..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/base/_typography.sass
+++ /dev/null
@@ -1,2 +0,0 @@
-h1
-    font-weight: normal
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/_default/components/_breadcrumb.sass b/app/assets/stylesheets/extranet/_default/components/_breadcrumb.sass
deleted file mode 100644
index 23391a0c8943e73eb29847249e016c0d0c4f81fb..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/components/_breadcrumb.sass
+++ /dev/null
@@ -1,2 +0,0 @@
-.breadcrumb
-    margin-bottom: $breadcrumb-margin-bottom !important
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/_default/components/_persons.sass b/app/assets/stylesheets/extranet/_default/components/_persons.sass
deleted file mode 100644
index 76c3ae6ae79f5438ec121f71b81cad6c53064605..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/components/_persons.sass
+++ /dev/null
@@ -1,3 +0,0 @@
-.person
-    line-height: px2rem(24)
-    position: relative
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/_default/layouts/_header.sass b/app/assets/stylesheets/extranet/_default/layouts/_header.sass
deleted file mode 100644
index e3b744dc724b2a5db72ae14c429d0d3a665e1fa3..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/layouts/_header.sass
+++ /dev/null
@@ -1,16 +0,0 @@
-header
-    align-items: center
-    border-bottom: 1px solid
-    border-top: 1px solid
-    padding: 20px 0
-    h1
-        margin-bottom: px2rem(10)
-    p
-        margin-bottom: 0
-    @include media-breakpoint-up(md)
-        display: flex
-        justify-content: space-between
-        min-height: 160px
-        h1, p
-            margin: 0
-            padding: 0
diff --git a/app/assets/stylesheets/extranet/_default/pages/_default.sass b/app/assets/stylesheets/extranet/_default/pages/_default.sass
deleted file mode 100644
index 02b6572f60f68ae120086fd2097070fe027f2011..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/pages/_default.sass
+++ /dev/null
@@ -1,19 +0,0 @@
-.action-show
-    @include media-breakpoint-up(md)
-        .top
-            align-items: stretch
-            header
-                align-items: center
-                display: flex
-                height: 100%
-            h1
-                margin: 0
-                padding: 0
-        .biography
-            padding-right: percentage(3/9)
-    dl
-        line-height: px2rem(26)
-        dt
-            font-size: $small-font-size
-        dd
-            margin-bottom: px2rem(26)
diff --git a/app/assets/stylesheets/extranet/_default/pages/_organization.sass b/app/assets/stylesheets/extranet/_default/pages/_organization.sass
deleted file mode 100644
index f3e43eba1b603ffee48ccf516c6f8172e0c72535..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/pages/_organization.sass
+++ /dev/null
@@ -1,32 +0,0 @@
-.organization
-    border-top: 1px solid $light-border-color
-    padding-bottom: 25px
-    padding-top: 25px
-    &:last-child
-        border-bottom: 1px solid $light-border-color
-    p:last-child
-        margin-bottom: 0
-    @include media-breakpoint-up(md)
-        align-items: center
-        display: flex
-        justify-content: space-between
-        
-.organizations-show
-    .experiences
-        margin-top: px2rem(80)
-        ul
-            padding-left: 0
-            li
-                @include make-row
-                display: flex
-                position: relative
-                > div
-                    @include make-col-ready
-                    &:nth-child(1)
-                        width: percentage(2/9)
-                    &:nth-child(2)
-                        @include pseudo-bottom-border
-                        @include pseudo-top-border
-                        padding-top: px2rem(20)
-                        width: percentage(7/9)
-
diff --git a/app/assets/stylesheets/extranet/_default/pages/_person.sass b/app/assets/stylesheets/extranet/_default/pages/_person.sass
deleted file mode 100644
index 503783c9aecc124b36aed60fe741b9d2ccb8dddf..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/_default/pages/_person.sass
+++ /dev/null
@@ -1,45 +0,0 @@
-.persons-show,
-.account-show
-    .top
-        h1
-            font-weight: normal
-        @include media-breakpoint-down(md)
-            header
-                border-bottom: 0
-    .experiences
-        margin-top: px2rem(70)
-        ul
-            padding-left: 0
-            li
-                @include make-row
-                @include pseudo-top-border
-                display: flex
-                padding: px2rem(16) 0
-                position: relative
-                p
-                    margin-bottom: px2rem(8)
-                > div
-                    @include make-col-ready
-                    padding-bottom: px2rem(10)
-                    padding-top: px2rem(10)
-                    &:nth-child(3)
-                        align-self: center
-                        padding-bottom: 0
-                        padding-top: 0
-                        text-align: right
-                    @include media-breakpoint-up(md)
-                        &:nth-child(1)
-                            width: percentage(4/9)
-                        &:nth-child(2)
-                            width: percentage(2/9)
-                        &:nth-child(3)
-                            width: percentage(3/9)
-                    @include media-breakpoint-down(md)
-                        &:nth-child(2)
-                            width: 50%
-                        &:nth-child(3)
-                            width: 50%
-                &:last-child
-                    @include pseudo-bottom-border
-                img
-                    max-height: 80px
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/_default/abstracts/_mixins.sass b/app/assets/stylesheets/extranet/_functions.sass
similarity index 72%
rename from app/assets/stylesheets/extranet/_default/abstracts/_mixins.sass
rename to app/assets/stylesheets/extranet/_functions.sass
index 748b128a944413ab09d4f038c1381a26971e0d7c..14698742b628ac9bdcbf4d695cb9bdbf1f07001d 100644
--- a/app/assets/stylesheets/extranet/_default/abstracts/_mixins.sass
+++ b/app/assets/stylesheets/extranet/_functions.sass
@@ -1,3 +1,11 @@
+@function px2rem($size)
+    $remSize: $size / 16
+    @return #{$remSize}rem
+
+@function pxr2rem($size)
+    $remSize: $size / 16 / 2
+    @return #{$remSize}rem
+
 @mixin pseudo-top-border($pseudo: before)
     position: relative
     &::#{$pseudo}
diff --git a/app/assets/stylesheets/extranet/_default/abstracts/_variables.sass b/app/assets/stylesheets/extranet/_variables.sass
similarity index 69%
rename from app/assets/stylesheets/extranet/_default/abstracts/_variables.sass
rename to app/assets/stylesheets/extranet/_variables.sass
index f096b4a16e7f4c62706fbed39f30f36465234060..bb22f27236cbbcb12bfc5807b76c1591c34193aa 100644
--- a/app/assets/stylesheets/extranet/_default/abstracts/_variables.sass
+++ b/app/assets/stylesheets/extranet/_variables.sass
@@ -1,14 +1,16 @@
 // Colors
 $primary: black
+$header-color: #F5F5F5
+$active-color: #0016ff
 
 // Fonts
 $font-family-sans-serif: "Basier Square", sans-serif
 $font-size-root: 1rem
 $font-size-base: 1.125rem
 
-$h1-font-size: px2rem(40)
-$h2-font-size: px2rem(18)
-$h3-font-size: px2rem(20)
+$h1-font-size: px2rem(60)
+$h2-font-size: px2rem(24)
+$h3-font-size: px2rem(18)
 $headings-font-weight: 700
 $headings-margin-bottom: px2rem(24)
 $small-font-size: px2rem(14)
@@ -33,7 +35,6 @@ $btn-facet-color: $primary
 $breadcrumb-font-size: px2rem(14)
 $breadcrumb-active-color: black
 $breadcrumb-divider-color: black
-$breadcrumb-margin-bottom: 45px
 
 // List
 $list-border-color: rgba(0, 0, 0, 0.15)
@@ -42,7 +43,13 @@ $list-border-color: rgba(0, 0, 0, 0.15)
 $pagination-border-width: 0
 $pagination-font-size: $small-font-size
 
-$navbar-link-active-color: $primary
+$navbar-link-active-color: $active-color
 
 // Border
-$light-border-color: rgba($primary, 0.3)
+$light-border-color: rgba($primary, 0.1)
+
+// Grid
+$grid-gutter-width: 3.75rem
+$container-max-widths: ( sm: 100%, md: 100%, lg: 100%, xl: 100%, xxl: 1980px )
+
+$enable-negative-margins: true
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/bootstrap-icons.sass b/app/assets/stylesheets/extranet/bootstrap-icons.sass
new file mode 100644
index 0000000000000000000000000000000000000000..f34004c8d870ba8aa2a7e0a4aa54e0632fbc978e
--- /dev/null
+++ b/app/assets/stylesheets/extranet/bootstrap-icons.sass
@@ -0,0 +1,5 @@
+@import 'bootstrap-icons/font/bootstrap-icons.css'
+
+@font-face
+  font-family: "bootstrap-icons"
+  src: font-url("bootstrap-icons/font/fonts/bootstrap-icons.woff2") format("woff2"), font-url("bootstrap-icons/font/fonts/bootstrap-icons.woff") format("woff")
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/layout/_autocomplete.sass b/app/assets/stylesheets/extranet/layout/_autocomplete.sass
new file mode 100644
index 0000000000000000000000000000000000000000..f3482d36eb60b4461cf4596bceec2c6a7d143075
--- /dev/null
+++ b/app/assets/stylesheets/extranet/layout/_autocomplete.sass
@@ -0,0 +1,12 @@
+.ui-autocomplete
+    list-style: none
+    padding: 0
+    max-width: 400px
+    .ui-menu-item
+        background: #F6F6F6
+        border-bottom: 1px solid #999999
+        cursor: pointer
+        .ui-menu-item-wrapper
+            padding: 10px
+            &.ui-state-active
+                background: #D4D4D4
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/_default/components/_buttons.sass b/app/assets/stylesheets/extranet/layout/_buttons.sass
similarity index 100%
rename from app/assets/stylesheets/extranet/_default/components/_buttons.sass
rename to app/assets/stylesheets/extranet/layout/_buttons.sass
diff --git a/app/assets/stylesheets/extranet/layout/_default.sass b/app/assets/stylesheets/extranet/layout/_default.sass
new file mode 100644
index 0000000000000000000000000000000000000000..a5b9fc61089829ad11af1f7ddc3807e61b2656a8
--- /dev/null
+++ b/app/assets/stylesheets/extranet/layout/_default.sass
@@ -0,0 +1,24 @@
+.container
+    @include media-breakpoint-up(md)
+        padding-right: var(--bs-gutter-x)
+        padding-left: var(--bs-gutter-x)
+
+.action-show
+    dl
+        line-height: px2rem(26)
+        dt
+            font-size: $small-font-size
+        dd
+            margin-bottom: px2rem(26)
+        a
+            transition: text-decoration 0.5s
+            text-decoration: underline
+            text-decoration-thickness: 1px
+            text-underline-offset: 4px
+            text-decoration-color: adjust-color(black, $alpha: -0.8)
+            &:hover
+                text-decoration-color: black
+
+
+ul
+    list-style: none
diff --git a/app/assets/stylesheets/extranet/_default/components/_facets.sass b/app/assets/stylesheets/extranet/layout/_facets.sass
similarity index 100%
rename from app/assets/stylesheets/extranet/_default/components/_facets.sass
rename to app/assets/stylesheets/extranet/layout/_facets.sass
diff --git a/app/assets/stylesheets/extranet/_default/layouts/_footer.sass b/app/assets/stylesheets/extranet/layout/_footer.sass
similarity index 53%
rename from app/assets/stylesheets/extranet/_default/layouts/_footer.sass
rename to app/assets/stylesheets/extranet/layout/_footer.sass
index 7090ab37c9e8d0f9b26bdb00f6bb5a804d01c8ba..177f77af40d8b256ca6c4c8791809a152fe97127 100644
--- a/app/assets/stylesheets/extranet/_default/layouts/_footer.sass
+++ b/app/assets/stylesheets/extranet/layout/_footer.sass
@@ -11,4 +11,11 @@ footer
         a
             display: block
             line-height: px2rem(26)
+            padding-bottom: 15px
             text-decoration: underline
+            text-decoration-thickness: 1px
+            text-underline-offset: 3px
+            text-decoration-color: #00000033
+            transition: text-decoration 0.5s, color 0.5s
+            &:hover
+                text-decoration-color: #000000
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/layout/_header.sass b/app/assets/stylesheets/extranet/layout/_header.sass
new file mode 100644
index 0000000000000000000000000000000000000000..444cef53578dbad447ee1a70efb6a7dea04b00d2
--- /dev/null
+++ b/app/assets/stylesheets/extranet/layout/_header.sass
@@ -0,0 +1,11 @@
+header,
+.header
+    background: $header-color
+    padding-top: 240px
+    padding-bottom: 50px
+    margin-bottom: 50px
+    &__additional_data
+        @include media-breakpoint-up(md)
+            text-align: right
+            margin-top: -60px
+            margin-bottom: 0
diff --git a/app/assets/stylesheets/extranet/_default/components/_list.sass b/app/assets/stylesheets/extranet/layout/_list.sass
similarity index 100%
rename from app/assets/stylesheets/extranet/_default/components/_list.sass
rename to app/assets/stylesheets/extranet/layout/_list.sass
diff --git a/app/assets/stylesheets/extranet/_default/layouts/_nav.sass b/app/assets/stylesheets/extranet/layout/_nav.sass
similarity index 61%
rename from app/assets/stylesheets/extranet/_default/layouts/_nav.sass
rename to app/assets/stylesheets/extranet/layout/_nav.sass
index 680d799a3f0633dbd0317f075e62a399211c0ff5..9e706d3f1c5780e670e2cef79f551968caf95bdc 100644
--- a/app/assets/stylesheets/extranet/_default/layouts/_nav.sass
+++ b/app/assets/stylesheets/extranet/layout/_nav.sass
@@ -1,5 +1,8 @@
 .navbar
-    margin-bottom: 50px
+    position: absolute
+    width: 100%
+    @include media-breakpoint-up(md)
+        padding-top: 30px
     .navbar-brand
         img
             max-width: 100px
@@ -10,8 +13,13 @@
             color: $navbar-link-active-color
     .navbar-collapse
         flex-grow: 0
-    
+    .navbar-nav
+        > .nav-item
+            margin-left: 20px
+        &__account
+            margin-left: 40px
     .dropdown-menu
+        background: transparent
         border: 0
         padding: 0
     .navbar-toggler
@@ -20,8 +28,17 @@
         line-height: px2rem(28)
         padding-right: 0
         text-transform: uppercase
+    .dropdown-toggle
+        &::after
+            width: 6px
+            height: 6px
+            border-bottom: 1px solid black
+            border-left: 0
+            border-right: 1px solid black
+            border-top: 0
+            transform: rotate(45deg)
+
     @include media-breakpoint-up(md)
-        margin-bottom: 100px
         .navbar-nav
             li:last-child .nav-link
                 padding-right: 0
diff --git a/app/assets/stylesheets/extranet/_default/components/_pagination.sass b/app/assets/stylesheets/extranet/layout/_pagination.sass
similarity index 100%
rename from app/assets/stylesheets/extranet/_default/components/_pagination.sass
rename to app/assets/stylesheets/extranet/layout/_pagination.sass
diff --git a/app/assets/stylesheets/extranet/layout/_typography.sass b/app/assets/stylesheets/extranet/layout/_typography.sass
new file mode 100644
index 0000000000000000000000000000000000000000..bfffe7a54371e4e05ad91f7fb1eac263b28050c6
--- /dev/null
+++ b/app/assets/stylesheets/extranet/layout/_typography.sass
@@ -0,0 +1,39 @@
+@font-face
+    font-display: swap
+    font-family: 'Basier Square'
+    font-style: normal
+    font-weight: 400
+    src: asset-url("Basier-Square/basiersquare-regular.woff2") format("woff2"), url("Basier-Square/basiersquare-regular.woff") format("woff")
+
+@font-face
+    font-display: swap
+    font-family: 'Basier Square'
+    font-style: normal
+    font-weight: 500
+    src: asset-url("Basier-Square/basiersquare-medium.woff2") format("woff2"), url("Basier-Square/basiersquare-medium.woff") format("woff")
+
+@font-face
+    font-display: swap
+    font-family: 'Basier Square'
+    font-style: normal
+    font-weight: 700
+    src: asset-url("Basier-Square/basiersquare-semibold.woff2") format("woff2"), url("Basier-Square/basiersquare-semibold.woff") format("woff")
+
+h1
+    margin-top: 20px
+    font-weight: 500
+    line-height: 125%
+    @include media-breakpoint-up(md)
+        max-width: 70vw
+    @include media-breakpoint-down(md)
+        font-size: px2rem(30)
+    a
+        color: $active-color
+        transition: text-decoration 0.5s, color 0.5s
+        text-decoration: underline
+        text-decoration-thickness: 1px
+        text-underline-offset: 5px
+        text-decoration-color: adjust-color($active-color, $alpha: -0.5)
+        &:hover
+            color: darken($active-color, 10)
+            text-decoration-color: $active-color
diff --git a/app/assets/stylesheets/extranet/pages/_devise.sass b/app/assets/stylesheets/extranet/pages/_devise.sass
new file mode 100644
index 0000000000000000000000000000000000000000..1912649d4e81c42ea626a6fc08596e52ca3e61f3
--- /dev/null
+++ b/app/assets/stylesheets/extranet/pages/_devise.sass
@@ -0,0 +1,9 @@
+.layout-devise
+    background-color: $header-color
+    .logo
+        max-width: 150px
+        margin: 120px 0
+    footer
+        margin-top: 100px
+        border-top: 1px solid $light-border-color
+        padding-bottom: 0
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/pages/_experiences.sass b/app/assets/stylesheets/extranet/pages/_experiences.sass
new file mode 100644
index 0000000000000000000000000000000000000000..39dbc8668dedc2b9523a4529269fb524698266e4
--- /dev/null
+++ b/app/assets/stylesheets/extranet/pages/_experiences.sass
@@ -0,0 +1,2 @@
+.experience__organization__logo
+    height: 100%
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/_default/pages/_home.sass b/app/assets/stylesheets/extranet/pages/_home.sass
similarity index 97%
rename from app/assets/stylesheets/extranet/_default/pages/_home.sass
rename to app/assets/stylesheets/extranet/pages/_home.sass
index bf1b57b4761d863b45133bfa837c1836596de8fd..7eeea3bfec5797ed89fa2a2b61e728443f725849 100644
--- a/app/assets/stylesheets/extranet/_default/pages/_home.sass
+++ b/app/assets/stylesheets/extranet/pages/_home.sass
@@ -1,4 +1,6 @@
 .home-index
+    h1
+        margin-bottom: 60px
     .experiences
         ul
             padding-left: 0
@@ -36,7 +38,6 @@
                         &:nth-child(1)
                             width: percentage(2/9)
                         &:nth-child(2)
-                            @include pseudo-bottom-border
                             @include pseudo-top-border
                             width: percentage(7/9)
     .promotions
diff --git a/app/assets/stylesheets/extranet/pages/_organization.sass b/app/assets/stylesheets/extranet/pages/_organization.sass
new file mode 100644
index 0000000000000000000000000000000000000000..8e4a3236a519efa4037433ce0efd94b0f294781d
--- /dev/null
+++ b/app/assets/stylesheets/extranet/pages/_organization.sass
@@ -0,0 +1,23 @@
+.organization
+    border-top: 1px solid $light-border-color
+    padding-bottom: 25px
+    padding-top: 25px
+    &:last-child
+        border-bottom: 1px solid $light-border-color
+    p:last-child
+        margin-bottom: 0
+    &__logo
+        border: 1px solid $light-border-color
+        background: white
+        padding: 60px
+        margin-top: -130px
+        margin-bottom: 50px
+        aspect-ratio: 1 / 1
+    @include media-breakpoint-up(md)
+        &__logo
+            margin-top: -200px
+
+    @include media-breakpoint-up(md)
+        align-items: center
+        display: flex
+        justify-content: space-between
diff --git a/app/assets/stylesheets/extranet/pages/_person.sass b/app/assets/stylesheets/extranet/pages/_person.sass
new file mode 100644
index 0000000000000000000000000000000000000000..e659fe32907045e38ec3989e2af3962ce8b0af5d
--- /dev/null
+++ b/app/assets/stylesheets/extranet/pages/_person.sass
@@ -0,0 +1,8 @@
+.person
+    line-height: px2rem(24)
+    position: relative
+    &__portrait
+        margin-top: -130px
+        margin-bottom: 50px
+        @include media-breakpoint-up(md)
+            margin-top: -200px
diff --git a/app/assets/stylesheets/extranet/_default/pages/_year.sass b/app/assets/stylesheets/extranet/pages/_year.sass
similarity index 100%
rename from app/assets/stylesheets/extranet/_default/pages/_year.sass
rename to app/assets/stylesheets/extranet/pages/_year.sass
diff --git a/app/assets/stylesheets/extranet/themes/IJBA/_variables.sass b/app/assets/stylesheets/extranet/themes/IJBA/_variables.sass
deleted file mode 100644
index 16c6699a16fa63dad84577425c3e4df9d71d218f..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/themes/IJBA/_variables.sass
+++ /dev/null
@@ -1,3 +0,0 @@
-$ijba-red: #E40130
-
-$navbar-link-active-color: $ijba-red
diff --git a/app/assets/stylesheets/extranet/themes/IJBA/ijba.sass b/app/assets/stylesheets/extranet/themes/IJBA/ijba.sass
deleted file mode 100644
index 13396b00fb1dd7ddf4ae91101d0e87d41088aa23..0000000000000000000000000000000000000000
--- a/app/assets/stylesheets/extranet/themes/IJBA/ijba.sass
+++ /dev/null
@@ -1,17 +0,0 @@
-// TODO : Add one compiled CSS per theme ?
-
-// @import 'extranet/abstracts/*'
-
-// // IJBA Theme
-// @import 'variables'
-
-// // Vendors
-// @import 'bootstrap'
-// @import 'simple_form_password_with_hints'
-// @import 'simple_form_bs5_file_input'
-// @import 'gdpr/cookie_consent'
-
-// // Default
-// @import 'extranet/_default/base/*'
-// @import 'extranet/_default/layouts/*'
-// @import 'extranet/_default/components/*'
diff --git a/app/controllers/admin/communication/extranets_controller.rb b/app/controllers/admin/communication/extranets_controller.rb
index 2d11a63183ae2d2ca3c8c34dd9c5850fb30f2dd3..b9e807a79fba5d54a0d17563696414b035a038d3 100644
--- a/app/controllers/admin/communication/extranets_controller.rb
+++ b/app/controllers/admin/communication/extranets_controller.rb
@@ -13,10 +13,10 @@ class Admin::Communication::ExtranetsController < Admin::Communication::Applicat
 
   def show
     @about = @extranet.about
-    @alumni = @about&.alumni
-    @cohorts = @about&.cohorts
-    @years = @about&.academic_years
-    @organizations = @about&.alumni_organizations
+    @alumni = @extranet.alumni
+    @cohorts = @extranet.cohorts
+    @years = @extranet.years
+    @organizations = @extranet.organizations
     breadcrumb
   end
 
@@ -64,6 +64,10 @@ class Admin::Communication::ExtranetsController < Admin::Communication::Applicat
 
   def extranet_params
     params.require(:communication_extranet)
-          .permit(:name, :domain, :about_type, :about_id, :logo, :logo_delete)
+          .permit(:name, :host, :about_type, :about_id,
+            :registration_contact, :logo, :logo_delete,
+            :terms, :privacy_policy, :cookies_policy, :color,
+            :has_sso, :sso_target_url, :sso_cert, :sso_name_identifier_format, :sso_mapping
+          )
   end
 end
diff --git a/app/controllers/admin/communication/websites_controller.rb b/app/controllers/admin/communication/websites_controller.rb
index d56f1e72a085005dc13e5d8b92d505acfc65422f..731546ff8b6a9a84275a9c8c6413238530d769e4 100644
--- a/app/controllers/admin/communication/websites_controller.rb
+++ b/app/controllers/admin/communication/websites_controller.rb
@@ -81,7 +81,8 @@ class Admin::Communication::WebsitesController < Admin::Communication::Applicati
 
   def website_params
     params.require(:communication_website).permit(
-      :name, :url, :repository, :access_token, :about_type, :about_id, :git_provider, :git_endpoint, :plausible_url, language_ids: []
+      :name, :url, :repository, :access_token, :about_type, :about_id, :in_production,
+      :git_provider, :git_endpoint, :git_branch, :plausible_url, language_ids: []
     )
   end
 end
diff --git a/app/controllers/application_controller/with_domain.rb b/app/controllers/application_controller/with_domain.rb
index 6311d132c8ee6c5ff8adba5992a960205c52a822..95edbff9d84a85214ba910175c7adfe573f154e2 100644
--- a/app/controllers/application_controller/with_domain.rb
+++ b/app/controllers/application_controller/with_domain.rb
@@ -26,5 +26,10 @@ module ApplicationController::WithDomain
       end
     end
     helper_method :current_context
+
+    def current_mode
+      current_extranet.present? ? 'extranet'  : 'university'
+    end
+    helper_method :current_mode
   end
 end
diff --git a/app/controllers/concerns/users/add_context_to_request_params.rb b/app/controllers/concerns/users/add_context_to_request_params.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d0e8c900c69fe667267c4294e0b712e475caf14d
--- /dev/null
+++ b/app/controllers/concerns/users/add_context_to_request_params.rb
@@ -0,0 +1,16 @@
+module Users::AddContextToRequestParams
+  extend ActiveSupport::Concern
+
+  included do
+    prepend_before_action :add_context_to_request_params, only: :create
+  end
+
+  protected
+
+  def add_context_to_request_params
+    # inject university_id & context in users params submitted
+    return if request.params[:user].nil?
+    request.params[:user][:university_id] = current_university.id
+    request.params[:user][:registration_context] = current_context
+  end
+end
diff --git a/app/controllers/concerns/users/add_university_to_request_params.rb b/app/controllers/concerns/users/add_university_to_request_params.rb
deleted file mode 100644
index 754392681d38ae197ed068460453d0ebe18cdfb1..0000000000000000000000000000000000000000
--- a/app/controllers/concerns/users/add_university_to_request_params.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-module Users::AddUniversityToRequestParams
-  extend ActiveSupport::Concern
-
-  included do
-    prepend_before_action :add_university_to_request_params, only: :create
-  end
-
-  protected
-
-  def add_university_to_request_params
-    # inject university_id in users params submitted
-    request.params[:user][:university_id] = current_university.id unless request.params[:user].nil?
-  end
-end
diff --git a/app/controllers/concerns/users/layout_choice.rb b/app/controllers/concerns/users/layout_choice.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2721bd54cba972f621bc7025a7aab39b2c062ff7
--- /dev/null
+++ b/app/controllers/concerns/users/layout_choice.rb
@@ -0,0 +1,20 @@
+module Users::LayoutChoice
+  extend ActiveSupport::Concern
+
+  included do
+    layout :extranet_or_default
+  end
+
+  private
+
+  def extranet_or_default
+    # extranet have their custom devise layout
+    # university osuny sessions have an "admin" layout for registration edit/update, else default devise layout.
+    case current_mode
+    when 'extranet'
+      'extranet/layouts/devise'
+    when 'university'
+      (controller_path == 'users/registrations' && ['edit', 'update'].include?(action_name)) ? 'admin/layouts/application' : 'devise'
+    end
+  end
+end
diff --git a/app/controllers/extranet/academic_years_controller.rb b/app/controllers/extranet/academic_years_controller.rb
index 8fe001a2b8684c27851afe89d915e84562c7a42d..27e47ab9872c88be80ae82cb71bbdd90457d1578 100644
--- a/app/controllers/extranet/academic_years_controller.rb
+++ b/app/controllers/extranet/academic_years_controller.rb
@@ -1,8 +1,4 @@
 class Extranet::AcademicYearsController < Extranet::ApplicationController
-  load_and_authorize_resource class: Education::AcademicYear,
-                              through: :about,
-                              through_association: :education_academic_years
-
   def index
     @academic_years = about&.education_academic_years
                             .ordered
@@ -13,6 +9,7 @@ class Extranet::AcademicYearsController < Extranet::ApplicationController
   end
 
   def show
+    @academic_year = about.education_academic_years.find(params[:id])
     @cohorts = @academic_year.cohorts_in_context(current_context.about)
     @alumni = @academic_year.alumni_in_context(current_context.about)
     breadcrumb
diff --git a/app/controllers/extranet/account_controller.rb b/app/controllers/extranet/account_controller.rb
index de458497330aadcfbbc1a04829406014cfa99883..47ded2d779c9b8130fc550c697a9ea505cef683a 100644
--- a/app/controllers/extranet/account_controller.rb
+++ b/app/controllers/extranet/account_controller.rb
@@ -4,7 +4,7 @@ class Extranet::AccountController < Extranet::ApplicationController
     @person = current_user.person
     breadcrumb
   end
-  
+
   def edit
     breadcrumb
     add_breadcrumb t('extranet.account.edit')
diff --git a/app/controllers/extranet/application_controller.rb b/app/controllers/extranet/application_controller.rb
index 493ed64fbfd2e0b77ccbebd1dc7c5aae2c8085be..a4a6731228372351ae07c62c8be95ce2d4a0ef9e 100644
--- a/app/controllers/extranet/application_controller.rb
+++ b/app/controllers/extranet/application_controller.rb
@@ -1,6 +1,9 @@
 class Extranet::ApplicationController < ApplicationController
   layout 'extranet/layouts/application'
 
+  before_action :redirect_if_no_extranet!,
+                :authorize_extranet_access!
+
   def breadcrumb
     add_breadcrumb t('home'), root_path
   end
@@ -8,4 +11,14 @@ class Extranet::ApplicationController < ApplicationController
   def about
     current_extranet.about || current_university
   end
+
+  private
+
+  def redirect_if_no_extranet!
+    redirect_to admin_root_path unless current_extranet
+  end
+
+  def authorize_extranet_access!
+    raise CanCan::AccessDenied if current_user.visitor? && about.alumni.find_by(id: current_user.person&.id).nil?
+  end
 end
diff --git a/app/controllers/extranet/cohorts_controller.rb b/app/controllers/extranet/cohorts_controller.rb
index b249e48a3a5073f7da8537cedfa599240000ee24..f4174abc4abdcc75507744a2f336edc753680ae7 100644
--- a/app/controllers/extranet/cohorts_controller.rb
+++ b/app/controllers/extranet/cohorts_controller.rb
@@ -1,8 +1,4 @@
 class Extranet::CohortsController < Extranet::ApplicationController
-  load_and_authorize_resource class: Education::Cohort,
-                              through: :about,
-                              through_association: :education_cohorts
-
   def index
     @facets = Education::Cohort::Facets.new params[:facets], {
       model: about.education_cohorts,
@@ -17,6 +13,7 @@ class Extranet::CohortsController < Extranet::ApplicationController
   end
 
   def show
+    @cohort = about.education_cohorts.find(params[:id])
     breadcrumb
   end
 
diff --git a/app/controllers/extranet/experiences_controller.rb b/app/controllers/extranet/experiences_controller.rb
index 72a2538afb050929412c0096de3896edf84c9227..2697cc7f87a314a9158035bb8121ac72d5d29b5c 100644
--- a/app/controllers/extranet/experiences_controller.rb
+++ b/app/controllers/extranet/experiences_controller.rb
@@ -1,16 +1,16 @@
 class Extranet::ExperiencesController < Extranet::ApplicationController
-  load_and_authorize_resource class: University::Person::Experience,
-                              through: :current_user,
-                              through_association: :experiences
   def new
+    @experience = current_user.experiences.new
     breadcrumb
   end
-  
+
   def edit
+    @experience = current_user.experiences.find(params[:id])
     breadcrumb
   end
 
   def create
+    @experience = current_user.experiences.new(experience_params)
     @experience.university = current_university
     if @experience.save
       redirect_to account_path, notice: 'Ok'
@@ -21,6 +21,7 @@ class Extranet::ExperiencesController < Extranet::ApplicationController
   end
 
   def update
+    @experience = current_user.experiences.find(params[:id])
     if @experience.update experience_params
       redirect_to account_path, notice: 'Ok'
     else
@@ -33,7 +34,7 @@ class Extranet::ExperiencesController < Extranet::ApplicationController
 
   def experience_params
     params.require(:university_person_experience)
-          .permit(:description, :from_year, :to_year, :organization_id)
+          .permit(:description, :from_year, :to_year, :organization_id, :organization_name)
   end
 
   def breadcrumb
diff --git a/app/controllers/extranet/home_controller.rb b/app/controllers/extranet/home_controller.rb
index 2fd1bc392397c974ead90cb20610ac81fabaa5df..a3b04c782c2bbc5517ac9cef8e515a0d89ebfc0a 100644
--- a/app/controllers/extranet/home_controller.rb
+++ b/app/controllers/extranet/home_controller.rb
@@ -1,7 +1,6 @@
 class Extranet::HomeController < Extranet::ApplicationController
   def index
-    return redirect_to admin_root_path unless current_extranet
     @cohorts = about&.education_cohorts.ordered.limit(5)
-    @experiences = about&.university_person_experiences.ordered.limit(10)
+    @experiences = about&.university_person_experiences.recent
   end
 end
diff --git a/app/controllers/extranet/organizations_controller.rb b/app/controllers/extranet/organizations_controller.rb
index ec718d441227937335a651247c3c12cdb6530ea3..d974426c2d2fa70e1035860a8666921def301fbe 100644
--- a/app/controllers/extranet/organizations_controller.rb
+++ b/app/controllers/extranet/organizations_controller.rb
@@ -1,8 +1,4 @@
 class Extranet::OrganizationsController < Extranet::ApplicationController
-  load_and_authorize_resource class: University::Organization,
-                              through: :about,
-                              through_association: :university_person_alumni_organizations
-
   def index
     @facets = University::Organization::Facets.new params[:facets], {
       model: about&.university_person_alumni_organizations,
@@ -16,7 +12,15 @@ class Extranet::OrganizationsController < Extranet::ApplicationController
     breadcrumb
   end
 
+  def search
+    @term = params[:term].to_s
+    @organizations = current_university.organizations
+                                      .search_by_siren_or_name(@term)
+                                      .ordered
+  end
+
   def show
+    @organization = about.university_person_alumni_organizations.find(params[:id])
     breadcrumb
   end
 
diff --git a/app/controllers/extranet/pages_controller.rb b/app/controllers/extranet/pages_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..90cfe247fb5639b56fc7516307849a3086af07d5
--- /dev/null
+++ b/app/controllers/extranet/pages_controller.rb
@@ -0,0 +1,12 @@
+class Extranet::PagesController < Extranet::ApplicationController
+  skip_before_action :authenticate_user!, :authorize_extranet_access!
+
+  def termes_of_use
+  end
+
+  def cookie_policy
+  end
+
+  def privacy_policy
+  end
+end
diff --git a/app/controllers/extranet/personal_data_controller.rb b/app/controllers/extranet/personal_data_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..62e632303346671c0cde885aa83b6cf6c37e7efe
--- /dev/null
+++ b/app/controllers/extranet/personal_data_controller.rb
@@ -0,0 +1,40 @@
+class Extranet::PersonalDataController < Extranet::ApplicationController
+  before_action :load_person
+
+  def edit
+    breadcrumb
+    add_breadcrumb t('extranet.account.edit_personal_data')
+  end
+
+  def update
+    if @person.update person_params
+      redirect_to account_path, notice: t('extranet.personal_data.updated')
+    else
+      render :edit
+      breadcrumb
+      add_breadcrumb t('extranet.account.edit_personal_data')
+    end
+  end
+
+  private
+
+  def load_person
+    @person = current_user.person
+    raise CanCan::AccessDenied if @person.nil?
+  end
+
+  def person_params
+    params.require(:university_person)
+          .permit(
+            :gender, :birthdate, :description_short, :biography,
+            :phone_mobile, :phone_professional, :phone_personal,
+            :address, :zipcode, :city, :country,
+            :url, :linkedin, :twitter
+          )
+  end
+
+  def breadcrumb
+    super
+    add_breadcrumb t('extranet.account.my'), account_path
+  end
+end
diff --git a/app/controllers/extranet/persons_controller.rb b/app/controllers/extranet/persons_controller.rb
index b94f7ad997e2b7a976ee182f733482614aa2e3ed..73df7551cfe7721522c9cef5004de5afb9519a82 100644
--- a/app/controllers/extranet/persons_controller.rb
+++ b/app/controllers/extranet/persons_controller.rb
@@ -1,8 +1,4 @@
 class Extranet::PersonsController < Extranet::ApplicationController
-  load_and_authorize_resource class: University::Person::Alumnus,
-                              through: :about,
-                              through_association: :university_person_alumni
-
   def index
     @facets = University::Person::Alumnus::Facets.new params[:facets], {
       model: about&.university_person_alumni,
@@ -17,6 +13,7 @@ class Extranet::PersonsController < Extranet::ApplicationController
   end
 
   def show
+    @person = about.university_person_alumni.find(params[:id])
     breadcrumb
   end
 
diff --git a/app/controllers/server/websites_controller.rb b/app/controllers/server/websites_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..764ba04caef5a98a4e509fa5a989802bd4b6fe70
--- /dev/null
+++ b/app/controllers/server/websites_controller.rb
@@ -0,0 +1,8 @@
+class Server::WebsitesController < Server::ApplicationController
+
+  def index
+    @websites = Communication::Website.all.ordered
+    breadcrumb
+  end
+
+end
\ No newline at end of file
diff --git a/app/controllers/users/confirmations_controller.rb b/app/controllers/users/confirmations_controller.rb
index 663067dd4e608b06cbb1caeaa10f99e7fc245f42..14962a300afaa6588b7bf148b6de12dbb42d606f 100644
--- a/app/controllers/users/confirmations_controller.rb
+++ b/app/controllers/users/confirmations_controller.rb
@@ -1,5 +1,6 @@
 class Users::ConfirmationsController < Devise::ConfirmationsController
-  include Users::AddUniversityToRequestParams
+  include Users::AddContextToRequestParams
+  include Users::LayoutChoice
 
   def resend
     unless signed_in_resource.confirmed?
diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb
index 47b36fc4d6bb9823d4f47ddda8486fe7f53d70e1..7a909aca6d9d195c7f0b56d872d8a940b599ead8 100644
--- a/app/controllers/users/omniauth_callbacks_controller.rb
+++ b/app/controllers/users/omniauth_callbacks_controller.rb
@@ -1,7 +1,4 @@
 class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
-  # include Users::AddBrandToRequestParams
-  # include I18nHelper
-
   protect_from_forgery except: :saml
   before_action :redirect_unless_university_has_sso
   skip_before_action :verify_authenticity_token, only: :saml
@@ -21,9 +18,9 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   def saml_setup
     # SAML config is stored in current brand
     request.env['omniauth.strategy'].options[:issuer] = "#{user_saml_omniauth_authorize_url}/metadata"
-    request.env['omniauth.strategy'].options[:idp_sso_target_url] = current_university.sso_target_url
-    request.env['omniauth.strategy'].options[:idp_cert] = current_university.sso_cert
-    request.env['omniauth.strategy'].options[:name_identifier_format] = current_university.sso_name_identifier_format
+    request.env['omniauth.strategy'].options[:idp_sso_target_url] = current_context.sso_target_url
+    request.env['omniauth.strategy'].options[:idp_cert] = current_context.sso_cert
+    request.env['omniauth.strategy'].options[:name_identifier_format] = current_context.sso_name_identifier_format
 
     render plain: "Omniauth SAML setup phase.", status: 404
   end
@@ -31,7 +28,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   private
 
   def manage_user(user_infos)
-    @user = User.from_omniauth(current_university, user_infos)
+    @user = User.from_omniauth(current_context, user_infos)
 
     if @user&.persisted?
       @user.remember_me = true
@@ -43,6 +40,6 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
   end
 
   def redirect_unless_university_has_sso
-    redirect_to root_path and return unless current_university.has_sso?
+    redirect_to root_path and return unless current_context.has_sso?
   end
 end
diff --git a/app/controllers/users/passwords_controller.rb b/app/controllers/users/passwords_controller.rb
index c0334ec485bd903f30bf6324a25e1b245ffd4c2e..4902f4ed6f10f03a06da97d58afa0892881285b1 100644
--- a/app/controllers/users/passwords_controller.rb
+++ b/app/controllers/users/passwords_controller.rb
@@ -1,5 +1,6 @@
 class Users::PasswordsController < Devise::PasswordsController
-  include Users::AddUniversityToRequestParams
+  include Users::AddContextToRequestParams
+  include Users::LayoutChoice
 
   def update
     super do |resource|
diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb
index 4e22f2bc2836ec5e89fcc8ca944ee2f9a3034174..840ef1be6bb094550c6e00122b175a415351ae1b 100644
--- a/app/controllers/users/registrations_controller.rb
+++ b/app/controllers/users/registrations_controller.rb
@@ -1,7 +1,6 @@
 class Users::RegistrationsController < Devise::RegistrationsController
-  include Users::AddUniversityToRequestParams
-
-  layout 'admin/layouts/application', only: [:edit, :update]
+  include Users::AddContextToRequestParams
+  include Users::LayoutChoice
 
   before_action :configure_sign_up_params, only: :create
   before_action :configure_account_update_params, only: :update
@@ -51,4 +50,8 @@ class Users::RegistrationsController < Devise::RegistrationsController
   def configure_account_update_params
     devise_parameter_sanitizer.permit(:account_update, keys: [:mobile_phone, :language_id, :first_name, :last_name, :picture, :picture_infos, :picture_delete])
   end
+
+  def sign_up_params
+    devise_parameter_sanitized = devise_parameter_sanitizer.sanitize(:sign_up).merge(registration_context: current_context)
+  end
 end
diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb
index 719343815f218d7c8ca598bee06f39e1f321d4d1..166de839e8614df6823045fa6e804f9d0f628170 100644
--- a/app/controllers/users/sessions_controller.rb
+++ b/app/controllers/users/sessions_controller.rb
@@ -1,10 +1,11 @@
 class Users::SessionsController < Devise::SessionsController
-  include Users::AddUniversityToRequestParams
+  include Users::AddContextToRequestParams
+  include Users::LayoutChoice
 
   # DELETE /resource/sign_out
   def destroy
     current_user.invalidate_all_sessions!
     super
   end
-  
+
 end
diff --git a/app/controllers/users/two_factor_authentication_controller.rb b/app/controllers/users/two_factor_authentication_controller.rb
index 1ab0e9e273a370736fb50634cba2a345a857061f..ecb05b9033313b96e02ca1ec78e11f94a5ed1cd8 100644
--- a/app/controllers/users/two_factor_authentication_controller.rb
+++ b/app/controllers/users/two_factor_authentication_controller.rb
@@ -1,2 +1,3 @@
 class Users::TwoFactorAuthenticationController < Devise::TwoFactorAuthenticationController
+  include Users::LayoutChoice
 end
diff --git a/app/controllers/users/unlocks_controller.rb b/app/controllers/users/unlocks_controller.rb
index b1ef889214da83bd699990b4c1110d132a004626..001af98ef133c8bf2baf7cd7c6b05baa6a5d26d0 100644
--- a/app/controllers/users/unlocks_controller.rb
+++ b/app/controllers/users/unlocks_controller.rb
@@ -1,3 +1,4 @@
 class Users::UnlocksController < Devise::UnlocksController
-  include Users::AddUniversityToRequestParams
+  include Users::AddContextToRequestParams
+  include Users::LayoutChoice
 end
diff --git a/app/mailers/devise_mailer.rb b/app/mailers/devise_mailer.rb
index 430eee58f6549df45103cc1bf97e6818bc454ecb..5796201ee95635b30c454735bf5d47989112143c 100644
--- a/app/mailers/devise_mailer.rb
+++ b/app/mailers/devise_mailer.rb
@@ -4,6 +4,7 @@ class DeviseMailer < Devise::Mailer
   default template_path: 'devise/mailer' # to make sure that your mailer uses the devise views
 
   def confirmation_instructions(record, token, opts={})
+    @record = record
     opts = merge_with_university_infos(record.university, opts)
     I18n.with_locale(record.language.iso_code.to_sym) do
       super
@@ -11,6 +12,7 @@ class DeviseMailer < Devise::Mailer
   end
 
   def reset_password_instructions(record, token, opts={})
+    @record = record
     opts = merge_with_university_infos(record.university, opts)
     I18n.with_locale(record.language.iso_code.to_sym) do
       super
@@ -18,6 +20,7 @@ class DeviseMailer < Devise::Mailer
   end
 
   def unlock_instructions(record, token, opts={})
+    @record = record
     opts = merge_with_university_infos(record.university, opts)
     I18n.with_locale(record.language.iso_code.to_sym) do
       super
@@ -25,6 +28,7 @@ class DeviseMailer < Devise::Mailer
   end
 
   def email_changed(record, opts={})
+    @record = record
     opts = merge_with_university_infos(record.university, opts)
     I18n.with_locale(record.language.iso_code.to_sym) do
       super
@@ -32,6 +36,7 @@ class DeviseMailer < Devise::Mailer
   end
 
   def password_change(record, opts={})
+    @record = record
     opts = merge_with_university_infos(record.university, opts)
     I18n.with_locale(record.language.iso_code.to_sym) do
       super
@@ -39,6 +44,7 @@ class DeviseMailer < Devise::Mailer
   end
 
   def two_factor_authentication_code(record, code, opts = {})
+    @record = record
     opts = merge_with_university_infos(record.university, opts)
     @code = code
     @duration =  ActiveSupport::Duration.build(Rails.application.config.devise.direct_otp_valid_for).inspect
@@ -49,7 +55,7 @@ class DeviseMailer < Devise::Mailer
 
   def default_url_options
     {
-      host: @university.host,
+      host: @record.registration_context.present? ? @record.registration_context.host : @university.host,
       port: Rails.env.development? ? 3000 : nil
     }
   end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 290054aa0875c8978c5b48b0da86c17ef0776cf8..fd09a644af516810ce08282a0293382e60da4fa8 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -11,24 +11,6 @@ class Ability
   protected
 
   def visitor
-    can :read, Administration::Qualiopi::Criterion
-    can :read, Administration::Qualiopi::Indicator
-    can :read, University::Person
-    can :read, Communication::Website, university_id: @user.university_id
-    can :read, Communication::Website::Page, university_id: @user.university_id
-    can :read, Communication::Website::Post, university_id: @user.university_id
-    can :read, Communication::Website::Imported::Website, university_id: @user.university_id
-    can :read, Communication::Website::Imported::Page, university_id: @user.university_id
-    can :read, Communication::Website::Imported::Post, university_id: @user.university_id
-    can :read, Education::Diploma, university_id: @user.university_id
-    can :read, Education::Program, university_id: @user.university_id
-    can :read, Education::School, university_id: @user.university_id
-    can :read, Research::Journal, university_id: @user.university_id
-    can :read, Research::Journal::Paper, university_id: @user.university_id
-    can :read, Research::Journal::Volume, university_id: @user.university_id
-    can :read, Research::Laboratory, university_id: @user.university_id
-    can :read, User, university_id: @user.university_id
-    can :read, Communication::Block, university_id: @user.university_id
   end
 
   def contributor
diff --git a/app/models/communication/block/template/organization_chart.rb b/app/models/communication/block/template/organization_chart.rb
index 334d745ed2b8280fb9618fd3c97e6a37f4edfbb9..0b12392157a8d8c16bc93050e2483c31eac7803c 100644
--- a/app/models/communication/block/template/organization_chart.rb
+++ b/app/models/communication/block/template/organization_chart.rb
@@ -4,5 +4,14 @@ class Communication::Block::Template::OrganizationChart < Communication::Block::
   has_component :description, :rich_text
   has_component :with_link, :boolean
   has_component :with_photo, :boolean
+  has_component :alphabetical, :boolean
 
+  def elements
+    if alphabetical
+      @elements.sort_by! do |element|
+        "#{element.person&.last_name&.parameterize&.downcase}"
+      end
+    end
+    @elements
+  end
 end
diff --git a/app/models/communication/block/template/partner.rb b/app/models/communication/block/template/partner.rb
index 25a1e19005a20bb52091de8f7804caf020a6c85f..8cc804f24ce7ec76abfd15386485abf5f5096d2e 100644
--- a/app/models/communication/block/template/partner.rb
+++ b/app/models/communication/block/template/partner.rb
@@ -2,5 +2,15 @@ class Communication::Block::Template::Partner < Communication::Block::Template::
 
   has_elements
   has_component :description, :rich_text
+  has_component :with_link, :boolean
+  has_component :alphabetical, :boolean
 
+  def elements
+    if alphabetical
+      @elements.sort_by! do |element|
+        "#{element.best_name&.parameterize&.downcase}"
+      end
+    end
+    @elements
+  end
 end
diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb
index 968f35b92c8cbbfeced7a55eac264ffd464505cc..cd9c9bd78c090602877456946bf0c1bb34930ad8 100644
--- a/app/models/communication/extranet.rb
+++ b/app/models/communication/extranet.rb
@@ -2,14 +2,25 @@
 #
 # Table name: communication_extranets
 #
-#  id            :uuid             not null, primary key
-#  about_type    :string           indexed => [about_id]
-#  domain        :string
-#  name          :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  about_id      :uuid             indexed => [about_type]
-#  university_id :uuid             not null, indexed
+#  id                         :uuid             not null, primary key
+#  about_type                 :string           indexed => [about_id]
+#  color                      :string
+#  cookies_policy             :text
+#  has_sso                    :boolean          default(FALSE)
+#  host                       :string
+#  name                       :string
+#  privacy_policy             :text
+#  registration_contact       :string
+#  sso_cert                   :text
+#  sso_mapping                :jsonb
+#  sso_name_identifier_format :string
+#  sso_provider               :integer          default("saml")
+#  sso_target_url             :string
+#  terms                      :text
+#  created_at                 :datetime         not null
+#  updated_at                 :datetime         not null
+#  about_id                   :uuid             indexed => [about_type]
+#  university_id              :uuid             not null, indexed
 #
 # Indexes
 #
@@ -22,26 +33,51 @@
 #
 class Communication::Extranet < ApplicationRecord
   include WithAbouts
+  include WithLegal
+  include WithSso
   include WithUniversity
 
-  validates_presence_of :name, :domain
+  validates_presence_of :name, :host
 
   has_one_attached_deletable :logo
 
   scope :ordered, -> { order(:name) }
   scope :for_search_term, -> (term) {
     where("
-      unaccent(communication_extranets.domain) ILIKE unaccent(:term) OR
+      unaccent(communication_extranets.host) ILIKE unaccent(:term) OR
       unaccent(communication_extranets.name) ILIKE unaccent(:term)
     ", term: "%#{sanitize_sql_like(term)}%")
   }
 
   def self.with_host(host)
-    find_by domain: host
+    find_by host: host
+  end
+
+  def should_show_years?
+    # For a single program, year is like cohort
+    return false if about.is_a? Education::Program
+    # if a school has a single program, same thing
+    about.programs.many?
+  end
+
+  def alumni
+    about&.university_person_alumni
+  end
+
+  def cohorts
+    about&.cohorts
+  end
+
+  def years
+    about&.academic_years
+  end
+
+  def organizations
+    about&.alumni_organizations
   end
 
   def url
-    "https://#{domain}"
+    @url ||= Rails.env.development? ? "http://#{host}:3000" : "https://#{host}"
   end
 
   def to_s
diff --git a/app/models/communication/extranet/with_legal.rb b/app/models/communication/extranet/with_legal.rb
new file mode 100644
index 0000000000000000000000000000000000000000..92fd5fe911a23787afcca127d6dde66a80c3131a
--- /dev/null
+++ b/app/models/communication/extranet/with_legal.rb
@@ -0,0 +1,19 @@
+module Communication::Extranet::WithLegal
+  extend ActiveSupport::Concern
+
+  included do
+    include ActionView::Helpers::SanitizeHelper
+  end
+
+  def has_terms?
+    strip_tags(terms).to_s.strip.present?
+  end
+
+  def has_cookies_policy?
+    strip_tags(cookies_policy).to_s.strip.present?
+  end
+
+  def has_privacy_policy?
+    strip_tags(privacy_policy).to_s.strip.present?
+  end
+end
diff --git a/app/models/communication/extranet/with_sso.rb b/app/models/communication/extranet/with_sso.rb
new file mode 100644
index 0000000000000000000000000000000000000000..223eae3bd898d779d7efa81d081dd0be4f90d274
--- /dev/null
+++ b/app/models/communication/extranet/with_sso.rb
@@ -0,0 +1,26 @@
+module Communication::Extranet::WithSso
+  extend ActiveSupport::Concern
+
+  included do
+    enum sso_provider: { saml: 0 }, _prefix: :with_sso_via
+
+    validates :sso_cert, :sso_name_identifier_format, :sso_target_url, presence: true, if: :has_sso?
+    validate :sso_mapping_should_have_email, if: :has_sso?
+  end
+
+  # Setter to serialize data as JSON
+  def sso_mapping=(value)
+    if value.empty?
+      value = nil
+    else
+      value = JSON.parse value if value.is_a? String
+    end
+    super(value)
+  end
+
+  private
+
+  def sso_mapping_should_have_email
+    errors.add(:sso_mapping, :missing_email) unless (sso_mapping || []).detect { |sso_item| sso_item['internal_key'] == 'email' }
+  end
+end
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index 9189e694225ef3dc8f8956c74f61ab2227915414..d0ceb1f691d281dfc9e88149ab3b59f7d52d0043 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -5,8 +5,10 @@
 #  id               :uuid             not null, primary key
 #  about_type       :string           indexed => [about_id]
 #  access_token     :string
+#  git_branch       :string
 #  git_endpoint     :string
 #  git_provider     :integer          default("github")
+#  in_production    :boolean          default(FALSE)
 #  name             :string
 #  plausible_url    :string
 #  repository       :string
@@ -52,6 +54,7 @@ class Communication::Website < ApplicationRecord
                           association_foreign_key: 'language_id'
 
   scope :ordered, -> { order(:name) }
+  scope :in_production, -> { where(in_production: true) }
   scope :for_search_term, -> (term) {
     where("
       unaccent(communication_websites.name) ILIKE unaccent(:term) OR
diff --git a/app/models/communication/website/configs/base_url.rb b/app/models/communication/website/configs/base_url.rb
index 2daeee8a29469d9f54419c721df481893f9f4e46..080e03ddd7e4bfabb0ec4ecb17b67e8beb1b9afd 100644
--- a/app/models/communication/website/configs/base_url.rb
+++ b/app/models/communication/website/configs/base_url.rb
@@ -5,8 +5,10 @@
 #  id               :uuid             not null, primary key
 #  about_type       :string           indexed => [about_id]
 #  access_token     :string
+#  git_branch       :string
 #  git_endpoint     :string
 #  git_provider     :integer          default("github")
+#  in_production    :boolean          default(FALSE)
 #  name             :string
 #  plausible_url    :string
 #  repository       :string
diff --git a/app/models/communication/website/configs/permalinks.rb b/app/models/communication/website/configs/permalinks.rb
index df46d3c8fecc75aba6cf25a7418402a7e225dbca..cf836fd47e1a754b79dd1922b498f0d4b5c0e929 100644
--- a/app/models/communication/website/configs/permalinks.rb
+++ b/app/models/communication/website/configs/permalinks.rb
@@ -5,8 +5,10 @@
 #  id               :uuid             not null, primary key
 #  about_type       :string           indexed => [about_id]
 #  access_token     :string
+#  git_branch       :string
 #  git_endpoint     :string
 #  git_provider     :integer          default("github")
+#  in_production    :boolean          default(FALSE)
 #  name             :string
 #  plausible_url    :string
 #  repository       :string
diff --git a/app/models/education/cohort.rb b/app/models/education/cohort.rb
index c086cf0d3a93432e4d178efbb8c686f8013f9474..e37605bda37291b7b373eff62351d342f0b56c83 100644
--- a/app/models/education/cohort.rb
+++ b/app/models/education/cohort.rb
@@ -53,7 +53,7 @@ class Education::Cohort < ApplicationRecord
   }
 
   def to_s
-    "#{school} #{program} #{academic_year}"
+    "#{program.to_short_s} #{academic_year}"
   end
 
   def year
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index bd3d3789cbfb0a1bb5b1c5856b774e66ae672c1e..f771c240205042fd33893a9b3b8e984d36a05a9d 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -130,6 +130,10 @@ class Education::Program < ApplicationRecord
     where(published: publication)
   }
 
+  def to_short_s
+    short_name.blank? ? to_s : short_name
+  end
+
   def to_s
     "#{name}"
   end
diff --git a/app/models/education/school/with_alumni.rb b/app/models/education/school/with_alumni.rb
index 36c5a9b5493bbec46e97b247b3b8a7ddd0d62ab0..976721f5c5c34bb1068ed92716a1f5bf7ed80703 100644
--- a/app/models/education/school/with_alumni.rb
+++ b/app/models/education/school/with_alumni.rb
@@ -3,8 +3,13 @@ module Education::School::WithAlumni
 
   included do
 
+      has_many    :education_cohorts,
+                  class_name: 'Education::Cohort'
+                  alias_attribute :cohorts, :education_cohorts
+
       has_many    :alumni, -> { distinct },
-                  through: :programs
+                  through: :education_cohorts,
+                  source: :people
                   alias_attribute :university_person_alumni, :alumni
 
       has_many    :alumni_experiences, -> { distinct },
@@ -19,11 +24,6 @@ module Education::School::WithAlumni
                   source: :organization
                   alias_attribute :university_person_alumni_organizations, :alumni_organizations
 
-      has_many    :education_cohorts, -> { distinct },
-                  class_name: 'Education::Cohort',
-                  through: :programs
-                  alias_attribute :cohorts, :education_cohorts
-
       has_many    :academic_years, -> { distinct },
                   class_name: 'Education::AcademicYear',
                   through: :education_cohorts,
diff --git a/app/models/university/organization.rb b/app/models/university/organization.rb
index 46d1f7b0c97d6ce285fe050dd7c83bdc8d3a5aff..f10ac6b36fc6696d53a4afab3863291c940993c2 100644
--- a/app/models/university/organization.rb
+++ b/app/models/university/organization.rb
@@ -38,6 +38,8 @@ class University::Organization < ApplicationRecord
   include WithSlug
   include WithBlocks
 
+  attr_accessor :created_from_extranet
+
   has_many :experiences,
            class_name: 'University::Person::Experience'
 
@@ -64,8 +66,17 @@ class University::Organization < ApplicationRecord
       unaccent(university_organizations.url) ILIKE unaccent(:term)
     ", term: "%#{sanitize_sql_like(term)}%")
   }
+  scope :search_by_siren_or_name, -> (term) {
+    where("
+      unaccent(university_organizations.siren) ILIKE unaccent(:term) OR
+      unaccent(university_organizations.name) ILIKE unaccent(:term)
+    ", term: "%#{sanitize_sql_like(term)}%")
+  }
 
   validates_presence_of :name
+  validates_uniqueness_of :name, scope: :university_id
+  # Organization can be created from extranet with only their name. Be careful for future validators.
+  # There is an attribute accessor above : `created_from_extranet`
 
   enum kind: {
     company: 10,
diff --git a/app/models/university/person.rb b/app/models/university/person.rb
index b74f00a392a408651b58a48fc7c5814a4de6bc87..ca6f03bb53cd18eed81fd58c44d6a838fef478df 100644
--- a/app/models/university/person.rb
+++ b/app/models/university/person.rb
@@ -213,6 +213,11 @@ class University::Person < ApplicationRecord
     teacher.for_website?(website)
   end
 
+  def full_street_address
+    return nil if [address, zipcode, city].all?(&:blank?)
+    [address, "#{zipcode} #{city} #{country}".strip].join(', ')
+  end
+
   protected
 
   def explicit_blob_ids
diff --git a/app/models/university/person/experience.rb b/app/models/university/person/experience.rb
index 10e5976298194425240406c6d8a9d2f893e28c0b..a5f0b47c74ddc53c34fe856bf59a0bbe8e730985 100644
--- a/app/models/university/person/experience.rb
+++ b/app/models/university/person/experience.rb
@@ -27,13 +27,50 @@
 class University::Person::Experience < ApplicationRecord
   include WithUniversity
 
+  attr_accessor :organization_name
+
   belongs_to :person
   belongs_to :organization, class_name: "University::Organization"
 
-  scope :ordered, -> { order(from_year: :desc)}
+  validates_presence_of :organization
+  validates_presence_of :from_year
+  # TODO validateur de comparaison
+  # validates_numericality_of :to_year, { greater_than_or_equal_to: :from_year }, allow_nil: true
+  validate :to_year, :not_before_from_year
+
+  before_validation :create_organization_if_needed
+
+  scope :ordered, -> { order('university_person_experiences.to_year DESC NULLS FIRST, university_person_experiences.from_year') }
+  scope :recent, -> {
+    where.not(from_year: nil)
+    .order(from_year: :desc, created_at: :desc)
+    .limit(10)
+  }
 
   def to_s
     persisted?  ? "#{description}"
                 : self.class.human_attribute_name('new')
   end
+
+  def organization_name
+    @organization_name || organization&.name
+  end
+
+  private
+
+  def not_before_from_year
+    if to_year.present? && to_year < from_year
+      errors.add :to_year
+    end
+  end
+
+  def create_organization_if_needed
+    if organization.nil? && organization_name.present?
+      self.organization_name = self.organization_name.strip
+      orga = university.organizations.find_by("name ILIKE ?", organization_name)
+      orga ||= university.organizations.find_by(siren: organization_name)
+      orga ||= university.organizations.create(name: organization_name, created_from_extranet: true)
+      self.organization = orga if orga.persisted?
+    end
+  end
 end
diff --git a/app/models/university/with_sso.rb b/app/models/university/with_sso.rb
index 91ef0d463e0143666a8bdaf6deff7b936dc8b30e..1bf5febd1c1d0a7cb548f084399cdc78d61801e9 100644
--- a/app/models/university/with_sso.rb
+++ b/app/models/university/with_sso.rb
@@ -18,6 +18,8 @@ module University::WithSso
     super(value)
   end
 
+  private
+
   def sso_mapping_should_have_email
     errors.add(:sso_mapping, :missing_email) unless (sso_mapping || []).detect { |sso_item| sso_item['internal_key'] == 'email' }
   end
diff --git a/app/models/user.rb b/app/models/user.rb
index 5beb59b86894660878943b89e3e573a7c165d264..57824a2c781069c0c97f01e1084b541dde01a3cc 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -56,6 +56,7 @@
 #
 class User < ApplicationRecord
   include WithAvatar
+  include WithRegistrationContext
   include WithUniversity
   include WithAuthentication
   include WithOmniauth
diff --git a/app/models/user/with_authentication.rb b/app/models/user/with_authentication.rb
index 5e68ea7505b38c8a540771d62b5510c81edcb56f..86a880834032231725a0fb57185d33e46bc141b7 100644
--- a/app/models/user/with_authentication.rb
+++ b/app/models/user/with_authentication.rb
@@ -24,6 +24,23 @@ module User::WithAuthentication
       where(email: warden_conditions[:email].downcase, university_id: warden_conditions[:university_id]).first
     end
 
+    def self.send_confirmation_instructions(attributes = {})
+      confirmable = find_by_unconfirmed_email_with_errors(attributes) if reconfirmable
+      unless confirmable.try(:persisted?)
+        confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
+      end
+      confirmable.registration_context = attributes[:registration_context] if attributes.has_key?(:registration_context)
+      confirmable.resend_confirmation_instructions if confirmable.persisted?
+      confirmable
+    end
+
+    def self.send_unlock_instructions(attributes = {})
+      lockable = find_or_initialize_with_errors(unlock_keys, attributes, :not_found)
+      lockable.registration_context = attributes[:registration_context] if attributes.has_key?(:registration_context)
+      lockable.resend_unlock_instructions if lockable.persisted?
+      lockable
+    end
+
     # Inject a session_token in user salt to prevent Cookie session hijacking
     # https://makandracards.com/makandra/53562-devise-invalidating-all-sessions-for-a-user
     def authenticatable_salt
@@ -38,6 +55,14 @@ module User::WithAuthentication
       true
     end
 
+    def send_new_otp(request, options = {})
+      current_extranet = Communication::Extranet.with_host(request.host)
+      current_university = University.with_host(request.host)
+      current_university ||= university
+      self.registration_context = current_extranet || current_university
+      super
+    end
+
     def direct_otp_default_delivery_method
       mobile_phone.present? ? :mobile_phone : :email
     end
diff --git a/app/models/user/with_omniauth.rb b/app/models/user/with_omniauth.rb
index 64ba7ddc5433e77746467b4deb1b35c2d82f0089..f57b43c5ab853059c2a06ebf2df7e09b27a532a4 100644
--- a/app/models/user/with_omniauth.rb
+++ b/app/models/user/with_omniauth.rb
@@ -3,8 +3,9 @@ module User::WithOmniauth
 
   included do
 
-    def self.from_omniauth(university, attributes)
-      mapping = university.sso_mapping || []
+    def self.from_omniauth(context, attributes)
+      mapping = context.sso_mapping || []
+      university = context.is_a?(University) ? context : context.university
 
       # first step: we find the email (we are supposed to have an email mapping)
       email = get_email_from_mapping(mapping, attributes)
@@ -12,6 +13,7 @@ module User::WithOmniauth
 
       user = User.where(university: university, email: email.downcase).first_or_create do |u|
         u.password = "#{Devise.friendly_token[0,20]}!" # meets password complexity requirements
+        u.registration_context = context
       end
 
       # update user data according to mapping & infos provided by SSO
diff --git a/app/models/user/with_person.rb b/app/models/user/with_person.rb
index 4e095ff6333a8abea03d42c34970be3d13b1266b..17b057863ea00d0e945e6df466bc3e12cace7113 100644
--- a/app/models/user/with_person.rb
+++ b/app/models/user/with_person.rb
@@ -6,6 +6,7 @@ module User::WithPerson
 
     delegate :experiences, to: :person
 
+    after_save_commit :sync_person, if: :person
     after_create_commit :find_or_create_person, unless: :server_admin?
   end
 
@@ -21,4 +22,13 @@ module User::WithPerson
     person.user = self
     person.save
   end
+
+  def sync_person
+    person.first_name = first_name
+    person.last_name = last_name
+    person.slug = person.to_s.parameterize
+    person.phone_mobile = mobile_phone
+    person.picture.purge if picture_infos.present? && person.picture&.attached?
+    person.save
+  end
 end
diff --git a/app/models/user/with_registration_context.rb b/app/models/user/with_registration_context.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f737c298b0674306b46ebefaedcdc1e2e9018914
--- /dev/null
+++ b/app/models/user/with_registration_context.rb
@@ -0,0 +1,22 @@
+module User::WithRegistrationContext
+  extend ActiveSupport::Concern
+
+  included do
+    attr_accessor :registration_context
+
+    validate :extranet_access, on: :create, if: -> { registration_context.is_a?(Communication::Extranet) }
+
+    private
+
+    def extranet_access
+      unless registration_context.alumni.where(email: email).any?
+        if registration_context.registration_contact.present?
+          errors.add :email, I18n.t('extranet.errors.email_not_allowed_with_contact', contact: registration_context.registration_contact)
+        else
+          errors.add :email, I18n.t('extranet.errors.email_not_allowed')
+        end
+      end
+    end
+
+  end
+end
diff --git a/app/services/git/providers/abstract.rb b/app/services/git/providers/abstract.rb
index be21a999ea56ef84f69cb6bb738aa7bfbcd4a09f..f84f7f76855da80299bda2ca602b52030f57e708 100644
--- a/app/services/git/providers/abstract.rb
+++ b/app/services/git/providers/abstract.rb
@@ -1,8 +1,9 @@
 class Git::Providers::Abstract
-  attr_reader :endpoint, :access_token, :repository
+  attr_reader :endpoint, :branch, :access_token, :repository
 
-  def initialize(endpoint, access_token, repository)
+  def initialize(endpoint, branch, access_token, repository)
     @endpoint = endpoint
+    @branch = branch
     @access_token = access_token
     @repository = repository
   end
diff --git a/app/services/git/providers/github.rb b/app/services/git/providers/github.rb
index f42b8b01f8d7721846a4ef3bf0606732dcb157ec..2bf52bf8daeb540eb6c3cab79bef8f5e1eb3a8c3 100644
--- a/app/services/git/providers/github.rb
+++ b/app/services/git/providers/github.rb
@@ -75,7 +75,8 @@ class Git::Providers::Github < Git::Providers::Abstract
   end
 
   def default_branch
-    @default_branch ||= client.repo(repository)[:default_branch]
+    @default_branch ||= branch.present? ? branch
+                                        : client.repo(repository)[:default_branch]
   end
 
   def branch_sha
diff --git a/app/services/git/providers/gitlab.rb b/app/services/git/providers/gitlab.rb
index 937b9c9044126723f2f208bc7d5cc2bd7079c066..73f4c87dd8afa616eb90a437ad1ddded4ac689d6 100644
--- a/app/services/git/providers/gitlab.rb
+++ b/app/services/git/providers/gitlab.rb
@@ -38,7 +38,7 @@ class Git::Providers::Gitlab < Git::Providers::Abstract
   def push(commit_message)
     return if !valid? || batch.empty?
     client.create_commit  repository,
-                          'main',
+                          branch,
                           commit_message,
                           batch
     true
@@ -59,6 +59,11 @@ class Git::Providers::Gitlab < Git::Providers::Abstract
     sha
   end
 
+  def branch
+    super.present?  ? super
+                    : 'main'
+  end
+
   protected
 
   def endpoint
@@ -76,7 +81,7 @@ class Git::Providers::Gitlab < Git::Providers::Abstract
   def find(path)
     client.get_file repository,
                     path,
-                    'main'
+                    branch
   rescue
     nil
   end
diff --git a/app/services/git/repository.rb b/app/services/git/repository.rb
index 6609f0fd57dd9f13542af9786e44b76fcdf2d0fb..80449c0742976fd9622cc591aa6fb0130b0db568 100644
--- a/app/services/git/repository.rb
+++ b/app/services/git/repository.rb
@@ -39,6 +39,7 @@ class Git::Repository
 
   def provider
     @provider ||= provider_class.new  website&.git_endpoint,
+                                      website&.git_branch,
                                       website&.access_token,
                                       website&.repository
   end
diff --git a/app/services/sendinblue/sms_service.rb b/app/services/sendinblue/sms_service.rb
index 123329dd8dcab2702269f910ea3181b78a9a1e29..41b11efe98e0921b771b3b526540e51748df35f9 100644
--- a/app/services/sendinblue/sms_service.rb
+++ b/app/services/sendinblue/sms_service.rb
@@ -4,7 +4,7 @@ module Sendinblue
 
     def self.send_mfa_code(user, code)
       duration =  ActiveSupport::Duration.build(Rails.application.config.devise.direct_otp_valid_for).inspect
-      message = I18n.t('sms_code', code: code, university: user.university, duration: duration)
+      message = I18n.t('sms_code', code: code, context: user.registration_context, duration: duration)
       self.send_message(user, message)
     end
 
diff --git a/app/views/admin/administration/qualiopi/evaluations/_list.html.erb b/app/views/admin/administration/qualiopi/evaluations/_list.html.erb
index c0651e4e222cb870d82ffb41c8f9c9748b106c6b..4a1a84b7826c88e413665b46bd6695ebce23b214 100644
--- a/app/views/admin/administration/qualiopi/evaluations/_list.html.erb
+++ b/app/views/admin/administration/qualiopi/evaluations/_list.html.erb
@@ -1,36 +1,38 @@
-<table class="table mt-5">
-  <thead>
-    <tr>
-      <th><%= Education::Program.model_name.human %></th>
-      <% checks.each do |check| %>
-        <th><%= Education::Program.human_attribute_name(check) %></th>
-      <% end %>
-    </tr>
-  </thead>
-  <tbody>
-    <% programs.each do |program| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %> mt-5">
+    <thead>
       <tr>
-        <td>
-          <% if program.ancestors.any? %>
-            <small>
-              <% program.ancestors.each do |program| %>
-                <%= program %> /
-              <% end %>
-            </small><br>
-          <% end %>
-          <%= link_to program, [:admin, program] %>
-        </td>
+        <th><%= Education::Program.model_name.human %></th>
         <% checks.each do |check| %>
-          <% valid = !program.public_send("best_#{check}").blank? %>
+          <th><%= Education::Program.human_attribute_name(check) %></th>
+        <% end %>
+      </tr>
+    </thead>
+    <tbody>
+      <% programs.each do |program| %>
+        <tr>
           <td>
-            <% if valid %>
-              <span class="fas fa-check text-success"></span>
-            <% else %>
-              <span class="fas fa-times text-danger"></span>
+            <% if program.ancestors.any? %>
+              <small>
+                <% program.ancestors.each do |program| %>
+                  <%= program %> /
+                <% end %>
+              </small><br>
             <% end %>
+            <%= link_to program, [:admin, program] %>
           </td>
-        <% end %>
-      </tr>
-    <% end %>
-  </tbody>
-</table>
+          <% checks.each do |check| %>
+            <% valid = !program.public_send("best_#{check}").blank? %>
+            <td>
+              <% if valid %>
+                <span class="fas fa-check text-success"></span>
+              <% else %>
+                <span class="fas fa-times text-danger"></span>
+              <% end %>
+            </td>
+          <% end %>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/administration/qualiopi/indicators/index.html.erb b/app/views/admin/administration/qualiopi/indicators/index.html.erb
index 1d20856ba8115cb94c189111131f3a050cf70dda..372ca77509d841363a420c9c344c3f55899637c6 100644
--- a/app/views/admin/administration/qualiopi/indicators/index.html.erb
+++ b/app/views/admin/administration/qualiopi/indicators/index.html.erb
@@ -1,25 +1,27 @@
 <% content_for :title, Administration::Qualiopi::Indicator.model_name.human(count: 2) %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= Administration::Qualiopi::Indicator.human_attribute_name('criterion') %></th>
-      <th><%= Administration::Qualiopi::Indicator.human_attribute_name('number') %></th>
-      <th><%= Administration::Qualiopi::Indicator.human_attribute_name('name') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @indicators.each do |indicator| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= indicator.criterion %></td>
-        <td><%= indicator.number %></td>
-        <td><%= link_to indicator, [:admin, indicator] %></td>
-        <td class="text-end">
-          <%= edit_link indicator %>
-          <%= destroy_link indicator %>
-        </td>
+        <th><%= Administration::Qualiopi::Indicator.human_attribute_name('criterion') %></th>
+        <th><%= Administration::Qualiopi::Indicator.human_attribute_name('number') %></th>
+        <th><%= Administration::Qualiopi::Indicator.human_attribute_name('name') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @indicators.each do |indicator| %>
+        <tr>
+          <td><%= indicator.criterion %></td>
+          <td><%= indicator.number %></td>
+          <td><%= link_to indicator, [:admin, indicator] %></td>
+          <td class="text-end">
+            <%= edit_link indicator %>
+            <%= destroy_link indicator %>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/application/_dependencies.html.erb b/app/views/admin/application/_dependencies.html.erb
index d15308a61d4382b9516e523e608a2406cd2385fa..ebfeae9508c71ee88469282da68c93ba59d06c04 100644
--- a/app/views/admin/application/_dependencies.html.erb
+++ b/app/views/admin/application/_dependencies.html.erb
@@ -15,42 +15,46 @@ expanded ||= false
         </div>
         <div class="card-body collapse <%= 'show' if expanded %>" id="dependencies">
             <h2 class="h5">git_dependencies</h2>
-            <table class="table">
-                <thead>
-                    <tr>
-                        <th>Id</th>
-                        <th>Class</th>
-                        <th>Name</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    <% git_dependencies.each do |dependency| %>
-                        <tr>
-                            <td><%= dependency.id %></td>
-                            <td><%= dependency.class %></td>
-                            <td><%= dependency.to_s %></td>
-                        </tr>
-                    <% end %>
-                </tbody>
-            </table>
+            <div class="table-responsive">
+              <table class="<%= table_classes %>">
+                  <thead>
+                      <tr>
+                          <th>Id</th>
+                          <th>Class</th>
+                          <th>Name</th>
+                      </tr>
+                  </thead>
+                  <tbody>
+                      <% git_dependencies.each do |dependency| %>
+                          <tr>
+                              <td><%= dependency.id %></td>
+                              <td><%= dependency.class %></td>
+                              <td><%= dependency.to_s %></td>
+                          </tr>
+                      <% end %>
+                  </tbody>
+              </table>
+            </div>
 
             <h2 class="h5 mt-5">active_storage_blobs</h2>
-            <table class="table">
-                <thead>
-                    <tr>
-                        <th>Id</th>
-                        <th>Filename</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    <% active_storage_blobs.each do |blob| %>
-                        <tr>
-                            <td><%= blob.id %></td>
-                            <td><%= blob.filename %></td>
-                        </tr>
-                    <% end %>
-                </tbody>
-            </table>
+            <div class="table-responsive">
+              <table class="<%= table_classes %>">
+                  <thead>
+                      <tr>
+                          <th>Id</th>
+                          <th>Filename</th>
+                      </tr>
+                  </thead>
+                  <tbody>
+                      <% active_storage_blobs.each do |blob| %>
+                          <tr>
+                              <td><%= blob.id %></td>
+                              <td><%= blob.filename %></td>
+                          </tr>
+                      <% end %>
+                  </tbody>
+              </table>
+            </div>
         </div>
     </div>
-<% end %>
\ No newline at end of file
+<% end %>
diff --git a/app/views/admin/application/_nav.html.erb b/app/views/admin/application/_nav.html.erb
index 147fc55253291a3f90850521a67cb1186fffc187..a3287598e602b741f480f752dc3a7201ad785cd1 100644
--- a/app/views/admin/application/_nav.html.erb
+++ b/app/views/admin/application/_nav.html.erb
@@ -1,5 +1,5 @@
 <% if current_user.can_display_global_menu? %>
-  <nav id="sidebar" class="sidebar<%= ' collapsed' if @menu_collapsed %>">
+  <nav id="sidebar" class="sidebar" <%= 'data-auto-collapsed' if @menu_collapsed %>>
     <div class="sidebar-content js-simplebar">
       <%= link_to admin_root_path, class: 'sidebar-brand' do %>
         <%= image_tag 'osuny-white.svg', class: 'img-fluid' %>
diff --git a/app/views/admin/communication/blocks/components/person/_edit.html.erb b/app/views/admin/communication/blocks/components/person/_edit.html.erb
index 679a74a4382d3530e09c1e8decc367a591f7b4e0..33c7acb4adcb78e50925d78773f924057d5bbb95 100644
--- a/app/views/admin/communication/blocks/components/person/_edit.html.erb
+++ b/app/views/admin/communication/blocks/components/person/_edit.html.erb
@@ -1,10 +1,12 @@
 <%
 people = current_university.people.ordered
 %>
-<label  class="form-label"
-        :for="<%= dom_id.html_safe %>">
-  <%= label %>
-</label>
+<% unless label.blank? %>
+  <label  class="form-label"
+          :for="<%= dom_id.html_safe %>">
+    <%= label %>
+  </label>
+<% end %>
 <select :id="<%= dom_id.html_safe %>"
         class="form-select select mb-3"
         v-model="<%= model %>.<%= property %>">
diff --git a/app/views/admin/communication/blocks/components/string/_edit.html.erb b/app/views/admin/communication/blocks/components/string/_edit.html.erb
index 9175fe2c8285bc98efc2445554f5d8ad16d75f41..9dc947a2be0bce3ef6d64f9853a8924b1de8832b 100644
--- a/app/views/admin/communication/blocks/components/string/_edit.html.erb
+++ b/app/views/admin/communication/blocks/components/string/_edit.html.erb
@@ -1,9 +1,11 @@
 <div class="mb-3">
-  <label  class="form-label" 
-          aria-label="<%= label %>"
-          :for="<%= dom_id.html_safe %>">
-    <%= label%>
-  </label>
+  <% unless label.blank? %>
+    <label  class="form-label" 
+            aria-label="<%= label %>"
+            :for="<%= dom_id.html_safe %>">
+      <%= label%>
+    </label>
+  <% end %>
   <input  :id="<%= dom_id.html_safe %>"
           class="form-control"
           v-model="<%= model %>.<%= property %>"
diff --git a/app/views/admin/communication/blocks/templates/contact/_preview.html.erb b/app/views/admin/communication/blocks/templates/contact/_preview.html.erb
index 579b9f6d22b5581c9ab0d68d43c9711a4076d050..5bd5fe34344bc90912b83fe2d2347fa26b9fc65b 100644
--- a/app/views/admin/communication/blocks/templates/contact/_preview.html.erb
+++ b/app/views/admin/communication/blocks/templates/contact/_preview.html.erb
@@ -8,12 +8,14 @@
   <%= block_component_preview :city %>
   <%= block_component_preview :country %>
 </p>
-<table class="table">
-<% @block.template.elements.each do |element| %>
-    <tr>
-        <td><%= block_component_preview :title, template: element %></td>
-        <td><%= block_component_preview :time_slot_morning, template: element %></td>
-        <td><%= block_component_preview :time_slot_afternoon, template: element %></td>
-    </tr>
-<% end %>
-</table>
\ No newline at end of file
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <% @block.template.elements.each do |element| %>
+      <tr>
+          <td><%= block_component_preview :title, template: element %></td>
+          <td><%= block_component_preview :time_slot_morning, template: element %></td>
+          <td><%= block_component_preview :time_slot_afternoon, template: element %></td>
+      </tr>
+    <% end %>
+  </table>
+</div>
diff --git a/app/views/admin/communication/blocks/templates/datatable/_preview.html.erb b/app/views/admin/communication/blocks/templates/datatable/_preview.html.erb
index 8b60311edd586990d2784fea40df45f7c3326ed1..8ae4ebc8c1c46bd2cfd5cfa89edb3ccbac6db340 100644
--- a/app/views/admin/communication/blocks/templates/datatable/_preview.html.erb
+++ b/app/views/admin/communication/blocks/templates/datatable/_preview.html.erb
@@ -1,6 +1,6 @@
 <div class="table-responsive">
   <caption><%= block_component_preview :caption %></caption>
-  <table class="table">
+  <table class="<%= table_classes %>">
     <thead>
       <tr>
         <%= block_component_preview :columns %>
diff --git a/app/views/admin/communication/blocks/templates/organization_chart/_edit.html.erb b/app/views/admin/communication/blocks/templates/organization_chart/_edit.html.erb
index 6f6e48d65f2d8cdad385c0974cf1fae32cfc64a2..3caeb14fb9f7bdc47a8750099aa15695c162a482 100644
--- a/app/views/admin/communication/blocks/templates/organization_chart/_edit.html.erb
+++ b/app/views/admin/communication/blocks/templates/organization_chart/_edit.html.erb
@@ -6,12 +6,11 @@
     <label class="form-label">&nbsp;</label>
     <%= block_component_edit :with_link %>
     <%= block_component_edit :with_photo %>
+    <%= block_component_edit :alphabetical %>
   </div>
 </div>
 
-<%= block_component_add_element t('.add_person') %>
-
-<draggable :list="data.elements" class="list-group" handle=".dragHandle">
+<draggable :list="data.elements" class="list-group mb-3" handle=".dragHandle">
   <div v-for="(element, index) in data.elements" class="list-group-item">
     <div class="d-flex">
       <div>
@@ -22,10 +21,10 @@
       <div class="flex-fill">
         <div class="row mb-n3">
           <div class="col-md-6">
-            <%= block_component_edit :id, template: @element %>
+            <%= block_component_edit :id, template: @element, label: '' %>
           </div>
           <div class="col-md-6">
-            <%= block_component_edit :role, template: @element %>
+            <%= block_component_edit :role, template: @element, label: '' %>
           </div>
         </div>
       </div>
@@ -39,3 +38,5 @@
     </div>
   </div>
 </draggable>
+
+<%= block_component_add_element t('.add_person') %>
\ No newline at end of file
diff --git a/app/views/admin/communication/blocks/templates/partners/_edit.html.erb b/app/views/admin/communication/blocks/templates/partners/_edit.html.erb
index 4741592e62edaece279adecaaa6057f63ee75c4a..57d9dd110f8592e7f27eadc46811171553c8a115 100644
--- a/app/views/admin/communication/blocks/templates/partners/_edit.html.erb
+++ b/app/views/admin/communication/blocks/templates/partners/_edit.html.erb
@@ -2,9 +2,13 @@
   <div class="col-xl-6">
     <%= block_component_edit :description %>
   </div>
+  <div class="col-xl-6">
+    <label class="form-label">&nbsp;</label>
+    <%= block_component_edit :with_link %>
+    <%= block_component_edit :alphabetical %>
+  </div>
 </div>
-<%= block_component_add_element t('.add_partner') %>
-<draggable :list="data.elements" class="list-group" handle=".partnerHandle">
+<draggable :list="data.elements" class="list-group mb-3" handle=".partnerHandle">
   <div v-for="(element, index) in data.elements" class="list-group-item">
     <div class="d-flex mb-n3">
       <div>
@@ -13,19 +17,15 @@
         </a>
       </div>
       <div class="flex-fill">
-        <div class="row">
-         <div class="col-lg-4">
-           <%= block_component_edit :id, template: @element, label: '' %>
-          </div>
-        </div>
+        <%= block_component_edit :id, template: @element, label: '' %>
         <div class="row"  v-if="!element.id">
-          <div class="col-lg-4">
+          <div class="col-xl-4 col-md-6">
             <%= block_component_edit :name, template: @element %>
           </div>
-          <div class="col-lg-4">
+          <div class="col-xl-4 col-md-6">
             <%= block_component_edit :url, template: @element %>
           </div>
-          <div class="col-lg-4">
+          <div class="col-xl-4 col-md-6">
             <%= block_component_edit :logo, template: @element %>
           </div>
         </div>
@@ -40,3 +40,4 @@
     </div>
   </div>
 </draggable>
+<%= block_component_add_element t('.add_partner') %>
diff --git a/app/views/admin/communication/blocks/templates/partners/_static.html.erb b/app/views/admin/communication/blocks/templates/partners/_static.html.erb
index 86b6271bc18373ecd2231b63789dec50a88998f5..163c5ee2dc6e27c257e4fb74f38a29ac7fc8c7a3 100644
--- a/app/views/admin/communication/blocks/templates/partners/_static.html.erb
+++ b/app/views/admin/communication/blocks/templates/partners/_static.html.erb
@@ -1,6 +1,8 @@
 <%= block_component_static :description %>
+<%= block_component_static :with_link %>
       partners:
 <% block.template.elements.each do |element| %>
+<% next if element.best_name.blank? %>
 <% if element.organization %>
         - slug: "<%= element.organization.slug %>"
 <% else %>
diff --git a/app/views/admin/communication/extranets/_form.html.erb b/app/views/admin/communication/extranets/_form.html.erb
index 0f75c225c965a8915f72fea1943b72003c36426e..db051c124f6adb141133f2d9c95cdd39caa99093 100644
--- a/app/views/admin/communication/extranets/_form.html.erb
+++ b/app/views/admin/communication/extranets/_form.html.erb
@@ -3,22 +3,21 @@
   <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
 
   <div class="row">
-    <div class="col-md-4">
+    <div class="col-md-6">
       <div class="card flex-fill w-100">
         <div class="card-header">
           <h5 class="card-title mb-0"><%= t('metadata') %></h5>
         </div>
         <div class="card-body">
           <%= f.input :name %>
-          <%= f.input :domain %>
+          <%= f.input :host %>
           <%= render 'admin/communication/abouts', f: f, i18n_key: 'activerecord.attributes.communication/extranet.about_' %>
+          <%= f.input :registration_contact %>
         </div>
       </div>
-    </div>
-    <div class="col-md-4">
       <div class="card flex-fill w-100">
         <div class="card-header">
-          <h5 class="card-title mb-0"><%= t('logo') %></h5>
+          <h5 class="card-title mb-0"><%= t('look_feel') %></h5>
         </div>
         <div class="card-body">
           <%= f.input :logo,
@@ -26,10 +25,41 @@
                       input_html: { accept: '.jpg,.jpeg,.png,.svg' },
                       preview: 200,
                       direct_upload: true %>
+          <%= f.input :color, as: :color %>
+        </div>
+      </div>
+    </div>
+    <div class="col-md-6">
+      <div class="card flex-fill w-100">
+        <div class="card-header">
+          <h5 class="card-title mb-0"><%= t('legal') %></h5>
+        </div>
+        <div class="card-body">
+          <%= f.input :terms, as: :summernote %>
+          <%= f.input :privacy_policy, as: :summernote %>
+          <%= f.input :cookies_policy, as: :summernote %>
         </div>
       </div>
     </div>
   </div>
+
+  <h3 class="mt-5"><%= t('university.sso') %></h3>
+  <div class="row">
+    <div class="col-md-6">
+      <%= f.input :has_sso %>
+      <div class="sso-inputs">
+        <%= f.input :sso_target_url, required: true %>
+        <%= f.input :sso_cert, required: true %>
+        <%= f.input :sso_name_identifier_format, required: true %>
+      </div>
+    </div>
+    <div class="col-md-6 sso-inputs">
+      <h4 class="mb-4"><%= University.human_attribute_name('sso_mapping') %></h4>
+      <%= f.error_notification message: f.object.errors[:sso_mapping].to_sentence if f.object.errors[:sso_mapping].present? %>
+      <%= render 'server/universities/sso_mapping', object: extranet %>
+    </div>
+  </div>
+
   <% content_for :action_bar_right do %>
     <%= submit f %>
   <% end %>
diff --git a/app/views/admin/communication/extranets/index.html.erb b/app/views/admin/communication/extranets/index.html.erb
index c0af0e6dab7d5aef15035bb07073dcbea050716e..1bf5f27a35356b4b25018dfe6744bee1cafbcc10 100644
--- a/app/views/admin/communication/extranets/index.html.erb
+++ b/app/views/admin/communication/extranets/index.html.erb
@@ -2,33 +2,35 @@
 
 <%= render 'filters', current_path: admin_communication_extranets_path, filters: @filters if @filters.any?  %>
 
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Communication::Extranet.human_attribute_name('name') %></th>
-      <th><%= Communication::Extranet.human_attribute_name('domain') %></th>
-      <th><%= Communication::Extranet.human_attribute_name('about_type') %></th>
-      <th><%= Communication::Extranet.human_attribute_name('about') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @extranets.each do |extranet| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to extranet, [:admin, extranet] %></td>
-        <td><%= link_to extranet.url, extranet.url, target: :_blank unless extranet.url.blank? %></td>
-        <td><%= I18n.t("activerecord.attributes.communication/extranet.about_#{extranet.about_type}") %></td>
-        <td><%= link_to extranet.about, [:admin, extranet.about] if extranet.about %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link extranet %>
-            <%= destroy_link extranet %>
-          </div>
-        </td>
+        <th><%= Communication::Extranet.human_attribute_name('name') %></th>
+        <th><%= Communication::Extranet.human_attribute_name('domain') %></th>
+        <th><%= Communication::Extranet.human_attribute_name('about_type') %></th>
+        <th><%= Communication::Extranet.human_attribute_name('about') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @extranets.each do |extranet| %>
+        <tr>
+          <td><%= link_to extranet, [:admin, extranet] %></td>
+          <td><%= link_to extranet.url, extranet.url, target: :_blank unless extranet.url.blank? %></td>
+          <td><%= I18n.t("activerecord.attributes.communication/extranet.about_#{extranet.about_type}") %></td>
+          <td><%= link_to extranet.about, [:admin, extranet.about] if extranet.about %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link extranet %>
+              <%= destroy_link extranet %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <%= paginate @extranets, theme: 'bootstrap-5' %>
 
diff --git a/app/views/admin/communication/websites/_form.html.erb b/app/views/admin/communication/websites/_form.html.erb
index 9484c19f183c12611641295474bc4438b8f33d2a..64f4e94841aabadb904dd2c0cd20fc2af4c664cc 100644
--- a/app/views/admin/communication/websites/_form.html.erb
+++ b/app/views/admin/communication/websites/_form.html.erb
@@ -13,6 +13,7 @@
           <%= f.input :url %>
           <%= render 'admin/communication/abouts', f: f, i18n_key: 'activerecord.attributes.communication/website.about_' %>
           <%= f.association :languages, as: :check_boxes %>
+          <%= f.input :in_production %>
         </div>
       </div>
     </div>
@@ -25,11 +26,12 @@
           <div class="row">
             <div class="col-md-6">
               <%= f.input :git_provider, include_blank: false %>
+              <%= f.input :git_endpoint %>
             </div>
             <div class="col-md-6">
-              <%= f.input :git_endpoint %>
               <%= f.input :access_token %>
               <%= f.input :repository %>
+              <%= f.input :git_branch %>
             </div>
           </div>
         </div>
diff --git a/app/views/admin/communication/websites/authors/_list.html.erb b/app/views/admin/communication/websites/authors/_list.html.erb
index 9914ed4f9f215e351cd8eb34b44749bbe0236c74..17348cbf0747ea5f56952d000b4a7ca483c08303 100644
--- a/app/views/admin/communication/websites/authors/_list.html.erb
+++ b/app/views/admin/communication/websites/authors/_list.html.erb
@@ -1,18 +1,20 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= University::Person.human_attribute_name('last_name') %></th>
-      <th><%= University::Person.human_attribute_name('first_name') %></th>
-      <th><%= t('communication.number_of_posts') %></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% authors.each do |author| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to author.last_name, admin_communication_website_author_path(website_id: @website.id, id: author.id) %></td>
-        <td><%= link_to author.first_name, admin_communication_website_author_path(website_id: @website.id, id: author.id) %></td>
-        <td><%= author.communication_website_posts.count %></td>
+        <th><%= University::Person.human_attribute_name('last_name') %></th>
+        <th><%= University::Person.human_attribute_name('first_name') %></th>
+        <th><%= t('communication.number_of_posts') %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% authors.each do |author| %>
+        <tr>
+          <td><%= link_to author.last_name, admin_communication_website_author_path(website_id: @website.id, id: author.id) %></td>
+          <td><%= link_to author.first_name, admin_communication_website_author_path(website_id: @website.id, id: author.id) %></td>
+          <td><%= author.communication_website_posts.count %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/communication/websites/categories/_list.html.erb b/app/views/admin/communication/websites/categories/_list.html.erb
index 25e053ef79540d24892f9c2bac35450cfc1b35ee..fb3df450a7401851ca209d8820a5076f25d9786b 100644
--- a/app/views/admin/communication/websites/categories/_list.html.erb
+++ b/app/views/admin/communication/websites/categories/_list.html.erb
@@ -1,27 +1,29 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Communication::Website::Category.human_attribute_name('title') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% categories.each do |category| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to category, admin_communication_website_category_path(website_id: category.website.id, id: category.id) %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                      edit_admin_communication_website_category_path(website_id: category.website.id, id: category.id),
-                      class: button_classes if can?(:update, category) %>
-            <%= link_to t('delete'),
-                      admin_communication_website_category_path(website_id: category.website.id, id: category.id),
-                      method: :delete,
-                      data: { confirm: t('please_confirm') },
-                      class: button_classes_danger if can?(:destroy, category) %>
-          </div>
-        </td>
+        <th><%= Communication::Website::Category.human_attribute_name('title') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% categories.each do |category| %>
+        <tr>
+          <td><%= link_to category, admin_communication_website_category_path(website_id: category.website.id, id: category.id) %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                        edit_admin_communication_website_category_path(website_id: category.website.id, id: category.id),
+                        class: button_classes if can?(:update, category) %>
+              <%= link_to t('delete'),
+                        admin_communication_website_category_path(website_id: category.website.id, id: category.id),
+                        method: :delete,
+                        data: { confirm: t('please_confirm') },
+                        class: button_classes_danger if can?(:destroy, category) %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/communication/websites/import.html.erb b/app/views/admin/communication/websites/import.html.erb
index 16acd2448050405bc4c12eb57e16942f08334a91..e40e2665d503ab01a38c6c80c396eb177df00019 100644
--- a/app/views/admin/communication/websites/import.html.erb
+++ b/app/views/admin/communication/websites/import.html.erb
@@ -10,28 +10,30 @@
   <div class="card-header">
     <h2><%= @imported_posts.total_count %> posts</h2>
   </div>
-  <table class="<%= table_classes %>">
-    <thead>
-      <tr>
-        <th><%= Communication::Website::Imported::Post.human_attribute_name('title') %></th>
-        <th><%= Communication::Website::Imported::Post.human_attribute_name('original') %></th>
-        <th class="text-end" width="150">Generated post</th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @imported_posts.each do |post| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td><%= post %></td>
-          <td class="small"><%= link_to post.path, post.url, target: :_blank %></td>
-          <td class="text-end">
-            <%= link_to t('show'),
-                          admin_communication_website_post_path(website_id: @website.id, id: post.post.id),
-                          class: button_classes if post.post.present? %>
-          </td>
+          <th><%= Communication::Website::Imported::Post.human_attribute_name('title') %></th>
+          <th><%= Communication::Website::Imported::Post.human_attribute_name('original') %></th>
+          <th class="text-end" width="150">Generated post</th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @imported_posts.each do |post| %>
+          <tr>
+            <td><%= post %></td>
+            <td class="small"><%= link_to post.path, post.url, target: :_blank %></td>
+            <td class="text-end">
+              <%= link_to t('show'),
+                            admin_communication_website_post_path(website_id: @website.id, id: post.post.id),
+                            class: button_classes if post.post.present? %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
   <div class="card-footer">
     <%= paginate @imported_posts, param_name: :posts_page, theme: 'bootstrap-5' %>
   </div>
@@ -41,28 +43,30 @@
   <div class="card-header">
     <h2><%= @imported_pages.total_count %> pages</h2>
   </div>
-  <table class="<%= table_classes %>">
-    <thead>
-      <tr>
-        <th><%= Communication::Website::Imported::Page.human_attribute_name('title') %></th>
-        <th><%= Communication::Website::Imported::Page.human_attribute_name('original') %></th>
-        <th class="text-end" width="150">Generated page</th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @imported_pages.each do |page| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td><%= page %></td>
-          <td class="small"><%= link_to page.path, page.url, target: :_blank %></td>
-          <td class="text-end">
-            <%= link_to t('show'),
-                          admin_communication_website_page_path(website_id: @website.id, id: page.page.id),
-                          class: button_classes if page.page.present? %>
-          </td>
+          <th><%= Communication::Website::Imported::Page.human_attribute_name('title') %></th>
+          <th><%= Communication::Website::Imported::Page.human_attribute_name('original') %></th>
+          <th class="text-end" width="150">Generated page</th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @imported_pages.each do |page| %>
+          <tr>
+            <td><%= page %></td>
+            <td class="small"><%= link_to page.path, page.url, target: :_blank %></td>
+            <td class="text-end">
+              <%= link_to t('show'),
+                            admin_communication_website_page_path(website_id: @website.id, id: page.page.id),
+                            class: button_classes if page.page.present? %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
   <div class="card-footer">
     <%= paginate @imported_pages, param_name: :pages_page, theme: 'bootstrap-5' %>
   </div>
@@ -72,33 +76,35 @@
   <div class="card-header">
     <h2><%= @imported_media.total_count %> media (<%= number_to_human_size(@imported_media_total_size) %>)</h2>
   </div>
-  <table class="<%= table_classes %>">
-    <thead>
-      <tr>
-        <th><%= Communication::Website::Imported::Medium.human_attribute_name('filename') %></th>
-        <th><%= t('communication.website.imported.media.file_size') %></th>
-        <th class="text-end" width="150">&nbsp;</th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @imported_media.each do |medium| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td><%= medium.filename %></td>
-          <td><%= number_to_human_size(medium.file.blob.byte_size) if medium&.file&.attached? %></td>
-          <td class="text-end">
-            <% if medium&.file&.attached? %>
-              <%= link_to t('show'),
-                            url_for(medium.file),
-                            class: button_classes,
-                            target: :blank %>
-            <% else %>
-              <%= t('communication.website.imported.media.not_imported_yet') %>
-            <% end %>
-          </td>
+          <th><%= Communication::Website::Imported::Medium.human_attribute_name('filename') %></th>
+          <th><%= t('communication.website.imported.media.file_size') %></th>
+          <th class="text-end" width="150">&nbsp;</th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @imported_media.each do |medium| %>
+          <tr>
+            <td><%= medium.filename %></td>
+            <td><%= number_to_human_size(medium.file.blob.byte_size) if medium&.file&.attached? %></td>
+            <td class="text-end">
+              <% if medium&.file&.attached? %>
+                <%= link_to t('show'),
+                              url_for(medium.file),
+                              class: button_classes,
+                              target: :blank %>
+              <% else %>
+                <%= t('communication.website.imported.media.not_imported_yet') %>
+              <% end %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
   <div class="card-footer">
     <%= paginate @imported_media, param_name: :media_page, theme: 'bootstrap-5' %>
   </div>
@@ -108,26 +114,28 @@
   <div class="card-header">
     <h2><%= @imported_authors.total_count %> authors</h2>
   </div>
-  <table class="<%= table_classes %>">
-    <thead>
-      <tr>
-        <th><%= University::Person.human_attribute_name('name') %></th>
-        <th class="text-end" width="150">&nbsp;</th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @imported_authors.each do |author| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td><%= author.name %></td>
-          <td class="text-end">
-            <%= link_to t('show'),
-                          admin_communication_website_author_path(website_id: @website.id, id: author.author.id),
-                          class: button_classes %>
-          </td>
+          <th><%= University::Person.human_attribute_name('name') %></th>
+          <th class="text-end" width="150">&nbsp;</th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @imported_authors.each do |author| %>
+          <tr>
+            <td><%= author.name %></td>
+            <td class="text-end">
+              <%= link_to t('show'),
+                            admin_communication_website_author_path(website_id: @website.id, id: author.author.id),
+                            class: button_classes %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
   <div class="card-footer">
     <%= paginate @imported_authors, param_name: :authors_page, theme: 'bootstrap-5' %>
   </div>
@@ -137,26 +145,28 @@
   <div class="card-header">
     <h2><%= @imported_categories.count %> categories</h2>
   </div>
-  <table class="<%= table_classes %>">
-    <thead>
-      <tr>
-        <th><%= Communication::Website::Category.human_attribute_name('name') %></th>
-        <th><%= Communication::Website::Imported::Category.human_attribute_name('original') %></th>
-        <th class="text-end" width="150">&nbsp;</th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @imported_categories.each do |category| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td><%= category.name %></td>
-          <td class="small"><%= link_to category.url, category.url, target: :_blank %></td>
-          <td class="text-end">
-            <%= link_to t('show'),
-                          admin_communication_website_category_path(website_id: @website.id, id: category.category.id),
-                          class: button_classes %>
-          </td>
+          <th><%= Communication::Website::Category.human_attribute_name('name') %></th>
+          <th><%= Communication::Website::Imported::Category.human_attribute_name('original') %></th>
+          <th class="text-end" width="150">&nbsp;</th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @imported_categories.each do |category| %>
+          <tr>
+            <td><%= category.name %></td>
+            <td class="small"><%= link_to category.url, category.url, target: :_blank %></td>
+            <td class="text-end">
+              <%= link_to t('show'),
+                            admin_communication_website_category_path(website_id: @website.id, id: category.category.id),
+                            class: button_classes %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
 </div>
diff --git a/app/views/admin/communication/websites/index.html.erb b/app/views/admin/communication/websites/index.html.erb
index 612fd9ba2c070b94aeb5289c25545b6ce12176a8..44dc1b675df84f808d8a17d21006d42658d09551 100644
--- a/app/views/admin/communication/websites/index.html.erb
+++ b/app/views/admin/communication/websites/index.html.erb
@@ -2,33 +2,35 @@
 
 <%= render 'filters', current_path: admin_communication_websites_path, filters: @filters if @filters.any?  %>
 
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Communication::Website.human_attribute_name('name') %></th>
-      <th><%= Communication::Website.human_attribute_name('url') %></th>
-      <th><%= Communication::Website.human_attribute_name('about_type') %></th>
-      <th><%= Communication::Website.human_attribute_name('about') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @websites.each do |website| %>
-    <tr>
-      <td><%= link_to website, [:admin, website] %></td>
-      <td><%= link_to website.url, website.url, target: :_blank unless website.url.blank? %></td>
-      <td><%= I18n.t("activerecord.attributes.communication/website.about_#{website.about_type}") %></td>
-      <td><%= link_to_if can?(:read, website.about), website.about, [:admin, website.about] if website.about %></td>
-      <td class="text-end">
-        <div class="btn-group" role="group">
-          <%= edit_link website %>
-          <%= destroy_link website %>
-        </div>
-      </td>
-    </tr>
-    <% end %>
-  </tbody>
-</table>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
+      <tr>
+        <th><%= Communication::Website.human_attribute_name('name') %></th>
+        <th><%= Communication::Website.human_attribute_name('url') %></th>
+        <th><%= Communication::Website.human_attribute_name('about_type') %></th>
+        <th><%= Communication::Website.human_attribute_name('about') %></th>
+        <th></th>
+      </tr>
+    </thead>
+    <tbody>
+      <% @websites.each do |website| %>
+      <tr>
+        <td><%= link_to website, [:admin, website] %></td>
+        <td><%= link_to website.url, website.url, target: :_blank unless website.url.blank? %></td>
+        <td><%= I18n.t("activerecord.attributes.communication/website.about_#{website.about_type}") %></td>
+        <td><%= link_to_if can?(:read, website.about), website.about, [:admin, website.about] if website.about %></td>
+        <td class="text-end">
+          <div class="btn-group" role="group">
+            <%= edit_link website %>
+            <%= destroy_link website %>
+          </div>
+        </td>
+      </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <%= paginate @websites, theme: 'bootstrap-5' %>
 
diff --git a/app/views/admin/communication/websites/menus/_list.html.erb b/app/views/admin/communication/websites/menus/_list.html.erb
index ed9f453b643d1cbb0abab554020825022e6ab5d0..28058373ffd712d6b5cdabdbca9ea1ab71133d27 100644
--- a/app/views/admin/communication/websites/menus/_list.html.erb
+++ b/app/views/admin/communication/websites/menus/_list.html.erb
@@ -1,29 +1,31 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Communication::Website::Menu.human_attribute_name('title') %></th>
-      <th><%= Communication::Website::Menu.human_attribute_name('items') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% menus.each do |menu| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to menu, admin_communication_website_menu_path(website_id: menu.website.id, id: menu.id) %></td>
-        <td><%= menu.items.count %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                      edit_admin_communication_website_menu_path(website_id: menu.website.id, id: menu.id),
-                      class: button_classes if can?(:update, menu) %>
-            <%= link_to t('delete'),
-                      admin_communication_website_menu_path(website_id: menu.website.id, id: menu.id),
-                      method: :delete,
-                      data: { confirm: t('please_confirm') },
-                      class: button_classes_danger if can?(:destroy, menu) %>
-          </div>
-        </td>
+        <th><%= Communication::Website::Menu.human_attribute_name('title') %></th>
+        <th><%= Communication::Website::Menu.human_attribute_name('items') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% menus.each do |menu| %>
+        <tr>
+          <td><%= link_to menu, admin_communication_website_menu_path(website_id: menu.website.id, id: menu.id) %></td>
+          <td><%= menu.items.count %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                        edit_admin_communication_website_menu_path(website_id: menu.website.id, id: menu.id),
+                        class: button_classes if can?(:update, menu) %>
+              <%= link_to t('delete'),
+                        admin_communication_website_menu_path(website_id: menu.website.id, id: menu.id),
+                        method: :delete,
+                        data: { confirm: t('please_confirm') },
+                        class: button_classes_danger if can?(:destroy, menu) %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/communication/websites/pages/_list.html.erb b/app/views/admin/communication/websites/pages/_list.html.erb
index 02f3cb6539c7fbe5f47ca48b83ca754d5ac68356..222f250462b44b020cd100c431674ec3704648ac 100644
--- a/app/views/admin/communication/websites/pages/_list.html.erb
+++ b/app/views/admin/communication/websites/pages/_list.html.erb
@@ -1,31 +1,33 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Communication::Website::Page.human_attribute_name('title') %></th>
-      <th width="150"></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% pages.each do |page| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td>
-          <%= link_to page,
-                      admin_communication_website_page_path(website_id: page.website.id, id: page.id),
-                      class: "#{'draft' unless page.published?}" %>
-        </td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                      edit_admin_communication_website_page_path(website_id: page.website.id, id: page.id),
-                      class: button_classes if can?(:update, page) %>
-            <%= link_to t('delete'),
-                      admin_communication_website_page_path(website_id: page.website.id, id: page.id),
-                      method: :delete,
-                      data: { confirm: page.children.any? ? t('please_confirm_with_children') : t('please_confirm') },
-                      class: button_classes_danger if can?(:destroy, page) && !page.is_special_page? %>
-          </div>
-        </td>
+        <th><%= Communication::Website::Page.human_attribute_name('title') %></th>
+        <th width="150"></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% pages.each do |page| %>
+        <tr>
+          <td>
+            <%= link_to page,
+                        admin_communication_website_page_path(website_id: page.website.id, id: page.id),
+                        class: "#{'draft' unless page.published?}" %>
+          </td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                        edit_admin_communication_website_page_path(website_id: page.website.id, id: page.id),
+                        class: button_classes if can?(:update, page) %>
+              <%= link_to t('delete'),
+                        admin_communication_website_page_path(website_id: page.website.id, id: page.id),
+                        method: :delete,
+                        data: { confirm: page.children.any? ? t('please_confirm_with_children') : t('please_confirm') },
+                        class: button_classes_danger if can?(:destroy, page) && !page.is_special_page? %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/communication/websites/posts/_list.html.erb b/app/views/admin/communication/websites/posts/_list.html.erb
index 7f9ded101fc4186c91da502a5344b7c8fea9a4d0..bc30187722ff808aaefe4b83588f728a1b3d74a0 100644
--- a/app/views/admin/communication/websites/posts/_list.html.erb
+++ b/app/views/admin/communication/websites/posts/_list.html.erb
@@ -4,71 +4,73 @@
   selectable |= false
 %>
 <% if selectable %>
-<input type="hidden" name="ids[]" value="">
+  <input type="hidden" name="ids[]" value="">
 <% end %>
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <% if selectable %>
-        <th>
-          <%= check_box_tag nil, nil, false, data: { batch_selectable_role: "select-all" } %>
-        </th>
-      <% end %>
-      <th><%= Communication::Website::Post.human_attribute_name('title') %></th>
-      <th><%= Communication::Website::Post.human_attribute_name('featured_image') %></th>
-      <% unless hide_author %>
-        <th><%= Communication::Website::Post.human_attribute_name('author') %></th>
-      <% end %>
-      <% unless hide_category %>
-        <th><%= Communication::Website::Post.human_attribute_name('categories') %></th>
-      <% end %>
-      <th colspan="2"><%= Communication::Website::Post.human_attribute_name('published_at') %></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% posts.each do |post| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
         <% if selectable %>
-          <td>
-            <%= check_box_tag "ids[]", post.id, false, data: { batch_selectable_role: "select-single" } %>
-          </td>
+          <th>
+            <%= check_box_tag nil, nil, false, data: { batch_selectable_role: "select-all" } %>
+          </th>
         <% end %>
-        <td><%= link_to post,
-                        admin_communication_website_post_path(website_id: post.website.id, id: post.id),
-                        class: "#{'draft' unless post.published?}" %></td>
-        <td><%= image_tag post.featured_image.representation(resize: 'x100'),
-                          height: 50 if post.featured_image.attached? && post.featured_image.representable? %></td>
+        <th><%= Communication::Website::Post.human_attribute_name('title') %></th>
+        <th><%= Communication::Website::Post.human_attribute_name('featured_image') %></th>
         <% unless hide_author %>
-          <td><%= link_to post.author, admin_communication_website_author_path(website_id: post.website.id, id: post.author.id) if post.author %></td>
+          <th><%= Communication::Website::Post.human_attribute_name('author') %></th>
         <% end %>
         <% unless hide_category %>
-          <td>
-            <ul class="list-unstyled mb-0">
-              <% post.categories.each do |category| %>
-                <li><%= link_to_if can?(:read, category), category, admin_communication_website_category_path(website_id: post.website.id, id: category.id) %></li>
-              <% end %>
-            </ul>
-          </td>
+          <th><%= Communication::Website::Post.human_attribute_name('categories') %></th>
         <% end %>
-        <td>
-          <%= l post.published_at, format: :date_with_explicit_month if post.published_at %>
-          <% if post.pinned %>
-            <span class="badge bg-success"><%= Communication::Website::Post.human_attribute_name('pinned') %></span>
-          <% end %>
-        </td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                        edit_admin_communication_website_post_path(website_id: post.website.id, id: post.id),
-                        class: button_classes if can?(:update, post) %>
-            <%= link_to t('delete'),
-                        admin_communication_website_post_path(website_id: post.website.id, id: post.id),
-                        method: :delete,
-                        data: { confirm: t('please_confirm') },
-                        class: button_classes_danger if can?(:destroy, post) %>
-          </div>
-        </td>
+        <th colspan="2"><%= Communication::Website::Post.human_attribute_name('published_at') %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% posts.each do |post| %>
+        <tr>
+          <% if selectable %>
+            <td>
+              <%= check_box_tag "ids[]", post.id, false, data: { batch_selectable_role: "select-single" } %>
+            </td>
+          <% end %>
+          <td><%= link_to post,
+                          admin_communication_website_post_path(website_id: post.website.id, id: post.id),
+                          class: "#{'draft' unless post.published?}" %></td>
+          <td><%= image_tag post.featured_image.representation(resize: 'x100'),
+                            height: 50 if post.featured_image.attached? && post.featured_image.representable? %></td>
+          <% unless hide_author %>
+            <td><%= link_to post.author, admin_communication_website_author_path(website_id: post.website.id, id: post.author.id) if post.author %></td>
+          <% end %>
+          <% unless hide_category %>
+            <td>
+              <ul class="list-unstyled mb-0">
+                <% post.categories.each do |category| %>
+                  <li><%= link_to_if can?(:read, category), category, admin_communication_website_category_path(website_id: post.website.id, id: category.id) %></li>
+                <% end %>
+              </ul>
+            </td>
+          <% end %>
+          <td>
+            <%= l post.published_at, format: :date_with_explicit_month if post.published_at %>
+            <% if post.pinned %>
+              <span class="badge bg-success"><%= Communication::Website::Post.human_attribute_name('pinned') %></span>
+            <% end %>
+          </td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_communication_website_post_path(website_id: post.website.id, id: post.id),
+                          class: button_classes if can?(:update, post) %>
+              <%= link_to t('delete'),
+                          admin_communication_website_post_path(website_id: post.website.id, id: post.id),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger if can?(:destroy, post) %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/education/academic_years/_list.html.erb b/app/views/admin/education/academic_years/_list.html.erb
index ab318d9dad3df35d28bc69c287f86a53c1e8f55c..87a40625c2fff1209364b819e11d606b73a7a491 100644
--- a/app/views/admin/education/academic_years/_list.html.erb
+++ b/app/views/admin/education/academic_years/_list.html.erb
@@ -1,20 +1,22 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Education::AcademicYear.human_attribute_name('year') %></th>
-      <th><%= Education::Cohort.model_name.human(count: 2) %></th>
-      <th><%= University::Person::Alumnus.model_name.human(count: 2) %></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% academic_years.ordered.each do |academic_year| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td>
-          <%= link_to academic_year, [:admin, academic_year] %>
-        </td>
-        <td><%= academic_year.cohorts.count %></td>
-        <td><%= academic_year.people.count %></td>
+        <th><%= Education::AcademicYear.human_attribute_name('year') %></th>
+        <th><%= Education::Cohort.model_name.human(count: 2) %></th>
+        <th><%= University::Person::Alumnus.model_name.human(count: 2) %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% academic_years.ordered.each do |academic_year| %>
+        <tr>
+          <td>
+            <%= link_to academic_year, [:admin, academic_year] %>
+          </td>
+          <td><%= academic_year.cohorts.count %></td>
+          <td><%= academic_year.people.count %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/education/cohorts/_list.html.erb b/app/views/admin/education/cohorts/_list.html.erb
index 9f593bd74d8dd545f7fbe6a484bcb84cce7dbab5..43d8908defcb2871c05d9b219e78ca5c7e96b357 100644
--- a/app/views/admin/education/cohorts/_list.html.erb
+++ b/app/views/admin/education/cohorts/_list.html.erb
@@ -1,25 +1,27 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Education::Cohort.human_attribute_name('year') %></th>
-      <th><%= Education::Cohort.human_attribute_name('school') %></th>
-      <th><%= Education::Cohort.human_attribute_name('program') %></th>
-      <th><%= Education::Cohort.human_attribute_name('alumni') %></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% cohorts.ordered.each do |cohort| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td>
-          <%= link_to [:admin, cohort] do %>
-            <%= cohort.academic_year %>
-            <%= cohort.name %>
-          <% end %>
-        </td>
-        <td><%= link_to_if can?(:read, cohort.school), cohort.school, [:admin, cohort.school] %></td>
-        <td><%= link_to_if can?(:read, cohort.program), cohort.program, [:admin, cohort.program] %></td>
-        <td><%= cohort.people.count %></td>
+        <th><%= Education::Cohort.human_attribute_name('year') %></th>
+        <th><%= Education::Cohort.human_attribute_name('school') %></th>
+        <th><%= Education::Cohort.human_attribute_name('program') %></th>
+        <th><%= Education::Cohort.human_attribute_name('alumni') %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% cohorts.ordered.each do |cohort| %>
+        <tr>
+          <td>
+            <%= link_to [:admin, cohort] do %>
+              <%= cohort.academic_year %>
+              <%= cohort.name %>
+            <% end %>
+          </td>
+          <td><%= link_to_if can?(:read, cohort.school), cohort.school, [:admin, cohort.school] %></td>
+          <td><%= link_to_if can?(:read, cohort.program), cohort.program, [:admin, cohort.program] %></td>
+          <td><%= cohort.people.count %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/education/diplomas/_list.html.erb b/app/views/admin/education/diplomas/_list.html.erb
index dd55353b3b6bced66b141dc9a6c66ef18832130f..afc51f7347ed9304537f182cd4278843cdb23063 100644
--- a/app/views/admin/education/diplomas/_list.html.erb
+++ b/app/views/admin/education/diplomas/_list.html.erb
@@ -1,29 +1,31 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Education::Diploma.human_attribute_name('name') %></th>
-      <th><%= Education::Diploma.human_attribute_name('short_name') %></th>
-      <th><%= Education::Diploma.human_attribute_name('ects') %></th>
-      <th><%= Education::Diploma.human_attribute_name('level') %></th>
-      <th><%= Education::Diploma.human_attribute_name('programs') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% diplomas.ordered.each do |diploma| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to diploma, [:admin, diploma] %></td>
-        <td><%= diploma.short_name %></td>
-        <td><%= diploma.ects %></td>
-        <td><%= diploma.level_i18n %></td>
-        <td><%= diploma.programs.count %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link diploma %>
-            <%= destroy_link diploma %>
-          </div>
-        </td>
+        <th><%= Education::Diploma.human_attribute_name('name') %></th>
+        <th><%= Education::Diploma.human_attribute_name('short_name') %></th>
+        <th><%= Education::Diploma.human_attribute_name('ects') %></th>
+        <th><%= Education::Diploma.human_attribute_name('level') %></th>
+        <th><%= Education::Diploma.human_attribute_name('programs') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% diplomas.ordered.each do |diploma| %>
+        <tr>
+          <td><%= link_to diploma, [:admin, diploma] %></td>
+          <td><%= diploma.short_name %></td>
+          <td><%= diploma.ects %></td>
+          <td><%= diploma.level_i18n %></td>
+          <td><%= diploma.programs.count %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link diploma %>
+              <%= destroy_link diploma %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/education/programs/_list.html.erb b/app/views/admin/education/programs/_list.html.erb
index 03e5e3bbd37a13f0c4c25180602309e5cc020178..4d511d9355db2f844d1defc2026fafedaa3b7e40 100644
--- a/app/views/admin/education/programs/_list.html.erb
+++ b/app/views/admin/education/programs/_list.html.erb
@@ -2,49 +2,51 @@
   hide_diploma |= false
   hide_parent |= false
 %>
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Education::Program.human_attribute_name('name') %></th>
-      <% unless hide_diploma %>
-        <th><%= Education::Program.human_attribute_name('diploma') %></th>
-      <% end %>
-      <% unless hide_parent %>
-        <th><%= Education::Program.human_attribute_name('parent') %></th>
-      <% end %>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% programs.each do |program| %>
-      <%
-      parent = program.parent
-      diploma = program.diploma
-      %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to_if  can?(:read, program),
-                            program,
-                            [:admin, program],
-                            class: "#{'draft' unless program.published?}" %></td>
+        <th><%= Education::Program.human_attribute_name('name') %></th>
         <% unless hide_diploma %>
-          <td><%= link_to_if can?(:read, diploma), diploma, [:admin, diploma] if diploma %></td>
+          <th><%= Education::Program.human_attribute_name('diploma') %></th>
         <% end %>
         <% unless hide_parent %>
-          <td><%= link_to_if can?(:read, parent), parent, [:admin, parent] if parent %></td>
+          <th><%= Education::Program.human_attribute_name('parent') %></th>
         <% end %>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                        edit_admin_education_program_path(program),
-                        class: button_classes if can?(:update, program) %>
-            <%= link_to t('delete'),
-                        admin_education_program_path(program),
-                        method: :delete,
-                        data: { confirm: program.children.any? ? t('please_confirm_with_children') : t('please_confirm') },
-                        class: button_classes_danger if can?(:destroy, program) %>
-          </div>
-        </td>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% programs.each do |program| %>
+        <%
+        parent = program.parent
+        diploma = program.diploma
+        %>
+        <tr>
+          <td><%= link_to_if  can?(:read, program),
+                              program,
+                              [:admin, program],
+                              class: "#{'draft' unless program.published?}" %></td>
+          <% unless hide_diploma %>
+            <td><%= link_to_if can?(:read, diploma), diploma, [:admin, diploma] if diploma %></td>
+          <% end %>
+          <% unless hide_parent %>
+            <td><%= link_to_if can?(:read, parent), parent, [:admin, parent] if parent %></td>
+          <% end %>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_education_program_path(program),
+                          class: button_classes if can?(:update, program) %>
+              <%= link_to t('delete'),
+                          admin_education_program_path(program),
+                          method: :delete,
+                          data: { confirm: program.children.any? ? t('please_confirm_with_children') : t('please_confirm') },
+                          class: button_classes_danger if can?(:destroy, program) %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/education/programs/preview.html.erb b/app/views/admin/education/programs/preview.html.erb
index 3db9eab1ef40b45548e74e1827f5a30405d29190..44ced32c00a74e313797584e89903d7c791a0a25 100644
--- a/app/views/admin/education/programs/preview.html.erb
+++ b/app/views/admin/education/programs/preview.html.erb
@@ -17,29 +17,31 @@
         </div>
         <div class="subpart">
           <h3>Informations administratives</h3>
-          <table class="table table-infos">
-            <caption>Informations administratives</caption>
-            <tbody>
-              <% if @program.diploma%>
+          <div class="table-responsive">
+            <table class="<%= table_classes %> table-infos">
+              <caption>Informations administratives</caption>
+              <tbody>
+                <% if @program.diploma%>
+                  <tr>
+                    <th>Crédits ECTS</th>
+                    <td><%= @program.diploma.ects %></td>
+                  </tr>
+                <% end %>
                 <tr>
-                  <th>Crédits ECTS</th>
-                  <td><%= @program.diploma.ects %></td>
+                  <th>Formation initiale</th>
+                  <td><%= t @program.initial %></td>
                 </tr>
-              <% end %>
-              <tr>
-                <th>Formation initiale</th>
-                <td><%= t @program.initial %></td>
-              </tr>
-              <tr>
-                <th>Formation continue</th>
-                <td><%= t @program.continuing %></td>
-              </tr>
-              <tr>
-                <th>Apprentissage</th>
-                <td><%= t @program.apprenticeship %></td>
-              </tr>
-            </tbody>
-          </table>
+                <tr>
+                  <th>Formation continue</th>
+                  <td><%= t @program.continuing %></td>
+                </tr>
+                <tr>
+                  <th>Apprentissage</th>
+                  <td><%= t @program.apprenticeship %></td>
+                </tr>
+              </tbody>
+            </table>
+          </div>
         </div>
       </div>
     </div>
@@ -59,29 +61,31 @@
       <div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('content') %></h3>
-          <%= @program.content %> 
+          <%= @program.content %>
         </div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('pedagogy') %></h3>
-          <%= @program.pedagogy %> 
+          <%= @program.pedagogy %>
         </div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('evaluation') %></h3>
-          <%= @program.evaluation %> 
+          <%= @program.evaluation %>
         </div>
         <div class="subpart">
           <h3>Enseignants·es</h3>
-          <table class="table-persons">
-            <caption>Enseignants·es</caption>
-            <tbody>
-              <% @program.university_person_involvements.each do |involvement| %>
-                <tr>
-                  <th scope="row"><a><%= involvement %></a></th>
-                  <td><%= involvement.description%></td>
-                </tr>
-              <% end %>
-            </tbody>
-          </table>
+          <div class="table-responsive">
+            <table class="table-persons">
+              <caption>Enseignants·es</caption>
+              <tbody>
+                <% @program.university_person_involvements.each do |involvement| %>
+                  <tr>
+                    <th scope="row"><a><%= involvement %></a></th>
+                    <td><%= involvement.description%></td>
+                  </tr>
+                <% end %>
+              </tbody>
+            </table>
+          </div>
         </div>
       </div>
     </div>
@@ -97,9 +101,9 @@
     <div>
     <div class="subpart">
       <h3><%= Education::Program.human_attribute_name('opportunities') %></h3>
-      <%= @program.opportunities %> 
+      <%= @program.opportunities %>
       <h3><%= Education::Program.human_attribute_name('results') %></h3>
-      <%= @program.results %> 
+      <%= @program.results %>
     </div>
   </div>
 </section>
@@ -113,23 +117,23 @@
       <div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('prerequisites') %></h3>
-          <%= @program.prerequisites %> 
+          <%= @program.prerequisites %>
         </div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('pricing') %></h3>
-          <%= @program.pricing %> 
+          <%= @program.pricing %>
         </div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('registration') %></h3>
-          <%= @program.registration %> 
+          <%= @program.registration %>
         </div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('accessibility') %></h3>
-          <%= @program.accessibility %> 
+          <%= @program.accessibility %>
         </div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('other') %></h3>
-          <%= @program.other %> 
+          <%= @program.other %>
         </div>
         <div class="subpart">
           <h3>Rôles</h3>
@@ -145,9 +149,9 @@
         </div>
         <div class="subpart">
           <h3><%= Education::Program.human_attribute_name('contacts') %></h3>
-          <%= @program.contacts %> 
+          <%= @program.contacts %>
         </div>
       </div>
     </div>
   </div>
-</section>
\ No newline at end of file
+</section>
diff --git a/app/views/admin/education/programs/roles/_list.html.erb b/app/views/admin/education/programs/roles/_list.html.erb
index 6362fc22b67d75f730ad6e9b29d8cce234696bef..cbcffad6dd69c965bd9893bd4362c77e030f2f02 100644
--- a/app/views/admin/education/programs/roles/_list.html.erb
+++ b/app/views/admin/education/programs/roles/_list.html.erb
@@ -1,41 +1,43 @@
 <% if roles.any? %>
-  <table class="table">
-    <thead>
-      <tr>
-        <% if can? :reorder, University::Role %>
-          <th width="20" class="ps-0">&nbsp;</th>
-        <% end %>
-        <th class="ps-0"><%= University::Role.model_name.human %></th>
-        <th><%= University::Role.human_attribute_name('people') %></th>
-        <th></th>
-      </tr>
-    </thead>
-    <tbody data-sortable data-sort-url="<%= reorder_admin_education_program_roles_path(program_id: @program.id) %>">
-      <% roles.each do |role| %>
-        <tr data-id="<%= role.id %>">
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
+        <tr>
           <% if can? :reorder, University::Role %>
-            <td><i class="fa fa-bars handle"></i></td>
+            <th width="20" class="ps-0">&nbsp;</th>
           <% end %>
-          <td class="ps-0">
-            <%= link_to_if  can?(:read, role),
-                            role,
-                            admin_education_program_role_path(role, { program_id: @program.id }) %>
-          </td>
-          <td><%= role.involvements.includes(:person).ordered.map { |involvement| involvement.person.to_s }.to_sentence %></td>
-          <td class="text-end pe-0">
-            <div class="btn-group" role="group">
-              <%= link_to t('edit'),
-                          edit_admin_education_program_role_path(role, { program_id: @program.id }),
-                          class: button_classes if can?(:edit, role) %>
-              <%= link_to t('delete'),
-                          admin_education_program_role_path(role, { program_id: @program.id }),
-                          method: :delete,
-                          data: { confirm: t('please_confirm') },
-                          class: button_classes_danger if can?(:destroy, role) %>
-            </div>
-          </td>
+          <th class="ps-0"><%= University::Role.model_name.human %></th>
+          <th><%= University::Role.human_attribute_name('people') %></th>
+          <th></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody data-sortable data-sort-url="<%= reorder_admin_education_program_roles_path(program_id: @program.id) %>">
+        <% roles.each do |role| %>
+          <tr data-id="<%= role.id %>">
+            <% if can? :reorder, University::Role %>
+              <td><i class="fa fa-bars handle"></i></td>
+            <% end %>
+            <td class="ps-0">
+              <%= link_to_if  can?(:read, role),
+                              role,
+                              admin_education_program_role_path(role, { program_id: @program.id }) %>
+            </td>
+            <td><%= role.involvements.includes(:person).ordered.map { |involvement| involvement.person.to_s }.to_sentence %></td>
+            <td class="text-end pe-0">
+              <div class="btn-group" role="group">
+                <%= link_to t('edit'),
+                            edit_admin_education_program_role_path(role, { program_id: @program.id }),
+                            class: button_classes if can?(:edit, role) %>
+                <%= link_to t('delete'),
+                            admin_education_program_role_path(role, { program_id: @program.id }),
+                            method: :delete,
+                            data: { confirm: t('please_confirm') },
+                            class: button_classes_danger if can?(:destroy, role) %>
+              </div>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
 <% end %>
diff --git a/app/views/admin/education/programs/roles/show.html.erb b/app/views/admin/education/programs/roles/show.html.erb
index df7fe59af918ff56fa09ce714fd24705b2886f4c..e19c7471b03bdedbcb7bafa164ca58fc0ab779cf 100644
--- a/app/views/admin/education/programs/roles/show.html.erb
+++ b/app/views/admin/education/programs/roles/show.html.erb
@@ -1,38 +1,40 @@
 <% content_for :title, @role %>
 
 <% if @involvements.any? %>
-  <table class="table">
-    <thead>
-      <tr>
-        <% if can? :reorder, University::Role %>
-          <th width="20" class="ps-0">&nbsp;</th>
-        <% end %>
-        <th class="ps-0"><%= University::Person.model_name.human %></th>
-        <th></th>
-      </tr>
-    </thead>
-    <tbody data-sortable data-sort-url="<%= reorder_admin_education_program_role_people_path(@role, { program_id: @program.id }) %>">
-      <% @involvements.each do |involvement| %>
-        <tr data-id="<%= involvement.id %>">
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
+        <tr>
           <% if can? :reorder, University::Role %>
-            <td><i class="fa fa-bars handle"></i></td>
+            <th width="20" class="ps-0">&nbsp;</th>
           <% end %>
-          <td class="ps-0">
-            <%= link_to_if  can?(:read, involvement.person),
-                            involvement.person,
-                            [:admin, involvement.person] %>
-          </td>
-          <td class="text-end pe-0">
-            <%= link_to t('remove'),
-                        admin_education_program_role_person_path(involvement, { program_id: @program.id, role_id: @role.id }),
-                        method: :delete,
-                        data: { confirm: t('please_confirm') },
-                        class: button_classes_danger if can?(:destroy, involvement) %>
-          </td>
+          <th class="ps-0"><%= University::Person.model_name.human %></th>
+          <th></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody data-sortable data-sort-url="<%= reorder_admin_education_program_role_people_path(@role, { program_id: @program.id }) %>">
+        <% @involvements.each do |involvement| %>
+          <tr data-id="<%= involvement.id %>">
+            <% if can? :reorder, University::Role %>
+              <td><i class="fa fa-bars handle"></i></td>
+            <% end %>
+            <td class="ps-0">
+              <%= link_to_if  can?(:read, involvement.person),
+                              involvement.person,
+                              [:admin, involvement.person] %>
+            </td>
+            <td class="text-end pe-0">
+              <%= link_to t('remove'),
+                          admin_education_program_role_person_path(involvement, { program_id: @program.id, role_id: @role.id }),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger if can?(:destroy, involvement) %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+</div>
 <% end %>
 
 
diff --git a/app/views/admin/education/programs/show/_cohorts.html.erb b/app/views/admin/education/programs/show/_cohorts.html.erb
index e954c2e8acf955de2e24648ea4b3a4c62442ac02..2abde6f5b7cd05b43bc30924221fdde89ab0f017 100644
--- a/app/views/admin/education/programs/show/_cohorts.html.erb
+++ b/app/views/admin/education/programs/show/_cohorts.html.erb
@@ -7,28 +7,30 @@
       </div>
       <h5 class="card-title mb-0"><%= Education::Cohort.model_name.human(count: 2) %></h5>
     </div>
-    <table class="<%= table_classes %>">
-      <thead>
-        <tr>
-          <th><%= Education::Cohort.human_attribute_name('year') %></th>
-          <th><%= Education::Cohort.human_attribute_name('school') %></th>
-          <th><%= Education::Cohort.human_attribute_name('alumni') %></th>
-        </tr>
-      </thead>
-      <tbody>
-        <% @program.cohorts.ordered.each do |cohort| %>
+    <div class="table-responsive">
+      <table class="<%= table_classes %>">
+        <thead>
           <tr>
-            <td>
-              <%= link_to [:admin, cohort] do %>
-                <%= cohort.academic_year %>
-                <%= cohort.name %>
-              <% end %>
-            </td>
-            <td><%= link_to_if can?(:read, cohort.school), cohort.school, [:admin, cohort.school] %></td>
-            <td><%= cohort.people.count %></td>
+            <th><%= Education::Cohort.human_attribute_name('year') %></th>
+            <th><%= Education::Cohort.human_attribute_name('school') %></th>
+            <th><%= Education::Cohort.human_attribute_name('alumni') %></th>
           </tr>
-        <% end %>
-      </tbody>
-    </table>
+        </thead>
+        <tbody>
+          <% @program.cohorts.ordered.each do |cohort| %>
+            <tr>
+              <td>
+                <%= link_to [:admin, cohort] do %>
+                  <%= cohort.academic_year %>
+                  <%= cohort.name %>
+                <% end %>
+              </td>
+              <td><%= link_to_if can?(:read, cohort.school), cohort.school, [:admin, cohort.school] %></td>
+              <td><%= cohort.people.count %></td>
+            </tr>
+          <% end %>
+        </tbody>
+      </table>
+    </div>
   </div>
 <% end %>
diff --git a/app/views/admin/education/programs/show/_roles.html.erb b/app/views/admin/education/programs/show/_roles.html.erb
index 39ad4adb7abb00c2e46d0ecb463020d053680bc9..eafdbce6638010c06384a9974f3b3faa7ef9540c 100644
--- a/app/views/admin/education/programs/show/_roles.html.erb
+++ b/app/views/admin/education/programs/show/_roles.html.erb
@@ -7,24 +7,26 @@
 </div>
 <h3 class="h5"><%= Education::Program.human_attribute_name('roles') %></h3>
 <% if @roles.any? %>
-  <table class="table">
-    <thead>
-      <tr>
-        <th class="ps-0"><%= University::Role.model_name.human %></th>
-        <th><%= University::Role.human_attribute_name('people') %></th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @roles.each do |role| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td class="ps-0">
-            <%= link_to_if  can?(:update, role),
-                            role,
-                            edit_admin_education_program_role_path(role, { program_id: @program.id }) %>
-          </td>
-          <td><%= role.involvements.includes(:person).ordered.map { |involvement| link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) }.to_sentence.html_safe %></td>
+          <th class="ps-0"><%= University::Role.model_name.human %></th>
+          <th><%= University::Role.human_attribute_name('people') %></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @roles.each do |role| %>
+          <tr>
+            <td class="ps-0">
+              <%= link_to_if  can?(:update, role),
+                              role,
+                              edit_admin_education_program_role_path(role, { program_id: @program.id }) %>
+            </td>
+            <td><%= role.involvements.includes(:person).ordered.map { |involvement| link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) }.to_sentence.html_safe %></td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+</div>
 <% end %>
diff --git a/app/views/admin/education/programs/show/_teachers.html.erb b/app/views/admin/education/programs/show/_teachers.html.erb
index a863f10e15c34353d01fce39df80881ff124f6b9..6c2533e8e7509c34c36028d054282eb432cd3729 100644
--- a/app/views/admin/education/programs/show/_teachers.html.erb
+++ b/app/views/admin/education/programs/show/_teachers.html.erb
@@ -7,22 +7,24 @@
 </div>
 <h3 class="h5"><%= Education::Program.human_attribute_name('teachers') %></h3>
 <% if @teacher_involvements.any? %>
-  <table class="table">
-    <thead>
-      <tr>
-        <th class="ps-0"><%= University::Person.model_name.human %></th>
-        <th><%= University::Person::Involvement.human_attribute_name('description') %></th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @teacher_involvements.each do |involvement| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td class="ps-0">
-            <%= link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) %>
-          </td>
-          <td><%= involvement.description %></td>
+          <th class="ps-0"><%= University::Person.model_name.human %></th>
+          <th><%= University::Person::Involvement.human_attribute_name('description') %></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @teacher_involvements.each do |involvement| %>
+          <tr>
+            <td class="ps-0">
+              <%= link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) %>
+            </td>
+            <td><%= involvement.description %></td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+</div>
 <% end %>
diff --git a/app/views/admin/education/programs/teachers/_list.html.erb b/app/views/admin/education/programs/teachers/_list.html.erb
index 2d7acf1dcdb15f68b4a35541726a5d16986d75d8..7073bbd48a31faa5ac6deb9277f233e3266249e7 100644
--- a/app/views/admin/education/programs/teachers/_list.html.erb
+++ b/app/views/admin/education/programs/teachers/_list.html.erb
@@ -1,33 +1,35 @@
 <% if involvements.any? %>
-  <table class="table">
-    <thead>
-      <tr>
-        <th class="ps-0"><%= University::Person.model_name.human %></th>
-        <th><%= University::Person::Involvement.human_attribute_name('description') %></th>
-        <th></th>
-      </tr>
-    </thead>
-    <tbody>
-      <% involvements.each do |involvement| %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td class="ps-0">
-            <%= link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) %>
-          </td>
-          <td><%= involvement.description %></td>
-          <td class="text-end pe-0">
-            <div class="btn-group" role="group">
-              <%= link_to t('edit'),
-                          edit_admin_education_program_teacher_path(involvement, { program_id: @program.id }),
-                          class: button_classes if can?(:edit, involvement) %>
-              <%= link_to t('remove'),
-                          admin_education_program_teacher_path(involvement, { program_id: @program.id }),
-                          method: :delete,
-                          data: { confirm: t('please_confirm') },
-                          class: button_classes_danger if can?(:destroy, involvement) %>
-            </div>
-          </td>
+          <th class="ps-0"><%= University::Person.model_name.human %></th>
+          <th><%= University::Person::Involvement.human_attribute_name('description') %></th>
+          <th></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% involvements.each do |involvement| %>
+          <tr>
+            <td class="ps-0">
+              <%= link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) %>
+            </td>
+            <td><%= involvement.description %></td>
+            <td class="text-end pe-0">
+              <div class="btn-group" role="group">
+                <%= link_to t('edit'),
+                            edit_admin_education_program_teacher_path(involvement, { program_id: @program.id }),
+                            class: button_classes if can?(:edit, involvement) %>
+                <%= link_to t('remove'),
+                            admin_education_program_teacher_path(involvement, { program_id: @program.id }),
+                            method: :delete,
+                            data: { confirm: t('please_confirm') },
+                            class: button_classes_danger if can?(:destroy, involvement) %>
+              </div>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+    </div>
 <% end %>
diff --git a/app/views/admin/education/schools/index.html.erb b/app/views/admin/education/schools/index.html.erb
index 0e30adb402c92321f1bc27e802fe74bf2039281e..ce92c37841a0058c18b584f26653e4bedfb2d634 100644
--- a/app/views/admin/education/schools/index.html.erb
+++ b/app/views/admin/education/schools/index.html.erb
@@ -2,33 +2,35 @@
 
 <%= render 'filters', current_path: admin_education_schools_path, filters: @filters if @filters.any?  %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= Education::School.human_attribute_name('name') %></th>
-      <th><%= Education::School.human_attribute_name('address') %></th>
-      <th><%= Education::School.human_attribute_name('zipcode') %></th>
-      <th><%= Education::School.human_attribute_name('city') %></th>
-      <th></th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <% @schools.each do |school| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to school.name, [:admin, school] %></td>
-        <td><%= school.address %></td>
-        <td><%= school.zipcode %></td>
-        <td><%= school.city %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link school %>
-            <%= destroy_link school %>
-          </div>
-        </td>
-    <% end %>
-  </tbody>
-</table>
+        <th><%= Education::School.human_attribute_name('name') %></th>
+        <th><%= Education::School.human_attribute_name('address') %></th>
+        <th><%= Education::School.human_attribute_name('zipcode') %></th>
+        <th><%= Education::School.human_attribute_name('city') %></th>
+        <th></th>
+      </tr>
+    </thead>
+
+    <tbody>
+      <% @schools.each do |school| %>
+        <tr>
+          <td><%= link_to school.name, [:admin, school] %></td>
+          <td><%= school.address %></td>
+          <td><%= school.zipcode %></td>
+          <td><%= school.city %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link school %>
+              <%= destroy_link school %>
+            </div>
+          </td>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <%= paginate @schools, theme: 'bootstrap-5' %>
 
diff --git a/app/views/admin/education/schools/roles/_list.html.erb b/app/views/admin/education/schools/roles/_list.html.erb
index 5d694d93e0a80f5a2afa8c1e21fa0088ea619f47..142980c552c649022e773b436cde2524b6ab97b5 100644
--- a/app/views/admin/education/schools/roles/_list.html.erb
+++ b/app/views/admin/education/schools/roles/_list.html.erb
@@ -1,41 +1,43 @@
 <% if roles.any? %>
-  <table class="table">
-    <thead>
-      <tr>
-        <% if can? :reorder, University::Role %>
-          <th width="20" class="ps-0">&nbsp;</th>
-        <% end %>
-        <th class="ps-0"><%= University::Role.model_name.human %></th>
-        <th><%= University::Role.human_attribute_name('people') %></th>
-        <th></th>
-      </tr>
-    </thead>
-    <tbody data-sortable data-sort-url="<%= reorder_admin_education_school_roles_path(school_id: @school.id) %>">
-      <% roles.each do |role| %>
-        <tr data-id="<%= role.id %>">
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
+        <tr>
           <% if can? :reorder, University::Role %>
-            <td><i class="fa fa-bars handle"></i></td>
+            <th width="20" class="ps-0">&nbsp;</th>
           <% end %>
-          <td class="ps-0">
-            <%= link_to_if  can?(:read, role),
-                            role,
-                            admin_education_school_role_path(role, { school_id: @school.id }) %>
-          </td>
-          <td><%= role.involvements.includes(:person).ordered.map { |involvement| involvement.person.to_s }.to_sentence %></td>
-          <td class="text-end pe-0">
-            <div class="btn-group" role="group">
-              <%= link_to t('edit'),
-                          edit_admin_education_school_role_path(role, { school_id: @school.id }),
-                          class: button_classes if can?(:edit, role) %>
-              <%= link_to t('delete'),
-                          admin_education_school_role_path(role, { school_id: @school.id }),
-                          method: :delete,
-                          data: { confirm: t('please_confirm') },
-                          class: button_classes_danger if can?(:destroy, role) %>
-            </div>
-          </td>
+          <th class="ps-0"><%= University::Role.model_name.human %></th>
+          <th><%= University::Role.human_attribute_name('people') %></th>
+          <th></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody data-sortable data-sort-url="<%= reorder_admin_education_school_roles_path(school_id: @school.id) %>">
+        <% roles.each do |role| %>
+          <tr data-id="<%= role.id %>">
+            <% if can? :reorder, University::Role %>
+              <td><i class="fa fa-bars handle"></i></td>
+            <% end %>
+            <td class="ps-0">
+              <%= link_to_if  can?(:read, role),
+                              role,
+                              admin_education_school_role_path(role, { school_id: @school.id }) %>
+            </td>
+            <td><%= role.involvements.includes(:person).ordered.map { |involvement| involvement.person.to_s }.to_sentence %></td>
+            <td class="text-end pe-0">
+              <div class="btn-group" role="group">
+                <%= link_to t('edit'),
+                            edit_admin_education_school_role_path(role, { school_id: @school.id }),
+                            class: button_classes if can?(:edit, role) %>
+                <%= link_to t('delete'),
+                            admin_education_school_role_path(role, { school_id: @school.id }),
+                            method: :delete,
+                            data: { confirm: t('please_confirm') },
+                            class: button_classes_danger if can?(:destroy, role) %>
+              </div>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+</div>
 <% end %>
diff --git a/app/views/admin/education/schools/roles/show.html.erb b/app/views/admin/education/schools/roles/show.html.erb
index a753a40f332e0f82f4d155cb964ca09ec8d94629..9bf7f70942a59115fd2db2ce34c352361b87042a 100644
--- a/app/views/admin/education/schools/roles/show.html.erb
+++ b/app/views/admin/education/schools/roles/show.html.erb
@@ -1,38 +1,40 @@
 <% content_for :title, @role %>
 
 <% if @involvements.any? %>
-  <table class="table">
-    <thead>
-      <tr>
-        <% if can? :reorder, University::Person::Involvement %>
-          <th width="20" class="ps-0">&nbsp;</th>
-        <% end %>
-        <th class="ps-0"><%= University::Person.model_name.human %></th>
-        <th></th>
-      </tr>
-    </thead>
-    <tbody data-sortable data-sort-url="<%= reorder_admin_education_school_role_people_path(@role, { school_id: @school.id }) %>">
-      <% @involvements.each do |involvement| %>
-        <tr data-id="<%= involvement.id %>">
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
+        <tr>
           <% if can? :reorder, University::Person::Involvement %>
-            <td><i class="fa fa-bars handle"></i></td>
+            <th width="20" class="ps-0">&nbsp;</th>
           <% end %>
-          <td class="ps-0">
-            <%= link_to_if  can?(:read, involvement.person),
-                            involvement.person,
-                            [:admin, involvement.person] %>
-          </td>
-          <td class="text-end pe-0">
-            <%= link_to t('remove'),
-                        admin_education_school_role_person_path(involvement, { school_id: @school.id, role_id: @role.id }),
-                        method: :delete,
-                        data: { confirm: t('please_confirm') },
-                        class: button_classes_danger if can?(:destroy, involvement) %>
-          </td>
+          <th class="ps-0"><%= University::Person.model_name.human %></th>
+          <th></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody data-sortable data-sort-url="<%= reorder_admin_education_school_role_people_path(@role, { school_id: @school.id }) %>">
+        <% @involvements.each do |involvement| %>
+          <tr data-id="<%= involvement.id %>">
+            <% if can? :reorder, University::Person::Involvement %>
+              <td><i class="fa fa-bars handle"></i></td>
+            <% end %>
+            <td class="ps-0">
+              <%= link_to_if  can?(:read, involvement.person),
+                              involvement.person,
+                              [:admin, involvement.person] %>
+            </td>
+            <td class="text-end pe-0">
+              <%= link_to t('remove'),
+                          admin_education_school_role_person_path(involvement, { school_id: @school.id, role_id: @role.id }),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger if can?(:destroy, involvement) %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
 <% end %>
 
 
diff --git a/app/views/admin/education/schools/show/_roles.html.erb b/app/views/admin/education/schools/show/_roles.html.erb
index c76b6046d3d5ef9a71cbbf3b58749e0dd0640aa5..224bc030bbf543fe85a61a4c1c938dcf38a0d2e9 100644
--- a/app/views/admin/education/schools/show/_roles.html.erb
+++ b/app/views/admin/education/schools/show/_roles.html.erb
@@ -9,32 +9,34 @@
   </div>
   <div class="card-body">
     <% if @roles.any? %>
-      <table class="table">
-        <thead>
-          <tr>
-            <th class="ps-0"><%= University::Role.model_name.human %></th>
-            <th><%= University::Role.human_attribute_name('people') %></th>
-          </tr>
-        </thead>
-        <tbody>
-          <% roles.each do |role| %>
+      <div class="table-responsive">
+        <table class="<%= table_classes %>">
+          <thead>
             <tr>
-              <td class="ps-0">
-                <%= link_to_if  can?(:read, role),
-                                role,
-                                edit_admin_education_school_role_path(role, { school_id: @school.id }) %>
-              </td>
-              <td>
-                <ul>
-                  <% role.involvements.includes(:person).ordered.each do |involvement| %>
-                    <li><%= link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) %></li>
-                  <% end %>
-                </ul>
-              </td>
+              <th class="ps-0"><%= University::Role.model_name.human %></th>
+              <th><%= University::Role.human_attribute_name('people') %></th>
             </tr>
-          <% end %>
-        </tbody>
-      </table>
+          </thead>
+          <tbody>
+            <% roles.each do |role| %>
+              <tr>
+                <td class="ps-0">
+                  <%= link_to_if  can?(:read, role),
+                                  role,
+                                  edit_admin_education_school_role_path(role, { school_id: @school.id }) %>
+                </td>
+                <td>
+                  <ul>
+                    <% role.involvements.includes(:person).ordered.each do |involvement| %>
+                      <li><%= link_to_if can?(:read, involvement.person), involvement.person.to_s, admin_university_person_path(involvement.person) %></li>
+                    <% end %>
+                  </ul>
+                </td>
+              </tr>
+            <% end %>
+          </tbody>
+        </table>
+      </div>
     <% end %>
   </div>
 </div>
diff --git a/app/views/admin/education/teachers/_list.html.erb b/app/views/admin/education/teachers/_list.html.erb
index cdcbf4649fcda328e908c0d62cc1d5e96c7c04a0..15ebdc732837a6c2204b744a1b5fa25c82e52188 100644
--- a/app/views/admin/education/teachers/_list.html.erb
+++ b/app/views/admin/education/teachers/_list.html.erb
@@ -1,31 +1,33 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= University::Person.human_attribute_name('last_name') %></th>
-      <th><%= University::Person.human_attribute_name('first_name') %></th>
-      <th><%= Education::Program.model_name.human(count: 2) %></th>
-      <th></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% teachers.each do |teacher| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to teacher.last_name, admin_education_teacher_path(teacher) %></td>
-        <td><%= link_to teacher.first_name, admin_education_teacher_path(teacher) %></td>
-        <td><%= teacher.involvements.size %></td>
-        <td class="p-0">
-          <%= kamifusen_tag teacher.best_picture,
-                            width: 40 if teacher.best_picture.attached? %>
-        </td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                      edit_admin_education_teacher_path(teacher),
-                      class: button_classes %>
-          </div>
-        </td>
+        <th><%= University::Person.human_attribute_name('last_name') %></th>
+        <th><%= University::Person.human_attribute_name('first_name') %></th>
+        <th><%= Education::Program.model_name.human(count: 2) %></th>
+        <th></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% teachers.each do |teacher| %>
+        <tr>
+          <td><%= link_to teacher.last_name, admin_education_teacher_path(teacher) %></td>
+          <td><%= link_to teacher.first_name, admin_education_teacher_path(teacher) %></td>
+          <td><%= teacher.involvements.size %></td>
+          <td class="p-0">
+            <%= kamifusen_tag teacher.best_picture,
+                              width: 40 if teacher.best_picture.attached? %>
+          </td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                        edit_admin_education_teacher_path(teacher),
+                        class: button_classes %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/education/teachers/show/_programs.html.erb b/app/views/admin/education/teachers/show/_programs.html.erb
index e5f6aef9b3e9bbf3c0d21d34c3b5e8c07b4ae2a6..6359d3abe1210b7074c2a10df9f83546e3d19145 100644
--- a/app/views/admin/education/teachers/show/_programs.html.erb
+++ b/app/views/admin/education/teachers/show/_programs.html.erb
@@ -4,33 +4,35 @@
     <div class="card-header">
       <h2 class="card-title mb-0 h5"><%= "#{Education::Program.model_name.human(count: 2)} (#{involvements.total_count})" %></h2>
     </div>
-    <table class="table">
-      <thead>
-        <tr>
-          <th><%= Education::Program.model_name.human %></th>
-          <th><%= Education::Program.human_attribute_name('level') %></th>
-          <th><%= University::Person::Involvement.human_attribute_name('description') %></th>
-          <th></th>
-        </tr>
-      </thead>
-      <tbody>
-        <% involvements.each do |involvement| %>
-          <% program = involvement.target %>
+    <div class="table-responsive">
+      <table class="<%= table_classes %>">
+        <thead>
           <tr>
-            <td><%= link_to_if can?(:read, program), program, [:admin, program] %></td>
-            <td><%= program.level_i18n %></td>
-            <td><%= involvement.description %></td>
-            <td class="text-end">
-              <%= link_to t('quit'),
-                          admin_education_program_teacher_path(involvement, { program_id: program.id }),
-                          method: :delete,
-                          data: { confirm: t('please_confirm') },
-                          class: button_classes_danger if can?(:destroy, involvement) %>
-            </td>
+            <th><%= Education::Program.model_name.human %></th>
+            <th><%= Education::Program.human_attribute_name('level') %></th>
+            <th><%= University::Person::Involvement.human_attribute_name('description') %></th>
+            <th></th>
           </tr>
-        <% end %>
-      </tbody>
-    </table>
+        </thead>
+        <tbody>
+          <% involvements.each do |involvement| %>
+            <% program = involvement.target %>
+            <tr>
+              <td><%= link_to_if can?(:read, program), program, [:admin, program] %></td>
+              <td><%= program.level_i18n %></td>
+              <td><%= involvement.description %></td>
+              <td class="text-end">
+                <%= link_to t('quit'),
+                            admin_education_program_teacher_path(involvement, { program_id: program.id }),
+                            method: :delete,
+                            data: { confirm: t('please_confirm') },
+                            class: button_classes_danger if can?(:destroy, involvement) %>
+              </td>
+            </tr>
+          <% end %>
+        </tbody>
+      </table>
+    </div>
 
     <% if involvements.total_pages > 1 %>
       <div class="card-footer">
diff --git a/app/views/admin/imports/_list.html.erb b/app/views/admin/imports/_list.html.erb
index 91a9935649b1202f5e14975f3fc8ca798b9456b9..1d744cd17a452282cead05f0deea5b0098e7ea49 100644
--- a/app/views/admin/imports/_list.html.erb
+++ b/app/views/admin/imports/_list.html.erb
@@ -1,22 +1,24 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Import.human_attribute_name('date') %></th>
-      <th><%= Import.human_attribute_name('number_of_lines') %></th>
-      <th><%= Import.human_attribute_name('status') %></th>
-      <th><%= Import.human_attribute_name('file') %></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% imports.each do |import| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to import, send(path_pattern, import) %></td>
-        <td><%= import.number_of_lines %></td>
-        <td class="<%= import.status_class %>"><%= t("enums.import.status.#{import.status}") %></td>
-        <td><%= link_to t('download'), url_for(import.file), class: button_classes if import.file.attached? %></td>
+        <th><%= Import.human_attribute_name('date') %></th>
+        <th><%= Import.human_attribute_name('number_of_lines') %></th>
+        <th><%= Import.human_attribute_name('status') %></th>
+        <th><%= Import.human_attribute_name('file') %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% imports.each do |import| %>
+        <tr>
+          <td><%= link_to import, send(path_pattern, import) %></td>
+          <td><%= import.number_of_lines %></td>
+          <td class="<%= import.status_class %>"><%= t("enums.import.status.#{import.status}") %></td>
+          <td><%= link_to t('download'), url_for(import.file), class: button_classes if import.file.attached? %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <%= paginate imports, theme: 'bootstrap-5' %>
diff --git a/app/views/admin/research/journals/index.html.erb b/app/views/admin/research/journals/index.html.erb
index 365ee4023e193d66c82e97375fe071583a15614a..e68f0ff4d8be62e4a0f663dbb38e72d595cf3f99 100644
--- a/app/views/admin/research/journals/index.html.erb
+++ b/app/views/admin/research/journals/index.html.erb
@@ -2,34 +2,36 @@
 
 <%= render 'filters', current_path: admin_research_journals_path, filters: @filters if @filters.any?  %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= Research::Journal.human_attribute_name('title') %></th>
-      <th><%= Research::Journal::Volume.model_name.human(count: 2) %></th>
-      <th><%= Research::Journal::Paper.model_name.human(count: 2) %></th>
-      <th></th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <% @journals.each do |journal| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to journal, [:admin, journal] %></td>
-        <td><%= link_to "#{journal.volumes.count}", admin_research_journal_volumes_path(journal_id: journal) %></td>
-        <td><%= link_to "#{journal.papers.count}", admin_research_journal_papers_path(journal_id: journal) %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link journal %>
-            <%= destroy_link journal %>
-          </div>
-        </td>
+        <th><%= Research::Journal.human_attribute_name('title') %></th>
+        <th><%= Research::Journal::Volume.model_name.human(count: 2) %></th>
+        <th><%= Research::Journal::Paper.model_name.human(count: 2) %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
-<%= paginate @journals, theme: 'bootstrap-5' %>
+    </thead>
 
+    <tbody>
+      <% @journals.each do |journal| %>
+        <tr>
+          <td><%= link_to journal, [:admin, journal] %></td>
+          <td><%= link_to "#{journal.volumes.count}", admin_research_journal_volumes_path(journal_id: journal) %></td>
+          <td><%= link_to "#{journal.papers.count}", admin_research_journal_papers_path(journal_id: journal) %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link journal %>
+              <%= destroy_link journal %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
+
+<%= paginate @journals, theme: 'bootstrap-5' %>
 
 <% content_for :action_bar_right do %>
   <%= create_link Research::Journal %>
diff --git a/app/views/admin/research/journals/papers/_list.html.erb b/app/views/admin/research/journals/papers/_list.html.erb
index 907248867d97de57d0895ca1d8e1dc71f9fd4d40..338966a1a9b6c8e9542071ec6a98c1a8f1043c96 100644
--- a/app/views/admin/research/journals/papers/_list.html.erb
+++ b/app/views/admin/research/journals/papers/_list.html.erb
@@ -1,33 +1,35 @@
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= Research::Journal::Paper.model_name.human %></th>
-      <th><%= Research::Journal::Paper.human_attribute_name('published_at') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% papers.each do |paper| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td>
-          <%= link_to paper,
-                      admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                      class: "#{'draft' unless paper.published?}" %>
-        </td>
-        <td><%= paper.published_at %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                        edit_admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                        class: button_classes %>
-            <%= link_to t('delete'),
-                        admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                        method: :delete,
-                        data: { confirm: t('please_confirm') },
-                        class: button_classes_danger %>
-          </div>
-        </td>
+        <th><%= Research::Journal::Paper.model_name.human %></th>
+        <th><%= Research::Journal::Paper.human_attribute_name('published_at') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% papers.each do |paper| %>
+        <tr>
+          <td>
+            <%= link_to paper,
+                        admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                        class: "#{'draft' unless paper.published?}" %>
+          </td>
+          <td><%= paper.published_at %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                          class: button_classes %>
+              <%= link_to t('delete'),
+                          admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/research/journals/volumes/index.html.erb b/app/views/admin/research/journals/volumes/index.html.erb
index 668bc4cc77842ed17443b33046fd998ead82838f..77aa6621036401cdfd30fc006568189425764d75 100644
--- a/app/views/admin/research/journals/volumes/index.html.erb
+++ b/app/views/admin/research/journals/volumes/index.html.erb
@@ -1,35 +1,37 @@
 <% content_for :title, Research::Journal::Volume.model_name.human(count: 2) %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= Research::Journal::Volume.model_name.human %></th>
-      <th><%= Research::Journal::Volume.human_attribute_name('featured_image') %></th>
-      <th><%= Research::Journal::Volume.human_attribute_name('published_at') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @volumes.each do |volume| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td>
-          <%= link_to volume,
-                      admin_research_journal_volume_path(journal_id: @journal, id: volume),
-                      class: "#{'draft' unless volume.published?}" %>
-        </td>
-        <td><%= image_tag volume.featured_image.variant(resize: 'x200'),
-                          height: 100 if volume.featured_image.attached? %></td>
-        <td><%= volume.published_at %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link volume, { journal_id: @journal.id } %>
-            <%#= destroy_link volume, journal_id: @journal.id %>
-          </div>
-        </td>
+        <th><%= Research::Journal::Volume.model_name.human %></th>
+        <th><%= Research::Journal::Volume.human_attribute_name('featured_image') %></th>
+        <th><%= Research::Journal::Volume.human_attribute_name('published_at') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @volumes.each do |volume| %>
+        <tr>
+          <td>
+            <%= link_to volume,
+                        admin_research_journal_volume_path(journal_id: @journal, id: volume),
+                        class: "#{'draft' unless volume.published?}" %>
+          </td>
+          <td><%= image_tag volume.featured_image.variant(resize: 'x200'),
+                            height: 100 if volume.featured_image.attached? %></td>
+          <td><%= volume.published_at %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link volume, { journal_id: @journal.id } %>
+              <%#= destroy_link volume, journal_id: @journal.id %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <% content_for :action_bar_right do %>
   <%= create_link Research::Journal::Volume %>
diff --git a/app/views/admin/research/journals/volumes/show.html.erb b/app/views/admin/research/journals/volumes/show.html.erb
index bf24bdfd716785c5ea88e6510bb4378064758bad..fa4fb014d02414af76bd155681d9530a02800063 100644
--- a/app/views/admin/research/journals/volumes/show.html.erb
+++ b/app/views/admin/research/journals/volumes/show.html.erb
@@ -9,45 +9,47 @@
       <div class="card-body">
         <% if @papers.any? %>
           <h3 class="h5 mt-4"><%= Research::Journal::Volume.human_attribute_name('papers') %></h3>
-          <table class="table">
-            <thead>
-              <tr>
-                <% if can? :reorder, Research::Journal::Paper %>
-                  <th width="20" class="ps-0">&nbsp;</th>
-                <% end %>
-                <th class="ps-0"><%= Research::Journal::Paper.model_name.human %></th>
-                <th><%= Research::Journal::Paper.human_attribute_name('published_at') %></th>
-                <th></th>
-              </tr>
-            </thead>
-            <tbody data-sortable data-sort-url="<%= reorder_admin_research_journal_papers_path(journal_id: @journal.id) %>">
-              <% @papers.each do |paper| %>
-                <tr data-id="<%= paper.id %>">
+          <div class="table-responsive">
+            <table class="<%= table_classes %>">
+              <thead>
+                <tr>
                   <% if can? :reorder, Research::Journal::Paper %>
-                    <td><i class="fa fa-bars handle"></i></td>
+                    <th width="20" class="ps-0">&nbsp;</th>
                   <% end %>
-                  <td>
-                    <%= link_to paper,
-                                admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                                class: "#{'draft' unless paper.published?}" %>
-                  </td>
-                  <td><%= paper.published_at %></td>
-                  <td class="text-end">
-                    <div class="btn-group" role="group">
-                      <%= link_to t('edit'),
-                                  edit_admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                                  class: button_classes %>
-                      <%= link_to t('delete'),
-                                  admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
-                                  method: :delete,
-                                  data: { confirm: t('please_confirm') },
-                                  class: button_classes_danger %>
-                    </div>
-                  </td>
+                  <th class="ps-0"><%= Research::Journal::Paper.model_name.human %></th>
+                  <th><%= Research::Journal::Paper.human_attribute_name('published_at') %></th>
+                  <th></th>
                 </tr>
-              <% end %>
-            </tbody>
-          </table>
+              </thead>
+              <tbody data-sortable data-sort-url="<%= reorder_admin_research_journal_papers_path(journal_id: @journal.id) %>">
+                <% @papers.each do |paper| %>
+                  <tr data-id="<%= paper.id %>">
+                    <% if can? :reorder, Research::Journal::Paper %>
+                      <td><i class="fa fa-bars handle"></i></td>
+                    <% end %>
+                    <td>
+                      <%= link_to paper,
+                                  admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                                  class: "#{'draft' unless paper.published?}" %>
+                    </td>
+                    <td><%= paper.published_at %></td>
+                    <td class="text-end">
+                      <div class="btn-group" role="group">
+                        <%= link_to t('edit'),
+                                    edit_admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                                    class: button_classes %>
+                        <%= link_to t('delete'),
+                                    admin_research_journal_paper_path(journal_id: paper.journal, id: paper),
+                                    method: :delete,
+                                    data: { confirm: t('please_confirm') },
+                                    class: button_classes_danger %>
+                      </div>
+                    </td>
+                  </tr>
+                <% end %>
+              </tbody>
+            </table>
+          </div>
         <% end %>
       </div>
     </div>
diff --git a/app/views/admin/research/laboratories/axes/_list.html.erb b/app/views/admin/research/laboratories/axes/_list.html.erb
index f9df418ab25be326c44cc61fbb9fc7d6fd69f149..551a5fba4639756867af50e6e8344e71ffe1e403 100644
--- a/app/views/admin/research/laboratories/axes/_list.html.erb
+++ b/app/views/admin/research/laboratories/axes/_list.html.erb
@@ -1,37 +1,39 @@
-<table class="table">
-  <thead>
-    <tr>
-      <% if can? :reorder, Research::Laboratory::Axis %>
-        <th width="20" class="ps-0">&nbsp;</th>
-      <% end %>
-      <th><%= Research::Laboratory::Axis.model_name.human %></th>
-      <th><%= Research::Laboratory::Axis.human_attribute_name('short_name') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody data-sortable data-sort-url="<%= reorder_admin_research_laboratory_axes_path(laboratory_id: @laboratory.id) %>">
-    <% axes.each do |axis| %>
-      <tr data-id="<%= axis.id %>">
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
+      <tr>
         <% if can? :reorder, Research::Laboratory::Axis %>
-          <td><i class="fa fa-bars handle"></i></td>
+          <th width="20" class="ps-0">&nbsp;</th>
         <% end %>
-        <td>
-          <%= link_to axis, admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis) %>
-        </td>
-        <td><%= axis.short_name %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                        edit_admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis),
-                        class: button_classes %>
-            <%= link_to t('delete'),
-                        admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis),
-                        method: :delete,
-                        data: { confirm: t('please_confirm') },
-                        class: button_classes_danger %>
-          </div>
-        </td>
+        <th><%= Research::Laboratory::Axis.model_name.human %></th>
+        <th><%= Research::Laboratory::Axis.human_attribute_name('short_name') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody data-sortable data-sort-url="<%= reorder_admin_research_laboratory_axes_path(laboratory_id: @laboratory.id) %>">
+      <% axes.each do |axis| %>
+        <tr data-id="<%= axis.id %>">
+          <% if can? :reorder, Research::Laboratory::Axis %>
+            <td><i class="fa fa-bars handle"></i></td>
+          <% end %>
+          <td>
+            <%= link_to axis, admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis) %>
+          </td>
+          <td><%= axis.short_name %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                          edit_admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis),
+                          class: button_classes %>
+              <%= link_to t('delete'),
+                          admin_research_laboratory_axis_path(laboratory_id: axis.laboratory, id: axis),
+                          method: :delete,
+                          data: { confirm: t('please_confirm') },
+                          class: button_classes_danger %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/research/laboratories/index.html.erb b/app/views/admin/research/laboratories/index.html.erb
index 7ee9816c49148cb81ce99f371d5dc9ed7d812214..4dd42af1f962712e61fb19cd19d34fcc19595f5f 100644
--- a/app/views/admin/research/laboratories/index.html.erb
+++ b/app/views/admin/research/laboratories/index.html.erb
@@ -2,30 +2,33 @@
 
 <%= render 'filters', current_path: admin_research_laboratories_path, filters: @filters if @filters.any?  %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= Research::Laboratory.human_attribute_name('name') %></th>
-      <th><%= Research::Laboratory.human_attribute_name('address') %></th>
-      <th></th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <% @laboratories.each do |laboratory| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to laboratory, [:admin, laboratory] %></td>
-        <td><%= laboratory.full_address %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link laboratory %>
-            <%= destroy_link laboratory %>
-          </div>
-        </td>
+        <th><%= Research::Laboratory.human_attribute_name('name') %></th>
+        <th><%= Research::Laboratory.human_attribute_name('address') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+
+    <tbody>
+      <% @laboratories.each do |laboratory| %>
+        <tr>
+          <td><%= link_to laboratory, [:admin, laboratory] %></td>
+          <td><%= laboratory.full_address %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link laboratory %>
+              <%= destroy_link laboratory %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
+
 <%= paginate @laboratories, theme: 'bootstrap-5' %>
 
 
diff --git a/app/views/admin/research/researchers/index.html.erb b/app/views/admin/research/researchers/index.html.erb
index 2d8f876f3560cc85416baa7d498a24bd535d30d2..8dd753f09bf0841137a842ca90250c07d928aa80 100644
--- a/app/views/admin/research/researchers/index.html.erb
+++ b/app/views/admin/research/researchers/index.html.erb
@@ -2,30 +2,32 @@
 
 <%= render 'filters', current_path: admin_research_researchers_path, filters: @filters if @filters.any?  %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= University::Person.human_attribute_name('name') %></th>
-      <th><%= University::Person.human_attribute_name('first_name') %></th>
-      <th></th>
-      <th><%= t('research.number_of_papers') %></th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <% @researchers.each do |researcher| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to researcher.last_name, admin_research_researcher_path(researcher) %></td>
-        <td><%= link_to researcher.first_name, admin_research_researcher_path(researcher) %></td>
-        <td class="p-0">
-          <%= kamifusen_tag researcher.best_picture,
-                            width: 40 if researcher.best_picture.attached? %>
-        </td>
-        <td><%= researcher.research_journal_papers.count %></td>
+        <th><%= University::Person.human_attribute_name('name') %></th>
+        <th><%= University::Person.human_attribute_name('first_name') %></th>
+        <th></th>
+        <th><%= t('research.number_of_papers') %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+
+    <tbody>
+      <% @researchers.each do |researcher| %>
+        <tr>
+          <td><%= link_to researcher.last_name, admin_research_researcher_path(researcher) %></td>
+          <td><%= link_to researcher.first_name, admin_research_researcher_path(researcher) %></td>
+          <td class="p-0">
+            <%= kamifusen_tag researcher.best_picture,
+                              width: 40 if researcher.best_picture.attached? %>
+          </td>
+          <td><%= researcher.research_journal_papers.count %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <%= paginate @researchers, theme: 'bootstrap-5' %>
 
diff --git a/app/views/admin/research/theses/index.html.erb b/app/views/admin/research/theses/index.html.erb
index 7f13d52478e3504a8917217c916b9be820873f95..916c3fc1cc40c8b0c1bcaadd7c8864283040c032 100644
--- a/app/views/admin/research/theses/index.html.erb
+++ b/app/views/admin/research/theses/index.html.erb
@@ -2,28 +2,31 @@
 
 <%= render 'filters', current_path: admin_research_theses_path, filters: @filters if @filters.any?  %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= Research::Thesis.human_attribute_name('title') %></th>
-      <th></th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <% @theses.each do |thesis| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to thesis, [:admin, thesis] %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link thesis %>
-            <%= destroy_link thesis %>
-          </div>
-        </td>
+        <th><%= Research::Thesis.human_attribute_name('title') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+
+    <tbody>
+      <% @theses.each do |thesis| %>
+        <tr>
+          <td><%= link_to thesis, [:admin, thesis] %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link thesis %>
+              <%= destroy_link thesis %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
+
 <%= paginate @theses, theme: 'bootstrap-5' %>
 
 
diff --git a/app/views/admin/university/alumni/_list.html.erb b/app/views/admin/university/alumni/_list.html.erb
index 212f867b40057810d3ddb5b1ac898737945cfed2..1bf691d00c3fdb29ee3e2f610ff305d8ac2b24df 100644
--- a/app/views/admin/university/alumni/_list.html.erb
+++ b/app/views/admin/university/alumni/_list.html.erb
@@ -1,26 +1,28 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= University::Person.human_attribute_name('last_name') %></th>
-      <th><%= University::Person.human_attribute_name('first_name') %></th>
-      <th><%= Education::Cohort.model_name.human(count: 2) %></th>
-      <th><%= University::Person::Experience.model_name.human(count: 2) %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% alumni.each do |alumnus| %>
-      <% path = admin_university_alumnus_path(alumnus) %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to_if can?(:read, alumnus), alumnus.last_name, path %></td>
-        <td><%= link_to_if can?(:read, alumnus), alumnus.first_name, path %></td>
-        <td><%= link_to_if can?(:update, alumnus), alumnus.cohorts.size, cohorts_admin_university_alumnus_path(alumnus) %></td>
-        <td><%= link_to_if can?(:update, alumnus), alumnus.experiences.size, experiences_admin_university_alumnus_path(alumnus) %></td>
-        <td class="p-0">
-          <%= kamifusen_tag alumnus.best_picture,
-                            width: 40 if alumnus.best_picture.attached? %>
-        </td>
+        <th><%= University::Person.human_attribute_name('last_name') %></th>
+        <th><%= University::Person.human_attribute_name('first_name') %></th>
+        <th><%= Education::Cohort.model_name.human(count: 2) %></th>
+        <th><%= University::Person::Experience.model_name.human(count: 2) %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% alumni.each do |alumnus| %>
+        <% path = admin_university_alumnus_path(alumnus) %>
+        <tr>
+          <td><%= link_to_if can?(:read, alumnus), alumnus.last_name, path %></td>
+          <td><%= link_to_if can?(:read, alumnus), alumnus.first_name, path %></td>
+          <td><%= link_to_if can?(:update, alumnus), alumnus.cohorts.size, cohorts_admin_university_alumnus_path(alumnus) %></td>
+          <td><%= link_to_if can?(:update, alumnus), alumnus.experiences.size, experiences_admin_university_alumnus_path(alumnus) %></td>
+          <td class="p-0">
+            <%= kamifusen_tag alumnus.best_picture,
+                              width: 40 if alumnus.best_picture.attached? %>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/university/alumni/cohorts/imports/new.html.erb b/app/views/admin/university/alumni/cohorts/imports/new.html.erb
index b63cdafac4e6f98da3929d1d07c999aee347cb98..e348a54b9368987ab3e9b4eb2e3f7d5d144b7fb3 100644
--- a/app/views/admin/university/alumni/cohorts/imports/new.html.erb
+++ b/app/views/admin/university/alumni/cohorts/imports/new.html.erb
@@ -25,89 +25,91 @@
 
   </div>
   <div class="col-md-6">
-    <table class="table table-small">
-      <tbody>
-        <tr>
-          <th>first_name*</th>
-          <td>Stéphane</td>
-        </tr>
-        <tr>
-          <th>last_name*</th>
-          <td>Dupond</td>
-        </tr>
-        <tr>
-          <th>gender</th>
-          <td>m</td>
-        </tr>
-        <tr>
-          <th>birth</th>
-          <td>2006-05-26</td>
-        </tr>
-        <tr>
-          <th>mail</th>
-          <td>stephane.dupond@gmail.com</td>
-        </tr>
-        <tr>
-          <th>photo</th>
-          <td>https://www.example.com/photo.jpg</td>
-        </tr>
-        <tr>
-          <th>url</th>
-          <td>https://www.stephanedupond.fr</td>
-        </tr>
-        <tr>
-          <th>phone_professional</th>
-          <td>+33 1 01 01 01 01</td>
-        </tr>
-        <tr>
-          <th>phone_personal</th>
-          <td>+33 1 01 01 01 01</td>
-        </tr>
-        <tr>
-          <th>mobile</th>
-          <td>+33 6 01 01 01 01</td>
-        </tr>
-        <tr>
-          <th>address</th>
-          <td>1 rue Jacques Ellul</td>
-        </tr>
-        <tr>
-          <th>zipcode</th>
-          <td>33000</td>
-        </tr>
-        <tr>
-          <th>city</th>
-          <td>Bordeaux</td>
-        </tr>
-        <tr>
-          <th>country</th>
-          <td>FR</td>
-        </tr>
-        <tr>
-          <th>biography</th>
-          <td>Product Designer</td>
-        </tr>
-        <tr>
-          <th>social_twitter</th>
-          <td>stephanedupond</td>
-        </tr>
-        <tr>
-          <th>social_linkedin</th>
-          <td>https://www.linkedin.com/in/stephanedupond</td>
-        </tr>
-        <tr>
-          <th>school*</th>
-          <td>af96c31c-2e6b-4485-b88f-e28843480e3f</td>
-        </tr>
-        <tr>
-          <th>program*</th>
-          <td>c6b78fac-0a5f-4c44-ad22-4ee68ed382bb</td>
-        </tr>
-        <tr>
-          <th>year*</th>
-          <td>2022</td>
-        </tr>
-      </tbody>
-    </table>
+    <div class="table-responsive">
+      <table class="<%= table_classes %>">
+        <tbody>
+          <tr>
+            <th>first_name*</th>
+            <td>Stéphane</td>
+          </tr>
+          <tr>
+            <th>last_name*</th>
+            <td>Dupond</td>
+          </tr>
+          <tr>
+            <th>gender</th>
+            <td>m</td>
+          </tr>
+          <tr>
+            <th>birth</th>
+            <td>2006-05-26</td>
+          </tr>
+          <tr>
+            <th>mail</th>
+            <td>stephane.dupond@gmail.com</td>
+          </tr>
+          <tr>
+            <th>photo</th>
+            <td>https://www.example.com/photo.jpg</td>
+          </tr>
+          <tr>
+            <th>url</th>
+            <td>https://www.stephanedupond.fr</td>
+          </tr>
+          <tr>
+            <th>phone_professional</th>
+            <td>+33 1 01 01 01 01</td>
+          </tr>
+          <tr>
+            <th>phone_personal</th>
+            <td>+33 1 01 01 01 01</td>
+          </tr>
+          <tr>
+            <th>mobile</th>
+            <td>+33 6 01 01 01 01</td>
+          </tr>
+          <tr>
+            <th>address</th>
+            <td>1 rue Jacques Ellul</td>
+          </tr>
+          <tr>
+            <th>zipcode</th>
+            <td>33000</td>
+          </tr>
+          <tr>
+            <th>city</th>
+            <td>Bordeaux</td>
+          </tr>
+          <tr>
+            <th>country</th>
+            <td>FR</td>
+          </tr>
+          <tr>
+            <th>biography</th>
+            <td>Product Designer</td>
+          </tr>
+          <tr>
+            <th>social_twitter</th>
+            <td>stephanedupond</td>
+          </tr>
+          <tr>
+            <th>social_linkedin</th>
+            <td>https://www.linkedin.com/in/stephanedupond</td>
+          </tr>
+          <tr>
+            <th>school*</th>
+            <td>af96c31c-2e6b-4485-b88f-e28843480e3f</td>
+          </tr>
+          <tr>
+            <th>program*</th>
+            <td>c6b78fac-0a5f-4c44-ad22-4ee68ed382bb</td>
+          </tr>
+          <tr>
+            <th>year*</th>
+            <td>2022</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
   </div>
 </div>
diff --git a/app/views/admin/university/alumni/experiences/imports/new.html.erb b/app/views/admin/university/alumni/experiences/imports/new.html.erb
index 0bd01c6d570fd37a5e5c2b219eeb86c93967fbf2..88246e722177c3023cd9b609cbef6fd117c942b4 100644
--- a/app/views/admin/university/alumni/experiences/imports/new.html.erb
+++ b/app/views/admin/university/alumni/experiences/imports/new.html.erb
@@ -25,101 +25,103 @@
 
   </div>
   <div class="col-md-6">
-    <table class="table table-small">
-      <tbody>
-        <tr>
-          <th>first_name*</th>
-          <td>Stéphane</td>
-        </tr>
-        <tr>
-          <th>last_name*</th>
-          <td>Dupond</td>
-        </tr>
-        <tr>
-          <th>gender</th>
-          <td>m</td>
-        </tr>
-        <tr>
-          <th>birth</th>
-          <td>2006-05-26</td>
-        </tr>
-        <tr>
-          <th>mail</th>
-          <td>stephane.dupond@gmail.com</td>
-        </tr>
-        <tr>
-          <th>photo</th>
-          <td>https://www.example.com/photo.jpg</td>
-        </tr>
-        <tr>
-          <th>url</th>
-          <td>https://www.stephanedupond.fr</td>
-        </tr>
-        <tr>
-          <th>phone_professional</th>
-          <td>+33 1 01 01 01 01</td>
-        </tr>
-        <tr>
-          <th>phone_personal</th>
-          <td>+33 1 01 01 01 01</td>
-        </tr>
-        <tr>
-          <th>mobile</th>
-          <td>+33 6 01 01 01 01</td>
-        </tr>
-        <tr>
-          <th>address</th>
-          <td>1 rue Jacques Ellul</td>
-        </tr>
-        <tr>
-          <th>zipcode</th>
-          <td>33000</td>
-        </tr>
-        <tr>
-          <th>city</th>
-          <td>Bordeaux</td>
-        </tr>
-        <tr>
-          <th>country</th>
-          <td>FR</td>
-        </tr>
-        <tr>
-          <th>biography</th>
-          <td>Product Designer</td>
-        </tr>
-        <tr>
-          <th>social_twitter</th>
-          <td>stephanedupond</td>
-        </tr>
-        <tr>
-          <th>social_linkedin</th>
-          <td>https://www.linkedin.com/in/stephanedupond</td>
-        </tr>
-        <tr>
-          <th>company_name</th>
-          <td>Le Monde</td>
-        </tr>
-        <tr>
-          <th>company_siren</th>
-          <td>433891850</td>
-        </tr>
-        <tr>
-          <th>company_nic</th>
-          <td>00052</td>
-        </tr>
-        <tr>
-          <th>experience_job</th>
-          <td>Journaliste</td>
-        </tr>
-        <tr>
-          <th>experience_from</th>
-          <td>2018</td>
-        </tr>
-        <tr>
-          <th>experience_to</th>
-          <td>2021</td>
-        </tr>
-      </tbody>
-    </table>
+    <div class="table-responsive">
+      <table class="<%= table_classes %>">
+        <tbody>
+          <tr>
+            <th>first_name*</th>
+            <td>Stéphane</td>
+          </tr>
+          <tr>
+            <th>last_name*</th>
+            <td>Dupond</td>
+          </tr>
+          <tr>
+            <th>gender</th>
+            <td>m</td>
+          </tr>
+          <tr>
+            <th>birth</th>
+            <td>2006-05-26</td>
+          </tr>
+          <tr>
+            <th>mail</th>
+            <td>stephane.dupond@gmail.com</td>
+          </tr>
+          <tr>
+            <th>photo</th>
+            <td>https://www.example.com/photo.jpg</td>
+          </tr>
+          <tr>
+            <th>url</th>
+            <td>https://www.stephanedupond.fr</td>
+          </tr>
+          <tr>
+            <th>phone_professional</th>
+            <td>+33 1 01 01 01 01</td>
+          </tr>
+          <tr>
+            <th>phone_personal</th>
+            <td>+33 1 01 01 01 01</td>
+          </tr>
+          <tr>
+            <th>mobile</th>
+            <td>+33 6 01 01 01 01</td>
+          </tr>
+          <tr>
+            <th>address</th>
+            <td>1 rue Jacques Ellul</td>
+          </tr>
+          <tr>
+            <th>zipcode</th>
+            <td>33000</td>
+          </tr>
+          <tr>
+            <th>city</th>
+            <td>Bordeaux</td>
+          </tr>
+          <tr>
+            <th>country</th>
+            <td>FR</td>
+          </tr>
+          <tr>
+            <th>biography</th>
+            <td>Product Designer</td>
+          </tr>
+          <tr>
+            <th>social_twitter</th>
+            <td>stephanedupond</td>
+          </tr>
+          <tr>
+            <th>social_linkedin</th>
+            <td>https://www.linkedin.com/in/stephanedupond</td>
+          </tr>
+          <tr>
+            <th>company_name</th>
+            <td>Le Monde</td>
+          </tr>
+          <tr>
+            <th>company_siren</th>
+            <td>433891850</td>
+          </tr>
+          <tr>
+            <th>company_nic</th>
+            <td>00052</td>
+          </tr>
+          <tr>
+            <th>experience_job</th>
+            <td>Journaliste</td>
+          </tr>
+          <tr>
+            <th>experience_from</th>
+            <td>2018</td>
+          </tr>
+          <tr>
+            <th>experience_to</th>
+            <td>2021</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
   </div>
 </div>
diff --git a/app/views/admin/university/alumni/show.html.erb b/app/views/admin/university/alumni/show.html.erb
index 7bce04550bcad56a8d1ab0c8eb0708d022636e2c..f7d6edd11c540b8e6bb64eb64f1bb46fe2b47187 100644
--- a/app/views/admin/university/alumni/show.html.erb
+++ b/app/views/admin/university/alumni/show.html.erb
@@ -16,27 +16,29 @@
     <div class="card-header">
       <h2 class="card-title mb-0 h5"><%= University::Person::Experience.model_name.human(count: @alumnus.experiences.count) %></h2>
     </div>
-    <table class="table">
-      <thead>
-        <tr>
-          <th><%= University::Person::Experience.human_attribute_name('description') %></th>
-          <th><%= University::Person::Experience.human_attribute_name('organization') %></th>
-          <th><%= University::Person::Experience.human_attribute_name('from_year') %></th>
-          <th><%= University::Person::Experience.human_attribute_name('to_year') %></th>
-        </tr>
-      </thead>
-      <tbody>
-        <% @alumnus.experiences.ordered.each do |experience| %>
-          <% organization = experience.organization %>
+    <div class="table-responsive">
+      <table class="<%= table_classes %>">
+        <thead>
           <tr>
-            <td><%= experience.description %></td>
-            <td><%= link_to_if can?(:read, organization), organization, [:admin, organization] %></td>
-            <td><%= experience.from_year %></td>
-            <td><%= experience.to_year %></td>
+            <th><%= University::Person::Experience.human_attribute_name('description') %></th>
+            <th><%= University::Person::Experience.human_attribute_name('organization') %></th>
+            <th><%= University::Person::Experience.human_attribute_name('from_year') %></th>
+            <th><%= University::Person::Experience.human_attribute_name('to_year') %></th>
           </tr>
-        <% end %>
-      </tbody>
-    </table>
+        </thead>
+        <tbody>
+          <% @alumnus.experiences.ordered.each do |experience| %>
+            <% organization = experience.organization %>
+            <tr>
+              <td><%= experience.description %></td>
+              <td><%= link_to_if can?(:read, organization), organization, [:admin, organization] %></td>
+              <td><%= experience.from_year %></td>
+              <td><%= experience.to_year %></td>
+            </tr>
+          <% end %>
+        </tbody>
+      </table>
+    </div>
   </div>
 <% end %>
 
diff --git a/app/views/admin/university/organizations/_list.html.erb b/app/views/admin/university/organizations/_list.html.erb
index 210d439e509c4a106be4aee195292b147efc7719..22e25d13a33f50fa5d16fd02dd72bef6e7c447a0 100644
--- a/app/views/admin/university/organizations/_list.html.erb
+++ b/app/views/admin/university/organizations/_list.html.erb
@@ -1,28 +1,30 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= University::Organization.human_attribute_name('name') %></th>
-      <th><%= University::Organization.human_attribute_name('kind') %></th>
-      <th></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% organizations.each do |organization| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to organization, admin_university_organization_path(organization) %></td>
-        <td><span class="badge bg-secondary"><%= organization.kind_i18n %></span></td>
-        <td class="p-0 bg-grey text-center">
-          <%= kamifusen_tag organization.logo,
-                            width: 40 if organization.logo.attached? %>
-        </td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link organization %>
-            <%= destroy_link organization %>
-          </div>
-        </td>
+        <th><%= University::Organization.human_attribute_name('name') %></th>
+        <th><%= University::Organization.human_attribute_name('kind') %></th>
+        <th></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% organizations.each do |organization| %>
+        <tr>
+          <td><%= link_to organization, admin_university_organization_path(organization) %></td>
+          <td><span class="badge bg-secondary"><%= organization.kind_i18n %></span></td>
+          <td class="p-0 bg-grey text-center">
+            <%= kamifusen_tag organization.logo,
+                              width: 40 if organization.logo.attached? %>
+          </td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link organization %>
+              <%= destroy_link organization %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/university/organizations/imports/new.html.erb b/app/views/admin/university/organizations/imports/new.html.erb
index 805435dcde20d0cc4966bc435927ca1def9b27e6..b1fb765b4c7d82ec0a4d99bc3b93358e91832930 100644
--- a/app/views/admin/university/organizations/imports/new.html.erb
+++ b/app/views/admin/university/organizations/imports/new.html.erb
@@ -15,7 +15,7 @@
 
       <%# as file can be empty the global object can be unset. To prevent crash in controller add an (unused) hidden field %>
       <%= f.input :id, as: :hidden %>
-      
+
       <%= f.input :file %>
 
       <% content_for :action_bar_right do %>
@@ -25,61 +25,63 @@
 
   </div>
   <div class="col-md-6">
-    <table class="table table-small">
-      <tbody>
-        <tr>
-          <th>name*</th>
-          <td>Le Monde</td>
-        </tr>
-        <tr>
-          <th>long_name</th>
-          <td>Société Editrice du Monde</td>
-        </tr>
-        <tr>
-          <th>kind</th>
-          <td>company</td>
-        </tr>
-        <tr>
-          <th>siren</th>
-          <td>433891850</td>
-        </tr>
-        <tr>
-          <th>nic</th>
-          <td>00052</td>
-        </tr>
-        <tr>
-          <th>description</th>
-          <td>Le quotidien de référence</td>
-        </tr>
-        <tr>
-          <th>address</th>
-          <td>13 rue Auguste Blanqui</td>
-        </tr>
-        <tr>
-          <th>zipcode</th>
-          <td>75013</td>
-        </tr>
-        <tr>
-          <th>city</th>
-          <td>Paris</td>
-        </tr>
-        <tr>
-          <th>country</th>
-          <td>FR</td>
-        </tr>
-        <tr>
-          <th>email</th>
-          <td>contact@lemonde.fr</td>
-        </tr>
-        <tr>
-          <th>phone</th>
-          <td>+33 1 01 01 01 01</td>
-        </tr>
-        <tr>
-          <th>url</th>
-          <td>https://www.lemonde.fr</td>
-        </tr>
-      </tbody>
-    </table>
+    <div class="table-responsive">
+      <table class="<%= table_classes %>">
+        <tbody>
+          <tr>
+            <th>name*</th>
+            <td>Le Monde</td>
+          </tr>
+          <tr>
+            <th>long_name</th>
+            <td>Société Editrice du Monde</td>
+          </tr>
+          <tr>
+            <th>kind</th>
+            <td>company</td>
+          </tr>
+          <tr>
+            <th>siren</th>
+            <td>433891850</td>
+          </tr>
+          <tr>
+            <th>nic</th>
+            <td>00052</td>
+          </tr>
+          <tr>
+            <th>description</th>
+            <td>Le quotidien de référence</td>
+          </tr>
+          <tr>
+            <th>address</th>
+            <td>13 rue Auguste Blanqui</td>
+          </tr>
+          <tr>
+            <th>zipcode</th>
+            <td>75013</td>
+          </tr>
+          <tr>
+            <th>city</th>
+            <td>Paris</td>
+          </tr>
+          <tr>
+            <th>country</th>
+            <td>FR</td>
+          </tr>
+          <tr>
+            <th>email</th>
+            <td>contact@lemonde.fr</td>
+          </tr>
+          <tr>
+            <th>phone</th>
+            <td>+33 1 01 01 01 01</td>
+          </tr>
+          <tr>
+            <th>url</th>
+            <td>https://www.lemonde.fr</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
   </div>
 </div>
diff --git a/app/views/admin/university/organizations/show.html.erb b/app/views/admin/university/organizations/show.html.erb
index 47e54179759dee949812ff91961ba074872365b1..09972c6ea8cc40c9bb1b58426676aadf45a8399e 100644
--- a/app/views/admin/university/organizations/show.html.erb
+++ b/app/views/admin/university/organizations/show.html.erb
@@ -117,30 +117,32 @@
 <% if @organization.experiences.any? %>
   <h2><%= t('university.organization.employees') %></h2>
 
-  <table class="<%= table_classes %>">
-    <thead>
-      <tr>
-        <th><%= University::Person.human_attribute_name('last_name') %></th>
-        <th><%= University::Person.human_attribute_name('first_name') %></th>
-        <th><%= t('university.person.experience.period') %></th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @organization.experiences.ordered.each do |experience| %>
-        <%
-          alumnus = experience.person
-          path = admin_university_alumnus_path(alumnus)
-        %>
+  <div class="table-responsive">
+    <table class="<%= table_classes %>">
+      <thead>
         <tr>
-          <td><%= link_to_if can?(:read, alumnus), alumnus.last_name, path %></td>
-          <td><%= link_to_if can?(:read, alumnus), alumnus.first_name, path %></td>
-          <td>
-            <%= "#{experience.from_year} - #{experience.to_year.present? ? experience.to_year : t('today')}" %>
-          </td>
+          <th><%= University::Person.human_attribute_name('last_name') %></th>
+          <th><%= University::Person.human_attribute_name('first_name') %></th>
+          <th><%= t('university.person.experience.period') %></th>
         </tr>
-      <% end %>
-    </tbody>
-  </table>
+      </thead>
+      <tbody>
+        <% @organization.experiences.ordered.each do |experience| %>
+          <%
+            alumnus = experience.person
+            path = admin_university_alumnus_path(alumnus)
+          %>
+          <tr>
+            <td><%= link_to_if can?(:read, alumnus), alumnus.last_name, path %></td>
+            <td><%= link_to_if can?(:read, alumnus), alumnus.first_name, path %></td>
+            <td>
+              <%= "#{experience.from_year} - #{experience.to_year.present? ? experience.to_year : t('today')}" %>
+            </td>
+          </tr>
+        <% end %>
+      </tbody>
+    </table>
+  </div>
 <% end %>
 
 <% content_for :action_bar_left do %>
diff --git a/app/views/admin/university/people/_form.html.erb b/app/views/admin/university/people/_form.html.erb
index cfc7beed1bcac347f7cba46deba5c7f5cd7f4259..3244a9df718c303227d9b636ca2be56d3dcc2faa 100644
--- a/app/views/admin/university/people/_form.html.erb
+++ b/app/views/admin/university/people/_form.html.erb
@@ -38,7 +38,6 @@
           </h5>
         </div>
         <div class="card-body">
-
           <div class="row">
             <div class="col-md-6">
               <%= f.input :email %>
diff --git a/app/views/admin/university/people/_list.html.erb b/app/views/admin/university/people/_list.html.erb
index c50c49b5039d4a99eb35132ba2bbcdff321ec50b..6ea19c82215d9022a484d6381f7b35641a8ef743 100644
--- a/app/views/admin/university/people/_list.html.erb
+++ b/app/views/admin/university/people/_list.html.erb
@@ -1,42 +1,44 @@
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= University::Person.human_attribute_name('last_name') %></th>
-      <th><%= University::Person.human_attribute_name('first_name') %></th>
-      <th><%= University::Person.human_attribute_name('roles') %></th>
-      <th></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% people.each do |person| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to person.last_name, admin_university_person_path(person) %></td>
-        <td><%= link_to person.first_name, admin_university_person_path(person) %></td>
-        <td>
-          <% person.roles.each do |role| %>
-            <span class="badge bg-secondary">
-              <%= t "activerecord.attributes.university/person.#{role}" %>
-            </span>
-          <% end %>
-        </td>
-        <td class="p-0">
-          <%= kamifusen_tag person.best_picture,
-                            width: 40 if person.best_picture.attached? %>
-        </td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                      edit_admin_university_person_path(person),
-                      class: button_classes if can?(:update, person) %>
-            <%= link_to t('delete'),
-                      admin_university_person_path(person),
-                      method: :delete,
-                      data: { confirm: t('please_confirm') },
-                      class: button_classes_danger if can?(:destroy, person) %>
-          </div>
-        </td>
+        <th><%= University::Person.human_attribute_name('last_name') %></th>
+        <th><%= University::Person.human_attribute_name('first_name') %></th>
+        <th><%= University::Person.human_attribute_name('roles') %></th>
+        <th></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% people.each do |person| %>
+        <tr>
+          <td><%= link_to person.last_name, admin_university_person_path(person) %></td>
+          <td><%= link_to person.first_name, admin_university_person_path(person) %></td>
+          <td>
+            <% person.roles.each do |role| %>
+              <span class="badge bg-secondary">
+                <%= t "activerecord.attributes.university/person.#{role}" %>
+              </span>
+            <% end %>
+          </td>
+          <td class="p-0">
+            <%= kamifusen_tag person.best_picture,
+                              width: 40 if person.best_picture.attached? %>
+          </td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                        edit_admin_university_person_path(person),
+                        class: button_classes if can?(:update, person) %>
+              <%= link_to t('delete'),
+                        admin_university_person_path(person),
+                        method: :delete,
+                        data: { confirm: t('please_confirm') },
+                        class: button_classes_danger if can?(:destroy, person) %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/admin/university/people/show/_roles.html.erb b/app/views/admin/university/people/show/_roles.html.erb
index b5dd022e56b1db8f65ffb8344ce0d9851970ad71..748082e5533eb7960ee00b6ad805c0654e1afae9 100644
--- a/app/views/admin/university/people/show/_roles.html.erb
+++ b/app/views/admin/university/people/show/_roles.html.erb
@@ -3,43 +3,45 @@
     <div class="card-header">
       <h2 class="card-title mb-0 h5"><%= t('university.person.administrator_roles') %> (<%= involvements.total_count %>)</h2>
     </div>
-    <table class="table">
-      <thead>
-        <tr>
-          <th><%= University::Role.model_name.human %></th>
-          <th></th>
-        </tr>
-      </thead>
-      <tbody>
-        <% involvements.each do |involvement| %>
-          <%
-          role = involvement.target
-          role_target = role.target
-          %>
+    <div class="table-responsive">
+      <table class="<%= table_classes %>">
+        <thead>
           <tr>
-            <td>
-              <%= role.to_s %>
-              <% if role_target.present? %>
-                <br>
-                <small>
-                  <%= role_target.class.model_name.human %> :
-                  <%= link_to_if  can?(:read, role_target),
-                                  role_target,
-                                  [:admin, role_target] if role_target.present? %>
-                </small>
-              <% end %>
-            </td>
-            <td class="text-end">
-              <%= link_to t('remove'),
-                          [:admin, role_target, :role_person, { role_id: role.id, id: involvement.id }],
-                          method: :delete,
-                          data: { confirm: t('please_confirm') },
-                          class: button_classes_danger if can?(:destroy, involvement) %>
-            </td>
+            <th><%= University::Role.model_name.human %></th>
+            <th></th>
           </tr>
-        <% end %>
-      </tbody>
-    </table>
+        </thead>
+        <tbody>
+          <% involvements.each do |involvement| %>
+            <%
+            role = involvement.target
+            role_target = role.target
+            %>
+            <tr>
+              <td>
+                <%= role.to_s %>
+                <% if role_target.present? %>
+                  <br>
+                  <small>
+                    <%= role_target.class.model_name.human %> :
+                    <%= link_to_if  can?(:read, role_target),
+                                    role_target,
+                                    [:admin, role_target] if role_target.present? %>
+                  </small>
+                <% end %>
+              </td>
+              <td class="text-end">
+                <%= link_to t('remove'),
+                            [:admin, role_target, :role_person, { role_id: role.id, id: involvement.id }],
+                            method: :delete,
+                            data: { confirm: t('please_confirm') },
+                            class: button_classes_danger if can?(:destroy, involvement) %>
+              </td>
+            </tr>
+          <% end %>
+        </tbody>
+      </table>
+    </div>
     <% if involvements.total_pages > 1 %>
       <div class="card-footer">
         <%= paginate involvements, theme: 'bootstrap-5', param_name: :roles_page %>
diff --git a/app/views/admin/users/index.html.erb b/app/views/admin/users/index.html.erb
index ba72682ee1b08d693970200749dfa7c7ffbe16b1..ce585ca206e8ceadc9041fd370f92e82e5fbc018 100644
--- a/app/views/admin/users/index.html.erb
+++ b/app/views/admin/users/index.html.erb
@@ -4,37 +4,40 @@
     current_path: admin_users_path,
     filters: @filters if @filters.any? %>
 
-<table class="table">
-  <thead>
-    <tr>
-      <th><%= User.human_attribute_name('last_name') %></th>
-      <th><%= User.human_attribute_name('first_name') %></th>
-      <th><%= User.human_attribute_name('email') %></th>
-      <th><%= User.human_attribute_name('role') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @users.each do |user| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to_if can?(:read, user), user.last_name, [:admin, user] %></td>
-        <td><%= link_to_if can?(:read, user), user.first_name, [:admin, user] %></td>
-        <td><%= link_to user.email, [:admin, user] %></td>
-        <td>
-          <span class="badge bg-secondary">
-            <%= t("activerecord.attributes.user.roles.#{user.role}") %>
-          </span>
-        </td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link user %>
-            <%= destroy_link user %>
-          </div>
-        </td>
+        <th><%= User.human_attribute_name('last_name') %></th>
+        <th><%= User.human_attribute_name('first_name') %></th>
+        <th><%= User.human_attribute_name('email') %></th>
+        <th><%= User.human_attribute_name('role') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @users.each do |user| %>
+        <tr>
+          <td><%= link_to_if can?(:read, user), user.last_name, [:admin, user] %></td>
+          <td><%= link_to_if can?(:read, user), user.first_name, [:admin, user] %></td>
+          <td><%= link_to user.email, [:admin, user] %></td>
+          <td>
+            <span class="badge bg-secondary">
+              <%= t("activerecord.attributes.user.roles.#{user.role}") %>
+            </span>
+          </td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= edit_link user %>
+              <%= destroy_link user %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
+
 <%= paginate @users, theme: 'bootstrap-5' %>
 
 <% content_for :action_bar_right do %>
diff --git a/app/views/admin/users/show.html.erb b/app/views/admin/users/show.html.erb
index 3bdd421afa0ebd100fd394a57f6892306c26f5b1..7c9769a98162e919a1ebedcc8405843d0a294350 100644
--- a/app/views/admin/users/show.html.erb
+++ b/app/views/admin/users/show.html.erb
@@ -8,32 +8,34 @@
       <div class="card-header">
         <h2 class="card-title mb-0 h5"><%= t('admin.infos') %></h2>
       </div>
-      <table class="table">
-        <tr>
-          <td><%= User.human_attribute_name('email') %></td>
-          <td class="text-end"><%= link_to @user.email, "mailto:#{@user.email}" %></td>
-        </tr>
-        <% ['first_name', 'last_name', 'mobile_phone'].each do |variable| %>
+      <div class="table-responsive">
+        <table class="<%= table_classes %>">
           <tr>
-            <td><%= User.human_attribute_name(variable) %></td>
-            <td class="text-end"><%= @user.public_send variable %></td>
+            <td><%= User.human_attribute_name('email') %></td>
+            <td class="text-end"><%= link_to @user.email, "mailto:#{@user.email}" %></td>
           </tr>
-        <% end %>
-        <tr>
-          <td><%= User.human_attribute_name('role') %></td>
-          <td class="text-end"><%= t("activerecord.attributes.user.roles.#{@user.role.to_s}") %></td>
-        </tr>
-        <tr>
-          <td><%= User.human_attribute_name('language') %></td>
-          <td class="text-end"><%= t("languages.#{@user.language.iso_code.to_s}") %></td>
-        </tr>
-        <% if @user.person %>
+          <% ['first_name', 'last_name', 'mobile_phone'].each do |variable| %>
+            <tr>
+              <td><%= User.human_attribute_name(variable) %></td>
+              <td class="text-end"><%= @user.public_send variable %></td>
+            </tr>
+          <% end %>
           <tr>
-            <td><%= User.human_attribute_name('person') %></td>
-            <td class="text-end"><%= link_to @user.person, [:admin, @user.person] %></td>
+            <td><%= User.human_attribute_name('role') %></td>
+            <td class="text-end"><%= t("activerecord.attributes.user.roles.#{@user.role.to_s}") %></td>
           </tr>
-        <% end %>
-      </table>
+          <tr>
+            <td><%= User.human_attribute_name('language') %></td>
+            <td class="text-end"><%= t("languages.#{@user.language.iso_code.to_s}") %></td>
+          </tr>
+          <% if @user.person %>
+            <tr>
+              <td><%= User.human_attribute_name('person') %></td>
+              <td class="text-end"><%= link_to @user.person, [:admin, @user.person] %></td>
+            </tr>
+          <% end %>
+        </table>
+      </div>
     </div>
   </div>
   <% if @user.picture.attached? %>
diff --git a/app/views/application/_logo.html.erb b/app/views/application/_logo.html.erb
index e98dff7805545100858d02858f82c3a7729c880f..210b239329d5eae639d60c4a97cf3824e7549f65 100644
--- a/app/views/application/_logo.html.erb
+++ b/app/views/application/_logo.html.erb
@@ -1,5 +1,5 @@
 <% if current_context.logo.attached? %>
-  <%= image_tag current_context.logo, width: 200, alt: current_context.to_s %>
+  <%= image_tag current_context.logo, width: 200, alt: current_context.to_s, class: 'logo' %>
 <% else %>
   <%= current_context %>
 <% end %>
diff --git a/app/views/devise/mailer/two_factor_authentication_code.html.erb b/app/views/devise/mailer/two_factor_authentication_code.html.erb
index 2f9f3a3a90b3a45461cd64173aaffc5c7d86cd85..599b0cc4ad62d9f7ec7abd0304342087c33bf077 100644
--- a/app/views/devise/mailer/two_factor_authentication_code.html.erb
+++ b/app/views/devise/mailer/two_factor_authentication_code.html.erb
@@ -1 +1 @@
-<p><%= t('devise.mailer.two_factor_authentication_code.text_html', university: @university, code: @code, duration: @duration) %></p>
+<p><%= t('devise.mailer.two_factor_authentication_code.text_html', context: @resource.registration_context, code: @code, duration: @duration) %></p>
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
index 2a6344f84c752e1f1bb5425685d2a9dcca72aada..f83922661f0638f6f0199a2330a210d480747458 100644
--- a/app/views/devise/sessions/new.html.erb
+++ b/app/views/devise/sessions/new.html.erb
@@ -1,22 +1,13 @@
 <div class="row">
   <div class="col-md-6 mb-5">
-    <h2 class="mb-4"><%= t('login.not_registered_yet') %></h2>
-    <p><%= t('login.not_registered_yet_details') %></p>
-    <div class="form-actions">
-      <%= link_to t("devise.registrations.new.sign_up"),
-                  new_registration_path(resource_name),
-                  class: 'btn btn-primary' %>
-    </div>
-  </div>
-  <div class="col-md-6">
     <h2 class="mb-4"><%= t('login.already_registered') %></h2>
-    <% if current_university.has_sso? %>
+    <% if current_context.has_sso? %>
       <p><%= link_to t('login.sign_in_with_sso'), omniauth_authorize_path(resource_name, current_university.sso_provider), method: :post, class: 'btn btn-primary' %></p>
       <p><%= t('login.or') %></p>
       <a href="#collapseLoginForm" class="btn btn-primary mb-3" data-bs-toggle="collapse"><%= t('login.sign_in_with_credentials') %></a>
     <% end %>
 
-    <div class="<%= 'collapse' if current_university.has_sso? %> <%= 'show' unless alert.blank? %>" id="collapseLoginForm">
+    <div class="<%= 'collapse' if current_context.has_sso? %> <%= 'show' unless alert.blank? %>" id="collapseLoginForm">
 
       <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
         <div class="form-inputs">
@@ -53,6 +44,14 @@
         <%= link_to t('devise.shared.links.didn_t_receive_unlock_instructions'), new_unlock_path(resource_name) %><br />
       <% end %>
     </div>
-
+  </div>
+  <div class="col-md-6">
+    <h2 class="mb-4"><%= t('login.not_registered_yet') %></h2>
+    <p><%= t('login.not_registered_yet_details') %></p>
+    <div class="form-actions">
+      <%= link_to t("devise.registrations.new.sign_up"),
+                  new_registration_path(resource_name),
+                  class: 'btn btn-primary' %>
+    </div>
   </div>
 </div>
diff --git a/app/views/extranet/academic_years/index.html.erb b/app/views/extranet/academic_years/index.html.erb
index d16617b4dcb76255558928a1fa4469d4f8402022..f3913b723e3bc07648d1d03bbe533ac61b28c2e5 100644
--- a/app/views/extranet/academic_years/index.html.erb
+++ b/app/views/extranet/academic_years/index.html.erb
@@ -1,12 +1,8 @@
 <% content_for :title, Education::AcademicYear.model_name.human(count: 2) %>
-
-<header class="mb-5">
-  <h1><%= Education::AcademicYear.model_name.human(count: 2) %></h1>
-  <p>
+<% content_for :header_right do %>
     <%= @count %>
     <%= Education::AcademicYear.model_name.human(count: @count).downcase %>
-  </p>
-</header>
+<% end %>
 
 <ul class="years">
   <% @academic_years.each do |year| %>
diff --git a/app/views/extranet/academic_years/show.html.erb b/app/views/extranet/academic_years/show.html.erb
index a4edc23a808fab642cc725da06d52e806a2810bc..4f9a6b708e533f2e23197e8a4bb22dedd2bd52c7 100644
--- a/app/views/extranet/academic_years/show.html.erb
+++ b/app/views/extranet/academic_years/show.html.erb
@@ -1,12 +1,8 @@
 <% content_for :title, @academic_year %>
-
-<header class="mb-5">
-  <h1><%= @academic_year %></h1>
-  <p>
-    <%= @alumni.count %>
-    <%= University::Person::Alumnus.model_name.human(count: @alumni.count).downcase %>
-  </p>
-</header>
+<% content_for :header_right do %>
+  <%= @alumni.count %>
+  <%= University::Person::Alumnus.model_name.human(count: @alumni.count).downcase %>
+<% end %>
 
 <div class="row">
   <div class="col-lg-4">
diff --git a/app/views/extranet/account/edit.html.erb b/app/views/extranet/account/edit.html.erb
index 25b2681db863441340122b34f868e3c7e7ef364b..0f9e85f66c71eebb25181c147a131ab6f087da30 100644
--- a/app/views/extranet/account/edit.html.erb
+++ b/app/views/extranet/account/edit.html.erb
@@ -36,4 +36,12 @@
     </div>
   </div>
   <%= submit f %>
-<% end %>
\ No newline at end of file
+
+  <% if current_user.visitor? %>
+    <%# we don't want the osuny priviledged account to be able to get deleted through extranet %>
+    <h3 class="mt-5 mb-4"><%= t("devise.registrations.edit.cancel_my_account") %></h3>
+
+    <p><%= t("devise.registrations.edit.unhappy") %> <%= link_to t("devise.registrations.edit.cancel_my_account"), registration_path(current_user), data: { confirm: t("devise.registrations.edit.are_you_sure") }, method: :delete %></p>
+  <% end %>
+
+<% end %>
diff --git a/app/views/extranet/account/show.html.erb b/app/views/extranet/account/show.html.erb
index 511cbd41b3952adc82833f0ae10f5a58f0d54989..0e982359e45e73b9dabca82537c4beb47df1ee78 100644
--- a/app/views/extranet/account/show.html.erb
+++ b/app/views/extranet/account/show.html.erb
@@ -1,31 +1,22 @@
 <% content_for :title, @person %>
 
-<%= render 'extranet/persons/header', person: @person unless @person.nil? %>
-
 <div class="row">
   <div class="col-md-9">
-    <div class="biography">
-      <p><%= @person.biography %></p>
-    </div>
-    <div class="experiences">
-      <%= link_to University::Person::Experience.human_attribute_name('new'),
-                  new_experience_path,
-                  class: 'btn btn-sm btn-secondary float-end mb-4' %>
-      <p class="mb-4">Parcours professionel</p>
-      <br>
-      <% if @person.experiences.any? %>
-        <ul>
-          <% @person.experiences.ordered.each do |experience| %>
-            <%= render 'extranet/experiences/experience', experience: experience, edit: true %>
-          <% end %>
-        </ul>
-        <% end %>
+    <div class="biography mb-5">
+      <p><%= @person&.biography %></p>
     </div>
+
+    <p><%= t('extranet.experiences.title') %></p>
+    <%= link_to University::Person::Experience.human_attribute_name('new'),
+                new_experience_path,
+                class: 'btn btn-sm btn-primary mt-md-n5 float-md-end' %>
+    <%= render 'extranet/experiences/list', person: @person, edit: true %>
   </div>
   <div class="col-md-3">
+    <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person&.best_picture.attached? %>
     <div class="mb-4">
-      <%= link_to t('extranet.account.edit'), edit_account_path, class: 'btn btn-primary' %>
-      <%= link_to t('extranet.account.logout'), destroy_user_session_path, method: :delete, class: 'btn text-danger' %>
+      <%= link_to t('extranet.account.edit'), edit_account_path, class: 'btn btn-primary mb-2' %>
+      <%= link_to t('extranet.account.edit_personal_data'), edit_personal_data_path, class: 'btn btn-primary mb-2' %>
     </div>
     <%= render 'extranet/persons/details', person: @person unless @person.nil? %>
   </div>
diff --git a/app/views/extranet/application/_footer.html.erb b/app/views/extranet/application/_footer.html.erb
index 0ea2da91e584d5cee8ea31a267f16ca24323f3ba..4f37174adcd36bfa3f9a722dd0b46dcfccf807d7 100644
--- a/app/views/extranet/application/_footer.html.erb
+++ b/app/views/extranet/application/_footer.html.erb
@@ -1,8 +1,12 @@
+<% hide_logo ||= false %>
+
 <footer class="pt-5">
   <div class="container">
-    <div class="footer-logo pb-5 mb-5 text-center">
-      <%= render 'logo' %>
-    </div>
+    <% unless hide_logo %>
+      <div class="footer-logo pb-5 mb-5 text-center">
+        <%= render 'logo' %>
+      </div>
+    <% end %>
     <div class="row justify-space-between">
       <% if current_extranet.about.is_a?(Education::School) %>
         <address class="col-md-6" itemscope itemtype="https://schema.org/CollegeOrUniversity">
@@ -21,17 +25,17 @@
 
       <nav class="text-md-end col-md-6">
         <%= link_to t('terms_of_service'),
-                    t('terms_of_service_url'),
+                    terms_of_service_path,
                     target: '_blank',
-                    rel: 'noreferrer' %>
+                    rel: 'noreferrer' if current_extranet.has_terms? %>
         <%= link_to t('privacy_policy'),
-                    t('privacy_policy_url'),
+                    privacy_policy_path,
                     target: '_blank',
-                    rel: 'noreferrer' %>
+                    rel: 'noreferrer' if current_extranet.has_privacy_policy? %>
         <%= link_to t('cookies_policy'),
-                    t('cookies_policy_url'),
+                    cookies_policy_path,
                     target: '_blank',
-                    rel: 'noreferrer' %>
+                    rel: 'noreferrer' if current_extranet.has_cookies_policy? %>
         <%= link_to t('cookies_consent_choice'),
                     '',
                     class: 'js-gdpr__cookie_consent__display_again' %>
diff --git a/app/views/extranet/application/_head.html.erb b/app/views/extranet/application/_head.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..5cb446c9c3f7a001762fd0046bccfea59cc157da
--- /dev/null
+++ b/app/views/extranet/application/_head.html.erb
@@ -0,0 +1,27 @@
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+<title><%= yield :title %></title>
+<%= csrf_meta_tags %>
+<%= csp_meta_tag %>
+<%= stylesheet_link_tag 'extranet', media: 'all' %>
+<%= javascript_include_tag 'extranet' %>
+<%= favicon_link_tag 'favicon.png' %>
+<% if current_extranet.color.present? && current_extranet.color != '#000000' %>
+  <style>
+  h1 a {
+    color: <%= current_extranet.color %>;
+    text-decoration-color: <%= current_extranet.color %>66;
+  }
+  h1 a:hover {
+    color: <%= current_extranet.color %>;
+    text-decoration-color: <%= current_extranet.color %>;
+  }
+  .navbar .active .nav-link {
+    color: <%= current_extranet.color %>;
+  }
+  .btn-primary {
+    background-color: <%= current_extranet.color %>;
+    border-color: <%= current_extranet.color %>;
+  }
+  </style>
+<% end %>
\ No newline at end of file
diff --git a/app/views/extranet/application/_header.html.erb b/app/views/extranet/application/_header.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..feb3b9778f4c324d5979e5d1ccf0aaf023e01da2
--- /dev/null
+++ b/app/views/extranet/application/_header.html.erb
@@ -0,0 +1,17 @@
+<header class="header">
+  <div class="container">
+    <%= render_breadcrumbs builder: Appstack::BreadcrumbsOnRailsBuilder if breadcrumbs.any? %>
+    <% if content_for(:header).present? %>
+      <%= yield :header %>
+    <% else %>
+      <h1><%= yield :title %></h1>
+      <p class="header__additional_data">
+        <% if content_for(:header_right).present? %>
+          <%= yield :header_right %>
+        <% else %>
+          &nbsp;
+        <% end %>
+      </p>
+    <% end %>
+  </div>
+</header>
\ No newline at end of file
diff --git a/app/views/extranet/application/_nav.html.erb b/app/views/extranet/application/_nav.html.erb
index 58e9bcb70542ef89bdb8a15e2e4e65ea81719153..13e9921f628e8fb1f88b3c08bf92f2848620e1ba 100644
--- a/app/views/extranet/application/_nav.html.erb
+++ b/app/views/extranet/application/_nav.html.erb
@@ -3,11 +3,27 @@
     <a class="navbar-brand" href="/">
       <%= render 'logo' %>
     </a>
-    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#menu" aria-controls="menu" aria-expanded="false" aria-label="Toggle menu">
-      menu <span class="navbar-toggler-icon"></span>
-    </button>
-    <div class="collapse navbar-collapse" id="menu">
-      <%= render_navigation %>
-    </div>
+    <% if user_signed_in? %>
+      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#menu" aria-controls="menu" aria-expanded="false" aria-label="Toggle menu">
+        <%= t('extranet.menu') %> <span class="navbar-toggler-icon"></span>
+      </button>
+      <div class="collapse navbar-collapse" id="menu">
+        <%= render_navigation context: :extranet %>
+        <ul class="navbar-nav navbar-nav__account">
+          <li class="nav-item dropdown<%= ' active' if '/account'.in?(request.path) %>">
+            <a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
+              <i class="bi bi-person-circle"></i>
+              <%= t('extranet.account.my') %>
+            </a>
+            <ul class="dropdown-menu dropdown-menu-end text-end">
+              <li><%= link_to current_user.to_s, account_path, class: "dropdown-item" %></li>
+              <li><%= link_to t('extranet.account.edit'), edit_account_path, class: "dropdown-item" %></li>
+              <li><%= link_to t('extranet.account.edit_personal_data'), edit_personal_data_path, class: "dropdown-item" %></li>
+              <li><%= link_to t('extranet.account.logout'), destroy_user_session_path, method: :delete, class: "dropdown-item" %></li>
+            </ul>
+          </li>
+        </ul>
+      </div>
+    <% end %>
   </div>
 </nav>
diff --git a/app/views/extranet/cohorts/_index.cards.html.erb b/app/views/extranet/cohorts/_index.cards.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..9128658501682aa86d0d19804ff340f28e4b2fe9
--- /dev/null
+++ b/app/views/extranet/cohorts/_index.cards.html.erb
@@ -0,0 +1,20 @@
+<% cohorts_paged = @cohorts.ordered.page(params[:page]).per(60) %>
+<div class="row">
+  <% cohorts_paged.each do |cohort| %>
+  <div class="col-md-4 col-xl-3">
+    <article class="card mb-5">
+      <div class="card-body">
+        <h2 class="mb-0"><%= link_to cohort.academic_year.year, cohort, class: 'stretched-link' %></h2>
+        <p class="small mb-0">
+          <%= cohort.people.count %>
+          <%= University::Person::Alumnus.model_name.human(count: cohort.people.count).downcase %>
+        </p>
+        <p class="text-end mb-n2">
+          <i class="bi bi-arrow-right"></i>
+        </p>
+      </div>
+    </article>
+  </div>
+  <% end %>
+</div>
+<%= paginate cohorts_paged, theme: 'bootstrap-5', window: 2 %>
diff --git a/app/views/extranet/cohorts/_index.facets.html.erb b/app/views/extranet/cohorts/_index.facets.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..642682d7c9dd4da7bd37f028ef481230577299a0
--- /dev/null
+++ b/app/views/extranet/cohorts/_index.facets.html.erb
@@ -0,0 +1,8 @@
+<div class="row">
+  <div class="col-md-3">
+    <%= render 'faceted_search/facets', facets: @facets %>
+  </div>
+  <div class="col-md-8 offset-md-1">
+    <%= render 'extranet/cohorts/list', cohorts: @cohorts %>
+  </div>
+</div>
diff --git a/app/views/extranet/cohorts/index.html.erb b/app/views/extranet/cohorts/index.html.erb
index 5cc630029fd4b47af9cb84d846dddbd13d48287e..df935d5bfc0a8e9d77c2cf9319ccb1a45607339b 100644
--- a/app/views/extranet/cohorts/index.html.erb
+++ b/app/views/extranet/cohorts/index.html.erb
@@ -1,18 +1,11 @@
 <% content_for :title, Education::Cohort.model_name.human(count: 2) %>
+<% content_for :header_right do %>
+  <%= @count %>
+  <%= Education::Cohort.model_name.human(count: @count).downcase %>
+<% end %>
 
-<header class="mb-5">
-  <h1><%= Education::Cohort.model_name.human(count: 2) %></h1>
-  <p>
-    <%= @count %>
-    <%= Education::Cohort.model_name.human(count: @count).downcase %>
-  </p>
-</header>
-
-<div class="row">
-  <div class="col-md-3">
-    <%= render 'faceted_search/facets', facets: @facets %>
-  </div>
-  <div class="col-md-8 offset-md-1">
-    <%= render 'extranet/cohorts/list', cohorts: @cohorts %>
-  </div>
-</div>
+<% if current_extranet.should_show_years? %>
+  <%= render 'index.facets' %>
+<% else %>
+  <%= render 'index.cards' %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/extranet/cohorts/show.html.erb b/app/views/extranet/cohorts/show.html.erb
index 3ef3148fabc6ce51948804c54d334fa233a43ff7..594c9713096f28fd9f6fd7e5ee45e61b2798b749 100644
--- a/app/views/extranet/cohorts/show.html.erb
+++ b/app/views/extranet/cohorts/show.html.erb
@@ -1,11 +1,12 @@
 <% content_for :title, @cohort %>
+<% content_for :header_right do %>
+  <%= @cohort.people.count %>
+  <%= University::Person::Alumnus.model_name.human(count: @cohort.people.count).downcase %>
+<% end %>
 
-<header class="mb-5">
-  <h1><%= @cohort %></h1>
-  <p>
-    <%= @cohort.people.count %>
-    <%= University::Person::Alumnus.model_name.human(count: @cohort.people.count).downcase %>
-  </p>
-</header>
+<p class="mb-5">
+  <%= @cohort.program.diploma %>
+  <%= @cohort.program %>
+</p>
 
 <%= render 'extranet/persons/list', people: @cohort.people %>
diff --git a/app/views/extranet/experiences/_experience.html.erb b/app/views/extranet/experiences/_experience.html.erb
index d2d10a82eb74f7cbe92af9988d419dfafa9d4781..3052ede2aaf7d300d7da2f531ccdb635f8a7973b 100644
--- a/app/views/extranet/experiences/_experience.html.erb
+++ b/app/views/extranet/experiences/_experience.html.erb
@@ -1,32 +1,28 @@
 <%
 edit ||= false
 %>
-<li>
-  <div>
-    <p><b><%= experience.description %></b></p>
-    <p class="mb-0">
-      <%= "#{experience.from_year} —" if experience.from_year %>
-      <%= experience.to_year || t('today') %>
-    </p>
-  </div>
-  <div>
-    <% if experience.organization.present? %>
-      <p><%= link_to experience.organization, experience.organization %></p>
-      <% if experience.organization.url %>
-        <p class="mb-0"><small><%= link_to experience.organization.url, experience.organization.url %></small></p>
-      <% end %>
-    <% end %>
-  </div>
-  <div>
-    <% if experience.organization.present? %>
-      <% if experience.organization.logo.attached? %>
-          <%= link_to experience.organization do %>
-            <%= kamifusen_tag experience.organization.logo, height: 80, class: 'img-fluid' %>
+<li class="experiences__experience py-4 border-top">
+  <div class="row">
+    <div class="col-md-6">
+      <p class="mb-0">
+        <b><%= experience.description %></b><br>
+        <%= "#{experience.from_year} —" if experience.from_year %>
+        <%= experience.to_year || t('today') %>
+      </p>
+      <%= link_to University::Person::Experience.human_attribute_name('edit'),
+                  edit_experience_path(experience),
+                  class: 'btn btn-sm btn-primary mt-2' if edit %>
+    </div>
+    <div class="col-md-6 text-end">
+      <% if experience.organization.present? %>
+        <%= link_to experience.organization do %>
+          <% if experience.organization.logo.attached? %>
+            <%= kamifusen_tag experience.organization.logo, width: 100, class: 'img-fluid experience__organization__logo' %>
+          <% else %>
+            <p class="text-end><%= link_to experience.organization, experience.organization %></p>
           <% end %>
-      <% end %>
+        <% end %>
+      <div>
     <% end %>
-    <%= link_to University::Person::Experience.human_attribute_name('edit'),
-                edit_experience_path(experience),
-                class: 'btn btn-sm btn-secondary float-end mt-2' if edit %>
   </div>
 </li>
diff --git a/app/views/extranet/experiences/_form.html.erb b/app/views/extranet/experiences/_form.html.erb
index 1c90372f669d745c6eab6da415be9e77eeec0736..96d09eece642aecd845668577659a0bd3b148e1e 100644
--- a/app/views/extranet/experiences/_form.html.erb
+++ b/app/views/extranet/experiences/_form.html.erb
@@ -1,4 +1,15 @@
 <%= simple_form_for experience, url: experience.persisted? ? experience_path(experience) : experiences_path do |f| %>
+
+  <% if experience.errors.any? %>
+    <div id="error_explanation" class="text-danger">
+      <ul class="list-unstyled">
+        <% experience.errors.each do |error| %>
+          <li><%= error.full_message %></li>
+        <% end %>
+      </ul>
+    </div>
+  <% end %>
+
   <div class="row">
     <div class="col-lg-6">
       <%= f.input :description, as: :string %>
@@ -12,8 +23,20 @@
       </div>
     </div>
     <div class="col-lg-6">
-      <%= f.association :organization, include_blank: false %>
-      <%= link_to 'Créer une nouvelle organisation', '', class: 'btn btn-sm btn-secondary mb-4' %>
+      <%= f.input :organization_name,
+                  label: University::Organization.model_name.human,
+                  as: :autocomplete,
+                  url: search_university_organizations_path,
+                  placeholder: t("extranet.experiences.search_organization"),
+                  input_html: {
+                    data: {
+                      "showNoMatches": "false",
+                      "autocomplete-target": "#university_person_experience_organization_id"
+                    },
+                    autocomplete: 'off',
+                    role: 'presentation'
+                  } %>
+      <%= f.hidden_field :organization_id %>
     </div>
   </div>
   <%= submit f %>
diff --git a/app/views/extranet/experiences/_list.html.erb b/app/views/extranet/experiences/_list.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..ae422741e753820cedfee5d7b1e20ea6ae681e6e
--- /dev/null
+++ b/app/views/extranet/experiences/_list.html.erb
@@ -0,0 +1,12 @@
+<%
+edit ||= false
+%>
+<% if person&.experiences.any? %>
+  <div class="experiences mt-4">
+    <ul class="list-unstyled">
+      <% @person.experiences.ordered.each do |experience| %>
+        <%= render 'extranet/experiences/experience', experience: experience, edit: edit %>
+      <% end %>
+    </ul>
+  </div>
+<% end %>
\ No newline at end of file
diff --git a/app/views/extranet/gdpr/_cookie_consent.html.erb b/app/views/extranet/gdpr/_cookie_consent.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..3a1cfe18e18ad1aff4e2fffef35dbf87a7a0dfd3
--- /dev/null
+++ b/app/views/extranet/gdpr/_cookie_consent.html.erb
@@ -0,0 +1,10 @@
+<div class="gdpr__cookie_consent js-gdpr__cookie_consent">
+  <div class="gdpr__cookie_consent__text">
+    <%= t('gdpr.cookie_consent.text') %>
+    <%= t('gdpr.cookie_consent.learn_more_html', link: cookies_policy_path) %>
+  </div>
+  <div class="gdpr__cookie_consent__buttons">
+    <button class="gdpr__cookie_consent__buttons__ok js-gdpr__cookie_consent__buttons__ok btn btn-primary btn-sm btn-xs"> <%= t('gdpr.cookie_consent.button_ok') %></button>
+    <button class="gdpr__cookie_consent__buttons__ko js-gdpr__cookie_consent__buttons__ko btn btn-primary btn-sm btn-xs"> <%= t('gdpr.cookie_consent.button_ko') %></button>
+  </div>
+</div>
\ No newline at end of file
diff --git a/app/views/extranet/home/index.html.erb b/app/views/extranet/home/index.html.erb
index d52d0fe629874f9a8ecc21990e7a37f89a5cf9d7..48168a94af5631bcf60db58abcd615011c0db5e8 100644
--- a/app/views/extranet/home/index.html.erb
+++ b/app/views/extranet/home/index.html.erb
@@ -1,16 +1,27 @@
 <% content_for :title, current_context %>
+<% content_for :header do %>
+  <h1><%# TODO i18n %>
+    Bienvenue sur l’extranet <%= current_context %>. 
+    Retrouvez les <%= link_to University::Person::Alumnus.model_name.human(count: 2).downcase, university_persons_path %>, 
+    <% if current_extranet.should_show_years? %>
+    recherchez par <%= link_to Education::AcademicYear.model_name.human(count: 2).downcase, education_academic_years_path %>, 
+    <% end %>
+    explorez les <%= link_to Education::Cohort.model_name.human(count: 2).downcase, education_cohorts_path %>,
+    découvrez les <%= link_to University::Organization.model_name.human(count: 2).downcase, university_organizations_path %>.
+  </h1>
+<% end %>
 
 <div class="row">
   <div class="col-md-8">
-    <h2>Mouvements récents</h2>
+    <h2><%= t('extranet.home.recent_experiences') %></h2>
     <div class="experiences">
       <ul>
           <% @experiences.ordered.each do |experience| %>
           <li>
             <div>
               <%= link_to experience.person, class: "stretched-link" do %>
-                <% if experience.person.picture.attached? %>
-                  <%= kamifusen_tag experience.person.picture, width: 400, class: 'img-fluid', sizes: {
+                <% if experience.person.best_picture.attached? %>
+                  <%= kamifusen_tag experience.person.best_picture, width: 400, class: 'img-fluid', sizes: {
                         '(max-width: 576px)': '400px',
                         '(max-width: 991px)': '200px'
                     } %>
@@ -25,7 +36,7 @@
                   <%= experience.person.first_name %> <%= experience.person.last_name %>
                   <br>
                   <%= experience.description %>
-                  <%= '—' if experience.description.present? && experience.organization.present? %> 
+                  <%= '—' if experience.description.present? && experience.organization.present? %>
                   <%= experience.organization %>
                 </p>
                 <small><%= l experience.created_at.to_date, format: :long %></small>
@@ -46,11 +57,11 @@
 
 
   <div class="col-md-4 mt-5 mt-md-0">
-    <h2>Promotions actuelles</h2>
+    <h2><%= t('extranet.home.recent_cohorts') %></h2>
     <ul class="promotions">
       <% @cohorts.each do |cohort| %>
         <li>
-          <%= link_to cohort, cohort %>
+          <%= link_to cohort.program.to_short_s, cohort %>
           <b><%= cohort.academic_year %></b>
         </li>
       <% end %>
diff --git a/app/views/extranet/layouts/application.html.erb b/app/views/extranet/layouts/application.html.erb
index 9415ecf20b80fbb782dee51b3b0ca25d654eebac..4d8ed5a4adf866000f9ead78fa6f98c6f8e20cb1 100644
--- a/app/views/extranet/layouts/application.html.erb
+++ b/app/views/extranet/layouts/application.html.erb
@@ -1,23 +1,16 @@
 <!DOCTYPE html>
 <html>
   <head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <title><%= yield :title %></title>
-    <%= csrf_meta_tags %>
-    <%= csp_meta_tag %>
-    <%= stylesheet_link_tag 'extranet', media: 'all' %>
-    <%= javascript_include_tag 'application' %>
-    <%= favicon_link_tag 'favicon.png' %>
+    <%= render 'extranet/application/head' %>
   </head>
   <body class="extranet <%= body_classes %>">
     <%= render 'extranet/application/nav' %>
+    <%= render 'extranet/application/header' %>
     <main class="container">
-      <%= render_breadcrumbs builder: Appstack::BreadcrumbsOnRailsBuilder if breadcrumbs.any? %>
       <%= yield %>
     </main>
     <%= render 'extranet/application/footer' %>
-    <%= render 'gdpr/cookie_consent' %>
+    <%= render 'extranet/gdpr/cookie_consent' %>
     <%= render 'bugsnag' %>
   </body>
 </html>
diff --git a/app/views/extranet/layouts/devise.html.erb b/app/views/extranet/layouts/devise.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b7f167481930971cbab88cf9a03da08a96ebb58e
--- /dev/null
+++ b/app/views/extranet/layouts/devise.html.erb
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <%= render 'extranet/application/head' %>
+  </head>
+  <body class="<%= body_classes %> layout-devise">
+    <main class="container">
+      <div class="row">
+        <div class="offset-md-2 col-md-8">
+          <h1 class="text-center">
+            <%= link_to root_path do %>
+              <%= render 'logo' %>
+            <% end %>
+          </h1>
+          <% unless notice.blank? %>
+            <div class="alert alert-success mt-2" role="alert"><%= notice.html_safe %></div>
+          <% end %>
+          <% unless alert.blank? %>
+            <div class="alert alert-danger mt-2" role="alert"><%= alert.html_safe %></div>
+          <% end %>
+          <%= yield %>
+          <footer>
+            <nav class="d-md-flex justify-content-between py-4">
+              <%= link_to t('terms_of_service'), terms_of_service_path, rel: 'noreferrer' if current_extranet.has_terms? %>
+              <%= link_to t('privacy_policy'), privacy_policy_path, rel: 'noreferrer' if current_extranet.has_privacy_policy? %>
+              <%= link_to t('cookies_policy'), cookies_policy_path, rel: 'noreferrer' if current_extranet.has_cookies_policy? %>
+              <%= link_to t('cookies_consent_choice'), '', class: 'js-gdpr__cookie_consent__display_again' %>
+          </footer>
+        </div>
+      </div>
+    </main>
+    <%= render 'extranet/gdpr/cookie_consent' %>
+    <%= render 'bugsnag' %>
+  </body>
+</html>
diff --git a/app/views/extranet/organizations/_list.erb b/app/views/extranet/organizations/_list.erb
index 4e325ac88aa4db30f86ed575d6867b8e9854fe24..2dc160a7fa2e289a738410d690501b1be08c12d0 100644
--- a/app/views/extranet/organizations/_list.erb
+++ b/app/views/extranet/organizations/_list.erb
@@ -1,8 +1,8 @@
 <% @organizations.each do |organization| %>
   <div class="organization">
-    <p><%= link_to organization, organization %></p>
+    <p class="mb-0"><%= link_to organization, organization %></p>
     <% if organization.url %>
-      <p><small><%= link_to organization.url, organization.url %></small></p>
+      <p class="mb-0 mt-n1"><small><%= link_to organization.url, organization.url %></small></p>
     <% end %>
   </div>
 <% end %>
diff --git a/app/views/extranet/organizations/index.html.erb b/app/views/extranet/organizations/index.html.erb
index 3ebd842b40b192cc05a9b7d7e1231ceebdf86edd..540c86027b1c9d044ce33a4f27f59327a0a71b77 100644
--- a/app/views/extranet/organizations/index.html.erb
+++ b/app/views/extranet/organizations/index.html.erb
@@ -1,13 +1,8 @@
 <% content_for :title, University::Organization.model_name.human(count: 2) %>
-
-<header class="mb-5">
-  <h1><%= University::Organization.model_name.human(count: 2) %></h1>
-  <p>
-    <%= @count %>
-    <%= University::Organization.model_name.human(count: @count).downcase %>
-  </p>
-</header>
-
+<% content_for :header_right do %>
+  <%= @count %>
+  <%= University::Organization.model_name.human(count: @count).downcase %>
+<% end %>
 
 <div class="row">
   <div class="col-md-3">
diff --git a/app/views/extranet/organizations/search.json.jbuilder b/app/views/extranet/organizations/search.json.jbuilder
new file mode 100644
index 0000000000000000000000000000000000000000..e7415127cc28da952dbbbfec3576288c24ba947e
--- /dev/null
+++ b/app/views/extranet/organizations/search.json.jbuilder
@@ -0,0 +1,5 @@
+json.array! @organizations do |organization|
+  json.id organization.id
+  json.label organization.to_s
+  json.value organization.to_s
+end
\ No newline at end of file
diff --git a/app/views/extranet/organizations/show.html.erb b/app/views/extranet/organizations/show.html.erb
index 67d044f7d9422422cebad5a343c9b20bf882274f..05921512fe64bd4b1a393634ce40b8173fdc824b 100644
--- a/app/views/extranet/organizations/show.html.erb
+++ b/app/views/extranet/organizations/show.html.erb
@@ -1,59 +1,59 @@
 <% content_for :title, @organization %>
-<div class="row mb-5 top">
-  <div class="<%= 'col-md-9' if @organization.logo.attached? %>">
-    <header>
-      <h1><%= @organization %></h1>
-      <% if @organization.url %>
-        <p><small><%= link_to @organization.url, @organization.url %></small></p>
-      <% end %>
-    </header>
-  </div>
-  <% if @organization.logo.attached? %>
-    <div class="col-md-3">
-      <%= kamifusen_tag @organization.logo, width: 400, class: 'img-fluid' %>
-    </div>
-  <% end %>
-</div>
-
 
 <div class="row">
-  <div class="col-md-9">
-    <div class="biography">
-      <p><%= @organization.text %></p>
+  <div class="col-md-8 order-2 order-md-1">
+    <div class="row">
+      <div class="col-md-9">
+        <div class="biography mb-5">
+          <p><%= @organization.text %></p>
+        </div>
+      </div>
     </div>
-    <div class="experiences">
-      <p class="mb-4">Alumni dans cette organisation (<%= @organization.experiences.count %>)</p>
-      <ul>
+    <% if @organization.experiences.any? %>
+      <div class="experiences">
+        <p class="mb-4"><%= t('extranet.organization.experiences', count: @organization.experiences.count) %></p>
+        <ul class="list-unstyled">
           <% @organization.experiences.ordered.each do |experience| %>
-          <li class="mb-3">
-            <div>
-              <%= link_to experience.person, class: "stretched-link" do %>
-                <% if experience.person.picture.attached? %>
-                  <%= kamifusen_tag experience.person.picture, width: 200, class: 'img-fluid' %>
-                <% else %>
-                  <%= image_tag 'extranet/avatar.png', width: 200, class: 'img-fluid' %>
-                <% end %>
-              <% end %>
-            </div>
-            <div>
-              <p><b><%= experience.person.name %></b></p>
-              <p>
-                <% if experience.description.present? %>
-                  <%= experience.description %><br>
-                <% end %>
-                <%= "#{experience.from_year} —" if experience.from_year %>
-                <%= experience.to_year || t('today') %>
-              </p>
-            </div>
-          </li>
-        <% end %>
-      </ul>
-    </div>
+            <li class="mb-4">
+              <article class="row position-relative">
+                <div class="col-md-3">
+                  <% if experience.person.best_picture.attached? %>
+                    <%= kamifusen_tag experience.person.best_picture, width: 400, class: 'img-fluid' %>
+                  <% else %>
+                    <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %>
+                  <% end %>
+                </div>
+                <div class="col-md-9 ms-md-n4">
+                  <div class="border-top">
+                    <div class="row pt-4">
+                      <div class="col-md-6">
+                        <p><b><%= link_to experience.person.name, experience.person, class: "stretched-link" %></b></p>
+                      </div>
+                      <div class="col-md-6">
+                        <p class="text-end">
+                          <% if experience.description.present? %>
+                            <%= experience.description %><br>
+                          <% end %>
+                          <%= "#{experience.from_year} —" if experience.from_year %>
+                          <%= experience.to_year || t('today') %>
+                        </p>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </article>
+            </li>
+          <% end %>
+        </ul>
+      </div>
+    <% end %>
   </div>
-  <div class="col-md-3">
+  <div class="offset-md-1 col-md-3 order-1 order-md-2">
+    <%= kamifusen_tag @organization.logo, width: 400, class: 'img-fluid organization__logo' if @organization.logo.attached? %>
+
     <dl>
         <dt><%= University::Organization.human_attribute_name(:kind) %></dt>
-        <dd><%= @organization.kind %></dd>
+        <dd><%= @organization.kind_i18n %></dd>
       <% if @organization.phone.present? %>
         <dt><%= University::Organization.human_attribute_name(:phone) %></dt>
         <dd><a href="tel:<%= @organization.phone %>" target="_blank" rel="noreferrer"><%= @organization.phone %></a></dd>
diff --git a/app/views/extranet/pages/cookies_policy.html.erb b/app/views/extranet/pages/cookies_policy.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..406e9d0b40467f76fe310d44aabf9347016f91af
--- /dev/null
+++ b/app/views/extranet/pages/cookies_policy.html.erb
@@ -0,0 +1,8 @@
+<% content_for :title, Communication::Extranet.human_attribute_name('cookies_policy') %>
+<% content_for :header do %>
+  <h1><%= Communication::Extranet.human_attribute_name('cookies_policy') %></h1>
+<% end %>
+
+<div class="content">
+  <%= sanitize current_extranet.cookies_policy %>
+</div>
\ No newline at end of file
diff --git a/app/views/extranet/pages/privacy_policy.html.erb b/app/views/extranet/pages/privacy_policy.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..f859cb73ed1c9b4b7767bee0f7ebe9e0ee13d94a
--- /dev/null
+++ b/app/views/extranet/pages/privacy_policy.html.erb
@@ -0,0 +1,8 @@
+<% content_for :title, Communication::Extranet.human_attribute_name('privacy_policy') %>
+<% content_for :header do %>
+  <h1><%= Communication::Extranet.human_attribute_name('privacy_policy') %></h1>
+<% end %>
+
+<div class="content">
+  <%= sanitize current_extranet.privacy_policy %>
+</div>
\ No newline at end of file
diff --git a/app/views/extranet/pages/terms_of_service.html.erb b/app/views/extranet/pages/terms_of_service.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..070b829790f0e08835b2b46a49acfb46bf1d5779
--- /dev/null
+++ b/app/views/extranet/pages/terms_of_service.html.erb
@@ -0,0 +1,8 @@
+<% content_for :title, Communication::Extranet.human_attribute_name('terms') %>
+<% content_for :header do %>
+  <h1><%= Communication::Extranet.human_attribute_name('terms') %></h1>
+<% end %>
+
+<div class="content">
+  <%= sanitize current_extranet.terms %>
+</div>
\ No newline at end of file
diff --git a/app/views/extranet/personal_data/edit.html.erb b/app/views/extranet/personal_data/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..76194f740d556de0e9db2f183ec5216adf148d5c
--- /dev/null
+++ b/app/views/extranet/personal_data/edit.html.erb
@@ -0,0 +1,72 @@
+<% content_for :title, @person %>
+
+<%= simple_form_for @person, url: personal_data_path do |f| %>
+  <%= f.error_notification %>
+  <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
+
+  <h2 class="h5 mt-5">
+    <%= University::Person.human_attribute_name('essentials') %>
+  </h2>
+
+  <div class="row">
+    <div class="col-md-4">
+      <%= f.input :gender, label_method: lambda { |g| t("activerecord.attributes.university/person.genders.#{g[1]}") } %>
+      <%= f.input :birthdate, discard_year: true, include_blank: true %>
+    </div>
+    <div class="col-md-8">
+      <%= f.input :biography, 
+                  as: :summernote,
+                  input_html: {
+                    data: { 'summernote-config' => 'mini' }
+                  } %>
+    </div>
+  </div>
+
+  <h2 class="h5 mt-5">
+    <%= University::Person.human_attribute_name('contacts') %>
+  </h2>
+
+  <div class="row">
+    <div class="col-md-4">
+      <%= f.input :phone_mobile %>
+      <%= f.input :phone_professional %>
+      <%= f.input :phone_personal %>
+    </div>
+    <div class="col-md-8">
+      <%= f.input :address %>
+      <div class="row">
+        <div class="col-md-4">
+          <%= f.input :zipcode %>
+        </div>
+        <div class="col-md-8">
+          <%= f.input :city %>
+        </div>
+      </div>
+      <%= f.input :country, input_html: { class: 'form-select' } %>
+    </div>
+  </div>
+  <div class="row">
+    <div class="col-md-6">
+    </div>
+  </div>
+  <div class="row">
+  </div>
+
+  <h2 class="h5 mt-5">
+    <%= University::Person.human_attribute_name('socials') %>
+  </h2>
+
+  <div class="row">
+    <div class="col-md-6">
+      <%= f.input :url %>
+    </div>
+    <div class="col-md-6">
+      <%= f.input :linkedin %>
+    </div>
+    <div class="col-md-6">
+      <%= f.input :twitter %>
+    </div>
+  </div>
+
+  <%= submit f %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/extranet/persons/_details.html.erb b/app/views/extranet/persons/_details.html.erb
index 8d95d637e87c54baa0743fc3546581b9c2a7ca51..e958cec6a1b07e4c3c531e672fc05e957afaf1a4 100644
--- a/app/views/extranet/persons/_details.html.erb
+++ b/app/views/extranet/persons/_details.html.erb
@@ -3,11 +3,12 @@
     <dt><%= cohort.program %></dt>
     <dd><%= link_to cohort.academic_year, cohort %></dd>
   <% end %>
-  <% if person.phone_mobile.present? %>
-    <dt><%= University::Person.human_attribute_name(:phone_mobile) %></dt>
+  <% [:phone_mobile, :phone_personal, :phone_professional].each do |attribute_name| %>
+    <% next if person.public_send(attribute_name).blank? %>
+    <dt><%= University::Person.human_attribute_name(attribute_name) %> :</dt>
     <dd>
-      <a href="tel:<%= person.phone_mobile %>" target="_blank" rel="noreferrer">
-        <%= person.phone_mobile %>
+      <a href="tel:<%= person.public_send(attribute_name) %>" target="_blank" rel="noreferrer">
+        <%= person.public_send(attribute_name) %>
       </a>
     </dd>
   <% end %>
@@ -19,6 +20,10 @@
       </a>
     </dd>
   <% end %>
+  <% if person.full_street_address.present? %>
+    <dt><%= University::Person.human_attribute_name("address") %></dt>
+    <dd><%= person.full_street_address %></dd>
+  <% end %>
   <% if person.url.present? %>
     <dt><%= University::Person.human_attribute_name(:url) %></dt>
     <dd>
diff --git a/app/views/extranet/persons/_header.html.erb b/app/views/extranet/persons/_header.html.erb
deleted file mode 100644
index 1f10fd55f651d71dce5e4522fc74aa853e73fb64..0000000000000000000000000000000000000000
--- a/app/views/extranet/persons/_header.html.erb
+++ /dev/null
@@ -1,14 +0,0 @@
-<div class="row mb-5 top">
-  <div class="col-md-9">
-    <header>
-      <h1><%= person.first_name %> <b><%= person.last_name %></b></h1>
-    </header>
-  </div>
-  <div class="col-md-3">
-    <% if person.best_picture.attached? %>
-      <%= kamifusen_tag person.best_picture, width: 400, class: 'img-fluid' %>
-    <% else %>
-      <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %>
-    <% end %>
-  </div>
-</div>
\ No newline at end of file
diff --git a/app/views/extranet/persons/_person.html.erb b/app/views/extranet/persons/_person.html.erb
index 1374df4e4aaea2a9b6dc0c69ba503dad9e26409c..c77c919cbad300fb80d9d64205a3e5bde5d40e91 100644
--- a/app/views/extranet/persons/_person.html.erb
+++ b/app/views/extranet/persons/_person.html.erb
@@ -1,14 +1,19 @@
-<article class="mb-4 person">
-  <% if person.picture.attached? %>
-    <%= kamifusen_tag person.picture, width: 400, class: 'img-fluid mb-2', 
-      sizes: {
-          '(max-width: 576px)': '400px',
-          '(max-width: 991px)': '200px'
-      } %>
-  <% else %>
-    <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid mb-2' %>
-  <% end %>
-  <%= link_to person, class: 'stretched-link' do %>
-    <%= person.first_name %> <%= person.last_name %>
-  <% end %>
+<article class="person mb-4">
+  <div class="row gx-3">
+    <div class="col-3 col-md-12 mb-md-2">
+      <% if person.best_picture.attached? %>
+        <%= kamifusen_tag person.best_picture, width: 400, class: 'img-fluid',
+          sizes: {
+              '(max-width: 576px)': '400px',
+              '(max-width: 991px)': '200px'
+          } %>
+      <% else %>
+        <%= image_tag 'extranet/avatar.png', width: 400, class: 'img-fluid' %>
+      <% end %>
+    </div>
+    <div class="col-9 col-md-12">
+      <%= link_to person, class: 'stretched-link' do %>
+        <%= person.first_name %> <%= person.last_name %>
+      <% end %>
+    </div>
 </article>
diff --git a/app/views/extranet/persons/index.html.erb b/app/views/extranet/persons/index.html.erb
index 98e8adb832eeb6c4d23bbe269797d8046795dbd0..8265919832f8e6dc457ff57e4ce7395216238633 100644
--- a/app/views/extranet/persons/index.html.erb
+++ b/app/views/extranet/persons/index.html.erb
@@ -1,11 +1,8 @@
 <% content_for :title, University::Person::Alumnus.model_name.human(count: 2) %>
-<header class="mb-5">
-  <h1><%= University::Person::Alumnus.model_name.human(count: 2) %></h1>
-  <p>
-    <%= @count %>
-    <%= University::Person::Alumnus.model_name.human(count: @count).downcase %>
-  </p>
-</header>
+<% content_for :header_right do %>
+  <%= @count %>
+  <%= University::Person::Alumnus.model_name.human(count: @count).downcase %>
+<% end %>
 
 <div class="row">
   <div class="col-lg-3">
diff --git a/app/views/extranet/persons/show.html.erb b/app/views/extranet/persons/show.html.erb
index ad3730db9f88516722aaf8f7cc3eef93837b44d1..538746476aa8ef8eb16ca1afe78d6d4d2a719ad6 100644
--- a/app/views/extranet/persons/show.html.erb
+++ b/app/views/extranet/persons/show.html.erb
@@ -1,24 +1,21 @@
 <% content_for :title, @person %>
 
-<%= render 'extranet/persons/header', person: @person %>
-
 <div class="row">
-  <div class="col-md-9">
-    <div class="biography">
-      <p><%= @person&.biography %></p>
-    </div>
-    <% if @person&.experiences.any? %>
-      <div class="experiences">
-        <p class="mb-4">Parcours professionel</p>
-        <ul>
-          <% @person.experiences.ordered.each do |experience| %>
-            <%= render 'extranet/experiences/experience', experience: experience %>
-          <% end %>
-        </ul>
+  <div class="col-md-8 order-2 order-md-1">
+    <div class="row">
+      <div class="col-md-9">
+        <div class="biography mb-5">
+          <%= @person&.biography %>
+        </div>
       </div>
-    <% end %>
+    </div>
+    <% if @person.experiences.any? %>
+      <p class="mb-4"><%= t('extranet.experiences.title') %></p>
+      <%= render 'extranet/experiences/list', person: @person %>
+    <% end %> 
   </div>
-  <div class="col-md-3">
+  <div class="offset-md-1 col-md-3 order-1 order-md-2">
+    <%= kamifusen_tag @person.best_picture, width: 400, class: 'img-fluid person__portrait' if @person.best_picture.attached? %>
     <%= render 'extranet/persons/details', person: @person %>
   </div>
 </div>
diff --git a/app/views/layouts/devise.html.erb b/app/views/layouts/devise.html.erb
index 1d4c61febad03503e020267c100bfca43418091a..ad40226ca8467fd3cd9691242cccb72b41a670ab 100644
--- a/app/views/layouts/devise.html.erb
+++ b/app/views/layouts/devise.html.erb
@@ -7,7 +7,7 @@
     <%= csrf_meta_tags %>
     <%= csp_meta_tag %>
     <%= stylesheet_link_tag 'admin', media: 'all' %>
-    <%= javascript_include_tag 'admin' %>
+    <%= javascript_include_tag 'devise' %>
     <%= favicon_link_tag 'favicon.png' %>
   </head>
   <body class="<%= body_classes %>">
diff --git a/app/views/server/blocks/index.html.erb b/app/views/server/blocks/index.html.erb
index c19fa8b04903938eeef8dc33fb7e048f186a3564..e4c4deb8970ac3369e70e2894651bb031fefac6b 100644
--- a/app/views/server/blocks/index.html.erb
+++ b/app/views/server/blocks/index.html.erb
@@ -1,18 +1,20 @@
 <% content_for :title, Communication::Block.model_name.human(count: 2) %>
 
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Communication::Block.human_attribute_name('name') %></th>
-      <th><%= Communication::Block.human_attribute_name('quantity') %></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @templates.each do |template| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to t("enums.communication.block.template_kind.#{template}"), server_block_path(template) %></td>
-        <td><%= Communication::Block.send(template).count %></td>
+        <th><%= Communication::Block.human_attribute_name('name') %></th>
+        <th><%= Communication::Block.human_attribute_name('quantity') %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @templates.each do |template| %>
+        <tr>
+          <td><%= link_to t("enums.communication.block.template_kind.#{template}"), server_block_path(template) %></td>
+          <td><%= Communication::Block.send(template).count %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
diff --git a/app/views/server/blocks/show.html.erb b/app/views/server/blocks/show.html.erb
index f942741ab2048afd0c50bd9c5426c070f58bc523..b56285d126ae23d1b69fca2f8add0894e7acb6bb 100644
--- a/app/views/server/blocks/show.html.erb
+++ b/app/views/server/blocks/show.html.erb
@@ -1,38 +1,40 @@
 <% content_for :title, t("enums.communication.block.template_kind.#{@template}") %>
 
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Communication::Block.human_attribute_name('name') %></th>
-      <th><%= Communication::Block.human_attribute_name('about') %></th>
-      <th><%= Communication::Block.human_attribute_name('data') %></th>
-      <th><%= Communication::Block.human_attribute_name('university') %></th>
-      <th><%= Communication::Block.human_attribute_name('url') %></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @blocks.each do |block| %>
-      <% next if block.about.nil?%>
-      <% url = "#{block.about.university.url }#{edit_admin_communication_block_path(block)}" %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= truncate "#{block}" %></td>
-        <td>
-          <%= truncate "#{block.about}" %>
-          <span class="badge bg-dark">
-            <%= block.about.class.model_name.human %>
-          </span>
-        </td>
-        <td>
-          <textarea rows="1" class="form-control"><%= block.data %></textarea>
-        </td>
-        <td><%= block.about.university %></td>
-        <td><%= link_to 'Open',
-                        url,
-                        target: :_blank %></td>
+        <th><%= Communication::Block.human_attribute_name('name') %></th>
+        <th><%= Communication::Block.human_attribute_name('about') %></th>
+        <th><%= Communication::Block.human_attribute_name('data') %></th>
+        <th><%= Communication::Block.human_attribute_name('university') %></th>
+        <th><%= Communication::Block.human_attribute_name('url') %></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @blocks.each do |block| %>
+        <% next if block.about.nil?%>
+        <% url = "#{block.about.university.url }#{edit_admin_communication_block_path(block)}" %>
+        <tr>
+          <td><%= truncate "#{block}" %></td>
+          <td>
+            <%= truncate "#{block.about}" %>
+            <span class="badge bg-dark">
+              <%= block.about.class.model_name.human %>
+            </span>
+          </td>
+          <td>
+            <textarea rows="1" class="form-control"><%= block.data %></textarea>
+          </td>
+          <td><%= block.about.university %></td>
+          <td><%= link_to 'Open',
+                          url,
+                          target: :_blank %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <% content_for :action_bar_right do %>
   <%= link_to t('resave'),
diff --git a/app/views/server/languages/index.html.erb b/app/views/server/languages/index.html.erb
index 5a26dd08137ad674666e8e1eb9f4c808a118fdec..ccc92cb8f45fa6fe91199c2021e0ee26505ad0f5 100644
--- a/app/views/server/languages/index.html.erb
+++ b/app/views/server/languages/index.html.erb
@@ -1,35 +1,37 @@
 <% content_for :title, Language.model_name.human(count: 2) %>
 
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= Language.human_attribute_name('name') %></th>
-      <th><%= Language.human_attribute_name('iso_code') %></th>
-      <th></th>
-    </tr>
-  </thead>
-
-  <tbody>
-    <% @languages.each do |language| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to language, [:server, language] %></td>
-        <td><%= language.iso_code %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                      edit_server_language_path(language),
-                      class: button_classes %>
-            <%= link_to t('delete'),
-                      server_language_path(language),
-                      method: :delete,
-                      data: { confirm: t('please_confirm') },
-                      class: button_classes_danger %>
-          </div>
-        </td>
+        <th><%= Language.human_attribute_name('name') %></th>
+        <th><%= Language.human_attribute_name('iso_code') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+
+    <tbody>
+      <% @languages.each do |language| %>
+        <tr>
+          <td><%= link_to language, [:server, language] %></td>
+          <td><%= language.iso_code %></td>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                        edit_server_language_path(language),
+                        class: button_classes %>
+              <%= link_to t('delete'),
+                        server_language_path(language),
+                        method: :delete,
+                        data: { confirm: t('please_confirm') },
+                        class: button_classes_danger %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <% content_for :action_bar_right do %>
   <%= link_to t('create'), new_server_language_path, class: button_classes %>
diff --git a/app/views/server/languages/show.html.erb b/app/views/server/languages/show.html.erb
index f1542c6c8b96a4eb8c1cf6718d54292d2615db4d..72b772534b1e75e877f5c3743272f60b6a26d35e 100644
--- a/app/views/server/languages/show.html.erb
+++ b/app/views/server/languages/show.html.erb
@@ -6,14 +6,16 @@
       <div class="card-header">
         <h2 class="card-title"><%= t('admin.infos') %></h2>
       </div>
-      <table class="table">
-        <% ['iso_code'].each do |variable| %>
-          <tr>
-            <td><%= Language.human_attribute_name(variable) %></td>
-            <td class="text-end"><%= @language.public_send variable %></td>
-          </tr>
-        <% end %>
-      </table>
+      <div class="table-responsive">
+        <table class="<%= table_classes %>">
+          <% ['iso_code'].each do |variable| %>
+            <tr>
+              <td><%= Language.human_attribute_name(variable) %></td>
+              <td class="text-end"><%= @language.public_send variable %></td>
+            </tr>
+          <% end %>
+        </table>
+      </div>
     </div>
   </div>
 </div>
diff --git a/app/views/server/universities/_form.html.erb b/app/views/server/universities/_form.html.erb
index a08d955d57cb8dd5b58ae9d2db276c7ecfce8559..9dfd61fc25e325fe42de748d554f22fe43fb095a 100644
--- a/app/views/server/universities/_form.html.erb
+++ b/app/views/server/universities/_form.html.erb
@@ -44,7 +44,7 @@
     <div class="col-md-6 sso-inputs">
       <h4 class="mb-4"><%= University.human_attribute_name('sso_mapping') %></h4>
       <%= f.error_notification message: f.object.errors[:sso_mapping].to_sentence if f.object.errors[:sso_mapping].present? %>
-      <%= render 'sso_mapping', university: university %>
+      <%= render 'sso_mapping', object: university %>
     </div>
   </div>
 
diff --git a/app/views/server/universities/_sso_mapping.html.erb b/app/views/server/universities/_sso_mapping.html.erb
index 7bdb320c2cdcf00863c2af89c69f1ae31dd29bae..19eee43d893cc54a8c7a160f55db7d0b0e955828 100644
--- a/app/views/server/universities/_sso_mapping.html.erb
+++ b/app/views/server/universities/_sso_mapping.html.erb
@@ -1,4 +1,11 @@
-<% mapping_keys = ['email', 'first_name', 'last_name', 'role', 'mobile_phone', 'language', 'picture_url'] %>
+<%
+kind = object.class.name.underscore.gsub('/', '_')
+if kind == 'university'
+  mapping_keys = ['email', 'first_name', 'last_name', 'role', 'mobile_phone', 'language', 'picture_url']
+else
+  mapping_keys = ['email', 'first_name', 'last_name', 'mobile_phone', 'language', 'picture_url']
+end
+%>
 
 <%# Include vue.js before call Vue.createApp %>
 <%= javascript_include_tag 'vue' %>
@@ -40,15 +47,17 @@
                 <option v-for="(label, key) in keys" :value="key">{{ label }}</option>
               </select>
             </div>
-            <div v-if="field.internal_key === 'role'">
-              <hr class="mt-4">
-              <% User.roles.keys.each do |role| %>
-                <div class="form-group">
-                  <label for="" class="form-label"><%= t("activerecord.attributes.user.roles.#{role}") %></label>
-                  <input v-model="field.roles.<%= role %>" type="text" class="form-control">
-                </div>
-              <% end %>
-            </div>
+            <% if kind == 'university' %>
+              <div v-if="field.internal_key === 'role'">
+                <hr class="mt-4">
+                <% User.roles.keys.each do |role| %>
+                  <div class="form-group">
+                    <label for="" class="form-label"><%= t("activerecord.attributes.user.roles.#{role}") %></label>
+                    <input v-model="field.roles.<%= role %>" type="text" class="form-control">
+                  </div>
+                <% end %>
+              </div>
+            <% end %>
           </div>
         </div>
       </div>
@@ -59,7 +68,7 @@
     </a>
   </div>
 
-  <textarea name="university[sso_mapping]" id="university_sso_mapping" rows="20" cols="200" class="d-none">
+  <textarea name="<%= kind %>[sso_mapping]" id="<%= kind %>_sso_mapping" rows="20" cols="200" class="d-none">
     {{ JSON.stringify(fields) }}
   </textarea>
 
@@ -72,7 +81,7 @@
     },
     data() {
       return {
-        fields: <%= university.sso_mapping.blank? ? '[]' : university.sso_mapping.to_json.html_safe %>,
+        fields: <%= object.sso_mapping.blank? ? '[]' : object.sso_mapping.to_json.html_safe %>,
         keys: <%= mapping_keys.map { |key| [key, User.human_attribute_name(key)] }.to_h.to_json.html_safe %>
       }
     }
diff --git a/app/views/server/universities/index.html.erb b/app/views/server/universities/index.html.erb
index 0c266778609d1ea9eaf1c654fe23ec78afee0e52..17c0ece0150f8fc9304043592a16a3678cdd0a87 100644
--- a/app/views/server/universities/index.html.erb
+++ b/app/views/server/universities/index.html.erb
@@ -1,45 +1,47 @@
-<% content_for :title, University.model_name.human(count: 2) %>
+<% content_for :title, "#{ @universities.count} #{University.model_name.human(count:  @universities.count).downcase}" %>
 
-<table class="<%= table_classes %>">
-  <thead>
-    <tr>
-      <th><%= University.human_attribute_name('name') %></th>
-      <th><%= University.human_attribute_name('url') %></th>
-      <th><%= University.human_attribute_name('public_or_private') %></th>
-      <th><%= University.human_attribute_name('invoice_date') %></th>
-      <th><%= University.human_attribute_name('invoice_amount') %></th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @universities.each do |university| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= link_to university, [:server, university] %></td>
-        <td><%= link_to university.url, university.url, target: :_blank %></td>
-        <td><%= university.private ? University.human_attribute_name('private') : University.human_attribute_name('public') %></td>
-        <% if university.invoice_amount.blank? %>
-          <td></td>
-          <td></td>
-        <% else %>
-          <td class="<%= university.invoice_proximity.blank? ? '' : "table-#{university.invoice_proximity}" %>"><%= l university.invoice_date, format: "%d %B" unless university.invoice_amount.blank? %></td>
-          <td class="<%= university.invoice_proximity.blank? ? '' : "table-#{university.invoice_proximity}" %>"><%= university.invoice_amount %></td>
-        <% end %>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= link_to t('edit'),
-                      edit_server_university_path(university),
-                      class: button_classes %>
-            <%= link_to t('delete'),
-                      server_university_path(university),
-                      method: :delete,
-                      data: { confirm: t('please_confirm') },
-                      class: button_classes_danger %>
-          </div>
-        </td>
+        <th><%= University.human_attribute_name('name') %></th>
+        <th><%= University.human_attribute_name('url') %></th>
+        <th><%= University.human_attribute_name('public_or_private') %></th>
+        <th><%= University.human_attribute_name('invoice_date') %></th>
+        <th><%= University.human_attribute_name('invoice_amount') %></th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @universities.each do |university| %>
+        <tr>
+          <td><%= link_to university, [:server, university] %></td>
+          <td><%= link_to university.url, university.url, target: :_blank %></td>
+          <td><%= university.private ? University.human_attribute_name('private') : University.human_attribute_name('public') %></td>
+          <% if university.invoice_amount.blank? %>
+            <td></td>
+            <td></td>
+          <% else %>
+            <td class="<%= university.invoice_proximity.blank? ? '' : "table-#{university.invoice_proximity}" %>"><%= l university.invoice_date, format: "%d %B" unless university.invoice_amount.blank? %></td>
+            <td class="<%= university.invoice_proximity.blank? ? '' : "table-#{university.invoice_proximity}" %>"><%= university.invoice_amount %></td>
+          <% end %>
+          <td class="text-end">
+            <div class="btn-group" role="group">
+              <%= link_to t('edit'),
+                        edit_server_university_path(university),
+                        class: button_classes %>
+              <%= link_to t('delete'),
+                        server_university_path(university),
+                        method: :delete,
+                        data: { confirm: t('please_confirm') },
+                        class: button_classes_danger %>
+            </div>
+          </td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <% content_for :action_bar_right do %>
   <%= link_to t('create'), new_server_university_path, class: button_classes %>
diff --git a/app/views/server/universities/show.html.erb b/app/views/server/universities/show.html.erb
index acdb02e7ae399f4a329a9f6abd3b90b9b22c7e8a..5c19f84f8010e83810729ee5e277b98c0a84d143 100644
--- a/app/views/server/universities/show.html.erb
+++ b/app/views/server/universities/show.html.erb
@@ -6,53 +6,57 @@
       <div class="card-header">
         <h2 class="card-title"><%= t('admin.infos') %></h2>
       </div>
-      <table class="table">
-        <tr>
-          <td><%= t('activerecord.attributes.university.url') %></td>
-          <td class="text-end"><%= link_to @university.url, @university.url, target: :_blank %></td>
-        </tr>
-        <% ['address', 'zipcode', 'city', 'country', 'private'].each do |variable| %>
+      <div class="table-responsive">
+        <table class="<%= table_classes %>">
           <tr>
-            <td><%= University.human_attribute_name(variable) %></td>
-            <td class="text-end"><%= @university.public_send variable %></td>
-          </tr>
-        <% end %>
-        <% unless @university.invoice_amount.blank? %>
-          <tr class="<%= @university.invoice_proximity.blank? ? '' : "table-#{@university.invoice_proximity}" %>">
-            <td><%= t('activerecord.attributes.university.invoice_date') %></td>
-            <td class="text-end"><%= l @university.invoice_date, format: "%d %B" %></td>
-          </tr>
-          <tr class="<%= @university.invoice_proximity.blank? ? '' : "table-#{@university.invoice_proximity}" %>">
-            <td><%= t('activerecord.attributes.university.invoice_amount') %></td>
-            <td class="text-end"><%= @university.invoice_amount %>€</td>
+            <td><%= t('activerecord.attributes.university.url') %></td>
+            <td class="text-end"><%= link_to @university.url, @university.url, target: :_blank %></td>
           </tr>
-        <% end %>
-      </table>
+          <% ['address', 'zipcode', 'city', 'country', 'private'].each do |variable| %>
+            <tr>
+              <td><%= University.human_attribute_name(variable) %></td>
+              <td class="text-end"><%= @university.public_send variable %></td>
+            </tr>
+          <% end %>
+          <% unless @university.invoice_amount.blank? %>
+            <tr class="<%= @university.invoice_proximity.blank? ? '' : "table-#{@university.invoice_proximity}" %>">
+              <td><%= t('activerecord.attributes.university.invoice_date') %></td>
+              <td class="text-end"><%= l @university.invoice_date, format: "%d %B" %></td>
+            </tr>
+            <tr class="<%= @university.invoice_proximity.blank? ? '' : "table-#{@university.invoice_proximity}" %>">
+              <td><%= t('activerecord.attributes.university.invoice_amount') %></td>
+              <td class="text-end"><%= @university.invoice_amount %>€</td>
+            </tr>
+          <% end %>
+        </table>
+      </div>
     </div>
   </div>
 </div>
 
 <h2>Blocks</h2>
-<table class="table">
-  <thead>
-    <tr>
-      <th>Block</th>
-      <th>About</th>
-      <th>Template</th>
-      <th></th>
-    </tr>
-  </thead>
-  <tbody>
-    <% @university.communication_blocks.each do |block| %>
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
       <tr>
-        <td><%= block %></td>
-        <td><%= block.about %></td>
-        <td><%= block.template_kind %></td>
-        <td><%= edit_link block %></td>
+        <th>Block</th>
+        <th>About</th>
+        <th>Template</th>
+        <th></th>
       </tr>
-    <% end %>
-  </tbody>
-</table>
+    </thead>
+    <tbody>
+      <% @university.communication_blocks.each do |block| %>
+        <tr>
+          <td><%= block %></td>
+          <td><%= block.about %></td>
+          <td><%= block.template_kind %></td>
+          <td><%= edit_link block %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
 
 <% content_for :action_bar_right do %>
   <%= link_to t('edit'), edit_server_university_path(@university), class: button_classes %>
diff --git a/app/views/server/websites/index.html.erb b/app/views/server/websites/index.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..e0766b309807af79a0d4acc01841e62b3287f57e
--- /dev/null
+++ b/app/views/server/websites/index.html.erb
@@ -0,0 +1,26 @@
+<% content_for :title, "#{@websites.count} #{Communication::Website.model_name.human(count: @websites.count).downcase}" %>
+
+<p><%= Communication::Website.in_production.count %> en production</p>
+
+<div class="table-responsive">
+  <table class="<%= table_classes %>">
+    <thead>
+      <tr>
+        <th><%= Communication::Website.human_attribute_name('name') %></th>
+        <th><%= Communication::Website.human_attribute_name('url') %></th>
+        <th><%= Communication::Website.human_attribute_name('in_production') %></th>
+        <th><%= University.model_name.human %></th>
+      </tr>
+    </thead>
+    <tbody>
+      <% @websites.each do |website| %>
+        <tr>
+          <td><%= website.name %></td>
+          <td><%= link_to website.url, website.url, target: :_blank if website.url.present? %></td>
+          <td><%= t website.in_production %></td>
+          <td><%= link_to website.university, [:server, website.university] %></td>
+        </tr>
+      <% end %>
+    </tbody>
+  </table>
+</div>
\ No newline at end of file
diff --git a/config/application.yml.sample b/config/application.sample.yml
similarity index 69%
rename from config/application.yml.sample
rename to config/application.sample.yml
index a8dd38dc1a8cf1fc45fcec05f523897f2a469684..338afbeee4ebf843c29d7e1157a09cf5817e6246 100644
--- a/config/application.yml.sample
+++ b/config/application.sample.yml
@@ -26,3 +26,12 @@ SMTP_PASSWORD:
 
 UNSPLASH_ACCESS_KEY:
 UNSPLASH_SECRET: 
+
+# Pour les tests automatisés
+TEST_GITHUB_ENDPOINT: '' # no use for github
+TEST_GITHUB_TOKEN: 
+TEST_GITHUB_REPOSITORY: 
+
+TEST_GITLAB_ENDPOINT: 
+TEST_GITLAB_TOKEN: 
+TEST_GITLAB_REPOSITORY: 
diff --git a/config/navigation.rb b/config/extranet_navigation.rb
similarity index 83%
rename from config/navigation.rb
rename to config/extranet_navigation.rb
index c3f27ac3c1cd5c88e3645a32172d488d45127d3d..2a505cb1d75da292af45324c85bd5fc484d5e1eb 100644
--- a/config/navigation.rb
+++ b/config/extranet_navigation.rb
@@ -9,15 +9,12 @@ SimpleNavigation::Configuration.run do |navigation|
                   university_persons_path
     primary.item  :years,
                   Education::AcademicYear.model_name.human(count: 2),
-                  education_academic_years_path
+                  education_academic_years_path if current_extranet.should_show_years?
     primary.item  :cohorts,
                   Education::Cohort.model_name.human(count: 2),
                   education_cohorts_path
     primary.item  :organizations,
                   University::Organization.model_name.human(count: 2),
                   university_organizations_path
-    primary.item  :account,
-                  t('extranet.account.my'),
-                  account_path
   end
-end
+end
\ No newline at end of file
diff --git a/config/locales/communication/en.yml b/config/locales/communication/en.yml
index 7f8b75f3d6e8ad2b336c572a89cba21dcfbe1b42..cd80a8effb9347564753b193cf4e9b3178b9528d 100644
--- a/config/locales/communication/en.yml
+++ b/config/locales/communication/en.yml
@@ -48,8 +48,19 @@ en:
         about_Research::Journal: Journal extranet
         about_Research::Laboratory: Laboratory extranet
         about_type: About
-        title: Title
-        domain: Domain
+        color: Couleur
+        cookies_policy: Cookies policy
+        privacy_policy: Privacy policy
+        terms: Terms of service
+        has_sso: Has SSO?
+        host: Domain
+        name: Name
+        registration_contact: Contact mail for registrations problems
+        sso_cert: Certificate
+        sso_inherit_from_university: SSO inherited from University
+        sso_mapping: Mapping
+        sso_name_identifier_format: Name Identifier Format
+        sso_target_url: Target URL
       communication/website:
         about: About
         about_: Independent website
@@ -59,8 +70,10 @@ en:
         about_Research::Laboratory: Laboratory website
         about_type: About
         access_token: Access token
+        git_branch: Git branch
         git_endpoint: Git endpoint
         git_provider: Git provider
+        in_production: Production
         languages: Languages
         name: Name
         repository: Repository
@@ -122,6 +135,12 @@ en:
         text: Text
         title: Title
         website: Website
+    errors:
+      models:
+        communication/extranet:
+          attributes:
+            sso_mapping:
+              missing_email: doesn't handle the email
   admin:
     communication:
       blocks:
@@ -214,23 +233,23 @@ en:
                 label: Description
                 placeholder: Enter description here
               element:
-                title: 
+                title:
                   label: Day
                   placeholder: Enter the day or period
                 time_slot_morning:
                   label: Morning (if necessary)
                 time_slot_afternoon:
                   label: Afternoon (or full day)
-              name: 
+              name:
                 label: Name (person, organization...)
                 placeholder: Enter the text
               zipcode:
                 label: Zipcode
                 placeholder: Enter the zipcode
-              mails: 
+              mails:
                 label: Mails
                 placeholder: Enter the mail
-              phones: 
+              phones:
                 label: Telephone numbers
                 placeholder: Enter the number
               slots: Opening times
@@ -324,10 +343,12 @@ en:
               add_person: Add person
               drag_title: Drag and drop to organize persons
               delete_title: Remove person
+              alphabetical:
+                label: Alphabetical order
               description:
                 label: Description
               with_link:
-                label: With clickable links to the person's page?
+                label: With clickable link to each person's page?
               with_photo:
                 label: With a portrait for each person?
               element:
@@ -355,11 +376,11 @@ en:
                 options:
                   children: Main page and children
                   selection: A specific selection of pages
-              show_main_description: 
+              show_main_description:
                 label: Show main page short description
-              show_description: 
+              show_description:
                 label: Show pages short descriptions
-              show_image: 
+              show_image:
                 label: Show pages images
               main_page:
                 title: Main page
@@ -379,8 +400,12 @@ en:
             edit:
               add_partner: Add partner
               remove_partner: Remove partner
+              alphabetical:
+                label: Alphabetical order
+              with_link:
+                label: With clickable link to each organization's page?
               element:
-                id: 
+                id:
                   label: Partner
                   placeholder: Choose organization
                   unregistered: Unregistered organization
@@ -463,7 +488,7 @@ en:
                 label: Video url
                 placeholder: Enter video's url
                 hint: >
-                  Ex: 
+                  Ex:
                   https://vimeo.com/732180675,
                   https://www.youtube.com/watch?v=lAYhfCPelO0
               video_title:
@@ -638,6 +663,7 @@ en:
   simple_form:
     hints:
       communication_website:
+        git_branch: 'If blank, default branch will be used'
         git_endpoint: 'If blank, default will be used (https://github.com or https://gitlab.com/api/v4)'
         languages: 'If you select at least one language the website will be considered as possibly multilingual, and therefore all urls will be prefixed with the language (/fr, /en)'
       communication_website_category:
@@ -645,6 +671,6 @@ en:
       communication_website_page:
         breadcrumb_title: If the field is empty, page title will be used in breadcrumbs.
         description: If this field is empty, the "lead text" field will be used. If also emty the main text's begining will be used.
-        full_width: On large screens, a full width page uses all available space for the content. This is good for landing pages, or to make them spectacular. If the page is not full width, the content column will be smaller to make reading easier. The unused space might be used for a table of contents. 
+        full_width: On large screens, a full width page uses all available space for the content. This is good for landing pages, or to make them spectacular. If the page is not full width, the content column will be smaller to make reading easier. The unused space might be used for a table of contents.
       communication_website_post:
         description: If this field is empty, the "lead text" field will be used. If also emty the main text's begining will be used.
diff --git a/config/locales/communication/fr.yml b/config/locales/communication/fr.yml
index a14ed5e956316c7022a426825656a24e8512bb75..708e029d0496406689b685e031b68ed5a7ded240 100644
--- a/config/locales/communication/fr.yml
+++ b/config/locales/communication/fr.yml
@@ -48,8 +48,19 @@ fr:
         about_Research::Journal: Extranet d'une revue scientifique
         about_Research::Laboratory: Extranet d'un laboratoire
         about_type: Type d'extranet
+        color: Couleur
+        cookies_policy: Politique de cookies
+        has_sso: A un SSO ?
+        host: Domaine
         name: Nom
-        domain: Domaine
+        privacy_policy: Politique de confidentialité
+        registration_contact: Mail de contact pour les problèmes d'inscription
+        sso_cert: Certificat
+        sso_inherit_from_university: SSO hérité de l'Université
+        sso_mapping: Mapping
+        sso_name_identifier_format: Name Identifier Format
+        sso_target_url: URL cible
+        terms: Conditions d'utilisation
       communication/website:
         about: Sujet du site
         about_: Site indépendant
@@ -59,8 +70,10 @@ fr:
         about_Research::Laboratory: Site de laboratoire
         about_type: Type de site
         access_token: Access token
+        git_branch: Branche
         git_endpoint: Point d'accès Git
         git_provider: Provider Git
+        in_production: Site en production
         languages: Langues
         name: Nom
         repository: Repository
@@ -123,6 +136,12 @@ fr:
         text: Texte
         title: Titre
         website: Site Web
+    errors:
+      models:
+        communication/extranet:
+          attributes:
+            sso_mapping:
+              missing_email: ne gère pas l'adresse email
   admin:
     communication:
       blocks:
@@ -215,26 +234,26 @@ fr:
                 label: Description
                 placeholder: Entrer la description
               element:
-                title: 
+                title:
                   label: Jour
                   placeholder: Entrer le jour ou la période
                 time_slot_morning:
                   label: Matin (si nécessaire)
                 time_slot_afternoon:
                   label: Après-midi (ou jour complet)
-              name: 
+              name:
                 label: Nom (personne, établissement...)
                 placeholder: Entrer le texte
               zipcode:
                 label: Code postal
                 placeholder: Entrer le code postal
-              mails: 
+              mails:
                 label: Mails
                 placeholder: Entrer le mail
-              phones: 
+              phones:
                 label: Téléphones
                 placeholder: Entrer le numéro
-              slots: Horaires  
+              slots: Horaires
           datatable:
             description: Un tableau de données, aussi responsive et accessible que possible.
             edit:
@@ -322,11 +341,13 @@ fr:
                   label: Description
                   placeholder: Entrer la description
           organization_chart:
-            description: Un organigramme présentant des personnes et leur fonction.
+            description: Une liste de personnes, avec photo, fonction et lien vers la page de la personne.
             edit:
               add_person: Ajouter une personne
               drag_title: Glisser-déposer pour organiser les personnes
               delete_title: Enlever la personne
+              alphabetical:
+                label: Ordre alphabétique
               with_link:
                 label: Avec des liens cliquables vers les pages des personnes ?
               with_photo:
@@ -378,12 +399,16 @@ fr:
               display:
                 title: Options d'affichage
           partners:
-            description: Une liste de partenaires, avec leur logo, leur site et leur nom.
+            description: Une liste d'organisations, avec leur logo, leur site et leur nom.
             edit:
               add_partner: Ajouter un partenaire
               remove_partner: Enlever le partenaire
               description:
                 label: Description
+              alphabetical:
+                label: Ordre alphabétique
+              with_link:
+                label: Avec des liens cliquables vers les pages des organisations?
               element:
                 id:
                   label: Organisation
@@ -468,7 +493,7 @@ fr:
                 label: Url de la vidéo
                 placeholder: Entrer l'url de la vidéo
                 hint: >
-                  Ex: 
+                  Ex:
                   https://vimeo.com/732180675,
                   https://www.youtube.com/watch?v=lAYhfCPelO0
               video_title:
@@ -608,9 +633,9 @@ fr:
           gallery: Galerie
           image: Image
           key_figures: Chiffres-clés
-          organization_chart: Organigramme
+          organization_chart: Personnes
           pages: Pages
-          partners: Partenaires
+          partners: Organisations
           posts: Actualités
           programs: Formations
           testimonials: Témoignages
@@ -643,6 +668,7 @@ fr:
   simple_form:
     hints:
       communication_website:
+        git_branch: 'Laisser vide pour la branche par défaut'
         git_endpoint: 'Laisser vide pour les valeurs par défaut (https://github.com ou https://gitlab.com/api/v4)'
         languages: 'Si vous sélectionnez au moins une langue le site sera considéré comme possiblement multilingue et donc toutes les urls seront préfixées avec la langue (/fr, /en)'
       communication_website_category:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 1045278c14de085e101813e69ce1fa9c36384247..a4dd9890f0d3ac23c76d2822c999d22b0d1e9d61 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -130,7 +130,7 @@ en:
     mailer:
       two_factor_authentication_code:
         subject: "Two-factor authentication code"
-        text_html: "Your two-factor authentication code for %{university} is: <br><br><b>%{code}</b><br><br>It will expire in %{duration}."
+        text_html: "Your two-factor authentication code for %{context} is: <br><br><b>%{code}</b><br><br>It will expire in %{duration}."
     omniauth_callbacks:
       failure: "Failed to sign in."
     passwords:
@@ -205,6 +205,7 @@ en:
   languages:
     en: English
     fr: French
+  legal: Legal
   loading: Loading...
   login:
     already_registered: Already registered?
@@ -214,6 +215,7 @@ en:
     sign_in_with_credentials: Sign in with credentials
     sign_in_with_sso: Sign in through SSO
     subtitle: Sign in to your account to continue
+  look_feel: Look & feel
   mailers:
     notifications:
       import:
@@ -268,7 +270,7 @@ en:
       test_chars: "%{min_length} characters min."
   show: Show
   slug_error: can only contain downcase letters, numbers, and dashes.
-  sms_code: "%{code} is your authentication code on %{university} (valid %{duration})"
+  sms_code: "%{code} is your authentication code on %{context} (valid %{duration})"
   static: Static file
   terms_of_service: Terms of service
   terms_of_service_url: https://osuny.org/conditions-d-utilisation
diff --git a/config/locales/extranet/en.yml b/config/locales/extranet/en.yml
index a71ded4f915ebe3cccbcaac513083f5d4b7fc47c..e7aa2085e8ce6b895865ec33b7a11097940bf6fd 100644
--- a/config/locales/extranet/en.yml
+++ b/config/locales/extranet/en.yml
@@ -1,7 +1,23 @@
 en:
   extranet:
-    account: 
+    account:
       my: My account
-      edit: Edit
+      edit: Edit account
+      edit_personal_data: Edit profile
       updated: Updated
       logout: Log out
+    errors:
+      email_not_allowed: is not authorized to access this extranet.
+      email_not_allowed_with_contact: is not authorized to access this extranet. Contact %{contact} for more information.
+    experiences:
+      new: Add experience
+      title: Professional path
+    home:
+      recent_cohorts: Recent cohorts
+      recent_experiences: Recent experiences
+    menu: Menu
+    organization:
+      experiences: Alumni in this organization (%{count})
+    personal_data:
+      title: My personal data
+      updated: Your personal data has been updated!
diff --git a/config/locales/extranet/fr.yml b/config/locales/extranet/fr.yml
index 4c4347226ba279c169357b181e615faf20f443f7..552f0a3ca3c782d423643aef319b029518d43c39 100644
--- a/config/locales/extranet/fr.yml
+++ b/config/locales/extranet/fr.yml
@@ -1,9 +1,25 @@
 fr:
   extranet:
-    experiences:
-      new: Ajouter une expérience
-    account: 
+    account:
       my: Mon compte
-      edit: Modifier
+      edit: Modifier mon compte
+      edit_personal_data: Modifier mon profil
       updated: Mise à jour effectuée
       logout: Déconnexion
+    errors:
+      email_not_allowed: n'est pas autorisé à accéder à cet extranet.
+      email_not_allowed_with_contact: n'est pas autorisé à accéder à cet extranet. Contactez %{contact} pour en savoir plus.
+    experiences:
+      new: Ajouter une expérience
+      search_organization: Rechercher par nom ou SIREN
+      title: Parcours professionnel
+    home:
+      recent_cohorts: Promotions récentes
+      recent_experiences: Mouvements récents
+    menu: Menu
+    organization:
+      experiences: Alumni dans cette organisation (%{count})
+    personal_data:
+      edit: Modifier
+      title: Mes données personnelles
+      updated: Mise à jour des donnes personnelles effectuée !
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 9343c22f7ed9793b7c0b7578f685a47d49b7a765..b8696c31a261e655dba27d87d4cc3acbeca77b11 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -130,7 +130,7 @@ fr:
     mailer:
       two_factor_authentication_code:
         subject: "Code d'authentification à deux facteurs"
-        text_html: "Votre code d'authentification pour %{university} est :<br><br><b>%{code}</b><br><br>Il expirera dans %{duration}."
+        text_html: "Votre code d'authentification pour %{context} est :<br><br><b>%{code}</b><br><br>Il expirera dans %{duration}."
     omniauth_callbacks:
       failure: "Échec de l'authentification."
     passwords:
@@ -205,6 +205,7 @@ fr:
   languages:
     en: Anglais
     fr: Français
+  legal: Légal
   loading: Chargement...
   login:
     already_registered: Déjà inscrit ?
@@ -214,6 +215,7 @@ fr:
     sign_in_with_credentials: Se connecter avec ses identifiants
     sign_in_with_sso: Se connecter en SSO
     subtitle: Vous devez être authentifié pour continuer
+  look_feel: Look & feel
   mailers:
     notifications:
       import:
@@ -268,7 +270,7 @@ fr:
       test_chars: "%{min_length} caractères min."
   show: Voir
   slug_error: ne peut contenir que des lettres minuscules, des chiffres et des traits d'union.
-  sms_code: "%{code} est votre code d'authentification sur %{university} (valide %{duration})"
+  sms_code: "%{code} est votre code d'authentification sur %{context} (valide %{duration})"
   static: Fichier statique
   terms_of_service: Conditions d'utilisation
   terms_of_service_url: https://osuny.org/conditions-d-utilisation
diff --git a/config/routes.rb b/config/routes.rb
index b97709544fd88aa66f8d83fe2ac3c1af4d12b478..a7435c556fabf4d352e2c536271f802d71a7e964 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -9,6 +9,7 @@ Rails.application.routes.draw do
     passwords: 'users/passwords',
     registrations: 'users/registrations',
     sessions: 'users/sessions',
+    two_factor_authentication: 'users/two_factor_authentication',
     unlocks: 'users/unlocks'
   }
 
diff --git a/config/routes/extranet.rb b/config/routes/extranet.rb
index 905cf1b2eef45cb2310f08f964e68e03a71fe12b..3d5d9c7c720b580ae2785927bcf552ff9445d00f 100644
--- a/config/routes/extranet.rb
+++ b/config/routes/extranet.rb
@@ -1,15 +1,21 @@
 get 'cohorts' => 'extranet/cohorts#index', as: :education_cohorts
 get 'cohorts/:id' => 'extranet/cohorts#show', as: :education_cohort
 get 'organizations' => 'extranet/organizations#index', as: :university_organizations
+get 'organizations/search' => 'extranet/organizations#search', as: :search_university_organizations, defaults: { format: 'json' }
 get 'organizations/:id' => 'extranet/organizations#show', as: :university_organization
 get 'persons' => 'extranet/persons#index', as: :university_persons
 get 'persons/:id' => 'extranet/persons#show', as: :university_person
 get 'years' => 'extranet/academic_years#index', as: :education_academic_years
 get 'years/:id' => 'extranet/academic_years#show', as: :education_academic_year
-get 'account' => 'extranet/account#show', as: :account 
-get 'account/edit' => 'extranet/account#edit', as: :edit_account 
+get 'account' => 'extranet/account#show', as: :account
+get 'account/edit' => 'extranet/account#edit', as: :edit_account
 patch 'account' => 'extranet/account#update'
-scope :account do 
+scope :account do
   resources :experiences, controller: 'extranet/experiences', except: [:index, :show]
+  get 'personal_data' => 'extranet/personal_data#edit', as: :edit_personal_data
+  patch 'personal_data' => 'extranet/personal_data#update', as: :personal_data
 end
+get 'terms-of-service' => 'extranet/pages#terms_of_service', as: :terms_of_service
+get 'privacy-policy' => 'extranet/pages#privacy_policy', as: :privacy_policy
+get 'cookies-policy' => 'extranet/pages#cookies_policy', as: :cookies_policy
 root to: 'extranet/home#index'
diff --git a/config/routes/server.rb b/config/routes/server.rb
index c76985a7568405bf60616262ae137c88794599a4..394797b297e66a17d1a60e96183e9301b2358de5 100644
--- a/config/routes/server.rb
+++ b/config/routes/server.rb
@@ -1,5 +1,5 @@
 namespace :server do
-  resources :universities, :languages
+  resources :universities, :languages, :websites
   get 'blocks' => 'blocks#index', as: :blocks
   get 'blocks/:id' => 'blocks#show', as: :block
   post 'blocks/:id' => 'blocks#resave', as: :resave_block
diff --git a/config/server_navigation.rb b/config/server_navigation.rb
index 5aca9b137d03c975282fb8a5b124076821bfb20f..c2b389ca7198b634a413ceb00bc244ea98343f36 100644
--- a/config/server_navigation.rb
+++ b/config/server_navigation.rb
@@ -11,6 +11,9 @@ SimpleNavigation::Configuration.run do |navigation|
     primary.item  :universities,
                   University.model_name.human(count: 2),
                   server_universities_path, { icon: 'university' } if can?(:read, University)
+    primary.item  :websites,
+                  Communication::Website.model_name.human(count: 2),
+                  server_websites_path, { icon: 'globe' }
     primary.item  :languages,
                   Language.model_name.human(count: 2),
                   server_languages_path,
diff --git a/db/migrate/20221011070402_add_fields_to_communication_website.rb b/db/migrate/20221011070402_add_fields_to_communication_website.rb
new file mode 100644
index 0000000000000000000000000000000000000000..eb4de5479d5e37d1c13c4256bf65d84db1e63d99
--- /dev/null
+++ b/db/migrate/20221011070402_add_fields_to_communication_website.rb
@@ -0,0 +1,6 @@
+class AddFieldsToCommunicationWebsite < ActiveRecord::Migration[6.1]
+  def change
+    add_column :communication_websites, :git_branch, :string
+    add_column :communication_websites, :in_production, :boolean, default: false
+  end
+end
diff --git a/db/migrate/20221017142108_add_registration_contact_to_communication_extranets.rb b/db/migrate/20221017142108_add_registration_contact_to_communication_extranets.rb
new file mode 100644
index 0000000000000000000000000000000000000000..da34f0cde40a67f87c3c6926387aff6fc1db9b4f
--- /dev/null
+++ b/db/migrate/20221017142108_add_registration_contact_to_communication_extranets.rb
@@ -0,0 +1,5 @@
+class AddRegistrationContactToCommunicationExtranets < ActiveRecord::Migration[6.1]
+  def change
+    add_column :communication_extranets, :registration_contact, :string
+  end
+end
diff --git a/db/migrate/20221020102138_add_sso_to_communication_extranet.rb b/db/migrate/20221020102138_add_sso_to_communication_extranet.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0114f39af5b4273a008e0870d5752e4cf1805b70
--- /dev/null
+++ b/db/migrate/20221020102138_add_sso_to_communication_extranet.rb
@@ -0,0 +1,11 @@
+class AddSsoToCommunicationExtranet < ActiveRecord::Migration[6.1]
+  def change
+    add_column :communication_extranets, :has_sso, :boolean, default: false
+    add_column :communication_extranets, :sso_inherit_from_university, :boolean, default: false
+    add_column :communication_extranets, :sso_cert, :text
+    add_column :communication_extranets, :sso_mapping, :jsonb
+    add_column :communication_extranets, :sso_name_identifier_format, :string
+    add_column :communication_extranets, :sso_provider, :integer, default: 0
+    add_column :communication_extranets, :sso_target_url, :integer, default: 0
+  end
+end
diff --git a/db/migrate/20221020102322_rename_domain_to_host_in_communication_extranets.rb b/db/migrate/20221020102322_rename_domain_to_host_in_communication_extranets.rb
new file mode 100644
index 0000000000000000000000000000000000000000..92ee954d7eb30a35e2259b1e243900a7785bd0c8
--- /dev/null
+++ b/db/migrate/20221020102322_rename_domain_to_host_in_communication_extranets.rb
@@ -0,0 +1,5 @@
+class RenameDomainToHostInCommunicationExtranets < ActiveRecord::Migration[6.1]
+  def change
+    rename_column :communication_extranets, :domain, :host
+  end
+end
diff --git a/db/migrate/20221020124935_change_extranet_sso_target_url_kind.rb b/db/migrate/20221020124935_change_extranet_sso_target_url_kind.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b8c3ffaa3e173bd6d900760aa5d075413cf79910
--- /dev/null
+++ b/db/migrate/20221020124935_change_extranet_sso_target_url_kind.rb
@@ -0,0 +1,5 @@
+class ChangeExtranetSsoTargetUrlKind < ActiveRecord::Migration[6.1]
+  def change
+    change_column :communication_extranets, :sso_target_url, :string, default: nil
+  end
+end
diff --git a/db/migrate/20221020141837_remove_sso_inherit_from_university.rb b/db/migrate/20221020141837_remove_sso_inherit_from_university.rb
new file mode 100644
index 0000000000000000000000000000000000000000..cd4437abdc71682e9e73edacde0a4e89239efa8a
--- /dev/null
+++ b/db/migrate/20221020141837_remove_sso_inherit_from_university.rb
@@ -0,0 +1,5 @@
+class RemoveSsoInheritFromUniversity < ActiveRecord::Migration[6.1]
+  def change
+    remove_column :communication_extranets, :sso_inherit_from_university
+  end
+end
diff --git a/db/migrate/20221024145323_add_legal_texts_to_communication_extranets.rb b/db/migrate/20221024145323_add_legal_texts_to_communication_extranets.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5846d437dc7a423d7bb8a9e2115e2909813bd2bc
--- /dev/null
+++ b/db/migrate/20221024145323_add_legal_texts_to_communication_extranets.rb
@@ -0,0 +1,7 @@
+class AddLegalTextsToCommunicationExtranets < ActiveRecord::Migration[6.1]
+  def change
+    add_column :communication_extranets, :terms, :text
+    add_column :communication_extranets, :privacy_policy, :text
+    add_column :communication_extranets, :cookies_policy, :text
+  end
+end
diff --git a/db/migrate/20221024145426_add_color_to_communication_extranets.rb b/db/migrate/20221024145426_add_color_to_communication_extranets.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e383bcd6950c39c42f4e4ee13aa95f057b9a7090
--- /dev/null
+++ b/db/migrate/20221024145426_add_color_to_communication_extranets.rb
@@ -0,0 +1,5 @@
+class AddColorToCommunicationExtranets < ActiveRecord::Migration[6.1]
+  def change
+    add_column :communication_extranets, :color, :string
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index db7324d8e9b8d7121c2c8ed1bc21662009dc5c5a..0234bec1660560f0ccdbb4af4dad555c9aa645c1 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.0].define(version: 2022_10_03_144016) do
+ActiveRecord::Schema[7.0].define(version: 2022_10_24_145426) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
   enable_extension "plpgsql"
@@ -96,11 +96,22 @@ ActiveRecord::Schema[7.0].define(version: 2022_10_03_144016) do
   create_table "communication_extranets", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
     t.string "name"
     t.uuid "university_id", null: false
-    t.string "domain"
+    t.string "host"
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.string "about_type"
     t.uuid "about_id"
+    t.string "registration_contact"
+    t.boolean "has_sso", default: false
+    t.text "sso_cert"
+    t.jsonb "sso_mapping"
+    t.string "sso_name_identifier_format"
+    t.integer "sso_provider", default: 0
+    t.string "sso_target_url"
+    t.text "terms"
+    t.text "privacy_policy"
+    t.text "cookies_policy"
+    t.string "color"
     t.index ["about_type", "about_id"], name: "index_communication_extranets_on_about"
     t.index ["university_id"], name: "index_communication_extranets_on_university_id"
   end
@@ -355,6 +366,8 @@ ActiveRecord::Schema[7.0].define(version: 2022_10_03_144016) do
     t.text "style"
     t.date "style_updated_at"
     t.string "plausible_url"
+    t.string "git_branch"
+    t.boolean "in_production", default: false
     t.index ["about_type", "about_id"], name: "index_communication_websites_on_about"
     t.index ["university_id"], name: "index_communication_websites_on_university_id"
   end
diff --git a/docs/extranet/readme.md b/docs/extranet/readme.md
deleted file mode 100644
index 1b6ee19a04935e2d58295e4c7fa14ed1f562fc9f..0000000000000000000000000000000000000000
--- a/docs/extranet/readme.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Osuny Extranet
-
-## Alumni
-
diff --git a/lib/active_storage/service/scaleway_service.rb b/lib/active_storage/service/scaleway_service.rb
deleted file mode 100644
index 28b7569b96cf8bf5149497c361c1ae19f7a2c17b..0000000000000000000000000000000000000000
--- a/lib/active_storage/service/scaleway_service.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-# cf https://github.com/rails/rails/issues/41070
-
-require 'active_storage/service/s3_service.rb'
-
-module ActiveStorage
-  class Service::ScalewayService < Service::S3Service
-
-    def headers_for_direct_upload(key, content_type:, checksum:, filename: nil, disposition: nil, **)
-      content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
-
-      headers = public? ? { "x-amz-acl" => "public-read" } : {}
-
-      headers.merge({ "Content-Type" => content_type, "Content-MD5" => checksum, "Content-Disposition" => content_disposition })
-    end
-
-    private
-
-    def public_url(key, **options)
-      disposition, filename, content_type = options.values_at(:disposition, :filename, :content_type)
-      uri = URI.parse(object_for(key).public_url)
-      uri.query = URI.encode_www_form({
-        "response-content-disposition" => content_disposition_with(type: disposition, filename: filename),
-        "response-content-type" => content_type
-      })
-      uri.to_s
-    end
-  end
-end
diff --git a/package.json b/package.json
index 287e8a5c791bc877fd9519b95c75ed0a896a6c4f..a2d8609753fa6d742370cbe63d1ffe0e334f4361 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,8 @@
   },
   "dependencies": {
     "16": "0.0.2",
+    "bootstrap-icons": "^1.9.1",
+    "bootstrap-print-css": "^1.0.1",
     "cropperjs": "^1.5.12",
     "jquery-cropper": "^1.0.1",
     "notyf": "^3.10.0",
diff --git a/test/fixtures/communication/extranets.yml b/test/fixtures/communication/extranets.yml
index 67008e68b84634849c8a0ed42ded99acb00fbab4..096e5b66c1bd77ea1abe94d2063174daa49f8763 100644
--- a/test/fixtures/communication/extranets.yml
+++ b/test/fixtures/communication/extranets.yml
@@ -2,14 +2,25 @@
 #
 # Table name: communication_extranets
 #
-#  id            :uuid             not null, primary key
-#  about_type    :string           indexed => [about_id]
-#  domain        :string
-#  name          :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  about_id      :uuid             indexed => [about_type]
-#  university_id :uuid             not null, indexed
+#  id                         :uuid             not null, primary key
+#  about_type                 :string           indexed => [about_id]
+#  color                      :string
+#  cookies_policy             :text
+#  has_sso                    :boolean          default(FALSE)
+#  host                       :string
+#  name                       :string
+#  privacy_policy             :text
+#  registration_contact       :string
+#  sso_cert                   :text
+#  sso_mapping                :jsonb
+#  sso_name_identifier_format :string
+#  sso_provider               :integer          default("saml")
+#  sso_target_url             :string
+#  terms                      :text
+#  created_at                 :datetime         not null
+#  updated_at                 :datetime         not null
+#  about_id                   :uuid             indexed => [about_type]
+#  university_id              :uuid             not null, indexed
 #
 # Indexes
 #
@@ -24,9 +35,9 @@
 one:
   name: MyString
   university: default_university
-  domain: MyString
+  host: MyString
 
 two:
   name: MyString
   university: default_university
-  domain: MyString
+  host: MyString
diff --git a/test/fixtures/communication/websites.yml b/test/fixtures/communication/websites.yml
index 78817fa75f2494d30e61980d680f224d40cc6ccb..a72ecbcf7dbf46b9c1cbaf45e61e852538f63d29 100644
--- a/test/fixtures/communication/websites.yml
+++ b/test/fixtures/communication/websites.yml
@@ -5,8 +5,10 @@
 #  id               :uuid             not null, primary key
 #  about_type       :string           indexed => [about_id]
 #  access_token     :string
+#  git_branch       :string
 #  git_endpoint     :string
 #  git_provider     :integer          default("github")
+#  in_production    :boolean          default(FALSE)
 #  name             :string
 #  plausible_url    :string
 #  repository       :string
diff --git a/test/models/communication/extranet_test.rb b/test/models/communication/extranet_test.rb
index 54e7cf1a80e1fe893549cc7327a91a469e705468..69be8d1cd6fe3afbadbecda1a9572a0cfb3e3eef 100644
--- a/test/models/communication/extranet_test.rb
+++ b/test/models/communication/extranet_test.rb
@@ -2,14 +2,25 @@
 #
 # Table name: communication_extranets
 #
-#  id            :uuid             not null, primary key
-#  about_type    :string           indexed => [about_id]
-#  domain        :string
-#  name          :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  about_id      :uuid             indexed => [about_type]
-#  university_id :uuid             not null, indexed
+#  id                         :uuid             not null, primary key
+#  about_type                 :string           indexed => [about_id]
+#  color                      :string
+#  cookies_policy             :text
+#  has_sso                    :boolean          default(FALSE)
+#  host                       :string
+#  name                       :string
+#  privacy_policy             :text
+#  registration_contact       :string
+#  sso_cert                   :text
+#  sso_mapping                :jsonb
+#  sso_name_identifier_format :string
+#  sso_provider               :integer          default("saml")
+#  sso_target_url             :string
+#  terms                      :text
+#  created_at                 :datetime         not null
+#  updated_at                 :datetime         not null
+#  about_id                   :uuid             indexed => [about_type]
+#  university_id              :uuid             not null, indexed
 #
 # Indexes
 #
diff --git a/yarn.lock b/yarn.lock
index 32fc5f3bcd3c8938621267e2d87194296d1cf723..3b61a7621ac123d36be4225421140ad4434b643c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -104,6 +104,16 @@
   resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.31.tgz#c90de7126d833dcd3a4c7534d534be2fb41faa4e"
   integrity sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==
 
+bootstrap-icons@^1.9.1:
+  version "1.9.1"
+  resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz#cf22d91a25447645e45c49ebde4e56eafdfe761b"
+  integrity sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g==
+
+bootstrap-print-css@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/bootstrap-print-css/-/bootstrap-print-css-1.0.1.tgz#acc0264388caebbad0805e60c869d42cd6fe55bf"
+  integrity sha512-I73Cw87BaxCccTjo3qEbvn7KRb55msMxTuT7mpkAAY4Obq8iG9xCybdxnJqq+RrykLD79O3092AiJwaKiEex7w==
+
 cropperjs@^1.5.12:
   version "1.5.12"
   resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50"