diff --git a/app/assets/stylesheets/admin/commons/blocks.sass b/app/assets/stylesheets/admin/commons/blocks.sass
index 462e9560fd62822a7cc407e1026476651520ed77..deaacc5e5d5a4542a0935ac673945c5d24930aba 100644
--- a/app/assets/stylesheets/admin/commons/blocks.sass
+++ b/app/assets/stylesheets/admin/commons/blocks.sass
@@ -1,7 +1,13 @@
 .blocks
     &__list
+        &__element
+            &:hover
+                .blocks__list__handle
+                    opacity: 1
         &__handle
+            opacity: 0
             width: 20px
+            transition: opacity 0.25s ease
         &__image
             width: 170px
             img
diff --git a/app/controllers/admin/communication/blocks/headings_controller.rb b/app/controllers/admin/communication/blocks/headings_controller.rb
index ee17fb8b353975272b200a3a8459e890ae73d9b5..5923bfb60b42fe92a8d1ee0addc22db427906ab8 100644
--- a/app/controllers/admin/communication/blocks/headings_controller.rb
+++ b/app/controllers/admin/communication/blocks/headings_controller.rb
@@ -3,24 +3,11 @@ class Admin::Communication::Blocks::HeadingsController < Admin::Communication::B
                               through: :current_university,
                               through_association: :communication_block_headings
 
-  def reorder
-    ids = params[:ids] || []
-    ids.each.with_index do |id, index|
-      @heading = current_university.communication_block_headings.find(id)
-      @heading.update position: index + 1
-    end
-    @heading.about.sync_with_git
-  end
-
   def new
     @heading.about = Polymorphic.find params, :about
     breadcrumb
   end
 
-  def show
-    breadcrumb
-  end
-
   def edit
     breadcrumb
   end
diff --git a/app/controllers/admin/communication/blocks_controller.rb b/app/controllers/admin/communication/blocks_controller.rb
index cc346f1ff2de7ed4527a3e36e9c56d7677d41bd0..511a159e2b81d0ba7a06c267122e0214db04d824 100644
--- a/app/controllers/admin/communication/blocks_controller.rb
+++ b/app/controllers/admin/communication/blocks_controller.rb
@@ -5,9 +5,23 @@ class Admin::Communication::BlocksController < Admin::Communication::Application
 
   def reorder
     ids = params[:ids] || []
-    ids.each.with_index do |id, index|
-      @block = current_university.communication_blocks.find(id)
-      @block.update position: index + 1
+    ids.each.with_index do |identifier, index|
+      parts = identifier.split('_')
+      kind = parts.first
+      id = parts.last
+      if kind == 'block'
+        @block = current_university.communication_blocks.find(id)
+        @block.heading = @heading
+        @block.position = index + 1
+        @block.save
+        @previous = nil
+      elsif kind == 'heading'
+        @heading = current_university.communication_block_headings.find(id)
+        @heading.position = index + 1
+        @heading.parent = @previous
+        @heading.save
+        @previous = @heading
+      end
     end
     @block.about.sync_with_git
   end
diff --git a/app/models/communication/block.rb b/app/models/communication/block.rb
index ed1cd6658bd8b56ea6754cdea1997025a078c4fe..04ab7f2dbc2c195e5c817cc70b57fc204c5de177 100644
--- a/app/models/communication/block.rb
+++ b/app/models/communication/block.rb
@@ -36,6 +36,7 @@ class Communication::Block < ApplicationRecord
   FILE_MAX_SIZE = 100.megabytes
 
   belongs_to :about, polymorphic: true
+  belongs_to :heading, optional: true
 
   # Used to purge images when unattaching them
   # template_blobs would be a better name, because there are files
@@ -70,6 +71,7 @@ class Communication::Block < ApplicationRecord
   }
 
   scope :published, -> { where(published: true) }
+  scope :with_no_heading, -> { where(heading: nil) }
 
   before_save :attach_template_blobs
 
diff --git a/app/models/communication/block/heading.rb b/app/models/communication/block/heading.rb
index b3ce66c1a7a7f61d3afab2d784afda6f0bc1879d..f8537a44cf004a572d7a074bbd3918b7a9bd2484 100644
--- a/app/models/communication/block/heading.rb
+++ b/app/models/communication/block/heading.rb
@@ -35,11 +35,23 @@ class Communication::Block::Heading < ApplicationRecord
   has_many    :children,
               class_name: 'Communication::Block::Heading',
               foreign_key: :parent_id
