diff --git a/Gemfile b/Gemfile
index 08975837562ea0532d3af8066bd4e9a67aa210a4..1f1e26e7eb68f3bc2e1b1f9f689b22c3797d8e30 100644
--- a/Gemfile
+++ b/Gemfile
@@ -22,6 +22,7 @@ gem 'devise'
 gem 'devise-i18n'
 gem 'enum_help'
 gem 'faceted_search'#, path: '../../noesya/faceted_search'
+gem 'font-awesome-sass'
 gem 'front_matter_parser'
 gem 'gdpr'
 gem 'gitlab'
diff --git a/Gemfile.lock b/Gemfile.lock
index 043362ea36d74360d57d3c53a15a0b22ac7fb730..779a34435d3ed37f2f8109d0ef0f60b3172ec5cc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -98,16 +98,16 @@ GEM
     autoprefixer-rails (10.4.7.0)
       execjs (~> 2)
     aws-eventstream (1.2.0)
-    aws-partitions (1.666.0)
-    aws-sdk-core (3.168.1)
+    aws-partitions (1.669.0)
+    aws-sdk-core (3.168.2)
       aws-eventstream (~> 1, >= 1.0.2)
       aws-partitions (~> 1, >= 1.651.0)
       aws-sigv4 (~> 1.5)
       jmespath (~> 1, >= 1.6.1)
-    aws-sdk-kms (1.59.0)
+    aws-sdk-kms (1.60.0)
       aws-sdk-core (~> 3, >= 3.165.0)
       aws-sigv4 (~> 1.1)
-    aws-sdk-s3 (1.117.1)
+    aws-sdk-s3 (1.117.2)
       aws-sdk-core (~> 3, >= 3.165.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.4)
@@ -126,7 +126,7 @@ GEM
       rails (>= 3.1)
     breadcrumbs_on_rails (4.1.0)
       railties (>= 5.0)
-    bugsnag (6.24.2)
+    bugsnag (6.25.0)
       concurrent-ruby (~> 1.0)
     builder (3.2.4)
     byebug (11.1.3)
@@ -211,7 +211,7 @@ GEM
     font-awesome-sass (6.2.1)
       sassc (~> 2.0)
     front_matter_parser (1.0.1)
-    gdpr (1.2.4)
+    gdpr (1.2.5)
       js_cookie_rails
       rails
       sassc-rails
@@ -526,6 +526,7 @@ DEPENDENCIES
   enum_help
   faceted_search
   figaro
+  font-awesome-sass
   front_matter_parser
   gdpr
   gitlab
diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js
index 4aa11843668581fcf726642ee320d12236367eac..d21c8c30dcefe75f9aaa5ccb154cbdf9a52f76ce 100644
--- a/app/assets/config/manifest.js
+++ b/app/assets/config/manifest.js
@@ -3,3 +3,7 @@
 //= link_directory ../stylesheets .css
 //= link_directory ../javascripts .js
 //= link vue.js
+//= link admin/appstack.css
+//= link admin/pure.css
+//= link admin/appstack.js
+//= link admin/pure.js
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.eot b/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.eot
new file mode 100755
index 0000000000000000000000000000000000000000..d9290eb94505cc3d3d809abad47c114a3fc74697
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.eot differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.ttf b/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.ttf
new file mode 100755
index 0000000000000000000000000000000000000000..0f12489dc53b2cd74a741f14b12cbc622771ca44
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.ttf differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bold.woff b/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.woff
old mode 100644
new mode 100755
similarity index 100%
rename from app/assets/fonts/Basier-Square/basiersquare-bold.woff
rename to app/assets/fonts/Basier-Square/basiersquare-bold-webfont.woff
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bold.woff2 b/app/assets/fonts/Basier-Square/basiersquare-bold-webfont.woff2
old mode 100644
new mode 100755
similarity index 100%
rename from app/assets/fonts/Basier-Square/basiersquare-bold.woff2
rename to app/assets/fonts/Basier-Square/basiersquare-bold-webfont.woff2
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.eot b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.eot
new file mode 100755
index 0000000000000000000000000000000000000000..a9152e4a4dc76be0fbe67738e83d77f80b93c31d
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.eot differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.ttf b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.ttf
new file mode 100755
index 0000000000000000000000000000000000000000..c68ac79ae33db130b838c688b3ac6c5605610782
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.ttf differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.woff b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.woff
new file mode 100755
index 0000000000000000000000000000000000000000..e01e76c7e22711136e7ac1d1383535a03dffb375
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.woff differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.woff2 b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.woff2
new file mode 100755
index 0000000000000000000000000000000000000000..1e98d5b9655091d9343e3c898ba20bc27675a7fc
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-bolditalic-webfont.woff2 differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-medium.woff b/app/assets/fonts/Basier-Square/basiersquare-medium.woff
deleted file mode 100755
index 1fca3b5ad86765fa93bc2dc7bdc784a15a06f306..0000000000000000000000000000000000000000
Binary files a/app/assets/fonts/Basier-Square/basiersquare-medium.woff and /dev/null differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-medium.woff2 b/app/assets/fonts/Basier-Square/basiersquare-medium.woff2
deleted file mode 100755
index 7de63d7fda6a40143347481c8fd6cd12901e773a..0000000000000000000000000000000000000000
Binary files a/app/assets/fonts/Basier-Square/basiersquare-medium.woff2 and /dev/null differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.eot b/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.eot
new file mode 100755
index 0000000000000000000000000000000000000000..6a323e6d600b3845e7e7fc909d0bf5fb55b6ce76
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.eot differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.ttf b/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.ttf
new file mode 100755
index 0000000000000000000000000000000000000000..05d465bf58738822bbf92bfe7622923f211e40c4
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.ttf differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regular.woff b/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.woff
old mode 100644
new mode 100755
similarity index 100%
rename from app/assets/fonts/Basier-Square/basiersquare-regular.woff
rename to app/assets/fonts/Basier-Square/basiersquare-regular-webfont.woff
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regular.woff2 b/app/assets/fonts/Basier-Square/basiersquare-regular-webfont.woff2
old mode 100644
new mode 100755
similarity index 100%
rename from app/assets/fonts/Basier-Square/basiersquare-regular.woff2
rename to app/assets/fonts/Basier-Square/basiersquare-regular-webfont.woff2
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.eot b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.eot
new file mode 100755
index 0000000000000000000000000000000000000000..5f73164a539ae0d369bf91ab39928ea2862c824b
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.eot differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.ttf b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.ttf
new file mode 100755
index 0000000000000000000000000000000000000000..4908247418f287b0601d4683f0fc51f5880404b4
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.ttf differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.woff b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.woff
new file mode 100755
index 0000000000000000000000000000000000000000..48baec477b13902f5fbae04ac200a1b8f5de85eb
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.woff differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.woff2 b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.woff2
new file mode 100755
index 0000000000000000000000000000000000000000..999143cd473b9591abdcdc06f770049552fd571b
Binary files /dev/null and b/app/assets/fonts/Basier-Square/basiersquare-regularitalic-webfont.woff2 differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-semibold.woff b/app/assets/fonts/Basier-Square/basiersquare-semibold.woff
deleted file mode 100755
index 0ddef095ff7f63abe723ac24456cfdb9f6cfb887..0000000000000000000000000000000000000000
Binary files a/app/assets/fonts/Basier-Square/basiersquare-semibold.woff and /dev/null differ
diff --git a/app/assets/fonts/Basier-Square/basiersquare-semibold.woff2 b/app/assets/fonts/Basier-Square/basiersquare-semibold.woff2
deleted file mode 100755
index 2d57f6eab291dbdd173c083093c1e1e42317c0a0..0000000000000000000000000000000000000000
Binary files a/app/assets/fonts/Basier-Square/basiersquare-semibold.woff2 and /dev/null differ
diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin/appstack.js
similarity index 76%
rename from app/assets/javascripts/admin.js
rename to app/assets/javascripts/admin/appstack.js
index 78287d1c61c91076bbcd78c89f0ef865eceebd42..23ae425c9b5a48cae95aec35f4bbf21415cd455e 100644
--- a/app/assets/javascripts/admin.js
+++ b/app/assets/javascripts/admin/appstack.js
@@ -13,9 +13,9 @@
 //= require slug/slug
 //= require cocoon
 //= require_self
