diff --git a/app/assets/javascripts/admin/communication/init.js b/app/assets/javascripts/admin/communication/init.js
index 19ec2dabb9dcf27049b92fe63ba758ef05065377..ab94a3b301ba8ab4a94bf8818c36b6e1025c164a 100644
--- a/app/assets/javascripts/admin/communication/init.js
+++ b/app/assets/javascripts/admin/communication/init.js
@@ -1,4 +1,5 @@
 //= require_self
 //= require ./menu_items
+//= require ./preview
 
 window.osuny.communication = {};
diff --git a/app/assets/javascripts/admin/communication/preview.js b/app/assets/javascripts/admin/communication/preview.js
new file mode 100644
index 0000000000000000000000000000000000000000..5a2d11e0da2ea0c0f6c7b281aaf57db9cd41983b
--- /dev/null
+++ b/app/assets/javascripts/admin/communication/preview.js
@@ -0,0 +1,11 @@
+$(function() {
+  'use strict';
+  var modes = ['mobile', 'tablet', 'desktop'],
+      mode = '';
+  $('.preview__button').on('click', function(){
+    mode = $(this).data('mode');
+    $('.preview__button').removeClass('btn-primary').addClass('btn-light');
+    $(this).removeClass('btn-light').addClass('btn-primary');
+    $('#preview').removeClass('preview--desktop').removeClass('preview--tablet').removeClass('preview--mobile').addClass('preview--' + mode);
+  });
+});
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin/preview.sass b/app/assets/stylesheets/admin/preview.sass
index 49596e58697528e98f5785bc863163d63fee1b70..7db0e22bde6f5296ad0d3743e4a1a4acbdabbae7 100644
--- a/app/assets/stylesheets/admin/preview.sass
+++ b/app/assets/stylesheets/admin/preview.sass
@@ -1,7 +1,17 @@
 .preview
-    img
-        height: auto
-        max-width: 100%
-    iframe
-        height: 220px
-        max-width: 100%
+    .modal-body
+        background: black
+        text-align: center
+        overflow: hidden
+        iframe
+            height: 100%
+            transition: width 0.5s ease
+    &--mobile
+        iframe
+            width: 415px
+    &--tablet
+        iframe
+            width: 768px
+    &--desktop
+        iframe
+            width: 100%
diff --git a/app/controllers/admin/communication/websites/pages_controller.rb b/app/controllers/admin/communication/websites/pages_controller.rb
index 4d3e9be9919a7c3aa44ef54327a4d706e9e02d07..c6c290817899f759a8648cd5b61c6146260fafc3 100644
--- a/app/controllers/admin/communication/websites/pages_controller.rb
+++ b/app/controllers/admin/communication/websites/pages_controller.rb
@@ -35,6 +35,10 @@ class Admin::Communication::Websites::PagesController < Admin::Communication::We
     render layout: false
   end
 
+  def preview
+    render layout: 'admin/layouts/preview'
+  end
+
   def new
     @page.website = @website
     breadcrumb
diff --git a/app/controllers/admin/communication/websites/posts_controller.rb b/app/controllers/admin/communication/websites/posts_controller.rb
index 3c711ef52fd17b9dafd94f0f68c83b0a299f38b9..0b432a85668a56f2dbb9afd84fbcd4f3aee8ee36 100644
--- a/app/controllers/admin/communication/websites/posts_controller.rb
+++ b/app/controllers/admin/communication/websites/posts_controller.rb
@@ -36,6 +36,10 @@ class Admin::Communication::Websites::PostsController < Admin::Communication::We
     breadcrumb
   end
 
+  def preview
+    render layout: 'admin/layouts/preview'
+  end
+
   def static
     @about = @post
     render layout: false
diff --git a/app/controllers/admin/communication/websites_controller.rb b/app/controllers/admin/communication/websites_controller.rb
index 030e0633e8b9701b6dcd5da8287e1080d74e4539..cc504ae9b52e6b269ebc7c9a0117af03cf83deae 100644
--- a/app/controllers/admin/communication/websites_controller.rb
+++ b/app/controllers/admin/communication/websites_controller.rb
@@ -18,6 +18,10 @@ class Admin::Communication::WebsitesController < Admin::Communication::Applicati
     breadcrumb
   end
 
+  def style
+    render body: @website.preview_style, content_type: "text/css"
+  end
+
   def new
     breadcrumb
   end
diff --git a/app/controllers/admin/education/programs_controller.rb b/app/controllers/admin/education/programs_controller.rb
index 230760853db7be73108426cfd5582281fb722471..edb22802238dd74a988112f6c3626beac2c65d94 100644
--- a/app/controllers/admin/education/programs_controller.rb
+++ b/app/controllers/admin/education/programs_controller.rb
@@ -54,6 +54,11 @@ class Admin::Education::ProgramsController < Admin::Education::ApplicationContro
     breadcrumb
   end
 