+  has_many    :blocks
+
+  DEFAULT_LEVEL = 2
   
-  scope :root, -> { where(level: 1) }
+  scope :root, -> { where(level: DEFAULT_LEVEL) }
   default_scope { order(:position) }
 
+  before_validation :compute_level
+
   def to_s
     "#{title}"
   end
+
+  protected
+
+  def compute_level
+    self.level = parent ? parent.level + 1
+                        : DEFAULT_LEVEL
+  end
 end
diff --git a/app/views/admin/application/a11y/_widget.html.erb b/app/views/admin/application/a11y/_widget.html.erb
index db26884e8fade959e33833d574f80b53d5ed1e35..b023bd180d17046d3398e3c191160293ef52fd0d 100644
--- a/app/views/admin/application/a11y/_widget.html.erb
+++ b/app/views/admin/application/a11y/_widget.html.erb
@@ -1,14 +1,17 @@
 <%
+horizontal ||= false
 color = about.accessible? ? 'text-success' : 'text-danger'
 action = "<i class=\"#{ Icon::A11Y } fa-2x float-end #{ color}\"></i>"
 %>
 <%= osuny_panel t('accessibility.label'), action: action do %>
+  <% if horizontal %>
+    <div class="row"><div class="offset-lg-4 col-lg-8">
+  <% end %>
   <% if about.accessibility_errors.any? %>
     <%= osuny_label t('accessibility.errors', count: about.accessibility_errors.count), classes: 'text-danger' %>
     <ol class="list-unstyled">
       <% about.accessibility_errors.each do |key| %>
         <li>
-          <hr>
           <%= osuny_label t("#{key}.title"), classes: 'text-danger' %>
           <p><%= t "#{key}.text_html" %></p>
         </li>
@@ -22,7 +25,6 @@ action = "<i class=\"#{ Icon::A11Y } fa-2x float-end #{ color}\"></i>"
     <ul class="list-unstyled">
       <% about.accessibility_warnings.each do |key| %>
       <li>
-        <hr>
         <%= osuny_label t("#{key}.title") %>
         <p>
           <%= t "#{key}.text_html" %>
@@ -31,4 +33,7 @@ action = "<i class=\"#{ Icon::A11Y } fa-2x float-end #{ color}\"></i>"
       <% end %>
     </ul>
   <% end %>
+  <% if horizontal %>
+    </div></div>
+  <% end %>
 <% end %>
\ No newline at end of file
diff --git a/app/views/admin/communication/blocks/_block.html.erb b/app/views/admin/communication/blocks/_block.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..bd15d7409b10c74aed01a15fbfbff65bc0b7f1d3
--- /dev/null
+++ b/app/views/admin/communication/blocks/_block.html.erb
@@ -0,0 +1,16 @@
+<div class="row" data-id="block_<%= block.id %>">
+  <div class="offset-lg-4 col-lg-8">
+    <article class="blocks__list__element mt-4 <%= 'draft' unless block.published? %>">
+      <div class="float-end">
+        <%= duplicate_link block %>
+        <%= edit_link block %>
+      </div>
+      <span class="small text-muted"><%= block.template_kind_i18n  %></span>
+      <span class="blocks__list__handle"><i class="<%= Icon::SORT %> handle"></i></span>
+      <div class="blocks__list__name">
+        <%= block.to_s.truncate(50) %><br>
+        <%= render 'admin/application/a11y/status', about: block unless block.accessible? %>
+      </div>
+    </article>
+  </div>
+</div>
\ No newline at end of file
diff --git a/app/views/admin/communication/blocks/_block_static.html.erb b/app/views/admin/communication/blocks/_block_static.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..e0deae9858fd0365d71898734579f44ec184f9b7
--- /dev/null
+++ b/app/views/admin/communication/blocks/_block_static.html.erb
@@ -0,0 +1,11 @@
+<%
+template_path = "admin/communication/blocks/templates/#{@block.template_kind}/static"
+should_render_data = @block.data && @block.data.present?
+%>
+  - kind: block
+    template: <%= @block.template_kind %>
+    position: <%= @block.position %>
+    data:
+<%= render  template_path, 
+            block: @block, 
+            about: @block.about if should_render_data %>
diff --git a/app/views/admin/communication/blocks/_list.html.erb b/app/views/admin/communication/blocks/_list.html.erb
index 78a27993151e2393ae91ab5e912e457c519022eb..8be64161d1bdc282bca9f993dc85ff7bb4ebaf07 100644
--- a/app/views/admin/communication/blocks/_list.html.erb
+++ b/app/views/admin/communication/blocks/_list.html.erb
@@ -1,56 +1,22 @@
-<%
-action = ''
-action += link_to t('admin.communication.blocks.add'),
-                  new_admin_communication_block_path(about_id: about.id, about_type: about.class.name),
-                  class: button_classes if can? :create, Communication::Block
-action += link_to t('admin.communication.blocks.headings.add'),
-                  new_admin_communication_heading_path(about_id: about.id, about_type: about.class.name),
-                  class: button_classes('ms-2') if can? :create, Communication::Block::Heading
-%>
-<%= osuny_panel Communication::Block.model_name.human(count: 2), action: action do %>
-  <% if about.headings.any? %>
+<%= osuny_panel Communication::Block.model_name.human(count: 2) do %>
+  <div class="blocks" data-sortable data-sort-url="<%= reorder_admin_communication_blocks_path %>">
+    <% about.blocks.with_no_heading.ordered.each do |block| %>
+      <%= render 'admin/communication/blocks/block', block: block %>
+    <% end %>
     <% about.headings.root.each do |heading| %>