-//= require_tree ./admin/commons
-//= require_tree ./application/plugins
-//= require_tree ./admin/plugins
-//= require ./admin/communication/init
+//= require_tree ./commons
+//= require_tree ../application/plugins
+//= require_tree ./plugins
+//= require ./communication/init
 
 window.osuny = {};
diff --git a/app/assets/javascripts/admin/pure.js b/app/assets/javascripts/admin/pure.js
new file mode 100644
index 0000000000000000000000000000000000000000..23ae425c9b5a48cae95aec35f4bbf21415cd455e
--- /dev/null
+++ b/app/assets/javascripts/admin/pure.js
@@ -0,0 +1,21 @@
+//= require activestorage
+//= 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 appstack/app
+//= require gdpr/cookie_consent
+//= require sortablejs/Sortable
+//= require summernote/summernote-bs5
+//= require slug/slug
+//= require cocoon
+//= require_self
+//= require_tree ./commons
+//= require_tree ../application/plugins
+//= require_tree ./plugins
+//= require ./communication/init
+
+window.osuny = {};
diff --git a/app/assets/stylesheets/admin/appstack.sass b/app/assets/stylesheets/admin/appstack.sass
index 8f70930f8f528c25fceb5695f2c1899b8dc8dcb1..06e674993f421ad82117422b524ea86c91d90846 100644
--- a/app/assets/stylesheets/admin/appstack.sass
+++ b/app/assets/stylesheets/admin/appstack.sass
@@ -1,40 +1,12 @@
-main.content
-    padding-bottom: 65px
-
-.sidebar
-    footer
-        a
-            padding: .125rem
-
-.sidebar.collapsed + .footer.fixed
-    left: 260px
-    @include media-breakpoint-up(lg)
-        left: 0
-
-.footer.fixed
-    bottom: 0
-    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
-        margin-bottom: 0
-
-.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
+@import 'appstack/fonts'
+@import 'bootstrap'
+@import 'notyf/notyf.min'
+@import 'appstack/light'
+@import 'simple_form_password_with_hints'
+@import 'simple_form_bs5_file_input'
+@import 'summernote-bs5'
+@import 'cropperjs/dist/cropper'
+@import 'gdpr/cookie_consent'
+@import '../commons/*'
+@import 'commons/*'
+@import 'appstack/*'
diff --git a/app/assets/stylesheets/admin/fonts.css b/app/assets/stylesheets/admin/appstack/fonts.css
similarity index 100%
rename from app/assets/stylesheets/admin/fonts.css
rename to app/assets/stylesheets/admin/appstack/fonts.css
diff --git a/app/assets/stylesheets/admin/forms.sass b/app/assets/stylesheets/admin/appstack/forms.sass
similarity index 100%
rename from app/assets/stylesheets/admin/forms.sass
rename to app/assets/stylesheets/admin/appstack/forms.sass
diff --git a/app/assets/stylesheets/admin/appstack/style.sass b/app/assets/stylesheets/admin/appstack/style.sass
new file mode 100644
index 0000000000000000000000000000000000000000..8f70930f8f528c25fceb5695f2c1899b8dc8dcb1
--- /dev/null
+++ b/app/assets/stylesheets/admin/appstack/style.sass
@@ -0,0 +1,40 @@
+main.content
+    padding-bottom: 65px
+
+.sidebar
+    footer
+        a
+            padding: .125rem
+
+.sidebar.collapsed + .footer.fixed
+    left: 260px
+    @include media-breakpoint-up(lg)
+        left: 0
+
+.footer.fixed
+    bottom: 0
+    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
+        margin-bottom: 0
+
+.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/admin/styles.sass b/app/assets/stylesheets/admin/appstack/styles.sass
similarity index 100%
rename from app/assets/stylesheets/admin/styles.sass
rename to app/assets/stylesheets/admin/appstack/styles.sass
diff --git a/app/assets/stylesheets/admin/websites.sass b/app/assets/stylesheets/admin/appstack/websites.sass
similarity index 100%
rename from app/assets/stylesheets/admin/websites.sass
rename to app/assets/stylesheets/admin/appstack/websites.sass
diff --git a/app/assets/stylesheets/admin/preview.sass b/app/assets/stylesheets/admin/commons/preview.sass
similarity index 100%
rename from app/assets/stylesheets/admin/preview.sass
rename to app/assets/stylesheets/admin/commons/preview.sass
diff --git a/app/assets/stylesheets/admin/treeview.sass b/app/assets/stylesheets/admin/commons/treeview.sass
similarity index 98%
rename from app/assets/stylesheets/admin/treeview.sass
rename to app/assets/stylesheets/admin/commons/treeview.sass
index 006dc95a0555e586cc8307a81eab149eaeaa2c24..b683239ec23342067392afe950424531d9a0617f 100644
--- a/app/assets/stylesheets/admin/treeview.sass
+++ b/app/assets/stylesheets/admin/commons/treeview.sass
@@ -1,6 +1,7 @@
 .treeview
     &__element