+  def preview
+    @website = @program.websites&.first
+    render layout: 'admin/layouts/preview'
+  end
+
   def new
     breadcrumb
   end
diff --git a/app/helpers/admin/application_helper.rb b/app/helpers/admin/application_helper.rb
index 9d9510fe2853d8a921240de1542eab66d31e9b2b..172a0b59cf999863426330d2436783dfd1cbfc25 100644
--- a/app/helpers/admin/application_helper.rb
+++ b/app/helpers/admin/application_helper.rb
@@ -38,7 +38,11 @@ module Admin::ApplicationHelper
   end
 
   def preview_link
-    raw "<button class=\"btn btn-primary\" type=\"button\" data-bs-toggle=\"offcanvas\" data-bs-target=\"#preview\" aria-controls=\"preview\">#{ t 'preview.button'}</button>"
+    raw "<button  class=\"btn btn-primary\"
+                  type=\"button\"
+                  data-bs-toggle=\"modal\"
+                  data-bs-target=\"#preview\"
+                  aria-controls=\"preview\">#{ t 'preview.button'}</button>"
   end
 
   def button_classes(additional = '', **options)
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index 5959845862662263129850d991a808be4edc302c..a52d485dd87b093b2938f5bc2f7e0a7cde038099 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -74,4 +74,20 @@ class Communication::Website < ApplicationRecord
     dependencies
   end
 
+  def preview_style
+    return '' if url.blank?
+    html = Nokogiri::HTML open(url)
+    css_files = html.xpath '//link[@rel="stylesheet"]/@href'
+    css = ''
+    css_files.each do |css_url|
+      css_uri = URI.parse css_url
+      data = Net::HTTP.get css_uri
+      data = data.force_encoding("UTF-8")
+      data = data.gsub "src:url(../", "src:url(#{url}/assets/"
+      data = data.gsub ",url(../", ",url(#{url}/assets/"
+      css << data
+    end
+    css
+  end
+
 end
diff --git a/app/views/admin/application/_preview.html.erb b/app/views/admin/application/_preview.html.erb
index 922eb15bfb434c14c90a5ee5acfe8a3a77a01e88..4a90bc7fe3250e74681f6d896dda9bbb9e42f1d8 100644
--- a/app/views/admin/application/_preview.html.erb
+++ b/app/views/admin/application/_preview.html.erb
@@ -1,9 +1,27 @@
-<div class="offcanvas offcanvas-start preview" tabindex="-1" id="preview" aria-labelledby="offcanvasRightLabel" aria-modal="true" role="dialog">
-  <div class="offcanvas-header border-bottom">
-    <h5 id="offcanvasRightLabel" class="pt-2"><%= t 'preview.title' %></h5>
-    <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+<div id="preview" class="preview modal fade preview--mobile">
+  <div class="modal-dialog modal-fullscreen">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h5 class="modal-title h4"><%= t 'preview.title' %></h5>
+        <div class="btn-group m-auto" role="group" aria-label="Basic example">
+          <button type="button" class="btn btn-primary preview__button" data-mode="mobile">
+            <i class="fas fa-mobile"></i>
+            <%= t 'preview.mobile' %>
+          </button>
+          <button type="button" class="btn btn-light preview__button" data-mode="tablet">
+            <i class="fas fa-tablet"></i>
+            <%= t 'preview.tablet' %>
+          </button>
+          <button type="button" class="btn btn-light preview__button" data-mode="desktop">
+            <i class="fas fa-desktop"></i>
+            <%= t 'preview.desktop' %>
+          </button>
+        </div>
+        <button type="button" class="btn-close ms-0" data-bs-dismiss="modal" aria-label="Close"></button>
+      </div>
+      <div class="modal-body p-2">
+        <iframe src="<%= request.path %>/preview" loading="lazy"></iframe>
+      </div>
+    </div>
   </div>