-      <%= link_to heading, edit_admin_communication_heading_path(heading) %>
+      <%= render 'admin/communication/blocks/headings/heading', heading: heading %>
     <% end %>
-  <% end %>
-  <% if about.blocks.any? %>
-    <div class="table-responsive">
-      <table class="<%= table_classes %>">
-        <thead>
-          <tr>
-            <th></th>
-            <th><%= Communication::Block.human_attribute_name :title %></th>
-            <th><%= Communication::Block.human_attribute_name :template %></th>
-            <th></th>
-          </tr>
-        </thead>
-        <tbody data-sortable data-sort-url="<%= reorder_admin_communication_blocks_path %>">
-          <% about.blocks.ordered.each do |block| %>
-            <tr data-id="<%= block.id %>" class="<%= 'draft' unless block.published? %>">
-              <% if can? :reorder, Communication::Block %>
-                <td class="ps-0 blocks__list__handle"><i class="<%= Icon::DRAG %> handle"></i></td>
-              <% end %>
-              <td class="blocks__list__name">
-                <%= block.to_s.truncate(50) %><br>
-                <span class="small"><%= block.template_kind_i18n  %></span>
-                <%= render 'admin/application/a11y/status', about: block %>
-              </td>
-              <td class="blocks__list__image">
-                <%= image_tag "communication/blocks/templates/#{block.template_kind}.jpg", alt: '' %>
-              </td>
-              <td class="blocks__list__buttons">
-                <div class="btn-group">
-                  <%= duplicate_link block %>
-                  <%= edit_link block %>
-                </div>
-              </td>
-            </tr>
-          <% end %>
-        </tbody>
-      </table>
-      <% if about.blocks.count > 9 %>
-        <%= raw action %>
-      <% end %>
+  </div>
+  <div class="row mt-5">
+    <div class="col-lg-4">
+      <%= link_to t('admin.communication.blocks.headings.add'),
+                  new_admin_communication_heading_path(about_id: about.id, about_type: about.class.name),
+                  class: 'p-5 d-block bg-light text-center h4' if can? :create, Communication::Block::Heading%>
+    </div>
+    <div class="col-lg-8">
+      <%= link_to t('admin.communication.blocks.add'),
+                  new_admin_communication_block_path(about_id: about.id, about_type: about.class.name),
+                  class: 'p-5 d-block bg-light text-center h4' if can? :create, Communication::Block%>
     </div>
-  <% end %>
+  </div>
 <% end %>