-
+        a
+            text-decoration: none
         & > .treeview__children .treeview__empty
             display: none
 
diff --git a/app/assets/stylesheets/admin.sass b/app/assets/stylesheets/admin/pure.sass
similarity index 56%
rename from app/assets/stylesheets/admin.sass
rename to app/assets/stylesheets/admin/pure.sass
index c38944de51ff355ffa88f4d6407c96f3e25758c9..b7fbeb0d0b706bc0130c63de3045c10b4941ef11 100644
--- a/app/assets/stylesheets/admin.sass
+++ b/app/assets/stylesheets/admin/pure.sass
@@ -1,11 +1,15 @@
-@import 'admin/fonts'
+@import 'pure/utils'
+@import 'pure/fonts'
+@import 'pure/variables'
 @import 'bootstrap'
+@import 'bootstrap-icons/font/bootstrap-icons'
+@import 'font-awesome'
 @import 'notyf/notyf.min'
-@import 'appstack/light'
 @import 'simple_form_password_with_hints'
 @import 'simple_form_bs5_file_input'
 @import 'summernote-bs5'
 @import 'cropperjs/dist/cropper'
 @import 'gdpr/cookie_consent'
+@import '../commons/*'
 @import 'commons/*'
-@import 'admin/*'
+@import 'pure/style'
diff --git a/app/assets/stylesheets/admin/pure/fonts.sass b/app/assets/stylesheets/admin/pure/fonts.sass
new file mode 100644
index 0000000000000000000000000000000000000000..001a9d14141e30dda057c97e7e284c9dbf26f9b2
--- /dev/null
+++ b/app/assets/stylesheets/admin/pure/fonts.sass
@@ -0,0 +1,27 @@
+@font-face
+    font-display: swap
+    font-family: 'Basier Square'
+    font-style: normal
+    font-weight: 400
+    src: asset-url("Basier-Square/basiersquare-regular-webfont.woff2") format("woff2"), url("Basier-Square/basiersquare-regular-webfont.woff") format("woff")
+
+@font-face
+    font-display: swap
+    font-family: 'Basier Square'
+    font-style: italic
+    font-weight: 400
+    src: asset-url("Basier-Square/basiersquare-regularitalic-webfont.woff2") format("woff2"), url("Basier-Square/basiersquare-regularitalic-webfont.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-webfont.woff2") format("woff2"), url("Basier-Square/basiersquare-bold-webfont.woff") format("woff")
+
+@font-face
+    font-display: swap
+    font-family: 'Basier Square'
+    font-style: italic
+    font-weight: 700
+    src: asset-url("Basier-Square/basiersquare-bolditalic-webfont.woff2") format("woff2"), url("Basier-Square/basiersquare-bolditalic-webfont.woff") format("woff")
diff --git a/app/assets/stylesheets/admin/pure/style.sass b/app/assets/stylesheets/admin/pure/style.sass
new file mode 100644
index 0000000000000000000000000000000000000000..3b97ec32dbf0c1a040b30a23f291d02aa20783bc
--- /dev/null
+++ b/app/assets/stylesheets/admin/pure/style.sass
@@ -0,0 +1,102 @@
+.navbar
+    position: absolute
+    left: 0
+    right: 0
+    padding-top: $spacing2
+    .navbar-brand
+        img
+            width: 100px
+#menu
+    position: fixed
+    top: 0
+    left: 0
+    right: 0
+    bottom: 0
+    background: black
+    color: white
+    overflow-y: scroll
+    z-index: 1000
+    padding-bottom: 30px
+    .menu-content
+        position: relative
+        margin-top: 150px
+        ul
+            list-style-type: none
+            padding: 0
+            li
+                padding: 5px 0
+                span
+                    opacity: 0.2
+        a
+            color: white
+            text-decoration: underline
+            text-decoration-color: #FFFFFF66
+            &:hover
+                text-decoration-color: #FFFFFFFF
+
+.hero
+    padding-top: 150px
+    padding-bottom: 30px
+    background-color: $color-background-alt
+    margin-bottom: 30px
+
+main
+    min-height: 70vh
+
+.container-fluid
+    padding-right: var(--bs-gutter-x)
+    padding-left: var(--bs-gutter-x)
+
+h2
+    font-weight: bold
+
+.section
+    font-size: $h5-font-size
+    margin-top: 60px !important
+    padding-bottom: 10px
+    border-bottom: 1px solid #00000033
+
+a
+    text-decoration: none
+    text-decoration-thickness: 1px
+    text-underline-offset: 5px
+    transition: text-decoration 0.5s, color 0.5s
+
+    &:hover
+        color: darken($primary, 10)
+
+.card
+    margin-bottom: $spacing2
+    .card-header
+        .card-title
+            font-size: $h5-font-size
+            text-transform: uppercase
+            color: $color-text-alt
+    .card-body
+        margin-top: $spacing1
+
+.list-group-item.active
+    color: $color-accent
+    font-weight: bold
+
+.btn-xs
+    font-size: 14px
+    padding: 2px 7px
+
+.commands
+    background: $color-background-alt
+    position: fixed
+    bottom: 0
+    left: 0
+    right: 0
+    z-index: 100
+
+.table
+    input[type=checkbox]
+        margin-right: 10px
+
+footer
+    min-height: 300px
+    a
+        text-decoration: none
+        color: white
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/pure/utils.sass b/app/assets/stylesheets/admin/pure/utils.sass
new file mode 100644
index 0000000000000000000000000000000000000000..ecae55eb75f89242df3a22e4c4fa7f0745f548eb
--- /dev/null
+++ b/app/assets/stylesheets/admin/pure/utils.sass
@@ -0,0 +1,3 @@
+@function px2rem($size)
+    $remSize: $size / 16
+    @return #{$remSize}rem
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/pure/variables.sass b/app/assets/stylesheets/admin/pure/variables.sass
new file mode 100644
index 0000000000000000000000000000000000000000..2f18f22fa3b18a55d44c0ffbd5036a85857844c7
--- /dev/null
+++ b/app/assets/stylesheets/admin/pure/variables.sass
@@ -0,0 +1,56 @@
+// MAIN COLORS
+$color-accent: #0038FF
+$color-text: #000000
+$color-text-alt: #454545
+$color-border: rgba(0, 0, 0, 0.30)
+$color-background-alt: #F2F2F2
+$color-background: #FFFFFF
+
+// Spacing
+$spacing0: px2rem(10)
+$spacing1: px2rem(20)
+$spacing2: px2rem(40)
+$spacing3: px2rem(60)
+$spacing4: px2rem(120)
+$spacing5: px2rem(240)
+
+// Bootstrap
+
+$primary: $color-accent
+$color-background-alt: #F5F5F5
+
+$font-family-sans-serif: "Basier Square", sans-serif
+
+$grid-gutter-width: 60px
+
+$border-radius: 0
+$border-radius-sm: 0
+$border-radius-lg: 0
+$border-radius-xl: 0
+$border-radius-2xl: 0
+
+$card-spacer-y: 0
+$card-spacer-x: 0
+$card-border-width: 0
+$card-cap-bg: transparent
+
+$transition-collapse: height 0
+
+$h2-font-size: 20px
+$h5-font-size: px2rem(14)
+
+$table-cell-padding-x: 0
+$table-cell-padding-x-sm: 0
+
+$badge-font-weight: normal
+
+$form-label-font-size: $h5-font-size
+
+$breadcrumb-font-size:  $h5-font-size
+$breadcrumb-padding-y: $spacing1
+
+$list-group-item-padding-x: 0
+$list-group-active-bg: $color-background
+$list-group-active-border-color: $color-accent
+
+$enable-negative-margins: true
\ No newline at end of file
diff --git a/app/assets/stylesheets/extranet/layout/_typography.sass b/app/assets/stylesheets/extranet/layout/_typography.sass
index bfffe7a54371e4e05ad91f7fb1eac263b28050c6..1da69d9fe841a674a87875baa8f1340de88e9194 100644
--- a/app/assets/stylesheets/extranet/layout/_typography.sass
+++ b/app/assets/stylesheets/extranet/layout/_typography.sass
@@ -3,21 +3,21 @@
     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")