-  <div class="offcanvas-body">
-    <%= yield :preview %>
-  </div>
-</div>
+</div>
\ No newline at end of file
diff --git a/app/views/admin/communication/blocks/_preview.html.erb b/app/views/admin/communication/blocks/_preview.html.erb
index b8c7348a6f9f073add47dc95237f4723d0b7f316..d58b3fae33005bda346eafe47995ffa252eb1d6f 100644
--- a/app/views/admin/communication/blocks/_preview.html.erb
+++ b/app/views/admin/communication/blocks/_preview.html.erb
@@ -1,3 +1,13 @@
-<h2 class="h4 mt-5"><%= block.title %></h2>
-<% @block = block %>
-<%= render "admin/communication/blocks/templates/#{@block.template_kind}/preview" %>
+<% about.blocks.ordered.each do |block| %>
+  <section class="block-<%= block.template_kind %>">
+    <div class="container">
+      <div class="block-content">
+        <div class="top">
+          <h2><%= block.title %></h2>
+        </div>
+        <% @block = block %>
+        <%= render "admin/communication/blocks/templates/#{@block.template_kind}/preview" %>
+      </div>
+    </div>
+  </section>
+<% end %>
\ No newline at end of file
diff --git a/app/views/admin/communication/blocks/templates/posts/_preview.html.erb b/app/views/admin/communication/blocks/templates/posts/_preview.html.erb
index e6bf09405e8aef1f356ed2ab6733913ff28b4c4e..61501a272d25a67b445702f1343ea7bff7d852fa 100644
--- a/app/views/admin/communication/blocks/templates/posts/_preview.html.erb
+++ b/app/views/admin/communication/blocks/templates/posts/_preview.html.erb
@@ -1,9 +1,20 @@
-<% if @block.data %>
-  <% if @block.template.category %>
-    <h2 class="mb-4"><%= @block.template.category %></h2>
+<div class="posts">
+  <% if @block.data %>
+    <% @block.template.selected_posts.each do |post| %>
+      <div>
+        <article class="post">
+          <div>
+            <p class="title"><%= post %></p>
+            <p><%= post.description_short %></p>
+            <time datetime="<%= post.published_at %>"><%= post.published_at.to_date %></time>
+          </div>
+          <% if post.best_featured_image.attached? %>
+            <div class="media">
+              <%= kamifusen_tag post.best_featured_image %>
+            </div>
+          <% end %>
+        </article>
+      </div>
+    <% end %>
   <% end %>
-  <% @block.template.selected_posts.each do |post| %>
-    <h3 class="h5"><%= post %></h3>
-    <p><%= post.description_short %></p>
-  <% end %>
-<% end %>
+</div>
\ No newline at end of file
diff --git a/app/views/admin/communication/websites/pages/preview.html.erb b/app/views/admin/communication/websites/pages/preview.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..2350e791275bc56bcada79583ec516a052c8721c
--- /dev/null
+++ b/app/views/admin/communication/websites/pages/preview.html.erb
@@ -0,0 +1,4 @@
+<div class="container">
+    <%= @page.text.to_s %>
+</div>
+<%= render 'admin/communication/blocks/preview', about: @page %>
diff --git a/app/views/admin/communication/websites/pages/show.html.erb b/app/views/admin/communication/websites/pages/show.html.erb
index bad7daf9c86e566b09b225c022c2b809f09d87da..641abd9c4ab89471a2796dbaf00c701bba52a119 100644
--- a/app/views/admin/communication/websites/pages/show.html.erb
+++ b/app/views/admin/communication/websites/pages/show.html.erb
@@ -110,13 +110,6 @@
   </div>
 <% end %>
 
-<% content_for :preview do %>
-  <%= @page.text.to_s %>
-  <% @page.blocks.ordered.each do |block| %>
-    <%= render 'admin/communication/blocks/preview', block: block %>
-  <% end %>
-<% end %>
-
 <% content_for :action_bar_left do %>
   <%= destroy_link @page if @page.is_regular_page? %>
   <%= link_to t('static'),
diff --git a/app/views/admin/communication/websites/posts/preview.html.erb b/app/views/admin/communication/websites/posts/preview.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..a390bba28a6ca0d54c2425f97de77897b3aeb958
--- /dev/null
+++ b/app/views/admin/communication/websites/posts/preview.html.erb
@@ -0,0 +1,4 @@
+<div class="container">
+    <%= @post.text.to_s %>
+</div>
+<%= render 'admin/communication/blocks/preview', about: @post %>
diff --git a/app/views/admin/communication/websites/posts/show.html.erb b/app/views/admin/communication/websites/posts/show.html.erb
index fd1c4ea35281c2bbb8c223eaf2179f9b114b579c..77aee23f876abb60567700e350f4bd07b91be64f 100644
--- a/app/views/admin/communication/websites/posts/show.html.erb
+++ b/app/views/admin/communication/websites/posts/show.html.erb
@@ -87,13 +87,6 @@
   </div>
 <% end %>
 
-<% content_for :preview do %>
-  <%= @post.text.to_s %>
-  <% @post.blocks.ordered.each do |block| %>
-    <%= render 'admin/communication/blocks/preview', block: block %>
-  <% end %>
-<% end %>
-
 <% content_for :action_bar_left do %>
   <%= destroy_link @post %>
   <%= link_to t('static'),