diff --git a/app/views/admin/communication/blocks/_static.html.erb b/app/views/admin/communication/blocks/_static.html.erb
index 73a53873c086579463f866a439cd3bfb47a5e67e..9280c0fb6d1739700c356acc60a0bdaca7bec3fa 100644
--- a/app/views/admin/communication/blocks/_static.html.erb
+++ b/app/views/admin/communication/blocks/_static.html.erb
@@ -1,3 +1,13 @@
+<%
+@university = about.university
+%>
+content:
+<% about.blocks.with_no_heading.published.ordered.each do |block| @block = block %>
+<%= render 'admin/communication/blocks/block_static' %>
+<% end %>
+<% about.headings.root.each do |heading| @heading = heading %>
+<%= render 'admin/communication/blocks/headings/heading_static' %>
+<% end %>
 <% if about.blocks.any? %>
 blocks:
 <% about.blocks.published.ordered.each do |block|
diff --git a/app/views/admin/communication/blocks/edit.html.erb b/app/views/admin/communication/blocks/edit.html.erb
index ef3bdd551b48abed3a1b9777a873eb1824610619..6af97a74bc0779b11093dbfa23f2bcd1feefda4a 100644
--- a/app/views/admin/communication/blocks/edit.html.erb
+++ b/app/views/admin/communication/blocks/edit.html.erb
@@ -13,9 +13,11 @@
     <div class="row">
       <div class="col-xxl-9 col-lg-8">
         <div class="row pure__row--small">
-          <div class="col-lg-6">
-            <%= f.input :title %>
-          </div>
+          <% if @block.title.present? %>
+            <div class="col-lg-6">
+              <%= f.input :title %>
+            </div>
+          <% end %>
           <div class="col-lg-6">
             <label class="form-label d-none d-lg-block">&nbsp;</label>
             <%= f.input :published %>
diff --git a/app/views/admin/communication/blocks/headings/_heading.html.erb b/app/views/admin/communication/blocks/headings/_heading.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..9fa692da97adcdf4e31853ef1748fc533fd27cb8
--- /dev/null
+++ b/app/views/admin/communication/blocks/headings/_heading.html.erb
@@ -0,0 +1,12 @@
+<div data-id="heading_<%= heading.id %>" class="blocks__list__element mt-5">
+  <div style="padding-left: <%= (heading.level - 1) * 48 %>px">
+    <%= link_to heading, edit_admin_communication_heading_path(heading), class: 'h4' %>
+    <span class="ps-0 blocks__list__handle"><i class="<%= Icon::SORT %> handle"></i></span>
+  </div>
+</div>
+<% heading.blocks.each do |block| %>
+  <%= render 'admin/communication/blocks/block', block: block %>
+<% end %>
+<% heading.children.each do |child| %>
+  <%= render 'admin/communication/blocks/headings/heading', heading: child %>
+<% end %>
diff --git a/app/views/admin/communication/blocks/headings/_heading_static.html.erb b/app/views/admin/communication/blocks/headings/_heading_static.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..676e103138c90e352c60022bb63522f17cf7356e
--- /dev/null
+++ b/app/views/admin/communication/blocks/headings/_heading_static.html.erb
@@ -0,0 +1,8 @@
+  - kind: heading
+    title: >-
+      <%= prepare_text_for_static @heading.title, 3 %>
+    position: <%= @heading.position %>
+    level: <%= @heading.level %>
+<% @heading.blocks.published.ordered.each do |block| @block = block %>
+<%= render 'admin/communication/blocks/block_static' %>
+<% end %>
diff --git a/app/views/admin/communication/websites/_sidebar.html.erb b/app/views/admin/communication/websites/_sidebar.html.erb
index e2205ef3eb35121a3d565933628ca3614643d482..690bb32c8142f6af02373add53952c48c0d4378e 100644
--- a/app/views/admin/communication/websites/_sidebar.html.erb
+++ b/app/views/admin/communication/websites/_sidebar.html.erb
@@ -1,5 +1,5 @@
 <div class="row mt-2 website__sidebar">