+    src: asset-url("Basier-Square/basiersquare-regular-webfont.woff2") format("woff2"), url("Basier-Square/basiersquare-regular-webfont.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")
+    src: asset-url("Basier-Square/basiersquare-medium-webfont.woff2") format("woff2"), url("Basier-Square/basiersquare-medium-webfont.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")
+    src: asset-url("Basier-Square/basiersquare-semibold-webfont.woff2") format("woff2"), url("Basier-Square/basiersquare-semibold-webfont.woff") format("woff")
 
 h1
     margin-top: 20px
diff --git a/app/controllers/application_controller/with_domain.rb b/app/controllers/application_controller/with_domain.rb
index 95edbff9d84a85214ba910175c7adfe573f154e2..407099b18e47babfe1b16ba25e93ba7d6bc7b10e 100644
--- a/app/controllers/application_controller/with_domain.rb
+++ b/app/controllers/application_controller/with_domain.rb
@@ -31,5 +31,10 @@ module ApplicationController::WithDomain
       current_extranet.present? ? 'extranet'  : 'university'
     end
     helper_method :current_mode
+
+    def current_admin_theme
+      current_user.nil? ? 'appstack' : current_user.admin_theme
+    end
+    helper_method :current_admin_theme
   end
 end
diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb
index 840ef1be6bb094550c6e00122b175a415351ae1b..14602622f75515cda898e4677d9a16d52ff1d32c 100644
--- a/app/controllers/users/registrations_controller.rb
+++ b/app/controllers/users/registrations_controller.rb
@@ -48,7 +48,7 @@ class Users::RegistrationsController < Devise::RegistrationsController
   end
 
   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])
+    devise_parameter_sanitizer.permit(:account_update, keys: [:mobile_phone, :language_id, :first_name, :last_name, :picture, :picture_infos, :picture_delete, :admin_theme])
   end
 
   def sign_up_params
diff --git a/app/helpers/admin/application_helper.rb b/app/helpers/admin/application_helper.rb
index d310aaf50372ba8bab825e0f78b8305f9dd09b76..81df5fccd9cee15bd8b449d22719afbd2d905ef7 100644
--- a/app/helpers/admin/application_helper.rb
+++ b/app/helpers/admin/application_helper.rb
@@ -38,7 +38,7 @@ module Admin::ApplicationHelper
   end
 
   def preview_link
-    raw "<button  class=\"btn btn-primary\"
+    raw "<button  class=\"btn btn-primary btn-xs\"
                   type=\"button\"
                   data-bs-toggle=\"modal\"
                   data-bs-target=\"#preview\"
diff --git a/app/models/user.rb b/app/models/user.rb
index 57824a2c781069c0c97f01e1084b541dde01a3cc..569270a99f6938fb281b3a5944e528b265872dbb 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -3,6 +3,7 @@
 # Table name: users
 #
 #  id                            :uuid             not null, primary key
+#  admin_theme                   :integer          default("appstack")
 #  confirmation_sent_at          :datetime
 #  confirmation_token            :string           indexed
 #  confirmed_at                  :datetime
@@ -55,6 +56,7 @@
 #  fk_rails_bd6f7212a9  (university_id => universities.id)
 #
 class User < ApplicationRecord
+  include WithAdminTheme
   include WithAvatar
   include WithRegistrationContext
   include WithUniversity