diff --git a/app/views/admin/education/programs/preview.html.erb b/app/views/admin/education/programs/preview.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..baeda9acb7b31cf1592575dea9528e1bccdd9f8d
--- /dev/null
+++ b/app/views/admin/education/programs/preview.html.erb
@@ -0,0 +1,25 @@
+<%  [
+    :presentation,
+    :objectives
+    ].each do |property| %>
+    <%= @program.send(property).to_s %>
+<% end %>
+
+<%= render 'admin/communication/blocks/preview', about: @program %>
+
+<%  [
+    :opportunities,
+    :results,
+    :accessibility,
+    :duration,
+    :pricing,
+    :content,
+    :pedagogy,
+    :evaluation,
+    :prerequisites,
+    :registration,
+    :other,
+    :contacts
+    ].each do |property| %>
+    <%= @program.send(property).to_s %>
+<% end %>
diff --git a/app/views/admin/education/programs/show.html.erb b/app/views/admin/education/programs/show.html.erb
index 1699cb9e83ce391edda4423c183a81dc156be25b..7c6c2659641c685fd2c61a792013a301489c99bc 100644
--- a/app/views/admin/education/programs/show.html.erb
+++ b/app/views/admin/education/programs/show.html.erb
@@ -179,27 +179,6 @@
   </div>
 </div>
 
-<% content_for :preview do %>
-  <%  [
-        :presentation,
-        :objectives,
-        :opportunities,
-        :results,
-        :accessibility,
-        :duration,
-        :pricing,
-        :content,
-        :pedagogy,
-        :evaluation,
-        :prerequisites,
-        :registration,
-        :other,
-        :contacts
-      ].each do |property| %>
-    <%= @program.send(property).to_s %>
-  <% end %>
-<% end %>
-
 <% content_for :action_bar_left do %>
   <%= destroy_link @program %>
 <% end %>
diff --git a/app/views/admin/layouts/preview.html.erb b/app/views/admin/layouts/preview.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..791854a7d1449b14f88d8accfbda64a904f7c50d
--- /dev/null
+++ b/app/views/admin/layouts/preview.html.erb
@@ -0,0 +1,20 @@
+<!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>
+    <% if @website %>
+      <link rel="stylesheet" media="all" href="<%= style_admin_communication_website_path @website.id, website_id: nil %>" />
+    <% else %>
+      <%= stylesheet_link_tag 'admin', media: 'all' %>
+    <% end %>
+  </head>
+  <body>
+    <main class="page-with-blocks" id="main" role="main" tabindex="-1">
+      <div class="blocks">
+        <%= yield %>
+      </div>
+    </main>
+  </body>
+</html>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0f1eab65c075872450d938ca347a083d43250f91..2c57fa25b03437b8f9b46a1e774716cdb5345e9a 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -226,7 +226,10 @@ en:
   please_confirm_with_children: "WARNING: deleting this element will also remove every child. Are you sure?"
   preview:
     button: Preview
-    title: Mobile preview
+    title: Preview
+    mobile: Mobile
+    tablet: Tablet
+    desktop: Desktop
   privacy_policy: Privacy policy
   privacy_policy_url: https://osuny.org/politique-de-confidentialite
   quit: Quit
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 7c42c1d15057e1e772f3879165e743dd791dc69c..2482496e188f3ae1dfef099eaedf4d1d0cdb6f66 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -229,7 +229,10 @@ fr:
   please_confirm_with_children: "ATTENTION : effacer cet élément supprimera aussi tous ses enfants. Est-ce que vous confirmez ?"
   preview:
     button: Prévisualiser
-    title: Prévisualisation mobile
+    title: Prévisualisation
+    mobile: Mobile
+    tablet: Tablette
+    desktop: Ordinateur de bureau
   privacy_policy: Politique de confidentialité
   privacy_policy_url: https://osuny.org/politique-de-confidentialite
   quit: Quitter
diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb
index a7ee40e9a3fc2a42abc8208162969350f53f783a..2d1b47145ac7924c0139c2e919947dc99029de03 100644
--- a/config/routes/admin/communication.rb
+++ b/config/routes/admin/communication.rb
@@ -4,6 +4,7 @@ namespace :communication do
     member do
       get :import
       post :import
+      get :style
     end
     resources :pages, controller: 'websites/pages' do
       collection do
@@ -12,6 +13,7 @@ namespace :communication do
       member do
         get :children
         get :static
+        get :preview
       end
     end
     resources :categories, controller: 'websites/categories' do
@@ -28,6 +30,7 @@ namespace :communication do
       post :publish, on: :collection
       member do
         get :static
+        get :preview
       end
     end
     resources :curations,
diff --git a/config/routes/admin/education.rb b/config/routes/admin/education.rb
index b2ebafe49b92cf9ae3d3d31cc6fad48ca0630fb7..acac8d244692957fc6a9cf4d645c3ae66e928e55 100644
--- a/config/routes/admin/education.rb
+++ b/config/routes/admin/education.rb
@@ -30,6 +30,7 @@ namespace :education do
     end
     member do
       get :children
+      get :preview
     end
   end
   resources :academic_years