-  <div class="col-lg-3 col-xl-2">
+  <div class="col-lg-3">
     <ul class="list-unstyled" role="tablist">
       <%
       navigation = [
@@ -62,7 +62,7 @@
       </select>
     <% end %>
   </div>
-  <div class="col-lg-9 col-xl-10">
+  <div class="col-lg-9">
     <%= yield %>
   </div>
 
diff --git a/app/views/admin/communication/websites/pages/show.html.erb b/app/views/admin/communication/websites/pages/show.html.erb
index 4f5b7bb22130a619635ed068a61cf3fabf6d2f89..92226d32277ce4b2adde8112c13f09d00c8a6c88 100644
--- a/app/views/admin/communication/websites/pages/show.html.erb
+++ b/app/views/admin/communication/websites/pages/show.html.erb
@@ -1,25 +1,37 @@
 <% content_for :title, @page %>
 
 <%= render 'admin/communication/websites/sidebar' do %>
-
   <div class="row">
-    <div class="col-md-8">
-      <%= render 'admin/application/summary/show', about: @page %>
-      <%= render 'admin/communication/blocks/list', about: @page %>
-      <%= render 'admin/application/dependencies',
-                  git_dependencies: @page.git_dependencies(@page.website),
-                  active_storage_blobs: @page.active_storage_blobs %>
+    <div class="col-lg-7">
+      <%= osuny_panel Communication::Website::Page.human_attribute_name(:title) do %>
+        <p class="lead"><%= @page.title %></p>
+      <% end %>
     </div>
-    <div class="col-md-4">
-      <%= render 'admin/application/a11y/widget', about: @page %>
-      <%= render 'admin/application/i18n/widget', about: @page %>
-      <%= render 'admin/communication/websites/pages/show/metadata' %>
+    <div class="offset-lg-1 col-lg-4">
       <%= render 'admin/application/featured_image/show', about: @page %>
+    </div>
+  </div>
+  <hr class="mb-5">
+  <%= render 'admin/application/a11y/widget', about: @page, horizontal: true %>
+  <hr class="mb-5">
+  <div class="row">
+    <div class="col-lg-4">
+      <%= render 'admin/communication/websites/pages/show/metadata' %>
+      <%= render 'admin/application/i18n/widget', about: @page %>
+    </div>
+    <div class="col-lg-8">
+      <%= render 'admin/application/summary/show', about: @page %>
       <%= render 'admin/application/meta_description/show', about: @page %>
     </div>
   </div>
+  <hr class="mb-5">
+  <%= render 'admin/communication/blocks/list', about: @page %>
 <% end %>
 
+<%= render 'admin/application/dependencies',
+            git_dependencies: @page.git_dependencies(@page.website),
+            active_storage_blobs: @page.active_storage_blobs %>
+
 <% content_for :action_bar_left do %>
   <%= destroy_link @page if @page.is_regular_page? %>
   <%= static_link static_admin_communication_website_page_path(@page) %>
diff --git a/app/views/admin/layouts/themes/pure/_commands.html.erb b/app/views/admin/layouts/themes/pure/_commands.html.erb
index 452c75a6a56e34ec7ef7533aae57b5c9ae4a7941..395c2341113e2d39070222e35853dcc774af0cef 100644
--- a/app/views/admin/layouts/themes/pure/_commands.html.erb
+++ b/app/views/admin/layouts/themes/pure/_commands.html.erb
@@ -1,6 +1,6 @@
 <% if content_for?(:action_bar_left) or content_for?(:action_bar_right) %>
   <div class="commands">
-    <div class="container-fluid py-3 d-flex">
+    <div class="p-3 d-flex">
       <div>
         <%= yield :action_bar_left %>
       </div>
diff --git a/db/migrate/20230321213542_change_communication_block_heading_default_level.rb b/db/migrate/20230321213542_change_communication_block_heading_default_level.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4da9e75f41f46b3cad5140c076ab86680c534fae
--- /dev/null
+++ b/db/migrate/20230321213542_change_communication_block_heading_default_level.rb
@@ -0,0 +1,5 @@
+class ChangeCommunicationBlockHeadingDefaultLevel < ActiveRecord::Migration[7.0]
+  def change
+    change_column :communication_block_headings, :level, :integer, default: 2
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index aac33c6b2b613e876a6597aa1c2c552a14a1bf30..8343f3524ad015b1cf380847672ad7720c0aca1c 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: 2023_03_21_082433) do
+ActiveRecord::Schema[7.0].define(version: 2023_03_21_213542) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
   enable_extension "plpgsql"
@@ -83,7 +83,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_082433) do
     t.string "about_type", null: false
     t.uuid "about_id", null: false
     t.string "title"
-    t.integer "level", default: 1
+    t.integer "level", default: 2
     t.uuid "parent_id"
     t.integer "position"
     t.string "slug"