diff --git a/app/models/user/with_admin_theme.rb b/app/models/user/with_admin_theme.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5b236358b486f3383aa27922c7ec6180524aa002
--- /dev/null
+++ b/app/models/user/with_admin_theme.rb
@@ -0,0 +1,10 @@
+module User::WithAdminTheme
+  extend ActiveSupport::Concern
+
+  included do
+    enum admin_theme: {
+      appstack: 0, 
+      pure: 1 
+    }
+  end
+end
\ No newline at end of file
diff --git a/app/services/osuny/breadcrumbs_on_rails_builder.rb b/app/services/osuny/breadcrumbs_on_rails_builder.rb
new file mode 100644
index 0000000000000000000000000000000000000000..db1e95cd3a7e2f089235f7b48dd2aa421fd516a3
--- /dev/null
+++ b/app/services/osuny/breadcrumbs_on_rails_builder.rb
@@ -0,0 +1,23 @@
+class Osuny::BreadcrumbsOnRailsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
+  def render
+    return '' unless @elements.many?
+    html = '<nav aria-label="breadcrumb"><ol class="breadcrumb m-0">'
+    html += @elements.collect do |element|
+      render_element(element)
+    end.join('')
+    html += '</ol></nav>'
+    html
+  end
+
+  def render_element(element)
+    if element.path == nil
+      content = compute_name(element)
+    else
+      content = @context.link_to_unless_current(compute_name(element), compute_path(element), element.options)
+    end
+    classes = 'breadcrumb-item'
+    current_page = @context.current_page? compute_path(element)
+    classes += ' active' if current_page
+    "<li class=\"#{classes}\"#{' aria-current="page"' if current_page}>#{content}</li>"
+  end
+end
diff --git a/app/services/osuny/simple_navigation_renderer.rb b/app/services/osuny/simple_navigation_renderer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..18d8d9238f79dd6a9bfe64b253061af9b27ef738
--- /dev/null
+++ b/app/services/osuny/simple_navigation_renderer.rb
@@ -0,0 +1,39 @@
+class Osuny::SimpleNavigationRenderer < SimpleNavigation::Renderer::Base
+  OPEN = "<div class=\"col-md-4 col-lg-3 mb-5\">"
+  CLOSE = "</div>"
+
+  attr_accessor :content, :index, :item
+
+  def render(item_container)
+    @content = ''
+    @index = 0
+    item_container.items.each do |item|
+      @item = item
+      build
+      @index += 1
+    end
+    @content << CLOSE
+    @content.html_safe
+  end
+
+  protected
+
+  def build
+    if @index.zero?
+      @content << "#{OPEN}<h2>#{item_name_and_link}</h2>"
+    elsif item_is_header?
+      @content << "</ul>#{CLOSE}#{OPEN}<h2>#{item_name_and_link}</h2><ul>"
+    else
+      @content << "<li>#{item_name_and_link}</li>"
+    end
+  end
+
+  def item_is_header?
+    item.send(:options)[:kind] == :header
+  end
+
+  def item_name_and_link
+    item.url.present? ? "<a href=\"#{item.url}\">#{item.name}</a>"
+                      : "<span>#{item.name}</span>"
+  end
+end
diff --git a/app/views/admin/application/_notice.html.erb b/app/views/admin/application/_notice.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..3b4ff192ce3c8b2d4fd2d1035c2d317e5899a8e7
--- /dev/null
+++ b/app/views/admin/application/_notice.html.erb
@@ -0,0 +1,12 @@
+<div class="toasts-container" style="position: fixed; top: 20px; right: 20px; z-index: 100000;">
+  <% unless notice.nil? %>
+    <div class="js-notyf-notice d-none">
+      <%= notice %>
+    </div>
+  <% end %>
+  <% unless alert.nil? %>
+    <div class="js-notyf-alert d-none">
+      <%= alert %>
+    </div>
+  <% end %>
+</div>
\ No newline at end of file
diff --git a/app/views/admin/communication/blocks/new.html.erb b/app/views/admin/communication/blocks/new.html.erb
index c754eafd14b6f706d6edf2dbda4bf9f7c2cac48a..6ba41853285842a7419cdd8d0397e62ad768f132 100644
--- a/app/views/admin/communication/blocks/new.html.erb
+++ b/app/views/admin/communication/blocks/new.html.erb
@@ -25,9 +25,7 @@
         <div class="card flex-fill">
           <%= image_tag "communication/blocks/templates/#{kind}.jpg", alt: '', class:"card-img-top" %>
           <div class="card-body d-flex flex-column">
-              <h5 class="card-title">
-                <%= t "enums.communication.block.template_kind.#{kind}" %>
-              </h5>
+              <h4><%= t "enums.communication.block.template_kind.#{kind}" %></h4>
               <p class="mb-0">
                 <%= t "admin.communication.blocks.templates.#{kind}.description" %>
               </p>
diff --git a/app/views/admin/communication/websites/posts/_list.html.erb b/app/views/admin/communication/websites/posts/_list.html.erb
index bc30187722ff808aaefe4b83588f728a1b3d74a0..d608f73ce3297e6d8ecd6dc094d042d30889a09e 100644
--- a/app/views/admin/communication/websites/posts/_list.html.erb
+++ b/app/views/admin/communication/websites/posts/_list.html.erb
@@ -17,13 +17,7 @@
         <% 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>
+        <th colspan="2"><%= Communication::Website::Post.human_attribute_name('meta') %></th>
       </tr>
     </thead>
     <tbody>
@@ -39,20 +33,22 @@
                           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>
+          <td>
+            <p class="small mb-0">
+              <%= l post.published_at, format: :date_with_explicit_month if post.published_at %>
+            </p>
+            <% if !hide_author && post.author %>
+              <p class="small mb-0">
+                <%= link_to post.author, admin_communication_website_author_path(website_id: post.website.id, id: post.author.id) %>
+              </p>
+            <% end %>
+            <% unless hide_category %>
               <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>
+                  <li><%= link_to_if can?(:read, category), category, admin_communication_website_category_path(website_id: post.website.id, id: category.id), class: 'small' %></li>
                 <% end %>
               </ul>
-            </td>
-          <% end %>
-          <td>
-            <%= l post.published_at, format: :date_with_explicit_month if post.published_at %>
+            <% end %>
             <% if post.pinned %>
               <span class="badge bg-success"><%= Communication::Website::Post.human_attribute_name('pinned') %></span>
             <% end %>
diff --git a/app/views/admin/dashboard/index.html.erb b/app/views/admin/dashboard/index.html.erb
index 0513c20e8644c8a34489efb507030905f6604235..0343ab54df599b8d77919050467d074fe4ba115d 100644
--- a/app/views/admin/dashboard/index.html.erb
+++ b/app/views/admin/dashboard/index.html.erb
@@ -34,29 +34,8 @@
   </div>
 </div>
 
-<% if current_university.research_journals.any? && can?(:read, Research::Journal) %>
-  <h2 class="h4 my-4"><%= Research::Journal.model_name.human(count: 2) %></h2>
-  <div class="row">
-    <% current_university.research_journals.each do |journal| %>
-      <% next unless can?(:read, journal) %>
-      <div class="<%= classes %>">
-        <div class="card flex-fill">
-          <div class="card-body">
-            <span class="float-end">
-              <i class="fas fa-<%= Icon::RESEARCH_JOURNAL %> fa-2x"></i>
-            </span>
-            <h4><%= journal %></h4>
-            <p>&nbsp;</p>
-            <%= link_to t('show'), [:admin, journal], class: button_classes('stretched-link') %>
-          </div>
-        </div>
-      </div>
-    <% end %>
-  </div>
-<% end %>
-
 <% if current_university.communication_websites.any? && can?(:read, Communication::Website) %>
-  <h2 class="h4 my-4"><%= Communication::Website.model_name.human(count: 2) %></h2>
+  <h2 class="h4 my-4 section"><%= Communication::Website.model_name.human(count: 2) %></h2>
   <div class="row">
     <% current_university.communication_websites.each do |website| %>
       <% next unless can?(:read, website) %>
@@ -77,7 +56,7 @@
 <% end %>
 
 <% if current_university.communication_extranets.any? && can?(:read, Communication::Extranet) %>
-  <h2 class="h4 my-4"><%= Communication::Extranet.model_name.human(count: 2) %></h2>
+  <h2 class="h4 my-4 section"><%= Communication::Extranet.model_name.human(count: 2) %></h2>
   <div class="row">
     <% current_university.communication_extranets.each do |extranet| %>
       <% next unless can?(:read, extranet) %>
@@ -97,23 +76,46 @@
   </div>
 <% end %>
 
-<div class="small mt-5">
-  <ul class="list-inline">
-    <li class="list-inline-item">
-      <%= link_to 'API', api_root_path %>
-    </li>
-    <%
-    [
-    :terms_of_service,
-    :privacy_policy,
-    :cookies_policy
-    ].each do |term| %>
+<% if current_university.research_journals.any? && can?(:read, Research::Journal) %>
+  <h2 class="h4 my-4 section"><%= Research::Journal.model_name.human(count: 2) %></h2>
+  <div class="row">
+    <% current_university.research_journals.each do |journal| %>
+      <% next unless can?(:read, journal) %>
+      <div class="<%= classes %>">
+        <div class="card flex-fill">
+          <div class="card-body">
+            <span class="float-end">
+              <i class="fas fa-<%= Icon::RESEARCH_JOURNAL %> fa-2x"></i>
+            </span>
+            <h4><%= journal %></h4>
+            <p>&nbsp;</p>
+            <%= link_to t('show'), [:admin, journal], class: button_classes('stretched-link') %>
+          </div>
+        </div>
+      </div>
+    <% end %>
+  </div>
+<% end %>
+
+<% if current_admin_theme == 'appstack' %>
+  <div class="small mt-5">
+    <ul class="list-inline">
       <li class="list-inline-item">
-        <%= link_to t("#{term}"), t("#{term}_url"), target: '_blank', rel: 'noreferrer' %>
+        <%= link_to 'API', api_root_path %>
       </li>
-    <% end %>
-    <li class="list-inline-item">
-      <%= link_to t('cookies_consent_choice'), '', class: 'js-gdpr__cookie_consent__display_again' %>
-    </li>
-  </ul>
-</div>
+      <%
+      [
+      :terms_of_service,
+      :privacy_policy,
+      :cookies_policy
+      ].each do |term| %>
+        <li class="list-inline-item">
+          <%= link_to t("#{term}"), t("#{term}_url"), target: '_blank', rel: 'noreferrer' %>
+        </li>
+      <% end %>
+      <li class="list-inline-item">
+        <%= link_to t('cookies_consent_choice'), '', class: 'js-gdpr__cookie_consent__display_again' %>
+      </li>
+    </ul>
+  </div>
+<% end %>
diff --git a/app/views/admin/layouts/application.html.erb b/app/views/admin/layouts/application.html.erb
index f83b836827ba0a626056ee3391bce537f261fdee..e87875475c5ecfb9f00d9554f57b71dc0a46a456 100644
--- a/app/views/admin/layouts/application.html.erb
+++ b/app/views/admin/layouts/application.html.erb
@@ -3,57 +3,14 @@
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <title><%= content_for?(:title) ? raw("#{yield(:title)} ∙ Osuny")
-                                    : 'Osuny' %></title>
+    <title><%= content_for?(:title) ? raw("#{yield(:title)} ∙ Osuny") : 'Osuny' %></title>
     <%= csrf_meta_tags %>
     <%= csp_meta_tag %>
     <script>
     // Avoid opening menu on load
     </script>
-    <%= stylesheet_link_tag 'admin', media: 'all' %>
+    <%= stylesheet_link_tag "admin/#{current_admin_theme}", media: 'all' %>
     <%= favicon_link_tag 'favicon.png' %>
   </head>
-  <body class="<%= body_classes %>" data-layout="fluid" data-sidebar-position="left">
-    <div class="toasts-container" style="position: fixed; top: 20px; right: 20px; z-index: 100000;">
-      <% unless notice.nil? %>
-        <div class="js-notyf-notice d-none">
-          <%= notice %>
-        </div>
-      <% end %>
-      <% unless alert.nil? %>
-        <div class="js-notyf-alert d-none">
-          <%= alert %>
-        </div>
-      <% end %>
-    </div>
-    <div class="wrapper">
-      <%= render 'admin/application/nav' %>
-      <%= render 'admin/application/footer' %>
-      <div class="main">
-        <%= render 'admin/application/top' %>
-        <main class="content">
-          <div class="container-fluid p-0">
-            <% unless current_user.confirmed? %>
-              <div class="alert alert-warning">
-                <div class="alert-message">
-                  <%= t('admin.users_alerts.pending_confirmation_html', duration: distance_of_time_in_words(Rails.configuration.devise.allow_unconfirmed_access_for)) %>
-                  <br>
-                  <%= link_to t('devise.confirmations.new.resend_confirmation_instructions'), resend_user_confirmation_path, method: :post, class: 'alert-link' %>
-                </div>
-              </div>
-            <% end %>
-            <div class="d-flex justify-content-between">
-              <h1><%= yield :title %></h1>
-              <p class="text-end pt-1"><%= yield :title_right %></p>
-            </div>
-            <%= yield %>
-          </div>
-          <%= render 'admin/application/preview' %>
-        </main>
-      </div>
-    </div>
-    <%= javascript_include_tag 'admin' %>
-    <%= render 'gdpr/cookie_consent' %>
-    <%= render 'bugsnag' %>
-  </body>
+  <%= render "admin/layouts/themes/#{current_admin_theme}" %>
 </html>
diff --git a/app/views/admin/layouts/themes/_appstack.html.erb b/app/views/admin/layouts/themes/_appstack.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..6191e7000989d28f1345afbef2040255b5f82057
--- /dev/null
+++ b/app/views/admin/layouts/themes/_appstack.html.erb
@@ -0,0 +1,32 @@
+<body class="<%= body_classes %>" data-layout="fluid" data-sidebar-position="left">
+  <%= render 'admin/application/notice' %>
+  <div class="wrapper">
+    <%= render "admin/layouts/themes/appstack/nav" %>
+    <%= render "admin/layouts/themes/appstack/footer" %>
+    <div class="main">
+      <%= render "admin/layouts/themes/appstack/top" %>
+      <main class="content">
+        <div class="container-fluid p-0">
+          <% unless current_user.confirmed? %>
+            <div class="alert alert-warning">
+              <div class="alert-message">
+                <%= t('admin.users_alerts.pending_confirmation_html', duration: distance_of_time_in_words(Rails.configuration.devise.allow_unconfirmed_access_for)) %>
+                <br>
+                <%= link_to t('devise.confirmations.new.resend_confirmation_instructions'), resend_user_confirmation_path, method: :post, class: 'alert-link' %>
+              </div>
+            </div>
+          <% end %>
+          <div class="d-flex justify-content-between">
+            <h1><%= yield :title %></h1>
+            <p class="text-end pt-1"><%= yield :title_right %></p>
+          </div>
+          <%= yield %>
+        </div>
+        <%= render 'admin/application/preview' %>
+      </main>
+    </div>
+  </div>
+  <%= javascript_include_tag 'admin/appstack' %>
+  <%= render 'gdpr/cookie_consent' %>
+  <%= render 'bugsnag' %>
+</body>
\ No newline at end of file
diff --git a/app/views/admin/layouts/themes/_pure.html.erb b/app/views/admin/layouts/themes/_pure.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..3e28659aaae47d865a730df0ff7868c69514d7d3
--- /dev/null
+++ b/app/views/admin/layouts/themes/_pure.html.erb
@@ -0,0 +1,23 @@
+<body class="<%= body_classes %>">
+  <%= render "admin/layouts/themes/pure/nav" %>
+  <%= render "admin/layouts/themes/pure/hero" %>
+  <%= render 'admin/application/notice' %>
+  <main class="container-fluid">
+    <% unless current_user.confirmed? %>
+      <div class="alert alert-warning">
+        <div class="alert-message">
+          <%= t('admin.users_alerts.pending_confirmation_html', duration: distance_of_time_in_words(Rails.configuration.devise.allow_unconfirmed_access_for)) %>
+          <br>
+          <%= link_to t('devise.confirmations.new.resend_confirmation_instructions'), resend_user_confirmation_path, method: :post, class: 'alert-link' %>
+        </div>
+      </div>
+    <% end %>
+    <%= yield %>
+    <%= render 'admin/application/preview' %>
+  </main>
+  <%= render "admin/layouts/themes/pure/commands" %>
+  <%= render "admin/layouts/themes/pure/footer" %>
+  <%= javascript_include_tag 'admin/pure' %>
+  <%= render 'gdpr/cookie_consent' %>
+  <%= render 'bugsnag' %>
+</body>
\ No newline at end of file
diff --git a/app/views/admin/application/_footer.html.erb b/app/views/admin/layouts/themes/appstack/_footer.html.erb
similarity index 96%
rename from app/views/admin/application/_footer.html.erb
rename to app/views/admin/layouts/themes/appstack/_footer.html.erb
index 85dcc754f505f6d713c1f64cbc74ccf27736d1a2..78bb9da727aea8159977e7f616c9e9eb7cf09e32 100644
--- a/app/views/admin/application/_footer.html.erb
+++ b/app/views/admin/layouts/themes/appstack/_footer.html.erb
@@ -7,4 +7,4 @@
       <%= yield :action_bar_right %>
     </div>
   </footer>
-<% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/admin/application/_nav.html.erb b/app/views/admin/layouts/themes/appstack/_nav.html.erb
similarity index 100%
rename from app/views/admin/application/_nav.html.erb
rename to app/views/admin/layouts/themes/appstack/_nav.html.erb
diff --git a/app/views/admin/application/_top.html.erb b/app/views/admin/layouts/themes/appstack/_top.html.erb
similarity index 100%
rename from app/views/admin/application/_top.html.erb
rename to app/views/admin/layouts/themes/appstack/_top.html.erb
diff --git a/app/views/admin/layouts/themes/pure/_commands.html.erb b/app/views/admin/layouts/themes/pure/_commands.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..452c75a6a56e34ec7ef7533aae57b5c9ae4a7941
--- /dev/null
+++ b/app/views/admin/layouts/themes/pure/_commands.html.erb
@@ -0,0 +1,12 @@
+<% if content_for?(:action_bar_left) or content_for?(:action_bar_right) %>
+  <div class="commands">
+    <div class="container-fluid py-3 d-flex">
+      <div>
+        <%= yield :action_bar_left %>
+      </div>
+      <div class="ms-auto">
+        <%= yield :action_bar_right %>
+      </div>
+    </div>
+  </div>
+<% end %>
\ No newline at end of file
diff --git a/app/views/admin/layouts/themes/pure/_footer.html.erb b/app/views/admin/layouts/themes/pure/_footer.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..155c826c4dbf0599650dd265435d1157348dbfcc
--- /dev/null
+++ b/app/views/admin/layouts/themes/pure/_footer.html.erb
@@ -0,0 +1,31 @@
+<footer class="bg-black py-5 mt-5">
+  <div class="container-fluid">
+    <div class="row">
+      <div class="col-md-3">
+        <%= link_to 'https://www.osuny.org', target: :_blank do %>
+          <%= image_tag 'osuny-white.svg', width: 100 %>
+        <% end %>
+      </div>
+      <div class="col-md-9 text-md-end small">
+        <ul class="list-inline">
+          <li class="list-inline-item">
+            <%= link_to 'API', api_root_path %>
+          </li>
+          <%
+          [
+          :terms_of_service,
+          :privacy_policy,
+          :cookies_policy
+          ].each do |term| %>
+            <li class="list-inline-item">
+              <%= link_to t("#{term}"), t("#{term}_url"), target: '_blank', rel: 'noreferrer' %>
+            </li>
+          <% end %>
+          <li class="list-inline-item">
+            <%= link_to t('cookies_consent_choice'), '', class: 'js-gdpr__cookie_consent__display_again' %>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</footer>
\ No newline at end of file
diff --git a/app/views/admin/layouts/themes/pure/_hero.html.erb b/app/views/admin/layouts/themes/pure/_hero.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..8d1232c39de7a49b9116eaaf17ae1fc7021e498a
--- /dev/null
+++ b/app/views/admin/layouts/themes/pure/_hero.html.erb
@@ -0,0 +1,9 @@
+<div class="hero">
+  <div class="container-fluid">
+    <h1><%= yield :title %></h1>
+    <div class="float-md-end text-end mt-md-n4">
+      <%= yield :title_right %>
+    </div>
+    <%= render_breadcrumbs builder: Osuny::BreadcrumbsOnRailsBuilder %>
+  </div>
+</div>
\ No newline at end of file
diff --git a/app/views/admin/layouts/themes/pure/_nav.html.erb b/app/views/admin/layouts/themes/pure/_nav.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..938dd2e09d1073bdf6d0d4d969f84f59405e658f
--- /dev/null
+++ b/app/views/admin/layouts/themes/pure/_nav.html.erb
@@ -0,0 +1,60 @@
+<nav class="navbar navbar-main navbar-light bg-transparent" aria-label="Navigation">
+  <div class="container-fluid">
+    <%= link_to admin_root_path, class: 'navbar-brand' do %>
+      <%= image_tag 'osuny-black.svg', class: 'img-fluid' %>
+    <% end %>
+    <button class="btn-open bg-transparent border-0"
+            type="button"
+            data-bs-toggle="collapse"
+            data-bs-target="#menu"
+            data-bs-animation=""
+            aria-controls="navbar-brand"
+            aria-expanded="false"
+            aria-label="Afficher la navigation">
+      Menu
+      <i class="fas fa-bars"></i>
+    </button>
+  </div>
+</nav>
+<div class="collapse" id="menu">
+  <div class="navbar">
+    <div class="container-fluid">
+      <%= link_to admin_root_path, class: 'navbar-brand' do %>
+        <%= image_tag 'osuny-white.svg', class: 'img-fluid', width: 100 %>
+      <% end %>
+      <button class="btn-open bg-transparent border-0 text-white"
+              type="button"
+              data-bs-toggle="collapse"
+              data-bs-target="#menu"
+              data-bs-animation=""
+              aria-controls="navbar-brand"
+              aria-expanded="false"
+              aria-label="Masquer la navigation">
+        Fermer
+        <i class="fas fa-xmark"></i>
+      </button>
+   </div>
+  </div>
+  <div class="menu-content">
+    <div class="container-fluid">
+      <div class="row">
+        <%= render_navigation context: :admin, renderer: Osuny::SimpleNavigationRenderer %>
+        <div class="col-md-4 col-lg-3">
+          <a class="float-end" href="#">
+            <% if current_user.picture.attached? && current_user.picture.variable? %>
+              <%= image_tag current_user.picture.variant(resize: '80x80'), class: 'avatar img-fluid rounded-circle' %>
+            <% else %>
+              <%= image_tag 'avatar.jpg', class: 'avatar img-fluid rounded-circle' %>
+            <% end %>
+          </a>
+          <h2><%= current_user.to_s %></h2>
+          <ul>
+            <li><%= link_to t('menu.profile'), edit_user_registration_path %></li>
+            <li><%= link_to t('menu.server_admin'), server_root_path if current_user.server_admin? %></li>
+            <li><%= link_to t('menu.sign_out'), destroy_user_session_path, method: :delete %></li>
+          </ul>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb
index 334f130b85e9d13fef685c98dbd7a2ededb0a18b..36cec043719237fb7541fc3d45b9d832e402e4ea 100644
--- a/app/views/devise/registrations/edit.html.erb
+++ b/app/views/devise/registrations/edit.html.erb
@@ -19,6 +19,7 @@
                         include_blank: false,
                         label_method: lambda { |l| t("languages.#{l.iso_code.to_s}") } %>
       <%= f.input :mobile_phone %>
+      <%= f.input :admin_theme, include_blank: false %>
     </div>
     <div class="col-md-4">
       <%= f.input :password,
diff --git a/app/views/layouts/devise.html.erb b/app/views/layouts/devise.html.erb
index ad40226ca8467fd3cd9691242cccb72b41a670ab..352fb34385d53fe8b4a9ec855fc11c5ca230c61a 100644
--- a/app/views/layouts/devise.html.erb
+++ b/app/views/layouts/devise.html.erb
@@ -6,7 +6,7 @@
     <title><%= yield :title %></title>
     <%= csrf_meta_tags %>
     <%= csp_meta_tag %>
-    <%= stylesheet_link_tag 'admin', media: 'all' %>
+    <%= stylesheet_link_tag "admin/#{current_admin_theme}", media: 'all' %>
     <%= javascript_include_tag 'devise' %>
     <%= favicon_link_tag 'favicon.png' %>
   </head>
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index b8696c31a261e655dba27d87d4cc3acbeca77b11..1024a31e7523611f2e5c2fb834d4e19bb5bbda19 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -44,6 +44,7 @@ fr:
         iso_code: Code Iso
         name: Nom
       user:
+        admin_theme: Thème de l'administration
         email: Email
         first_name: Prénom
         language: Langue préférée
diff --git a/db/migrate/20221127172028_add_admin_theme_to_users.rb b/db/migrate/20221127172028_add_admin_theme_to_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2bfe2a683732337c60224cce039f979a43a664c5
--- /dev/null
+++ b/db/migrate/20221127172028_add_admin_theme_to_users.rb
@@ -0,0 +1,5 @@
+class AddAdminThemeToUsers < ActiveRecord::Migration[6.1]
+  def change
+    add_column :users, :admin_theme, :integer, default: 0
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index efeb6ffedf8fc615acb05d970eac004f2e0d7470..bfb0bbe3dec8739bdaa3c343cc53dbba46b9f23b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -810,6 +810,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_11_28_112830) do
     t.string "session_token"
     t.string "picture_url"
     t.string "direct_otp_delivery_method"
+    t.integer "admin_theme", default: 0
     t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
     t.index ["email", "university_id"], name: "index_users_on_email_and_university_id", unique: true
     t.index ["encrypted_otp_secret_key"], name: "index_users_on_encrypted_otp_secret_key", unique: true