diff --git a/application/modules/opac/controllers/CmsController.php b/application/modules/opac/controllers/CmsController.php
index bb425109f291108065fef9a8911a2a0648b484f9..e743955ef5bd61e7eda00a8f4b94d2b868312141 100644
--- a/application/modules/opac/controllers/CmsController.php
+++ b/application/modules/opac/controllers/CmsController.php
@@ -57,6 +57,15 @@ class CmsController extends ZendAfi_Controller_Action {
     $preferences['id_bib']        = $this->_getParam('b');
     $preferences['events_only']   = true;
 
+    if ( ! Class_Template::current()->isLegacy()) {
+      $this->view->titre = $this->_('%s - %s',
+                                    $preferences [ 'titre' ],
+                                    Class_Date::humanDate(strtotime($this->_getParam('d')), 'MMMM yyyy'));
+      $this->view->articles = $this->_getArticlesByPreferences($preferences);
+      $this->renderScript('cms/articlesview.phtml');
+    }
+
+
     if(!isset($preferences['display_mode']))
        $preferences['display_mode']='Title';
 
@@ -290,7 +299,7 @@ class CmsController extends ZendAfi_Controller_Action {
   protected function _initCalendarAndPreferences() {
     $id_module = $this->_getParam('id_module');
 
-    if (false !== strpos($id_module, 'library'))
+    if (0 === strpos($id_module, 'library_'))
       return $this->_loadLibraryAgenda((int) filter_var($id_module, FILTER_SANITIZE_NUMBER_INT));
 
     $module = Class_Profil::getCurrentProfil()->getModuleAccueilPreferences($id_module, 'CALENDAR');
@@ -319,7 +328,8 @@ class CmsController extends ZendAfi_Controller_Action {
       ->setView($this->view);
 
     $this->view->preferences = $wrapper->getPreferences();
-    $this->view->calendar = $wrapper->getCalendar($this->_request->getParams());
+    $this->view->calendar = $wrapper->getCalendar($this->_request->getParams(),
+                                                  $this->_helper->selectedFilters());
   }
 
 
diff --git a/library/Class/Article.php b/library/Class/Article.php
index 81f34174073a83e03ff681a6addf7b51030a0168..2c1e4b3981cb484f8d446c4817ce4f2257123a46 100644
--- a/library/Class/Article.php
+++ b/library/Class/Article.php
@@ -313,6 +313,10 @@ class ArticleLoader extends Storm_Model_Loader {
       return $this;
     }
 
+    if (null === $this->_select) {
+      return $this;
+    }
+
     $this->_select->where('STATUS in (?)', $this->_status);
 
     return $this;
diff --git a/library/Class/Calendar.php b/library/Class/Calendar.php
index 37e460e15fcc8003e26af24b453b873c43b16a86..a48ebdefa674a7bcd62d7a75c9ea111c93939c3e 100644
--- a/library/Class/Calendar.php
+++ b/library/Class/Calendar.php
@@ -85,6 +85,7 @@ class Class_Calendar {
     $this->_initSelectIdCat();
 
     $this->place = $this->_getParam('place');
+
     $this->custom_fields = $custom_fields;
   }
 
@@ -152,6 +153,11 @@ class Class_Calendar {
 
 
   protected function _loadArticles($extra_prefs) {
+    $id_lieu = $this->getPlaceParam();
+
+    if ( (0 === strpos($this->id_module, 'library_')) && (!$id_lieu))
+      return [];
+
     $prefs = array_merge(['display_order' => (isset($this->preferences['display_order'])
                                               ? $this->preferences['display_order']
                                               : $this->preferences['order']),
@@ -159,7 +165,7 @@ class Class_Calendar {
                           'events_only' => true,
                           'event_date' => $this->date,
                           'id_bib' => $this->id_bib,
-                          'id_lieu' => $this->getPlaceParam(),
+                          'id_lieu' => $id_lieu,
                           'custom_fields' => $this->getCustomFields(),
                           'published' => $this->date >= strftime('%Y-%m', $this->getTimeSource()->time())],
                          $extra_prefs);
@@ -274,15 +280,29 @@ class Class_Calendar {
   }
 
 
-  public function getHumanDate() {
+  public function getArticlesInMonth() {
+    $articles = Class_Article::getArticlesByPreferences(['event_date'=> self::getTimeSource()->getMonth($this->month),
+                                                         'events_only' => true,
+                                                         'status' => 3]);
+    return array_slice($articles, 0, $this->_getSize());
+  }
+
+
+  public function getNextEvents() {
+    $articles = $this->_getNextEvents();
+    return array_slice($articles, 0, $this->_getSize());
+  }
+
+
+  public function getHumanDate($format_day = 'dd/MM/yyyy', $format_month = 'MM/yyyy') {
     if ($this->day)
-      return Class_Date::getHumanDate($this->day, 'dd/MM/yyyy');
+      return Class_Date::getHumanDate($this->day, $format_day);
 
     if ($day = $this->_getParam('day'))
-      return Class_Date::getHumanDate($day . '-01', 'MM/yyyy');
+      return Class_Date::getHumanDate($day . '-01', $format_month);
 
     if ($date = $this->_getParam('date'))
-      return Class_Date::getHumanDate($date . '-01', 'MM/yyyy');
+      return Class_Date::getHumanDate($date . '-01', $format_month);
 
     return '';
   }
@@ -369,4 +389,10 @@ class Class_Calendar {
       ? $this->params[$name]
       : $default;
   }
+
+
+  public function setDisplayFullPage($boolean) {
+    $this->preferences['display_full_page'] = $boolean;
+    return $this;
+  }
 }
\ No newline at end of file
diff --git a/library/Class/CompareUrl.php b/library/Class/CompareUrl.php
index 8e70947939ed667c11a25a895fe89bd7faee82b2..4df34560771d6a11353ffbc237f4b0895d6ed625 100644
--- a/library/Class/CompareUrl.php
+++ b/library/Class/CompareUrl.php
@@ -21,7 +21,12 @@
 
 
 class Class_CompareUrl {
-  protected static $_request;
+
+  protected static
+    $_request,
+    $_detector,
+    $_router;
+
 
   public static function isInRequestUrl($url) {
     if(!$url)
@@ -45,6 +50,77 @@ class Class_CompareUrl {
   }
 
 
+  public function sameAsRequest($url) {
+    if(!$url)
+      return false;
+
+    if(!is_string($url))
+      return false;
+
+    if (!$request_path = static::getRequestPath())
+      return false;
+
+    $request_path = Class_Url::absolute($request_path);
+
+    if ('/' == $request_path)
+      return false;
+
+    return $this->_checkByStrPos($request_path, $url)
+      ? true
+      : $this->_checkByProfil($url);
+  }
+
+
+  protected function _checkByStrPos($current_url, $url) {
+    $pos = strpos($url, $current_url);
+
+    if(null === $pos)
+      return false;
+
+    return false !== $pos;
+  }
+
+
+  protected function _checkByProfil($url) {
+    return $this->_extractProfileIdFormUrl($url) == Class_Profil::getCurrentProfil()->getId();
+  }
+
+
+  protected function _extractProfileIdFormUrl($url) {
+    $url = Class_Url::absolute($url);
+
+    if (false === strpos($url, BASE_URL))
+      return null;
+
+    if ( ! $url_request = new Zend_Controller_Request_Http($url))
+      return null;
+
+    $router = $this->_getRouter();
+    $router->route($url_request);
+
+    $detector = $this->_getDetector();
+
+    if ( ! $profil = $detector->detectFrom($url_request))
+      return null;
+
+    return $profil->getId();
+  }
+
+
+  protected function _getRouter() {
+    if (static::$_router)
+      return static::$_router;
+    return static::$_router = new  ZendAfi_Controller_Router_RewriteWithoutBaseUrl();
+  }
+
+
+  protected function _getDetector() {
+    if (static::$_detector)
+      return static::$_detector;
+    return static::$_detector = new ZendAfi_Controller_Plugin_DefineURLs_ProfileDetector();
+  }
+
+
   public static function getRequestPath() {
     return static::getRequest()->getPathInfo();
   }
diff --git a/library/Class/Profil/Promoter.php b/library/Class/Profil/Promoter.php
index 8497d1703c7cfc38913103a6a5f84b5d94804192..5a08e2945a0fd0869fe8002066aec3dbdf54633d 100644
--- a/library/Class/Profil/Promoter.php
+++ b/library/Class/Profil/Promoter.php
@@ -42,7 +42,13 @@ class Class_Profil_Promoter {
     $profile
       ->bePortail()
       ->setCommentaire($portal->getCommentaire());
+
+    $this->_upgradeWidgets($id, $profile);
+
+    $this->_upgradeMenus($id, $profile);
+
     $this->_removeSavePrefix($profile);
+
     $profile->save();
 
     array_map(function($page)
@@ -52,12 +58,54 @@ class Class_Profil_Promoter {
               $profile_pages);
 
     Class_Profil::clearCache();
+
     Class_Profil::find($id)->delete();
 
     return $this;
   }
 
 
+  protected function _upgradeWidgets($old_id, $profile) {
+    $home = $profile->getCfgAccueilAsArray();
+
+    $new_home_cfg = [];
+
+    foreach ($home['modules'] as $widget_id => $cfg)
+      $new_home_cfg = $this->_upgradeCfg($new_home_cfg, $widget_id, $cfg, $old_id);
+
+    $home ['modules'] = $new_home_cfg;
+
+    $profile->setCfgAccueil($home);
+  }
+
+
+  protected function _upgradeMenus($old_id, $profile) {
+    $menus = $profile->getCfgMenusAsArray();
+
+    $new_menus_cfg = [];
+    foreach ($menus as $menu_id => $cfg)
+      $new_menus_cfg = $this->_upgradeCfg($new_menus_cfg, $menu_id, $cfg, $old_id);
+
+    $profile->setCfgMenus($new_menus_cfg);
+  }
+
+
+  protected function _upgradeCfg($cfg_collection, $id, $cfg, $old_id) {
+    $new_cfg = $cfg;
+
+    foreach($cfg as $key => $value) {
+      if ( is_array($value))
+        $new_cfg = $this->_upgradeCfg($new_cfg, $key, $value, $old_id);
+
+      if ( ( 'menu' === $key ) || ( 'use_profil' === $key ) )
+        $new_cfg [$key] = str_replace($old_id, Class_Profil::DEFAULT_PROFIL, $value);
+    }
+
+    $cfg_collection [$id] = $new_cfg;
+    return $cfg_collection;
+  }
+
+
   protected function _backup($portal) {
     $backup = $portal->deepCopy();
     $backup->setLibelle($portal->getLibelle());
diff --git a/library/Class/Template.php b/library/Class/Template.php
index 5145f6b53a6860a98d6c36fef8b681c8f94bd4ac..e577bbdd40ef6bb10e2b53e5aa4c21b766d20200 100644
--- a/library/Class/Template.php
+++ b/library/Class/Template.php
@@ -360,6 +360,31 @@ class Class_Template {
   }
 
 
+  public function getLivingWidgets() {
+    $sections = [new Class_Systeme_Widget_Section_Header,
+                 new Class_Systeme_Widget_Section_FirstSide,
+                 new Class_Systeme_Widget_Section_Main,
+                 new Class_Systeme_Widget_Section_SecondSide,
+                 new Class_Systeme_Widget_Section_Footer,
+                 new Class_Systeme_Widget_Section_FloatSide];
+
+    array_map(function($section)
+              {
+                $section
+                  ->setProfileId($this->getProfile()->getId())
+                  ->load();
+              },
+              $sections);
+
+    $widgets = [];
+
+    foreach ($sections as $section)
+      $widgets [$section->getTitle()] = $section->getWidgets();
+
+    return $widgets;
+  }
+
+
   public function getSettings() {
     return $this->_settings
       ? $this->_settings
diff --git a/library/ZendAfi/View/Helper/Accueil/Base.php b/library/ZendAfi/View/Helper/Accueil/Base.php
index b3a9d032f572d3927a94298e9c4fa92e1bb678f2..7fe67ba46a1925bc503e890521661d143dfd26c2 100644
--- a/library/ZendAfi/View/Helper/Accueil/Base.php
+++ b/library/ZendAfi/View/Helper/Accueil/Base.php
@@ -552,4 +552,18 @@ class ZendAfi_View_Helper_Accueil_Base extends ZendAfi_View_Helper_ModuleAbstrac
 
 
   public function getHtml() {}
+
+
+  public function visibleWhenHidden() {
+    if ( ! $hidden_id = $this->_settings->getVisibleWhenHidden())
+      return false;
+
+    Class_ScriptLoader::getInstance()
+      ->addOPACScript('visible_when_hidden')
+      ->addJQueryReady(sprintf('$("#boite_%s").visible_when_hidden("#boite_%s")',
+                               $this->id_module,
+                               $hidden_id));
+
+    return true;
+  }
 }
diff --git a/library/ZendAfi/View/Helper/Calendar/Table.php b/library/ZendAfi/View/Helper/Calendar/Table.php
index cb7833917dee3a8593861b5359df94559b6454e5..3a9d9ae7ed64b5d3f8c0cdf369fee1216e355e2a 100644
--- a/library/ZendAfi/View/Helper/Calendar/Table.php
+++ b/library/ZendAfi/View/Helper/Calendar/Table.php
@@ -216,32 +216,36 @@ class ZendAfi_View_Helper_Calendar_Table extends ZendAfi_View_Helper_BaseHelper
                                 array_filter(['calendar_title_month_clickable',
                                               $this->_getAjaxClass()]));
 
-    $next = $this->view->tagAnchor($this->getUrl('NEXT_MONTH'),
-                                   ' »',
-                                   array_merge($attribs,
-                                               ['title' => $this->_('Mois suivant')]));
-
-    $previous = $this->view->tagAnchor($this->getUrl('LAST_MONTH'),
-                                       '« ',
-                                       array_merge($attribs,
-                                               ['title' => $this->_('Mois précédent')]));
-
-    $current = $this->view->tagAnchor($this->getUrl('MONTH'),
-                                      $this->MONTHS[$this->month-1] .
-                                      strftime(' %Y', mktime(5,0,0, $this->month, 1, $this->year)),
-                                      array_merge($attribs,
-                                                  ['title' => $this->_('Mois courant')]));
-
-
-    return $this->_tag('tr',
+       return $this->_tag('tr',
                        $this->_tag('td', '', ['class' => 'calendar_title_left_arrow'])
-                       . $this->_tag('td', $previous . $current . $next,
+                       . $this->_tag('td', $this->_getMonthLinks($attribs),
                                      ['class' => 'calendar_title_month'])
                        .  $this->_tag('td', '', ['class' => 'calendar_title_right_arrow']),
                        ['class' => 'calendar_title']);
   }
 
 
+  protected function _getMonthLinks($attribs) {
+    $html = [$this->view->tagAnchor($this->getUrl('LAST_MONTH'),
+                                    '« ',
+                                    array_merge($attribs,
+                                                ['title' => $this->_('Mois précédent')])),
+
+             $this->view->tagAnchor($this->getUrl('MONTH'),
+                                    $this->MONTHS[$this->month-1] .
+                                    strftime(' %Y', mktime(5,0,0, $this->month, 1, $this->year)),
+                                    array_merge($attribs,
+                                                ['title' => $this->_('Mois courant')])),
+
+             $this->view->tagAnchor($this->getUrl('NEXT_MONTH'),
+                                    ' »',
+                                    array_merge($attribs,
+                                                ['title' => $this->_('Mois suivant')]))];
+
+    return implode($html);
+  }
+
+
   protected function _getAjaxClass() {
     return (1 == $this->calendar->getDisplayFullPage()) ? '' : ' calendar_ajax_ready';
   }
@@ -325,13 +329,13 @@ class ZendAfi_View_Helper_Calendar_Table extends ZendAfi_View_Helper_BaseHelper
 
 
   protected function _renderCellContent($time, $events) {
-    $day = date('j', $time);
+    $day = $this->_todayCellContent($time);
     $month = date('n', $time);
 
     $classes = array_merge($this->_getCellBasicClasses($time),
                            $this->_getCellEventsClasses($time, $events));
 
-    if (!in_array('day_clickable', $classes))
+    if ($this->_hasNoEvent($classes))
       return $this->_tag('span', $day,
                          ['class' => implode(' ', $classes)]);
 
@@ -347,6 +351,16 @@ class ZendAfi_View_Helper_Calendar_Table extends ZendAfi_View_Helper_BaseHelper
   }
 
 
+  protected function _hasNoEvent($classes) {
+    return !in_array('day_clickable', $classes);
+  }
+
+
+  protected function _todayCellContent($time) {
+    return date('j', $time);
+  }
+
+
   protected function _isTimestampToday($time) {
     return date('dmY', $time) == $this->today;
   }
diff --git a/library/ZendAfi/View/Helper/Filters/Element.php b/library/ZendAfi/View/Helper/Filters/Element.php
index 49f8b1d3893a836e73560a414bab94205cc4b25c..fe9047a62a9e987e7535e5474773cf578c27f326 100644
--- a/library/ZendAfi/View/Helper/Filters/Element.php
+++ b/library/ZendAfi/View/Helper/Filters/Element.php
@@ -138,6 +138,11 @@ abstract class ZendAfi_View_Helper_Filters_Element extends ZendAfi_View_Helper_B
   }
 
 
+  public function isReset() {
+    return false;
+  }
+
+
   public function isActive() {
     return isset($this->_active_filters[$this->_custom_field_id]);
   }
diff --git a/library/ZendAfi/View/Helper/Filters/Element/Reset.php b/library/ZendAfi/View/Helper/Filters/Element/Reset.php
new file mode 100644
index 0000000000000000000000000000000000000000..338e04f7994dc70a40564cb362d21d6f6d438368
--- /dev/null
+++ b/library/ZendAfi/View/Helper/Filters/Element/Reset.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_View_Helper_Filters_Element_Reset extends ZendAfi_View_Helper_Filters_Element {
+  public function __construct($custom_field_id = null) {
+    $this->_custom_field_id = 'reset';
+  }
+
+
+  public function isReset() {
+    return true;
+  }
+
+
+  public function elements() {
+  }
+
+
+  public function getUrlParams() {
+    return array_intersect_key(parent::getUrlParams(),
+                               ['controller' => true,
+                                'action' => true,
+                                'id_module' => true]);
+  }
+}
diff --git a/library/ZendAfi/View/Helper/Filters/Strategy/Abstract.php b/library/ZendAfi/View/Helper/Filters/Strategy/Abstract.php
index 28c6a009830440b7409be933e1c813b2989da5b0..bbd4ee5254a3572642248237a4a06ed4cc27ed84 100644
--- a/library/ZendAfi/View/Helper/Filters/Strategy/Abstract.php
+++ b/library/ZendAfi/View/Helper/Filters/Strategy/Abstract.php
@@ -34,6 +34,7 @@ abstract class ZendAfi_View_Helper_Filters_Strategy_Abstract extends ZendAfi_Vie
   public static function newFor($filter_elements) {
     $name = 'Facet';
     foreach(['Checkbox' => 'isCheckBox',
+             'Reset' => 'isReset',
              'Search'   => 'isSearch',
              'Calendar' => 'isCalendar'] as $k => $v) {
       if ($filter_elements->$v()) {
diff --git a/library/ZendAfi/View/Helper/Filters/Strategy/Reset.php b/library/ZendAfi/View/Helper/Filters/Strategy/Reset.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad322689057aa54e3dcc43636a748e2daa428fe9
--- /dev/null
+++ b/library/ZendAfi/View/Helper/Filters/Strategy/Reset.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_View_Helper_Filters_Strategy_Reset
+  extends ZendAfi_View_Helper_Filters_Strategy_Abstract {
+
+  protected function _renderContent() {
+    return '';
+  }
+
+
+  protected function _renderTitle() {
+    return $this->view->tagAction(new Intonation_Library_Link(['Text' => $this->_('Réinitialiser'),
+                                                               'Image' => (Class_Template::current()
+                                                                           ->getIco($this->view,
+                                                                                    'delete',
+                                                                                    'utils')),
+                                                               'Class' => 'filter_reset_button',
+                                                               'Url' => $this->view->url($this->_getUrlParams(), null, true),
+                                                               'Title' => $this->_('Réinitialiser les filtres')]));
+  }
+}
diff --git a/library/ZendAfi/View/Helper/FonctionsAdmin.php b/library/ZendAfi/View/Helper/FonctionsAdmin.php
index 0ade00e4b78471fb6df8026f7a7415593b93e981..715794c695272640849f8a1ecb8ab1ef03712853 100644
--- a/library/ZendAfi/View/Helper/FonctionsAdmin.php
+++ b/library/ZendAfi/View/Helper/FonctionsAdmin.php
@@ -46,9 +46,7 @@ class ZendAfi_View_Helper_FonctionsAdmin extends ZendAfi_View_Helper_BaseHelper
         ->setProfileId($this->id_profil)
         ->load();
 
-    $this->_title = $this->_widget
-      ? $this->_widget->getTitle()
-      : '';
+    $this->_title = $this->_getTitle();
 
     $actions = [$this->_extended($extended_actions)];
 
@@ -73,6 +71,13 @@ class ZendAfi_View_Helper_FonctionsAdmin extends ZendAfi_View_Helper_BaseHelper
   }
 
 
+  protected function _getTitle() {
+    return $this->_widget
+      ? $this->_widget->getTitle()
+      : '';
+  }
+
+
   protected function _extended($actions) {
     if (!$actions)
       return '';
diff --git a/library/ZendAfi/View/Helper/Template/Base.php b/library/ZendAfi/View/Helper/Template/Base.php
index 19c019e87cb782267ffb115fad8b652f1dd7eabe..1bf2c536af13a49f533335c1a9bb46fac3289cbc 100644
--- a/library/ZendAfi/View/Helper/Template/Base.php
+++ b/library/ZendAfi/View/Helper/Template/Base.php
@@ -52,12 +52,15 @@ class ZendAfi_View_Helper_Template_Base extends ZendAfi_View_Helper_BaseHelper {
       if($this->_widget->showFooter())
         $html [] = $this->_tag('div', $this->_getFooter(), ['class' => $this->_widget->footerClasses()]);
 
+      $d_none = $this->_visibleWhenHidden() ? ' d-none' : '';
+
       return $this->_tag('div',
                          implode($html) . $this->_getAdminTools(),
                          ['id' => 'boite_' . $this->_widget->getIdForHtml(),
-                          'class' => sprintf('boite %s %s',
+                          'class' => sprintf('boite %s %s%s',
                                              $this->_getClasses(),
-                                             $this->_widget->wrapperClasses())]);
+                                             $this->_widget->wrapperClasses(),
+                                             $d_none)]);
     };
 
     return $this->_render($closure);
@@ -95,6 +98,11 @@ class ZendAfi_View_Helper_Template_Base extends ZendAfi_View_Helper_BaseHelper {
   }
 
 
+  protected function _visibleWhenHidden() {
+    return $this->_view_helper->visibleWhenHidden();
+  }
+
+
   protected function _getClasses() {
     return $this->_view_helper->getClass();
   }
diff --git a/library/templates/Intonation/Assets/css/intonation.css b/library/templates/Intonation/Assets/css/intonation.css
index 969dfa2e6a3646d2cb12593a2837af520498f343..33f068f6efd6b30b1dc065a6936a9f96b72f1b1d 100644
--- a/library/templates/Intonation/Assets/css/intonation.css
+++ b/library/templates/Intonation/Assets/css/intonation.css
@@ -22,9 +22,6 @@
     --front-card-footer-background: linear-gradient(rgba(255, 255, 255, 0), white);
 }
 
-html {
-    scroll-behavior: smooth;
-}
 
 body {
     color: var(--front-text);
diff --git a/library/templates/Intonation/Library/FormCustomizer/Abstract.php b/library/templates/Intonation/Library/FormCustomizer/Abstract.php
index a842eaee21b25e31d2fa0077674c86cbd03ba03f..273151697512af085c812e32e6ab797e7007a2d7 100644
--- a/library/templates/Intonation/Library/FormCustomizer/Abstract.php
+++ b/library/templates/Intonation/Library/FormCustomizer/Abstract.php
@@ -260,6 +260,12 @@ class Intonation_Library_FormCustomizer_Abstract {
                                        Intonation_Library_Constants::RESPONSIVE_MODE_LARGE => $this->_('grande ( entre 991px et 1199px ) '),
                                        Intonation_Library_Constants::RESPONSIVE_MODE_XLARGE => $this->_('très grande ( supérieur à 1200px )')]])
 
+      ->addElement('select',
+                   $this->_template->withNameSpace('visible_when_hidden'),
+                   ['label' => $this->_('Visible lorsque la boite sélectionnée n\'est plus à l\'écran'),
+                    'value' => '',
+                    'multiOptions' => $this->_getLivingWidgetsTable()])
+
       ->addElement('checkbox',
                    $this->_template->withNameSpace('visibility_index'),
                    ['label' => $this->_('Index'),
@@ -290,7 +296,12 @@ class Intonation_Library_FormCustomizer_Abstract {
                    ['label' => $this->_('Authentification'),
                     'value' => 1]);
 
-    $elements_list = array_merge([$this->_template->withNameSpace('hidden_mode')],
+    $this->_form
+      ->getElement($this->_template->withNameSpace('visible_when_hidden'))
+      ->setRegisterInArrayValidator(false);
+
+    $elements_list = array_merge([$this->_template->withNameSpace('hidden_mode'),
+                                  $this->_template->withNameSpace('visible_when_hidden')],
                                  array_map(function($element)
                                            {
                                              return $this->_template->withNameSpace('visibility_' . $element);
@@ -310,6 +321,23 @@ class Intonation_Library_FormCustomizer_Abstract {
   }
 
 
+  protected function _getLivingWidgetsTable() {
+    $widgets_groups = Class_Template::current()->getLivingWidgets();
+
+    $options_for_select = [0 => ''];
+    foreach ( $widgets_groups as $group => $widgets) {
+      foreach ( $widgets as $widget) {
+        if (!isset($options_for_select [$group]))
+          $options_for_select [$group] = [];
+
+        $options_for_select [$group] = $options_for_select [$group] + [$widget->getId() => $widget->getLabel()];
+      }
+    }
+
+    return $options_for_select;
+  }
+
+
   protected function _getWidthsOptions() {
     return ['' => $this->_('auto'),
             '1' => 1,
diff --git a/library/templates/Intonation/Library/Settings.php b/library/templates/Intonation/Library/Settings.php
index 0d61c18d5af0e3d9c8c0e31c4c54774a47049d05..fb460674acb69d5f752fb07c124d97d551b91e56 100644
--- a/library/templates/Intonation/Library/Settings.php
+++ b/library/templates/Intonation/Library/Settings.php
@@ -137,6 +137,10 @@ class Intonation_Library_Settings extends Intonation_System_Abstract {
                                                   'a class active' => '',
                                                   'a class card-link' => '',
                                                   'a class list-group-item' => '',
+                                                  'a class calendar_day_event_start' => 'border-bottom border-info',
+                                                  'span class calendar_day_event_start' => 'border-bottom border-info',
+                                                  'a class day_clickable' => 'text-success font-weight-bold',
+                                                  'a class filter_reset_button' => 'btn btn-warning',
                                                   'ul' => 'list-unstyled',
                                                   'div class navbar-header' => 'justify-content-between',
                                                   'div class navbar-collapse' => 'justify-content-center',
@@ -152,6 +156,7 @@ class Intonation_Library_Settings extends Intonation_System_Abstract {
                                                   'span class search_axe_input' => 'col-12 col-sm-7',
                                                   'p class opened' => 'text-white bg-success p-1 rounded d-inline-block',
                                                   'p class closed' => 'text-white bg-danger p-1 rounded d-inline-block',
+                                                  'p class empty_list_message' => 'text-warning',
                                                   'div class search_dropdown_menu' => 'dropdown-menu-right',
 
                                                   'ul class result_tools_nav' => 'list-unstyled row no-gutters',
diff --git a/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Agenda.php b/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Agenda.php
index 3f4ed8d3dd7186fbc8e963f498773f4a0a0f5749..7e963e99e2fb7a6319f907705b39920f4d2c7047 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Agenda.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Agenda.php
@@ -36,12 +36,12 @@ class Intonation_Library_View_Wrapper_Library_RichContent_Agenda extends Intonat
   }
 
 
-  public function getCalendar($params = []) {
-    $calendar = new Class_Calendar('library_' . $this->_model->getId(),
-                                   $this->getPreferences(),
-                                   array_merge($params,
-                                               ['place' => $this->_model->getIdLieu()]));
-    return $calendar;
+  public function getCalendar($params = [], $filters = []) {
+    return new Class_Calendar('library_' . $this->_model->getId(),
+                              $this->getPreferences(),
+                              array_merge($params,
+                                          ['place' => $this->_model->getIdLieu()]),
+                              $filters);
   }
 
 
diff --git a/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Navigation.php b/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Navigation.php
index 12072e95cf2ad1f504efbb5014e52a403021267a..1567671854c19b42e0be3072caccfa675fc391f3 100644
--- a/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Navigation.php
+++ b/library/templates/Intonation/Library/View/Wrapper/Library/RichContent/Navigation.php
@@ -54,7 +54,7 @@ class Intonation_Library_View_Wrapper_Library_RichContent_Navigation {
                                                                             'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB]);
                                 });
 
-    while ((current($this->_list)->getId()) != $this->_model->getId())
+    while ( (false !== (current($this->_list))) && ((current($this->_list)->getId()) != $this->_model->getId()))
       next($this->_list);
 
     return $this->_list;
diff --git a/library/templates/Intonation/Library/Widget/Carousel/Agenda/Definition.php b/library/templates/Intonation/Library/Widget/Carousel/Agenda/Definition.php
index 725bca92659abab987e8d4e7c65c7c4c8b57d609..5fcff9df3f0b0a2e1c5e60b326400605392b21be 100644
--- a/library/templates/Intonation/Library/Widget/Carousel/Agenda/Definition.php
+++ b/library/templates/Intonation/Library/Widget/Carousel/Agenda/Definition.php
@@ -25,6 +25,8 @@ class Intonation_Library_Widget_Carousel_Agenda_Definition extends Intonation_Li
   const
     CODE = 'CALENDAR',
 
+    CALENDAR = 'calendar',
+
     SORT_PUBLICATION_DESC = 'DebutPublicationDesc',
     SORT_EVENT = 'EventDebut';
 
diff --git a/library/templates/Intonation/Library/Widget/Carousel/Agenda/Form.php b/library/templates/Intonation/Library/Widget/Carousel/Agenda/Form.php
index 1cba634972076386ae0c0aab8838864629cb48dc..a380150e90c994f49100d77461e690e37bdde1a4 100644
--- a/library/templates/Intonation/Library/Widget/Carousel/Agenda/Form.php
+++ b/library/templates/Intonation/Library/Widget/Carousel/Agenda/Form.php
@@ -25,6 +25,9 @@ class Intonation_Library_Widget_Carousel_Agenda_Form extends Intonation_Library_
   public function init() {
     parent::init();
 
+    Class_ScriptLoader::getInstance()
+      ->addJQueryReady('formSelectToggleVisibilityForElement("#layout", $("#rendering, #order, #enabled_filters, #size").closest("tr"), ["' . Intonation_Library_Widget_Carousel_Definition::CAROUSEL . '", "' . Intonation_Library_Widget_Carousel_Definition::MULTIPLE_CAROUSEL . '", "' . Intonation_Library_Widget_Carousel_Definition::HORIZONTAL_LISTING . '", "' . Intonation_Library_Widget_Carousel_Definition::LISTING . '", "' . Intonation_Library_Widget_Carousel_Definition::LISTING_WITH_OPTIONS . '", "' . Intonation_Library_Widget_Carousel_Definition::WALL . '"]);');
+
     $this
       ->addElement('treeSelect',
                    'articles_selector')
@@ -59,4 +62,11 @@ class Intonation_Library_Widget_Carousel_Agenda_Form extends Intonation_Library_
     return [Intonation_Library_Widget_Carousel_Agenda_Definition::SORT_EVENT => $this->_('Date de début d\'événement'),
             Intonation_Library_Widget_Carousel_Agenda_Definition::SORT_PUBLICATION_DESC => $this->_('Date de publication')];
   }
+
+
+  public function getLayouts() {
+    return
+      [Intonation_Library_Widget_Carousel_Agenda_Definition::CALENDAR => $this->_('Calendrier')]
+      + parent::getLayouts();
+  }
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/Library/Widget/Carousel/Agenda/View.php b/library/templates/Intonation/Library/Widget/Carousel/Agenda/View.php
index 679abd71f77d1b12bc26de0189ed7e26e175e1a1..dc802adcaf9a4a7e7b11ebb9e77219bbbc19acd5 100644
--- a/library/templates/Intonation/Library/Widget/Carousel/Agenda/View.php
+++ b/library/templates/Intonation/Library/Widget/Carousel/Agenda/View.php
@@ -34,7 +34,8 @@ class Intonation_Library_Widget_Carousel_Agenda_View extends Intonation_Library_
 
 
   protected function _findElements() {
-    return $this->_calendar->getArticles();
+    $this->_initCalendar();
+    return $this->_calendar->getArticlesInMonth();
   }
 
 
@@ -79,15 +80,46 @@ class Intonation_Library_Widget_Carousel_Agenda_View extends Intonation_Library_
   }
 
 
+  protected function _emptyListMessage() {
+    $this->_initCalendar();
+    $date = $this->_calendar->getHumanDate('MMMM yyyy', 'MMMM yyyy');
+    $next_events = $this->_calendar->getNextEvents();
+
+    if ( ( ! $date) && empty($next_events))
+      return $this->_tag('p', $this->_('Aucun événement'), ['class' => 'empty_list_message']);
+
+    if ( empty($next_events))
+      return $this->_tag('p',
+                         $this->_('Aucun événement en %s ni les mois suivant.',
+                                  $date),
+                         ['class' => 'empty_list_message']);
+
+    $message = $date
+      ? $this->_('Aucun événement en %s. ',
+                 $date)
+      : '';
+
+    $first_event = $next_events[0];
+
+    $message .= $this->_('Prochains événements en %s',
+                        Class_Date::humanDate(strtotime($first_event->getEventsDebut()),'MMMM yyyy'));
+
+    $next_events = $this->_renderElements($next_events);
+
+    $html = [$this->_div(['class' => 'col-12'],
+                         $this->_tag('p', $message, ['class' => 'empty_list_message'])),
+
+             $this->_div(['class' => 'col-12'],
+                         $next_events)];
+
+    return $this->view->grid(implode($html));
+  }
+
+
   public function getLinkToAllContent() {
     $this->view->titre = $this->_settings->getTitre();
     $this->_initCalendar();
     $this->_calendar->setSize(100);
     return $this->view->calendarLinkToAll($this->_calendar, $this->_settings);
   }
-
-
-  protected function _emptyListMessage() {
-    return $this->view->tag('p', $this->_('Aucun événement'));
-  }
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/Library/Widget/Carousel/View.php b/library/templates/Intonation/Library/Widget/Carousel/View.php
index bb82c26dc6eee618afa48fd051e18cbb5fc27d6f..60670ec72e02ac2c188d1e62983e0b8da3b30793 100644
--- a/library/templates/Intonation/Library/Widget/Carousel/View.php
+++ b/library/templates/Intonation/Library/Widget/Carousel/View.php
@@ -150,9 +150,13 @@ abstract class Intonation_Library_Widget_Carousel_View extends Zendafi_View_Help
 
 
   protected function _getHTML() {
-    if (!$elements = $this->_findElements())
-      return $this->_emptyListMessage();
+    return ($elements = $this->_findElements())
+      ? $this->_renderElements($elements)
+      : $this->_emptyListMessage();
+  }
+
 
+  protected function _renderElements($elements) {
     $content_callback = $this->_getContentCallback($this->_settings->getRendering());
 
     $elements = array_slice($elements, 0, $this->_settings->getSize());
diff --git a/library/templates/Intonation/Library/Widget/Nav/View.php b/library/templates/Intonation/Library/Widget/Nav/View.php
index b30fda991f6ee567b60200d726078f767fc0b252..7ed2ab33e3edba6adc9b8137a99665f6f4240773 100644
--- a/library/templates/Intonation/Library/Widget/Nav/View.php
+++ b/library/templates/Intonation/Library/Widget/Nav/View.php
@@ -161,7 +161,7 @@ class Intonation_Library_Widget_Nav_View extends Zendafi_View_Helper_Accueil_Bas
   protected function _getActiveClass($entry) {
    $classes = [];
 
-   if (Class_CompareUrl::isInRequestUrl($entry->getLink()))
+   if ((new Class_CompareUrl)->sameAsRequest($entry->getLink()))
      $classes [] = 'active_item';
 
    return implode(' ', $classes);
diff --git a/library/templates/Intonation/View/Calendar/Table.php b/library/templates/Intonation/View/Calendar/Table.php
index 63316ce4d04ee75d445ebe407895f57eba4fa67f..5d226de455d3c56ae3bdc06fa3ce3817fdbf103a 100644
--- a/library/templates/Intonation/View/Calendar/Table.php
+++ b/library/templates/Intonation/View/Calendar/Table.php
@@ -21,9 +21,44 @@
 
 
 class Intonation_View_Calendar_Table extends ZendAfi_View_Helper_Calendar_Table {
-  protected function buildUrl($url = []) {
-    $params = parent::buildUrl($url);
-    unset($params['action']);
-    return $params;
+
+  public function calendar_Table($calendar) {
+    $calendar->setDisplayFullPage(true);
+    return parent::calendar_Table($calendar);
+  }
+
+
+  protected function _getMonthLinks($attribs) {
+    $html =
+      [$this->view->div(['class' => 'col-3'],
+                        $this->view->tagAnchor($this->getUrl('LAST_MONTH'),
+                                               Class_Template::current()->getIco($this->view,
+                                                                                 'previous',
+                                                                                 'utils'),
+                                               array_merge($attribs,
+                                                           ['title' => $this->_('Mois précédent')]))),
+
+       $this->view->div(['class' => 'col-6'],
+                        $this->view->tagAnchor($this->getUrl('MONTH'),
+                                               $this->MONTHS[$this->month-1] .
+                                               strftime(' %Y', mktime(5,0,0, $this->month, 1, $this->year)),
+                                               ['class' => 'calendar_title_month',
+                                                'title' => $this->_('Mois courant')])),
+
+       $this->view->div(['class' => 'col-3'],
+                        $this->view->tagAnchor($this->getUrl('NEXT_MONTH'),
+                                               Class_Template::current()->getIco($this->view,
+                                                                                 'next',
+                                                                                 'utils'),
+                                               array_merge($attribs,
+                                                           ['title' => $this->_('Mois suivant')])))];
+
+    return $this->view->grid(implode($html), ['class' => 'text-center']);
+  }
+
+
+  protected function _todayCellContent($time) {
+    $day = date('j', $time);
+    return $this->_isTimestampToday($time) ? $this->_tag('b', $day) : $day;
   }
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/View/Calendar/TableFilter.php b/library/templates/Intonation/View/Calendar/TableFilter.php
index be040b2dd060b3a85699ea2151a03022a50a2bad..0f276d38a7ff1b719cc42168be70ac90b9765366 100644
--- a/library/templates/Intonation/View/Calendar/TableFilter.php
+++ b/library/templates/Intonation/View/Calendar/TableFilter.php
@@ -21,7 +21,41 @@
 
 
 class Intonation_View_Calendar_TableFilter extends Intonation_View_Calendar_Table {
+
   public function calendar_TableFilter($calendar) {
     return parent::calendar_Table($calendar);
   }
+
+
+  protected function _lastMonthUrl() {
+    $params = parent::_lastMonthUrl();
+    $params['day'] = $params['date'];
+    return $params;
+  }
+
+
+  protected function _currentMonthUrl() {
+    $params = parent::_currentMonthUrl();
+    $params['action'] = 'calendar';
+    $params['day'] = $params['date'] = $params['d'];
+    unset($params['d']);
+    return $params;
+  }
+
+
+  protected function _nextMonthUrl() {
+    $params = parent::_nextMonthUrl();
+    $params['day'] = $params['date'];
+    return $params;
+  }
+
+
+  protected function _dayUrl($day, $month) {
+    $params = parent::_dayUrl($day, $month);
+    $params['action'] = 'calendar';
+    $params['day'] = $params['d'];
+    unset($params['d']);
+    $params['date'] = null;
+    return $params;
+  }
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/View/CalendarContent.php b/library/templates/Intonation/View/CalendarContent.php
index 4160c675b006602fd1f508ce78638bd0bae23af4..46b22bbf913efe38a22df9fcee137f47b21aa3f4 100644
--- a/library/templates/Intonation/View/CalendarContent.php
+++ b/library/templates/Intonation/View/CalendarContent.php
@@ -28,15 +28,17 @@ class Intonation_View_CalendarContent extends ZendAfi_View_Helper_CalendarConten
     $this->param = $settings;
     $this->calendar = $calendar;
 
-    $calendar->setTimeSource($this->getTimeSource());
-    $calendar->initializeParams();
+    $this->calendar->setTimeSource($this->getTimeSource());
+    $this->calendar->initializeParams();
 
-    $html = [$this->renderFilters($calendar),
-             (new Intonation_Library_Widget_Carousel_Agenda_View($calendar->getIdModule(),
-                                                                 $settings))
-             ->setView($this->view)
-             ->setCalendar($calendar)
-             ->renderElements()];
+    $html = ((isset($settings['layout'])) && ( $settings['layout'] == Intonation_Library_Widget_Carousel_Agenda_Definition::CALENDAR)
+             ? [$this->view->calendar_Table($this->calendar)]
+             : [$this->renderFilters($calendar),
+                (new Intonation_Library_Widget_Carousel_Agenda_View($this->calendar->getIdModule(),
+                                                                    $settings))
+                ->setView($this->view)
+                ->setCalendar($this->calendar)
+                ->renderElements()]);
 
     return $this->view->div(['class' => 'calendar'], implode($html));
   }
diff --git a/library/templates/Intonation/View/Filters/Render.php b/library/templates/Intonation/View/Filters/Render.php
index 1182218b6d1db74cf2621a6171b8987f754aeb61..8a58031dbbb6eaa1eb2066fe735c1b24a7623d02 100644
--- a/library/templates/Intonation/View/Filters/Render.php
+++ b/library/templates/Intonation/View/Filters/Render.php
@@ -28,11 +28,16 @@ class Intonation_View_Filters_Render extends ZendAfi_View_Helper_BaseHelper {
     if(empty($filters))
       return '';
 
+    $filters [] = 'reset';
+
     $html = [];
     foreach ($filters as $filter) {
       $renderer = $this->_getFilterRenderer($filter, $settings);
+      $content = ($content = $renderer->getContent())
+        ? $this->view->renderDropdown($content, $renderer->getTitle())
+        : $renderer->getTitle();
       $html [] = $this->view->div(['class' => 'col ' . $filter],
-                                  $this->view->renderDropdown($renderer->getContent(), $renderer->getTitle()));
+                                  $content);
     }
 
     return $this->view->div($settings->getCssClass(),
diff --git a/library/templates/Intonation/View/FonctionsAdmin/Boite.php b/library/templates/Intonation/View/FonctionsAdmin/Boite.php
new file mode 100644
index 0000000000000000000000000000000000000000..e6eb0934fb0e2e6c3206b48476e698e70e5e21be
--- /dev/null
+++ b/library/templates/Intonation/View/FonctionsAdmin/Boite.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright (c) 2012-2020, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Intonation_View_FonctionsAdmin_Boite extends ZendAfi_View_Helper_FonctionsAdmin_Boite {
+  protected function _getTitle() {
+    return $this->_widget
+      ? $this->_widget->getLabel()
+      : '';
+  }
+
+
+  protected function _properties($url_params) {
+    return $this->_renderActionLink('box_configuration',
+                                    $this->_('Modifier la configuration de la boite %s', $this->_title),
+                                    Class_Url::assemble($url_params));
+  }
+}
diff --git a/library/templates/Intonation/View/Opac.php b/library/templates/Intonation/View/Opac.php
index 6f701bd074ed750bb32060628ff8310825eb3215..bea83f5d41194c305de6fe61da979c663e310ec2 100644
--- a/library/templates/Intonation/View/Opac.php
+++ b/library/templates/Intonation/View/Opac.php
@@ -122,7 +122,7 @@ class Intonation_View_Opac extends ZendAfi_View_Helper_BaseHelper {
                                 URL_ADMIN_CSS,
                                 USERFILESURL));
 
-    $script_loader->addJQueryReady('if (window.location.hash) return false; var search_input = $(".search_title_col").closest("body").find(".boite.rech_simple"); var anchors = $("li + li a.active.jumbotron_nav_link"); anchors += search_input; if (!anchors.length) return false; $("html, body").scrollTop(anchors.offset().top);');
+    $script_loader->addJQueryReady('if (window.location.hash) return false; var search_input = $(".search_title_col").closest("body").find(".boite.rech_simple"); var anchors = $("li + li a.active.jumbotron_nav_link"); anchors = $.merge(anchors, search_input); if (!anchors.length) return false; $("html, body").scrollTop(anchors.offset().top);');
 
     if($this->_template->getJquery())
       $head_scripts->loadJQuery();
diff --git a/library/templates/Intonation/View/RenderArticles.php b/library/templates/Intonation/View/RenderArticles.php
index a858a65112090ee4ed1d92a88f495408eb5d0ce2..f858c7f45b98dc20d2fccb3a3314e8849fb7b6c1 100644
--- a/library/templates/Intonation/View/RenderArticles.php
+++ b/library/templates/Intonation/View/RenderArticles.php
@@ -25,22 +25,27 @@ class Intonation_View_RenderArticles extends ZendAfi_View_Helper_BaseHelper {
     if (!$this->view->titre)
       $this->view->titre = $this->_('Liste d\'articles');
 
-    $content = [$this->_tag('h1',
-                            $this->view->titre),
-                $this->_getHtml($articles)];
+    $content = [$this->_div(['class' => 'col-12 articles_list_title'],
+                            $this->_tag('h1',
+                                        $this->view->titre)),
 
-    return implode($content);
+                $this->_div(['class' => 'col-12 articles_list_content'],
+                            $this->_getHtml($articles))];
+
+    return $this->view->grid(implode($content));
   }
 
 
   protected function _getHtml($articles) {
+    if (empty($articles))
+      return $this->_tag('p', $this->_('Aucun événement'));
+
     $html = [];
     foreach($articles as $article)
-      $html [] = $this->_htmlForArticle($article);
+      $html [] = $this->_div(['class' => 'col-12 wrapper_article_content'],
+                              $this->_htmlForArticle($article));
 
-    return $this->_tag('div',
-                       implode($html),
-                       ['class' => 'row no-gutters no_overflow']);
+    return $this->view->grid(implode($html));
   }
 
 
diff --git a/library/templates/Intonation/View/RenderDropdown.php b/library/templates/Intonation/View/RenderDropdown.php
index d0f088fadcc7f24e36b3e3c50d2d5ddfe35f9d9c..b4698a18cca68c45a86174d122f08c9f1e488c13 100644
--- a/library/templates/Intonation/View/RenderDropdown.php
+++ b/library/templates/Intonation/View/RenderDropdown.php
@@ -38,7 +38,7 @@ class Intonation_View_RenderDropdown extends ZendAfi_View_Helper_BaseHelper {
                      'data-toggle' => 'dropdown',
                      'aria-haspopup' => 'true',
                      'type' => 'button',
-                     'class' => 'btn dropdown-toggle']);
+                     'class' => 'btn dropdown-toggle button_' . Storm_Inflector::camelize($button)]);
 
     return
       $this->view->div(['class' => 'dropdown ' . $direction],
diff --git a/library/templates/Muscle/Library/ProfilePatcher.php b/library/templates/Muscle/Library/ProfilePatcher.php
index 8f5b2d0b4f25d7be47e39fcb2e0efee3911c76f7..b00d7d447f8ac8afaf3ab2698a4a18347e3af1e9 100644
--- a/library/templates/Muscle/Library/ProfilePatcher.php
+++ b/library/templates/Muscle/Library/ProfilePatcher.php
@@ -267,7 +267,7 @@ class Muscle_Library_ProfilePatcher extends Intonation_Library_ProfilePatcher {
 
       ->_addWidget(Intonation_Library_Widget_Nav_Definition::CODE,
                    Class_Profil::DIV_BANNIERE,
-                   ['titre' => $this->_('Menu réseau sociaux haut'),
+                   ['titre' => $this->_('Navigation principal'),
                     'boite' => ['no_border', 'no_border_radius', 'no_shadow', 'justify-content-start', 'pt-3'],
                     'menu' => $this->_profile_id . '-' . $this->_main_menu,
                     $this->_template->withNameSpace('expand_breakpoint') => Intonation_Library_Constants::RESPONSIVE_MODE_SMALL,
diff --git a/library/templates/Muscle/Library/Settings.php b/library/templates/Muscle/Library/Settings.php
index d615f70b4332cb66fb680906f412ef7b4415000a..09c3d0f2e68fadbfc52b7d5032f38e6d6f27e90a 100644
--- a/library/templates/Muscle/Library/Settings.php
+++ b/library/templates/Muscle/Library/Settings.php
@@ -41,6 +41,9 @@ class Muscle_Library_Settings extends Intonation_Library_Settings {
     $hydrating_mapping['div class navbar-header'] = '';
     $hydrating_mapping['div class navbar-collapse'] = '';
     $hydrating_mapping['div id site_web_wrapper'] = 'container align-self-center';
+    $hydrating_mapping['a class calendar_day_event_start'] = 'border-bottom border-danger';
+    $hydrating_mapping['span class calendar_day_event_start'] = 'text-secondary border-bottom border-secondary';
+    $hydrating_mapping['a class day_clickable'] = 'text-danger font-weight-bold';
 
     $settings[$this->_template->withNameSpace('hydrating_mapping')] = $hydrating_mapping;
     return $settings;
diff --git a/public/opac/js/visible_when_hidden.js b/public/opac/js/visible_when_hidden.js
new file mode 100644
index 0000000000000000000000000000000000000000..f38112b35528e84c225e38b89eea52319195815c
--- /dev/null
+++ b/public/opac/js/visible_when_hidden.js
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2018, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ */
+
+(function ( $ ) {
+  $.fn.visible_when_hidden = function (hidden_selector) {
+    var this_widget = $(this);
+
+    var visible = function(element) {
+      var rect = element.getBoundingClientRect(),
+    	  top = rect.top,
+    	  height = rect.height;
+
+      return top + height > 0;
+    };
+
+    var update = function() {
+      return visible($(hidden_selector)[0])
+        ? this_widget.addClass('d-none')
+    	: this_widget.removeClass('d-none');
+    }
+
+    $(window).on('scroll', update);
+    
+    update();
+  }
+} (jQuery));
diff --git a/tests/library/Class/CompareUrlTest.php b/tests/library/Class/CompareUrlTest.php
index 731372bbf637a48228d3ca537dde1c91325d91b8..3d81d834f9d9c364f267558883df65f6c65f20eb 100644
--- a/tests/library/Class/CompareUrlTest.php
+++ b/tests/library/Class/CompareUrlTest.php
@@ -25,4 +25,72 @@ class CompareUrlIsInRequestUrlTest extends ModelTestCase {
   public function withWrongParamShouldReturnFalse() {
     $this->assertFalse(Class_CompareUrl::isInRequestUrl([]));
   }
+}
+
+
+
+class CompareUrlSameAsRequestTest extends AbstractControllerTestCase {
+
+  protected $_storm_default_to_volatile = true;
+
+
+  public function setUp() {
+    parent::setUp();
+    Class_Profil::find(1)->setRewriteUrl('accueil')->save();
+
+    $this->fixture('Class_Profil',
+                   ['id' => 2,
+                    'rewrite_url' => 'agenda'
+                   ]);
+  }
+
+
+  public function dispatchToUrls() {
+    return [
+            ['/index/index/id_profil/1', '/accueil', true],
+            ['/accueil', '/index/index/id_profil/1', true],
+            ['/accueil', '/accueil', true],
+            ['/index/index/id_profil/1', '/index/index/id_profil/1', true],
+            ['/index/index/id_profil/1', '/', true],
+            ['/accueil', '/', true],
+
+            ['/index/index/id_profil/2', '/agenda', true],
+            ['/agenda', '/index/index/id_profil/2', true],
+            ['/agenda', '/agenda', true],
+            ['/index/index/id_profil/2', '/index/index/id_profil/2', true],
+            ['/index/index/id_profil/2', '/', true],
+            ['/agenda', '/', true],
+
+            ['/index/index/id_profil/1', '', false],
+            ['/index/index/id_profil/1', null, false],
+            ['/index/index/id_profil/1', [], false],
+
+            ['/index/index/id_profil/2', '', false],
+            ['/index/index/id_profil/2', null, false],
+            ['/index/index/id_profil/2', [], false],
+
+            ['/index/index/id_profil/1', '/index/index/id_profil/2', false],
+            ['/index/index/id_profil/1', '/agenda', false],
+            ['/accueil', '/index/index/id_profil/2', false],
+            ['/accueil', '/agenda', false],
+
+            ['/index/index/id_profil/2', '/index/index/id_profil/1', false],
+            ['/index/index/id_profil/2', '/accueil', false],
+            ['/agenda', '/index/index/id_profil/1', false],
+            ['/agenda', '/accueil', false],
+
+            ['/agenda', 'https://library-portal.org/agenda', false],
+
+    ];
+  }
+
+
+  /**
+   * @test
+   * @dataProvider dispatchToUrls
+   */
+  public function urlShouldBeInDispatchedUrl($url_to_dispatch, $url_in_menu, $expected) {
+    $this->dispatch($url_to_dispatch);
+    $this->assertEquals($expected, (new Class_CompareUrl())->sameAsRequest($url_in_menu));
+  }
 }
\ No newline at end of file
diff --git a/tests/scenarios/Templates/MuscleTemplateTest.php b/tests/scenarios/Templates/MuscleTemplateTest.php
index 95cb20e091a7906aea7bdeaf982b058c4e982b7f..78ea72a2a120e6b0bb52ebf51734ef33c2bfa107 100644
--- a/tests/scenarios/Templates/MuscleTemplateTest.php
+++ b/tests/scenarios/Templates/MuscleTemplateTest.php
@@ -536,6 +536,12 @@ class MuscleTemplateNotLoggedTest extends MuscleTemplateTestCase {
   }
 
 
+  /** @test */
+  public function menuAccueilShouldHaveClassActiveItem() {
+    $this->assertXPath('//nav//a[contains(@href, "/index/index/id_profil/1")][contains(@class, "active_item")]');
+  }
+
+
   /** @test */
   public function inputUsernameShouldBeHydratedWithOrder3() {
     $this->assertXPath('//form/div[@class="form-group container-fluid no-gutters py-1 wrapper_zendafi_form_login_username col-12 order-1"]//input[@id="username"][@class= "zendafi_form_login_username form-control form-control-sm"]');
diff --git a/tests/scenarios/Templates/TemplatesTest.php b/tests/scenarios/Templates/TemplatesTest.php
index 008db272d3870aa9e87b485c2e0772a553d6f914..029e7ae3d0cdb93ed1be066dcd838e0eb7a66eba 100644
--- a/tests/scenarios/Templates/TemplatesTest.php
+++ b/tests/scenarios/Templates/TemplatesTest.php
@@ -340,7 +340,7 @@ abstract class TemplatesIntonationTestCase extends TemplatesEnabledTestCase {
 
               '9' => ['division' => 6,
                       'type_module' => 'LANGUE',
-                      'preferences' => []],
+                      'preferences' => ['IntonationVisibleWhenHidden' => 8]],
 
               '10' => ['division' => 2,
                        'type_module' => 'LOGIN',
@@ -538,7 +538,13 @@ class TemplatesDispatchIntonationTest extends TemplatesIntonationTestCase {
 
   /** @test */
   public function languageWidgetShouldBePresent() {
-    $this->assertXPath('//footer//div[contains(@class, "boite langue")]');
+    $this->assertXPath('//footer//div[contains(@class, "boite langue widget col d-none card")]');
+  }
+
+
+  /** @test */
+  public function languageWidgetShouldBeVisibleWhenSearchIsHidden() {
+    $this->assertXPathContentContains('//script', '$("#boite_9").visible_when_hidden("#boite_8")');
   }
 
 
@@ -1235,7 +1241,11 @@ class TemplatesIntonationHydratingtest extends ModelTestCase {
 
             [['element' => 'button',
               'attribs' => ['class' => 'btn search-button']],
-             'btn search-button']
+             'btn search-button'],
+
+            [['element' => 'a',
+              'attribs' => ['class' => 'calendar_day_non_clickable day_clickable calendar_day_event_start text-secondary']],
+             'calendar_day_non_clickable day_clickable calendar_day_event_start text-secondary text-success font-weight-bold border-bottom border-info']
     ];
   }
 
@@ -1276,7 +1286,8 @@ class TemplatesWidgetSettingsPostTest extends TemplatesIntonationTestCase {
   public function setUp() {
     parent::setUp();
     $this->postDispatch('/admin/widget/edit-widget/id/8/id_profil/72',
-                        ['IntonationVisibilityIndex' => 0]);
+                        ['IntonationVisibilityIndex' => 0,
+                         'IntonationVisibleWhenHidden' => 7]);
   }
 
 
@@ -1289,6 +1300,17 @@ class TemplatesWidgetSettingsPostTest extends TemplatesIntonationTestCase {
 
     $this->assertEquals(0, $widget->getIntonationVisibilityIndex());
   }
+
+
+  /** @test */
+  public function widgetSettingsVisibleWhenHiddenShouldHaveBeenSet() {
+    $widget = ((new Class_Systeme_Widget_Widget)
+               ->setId(8)
+               ->setProfileId(72)
+               ->load());
+
+    $this->assertEquals(7, $widget->getIntonationVisibleWhenHidden());
+  }
 }
 
 
@@ -3852,6 +3874,13 @@ class TemplatesDispatchLibraryWidgetTest extends TemplatesIntonationTestCase {
   }
 
 
+  /** @test */
+  public function annecyLAgendaShouldRenderButtonReset() {
+    $this->dispatch('/opac/bib/agenda/id/1/id_profil/72');
+    $this->assertXPathContentContains('//div//a[@href="/cms/calendar/id_module/21"][contains(@class, "filter_reset_button btn btn-warning")]', 'Réinitialiser');
+  }
+
+
   /** @test */
   public function annecyCalendarShouldRenderAgenda() {
     $this->dispatch('/opac/cms/calendar/id_module/library_1/id_profil/72');
@@ -4208,6 +4237,18 @@ class TemplatesDispatchEditFreeWidgetTest extends TemplatesIntonationTestCase {
   public function inputTitreTypeShouldBeText() {
     $this->assertXpath('//input[@name="titre"][@type="text"]');
   }
+
+
+  /** @test */
+  public function selectHiddenModeShouldBePresent() {
+    $this->assertXpath('//select[contains(@name, "HiddenMode")]');
+  }
+
+
+  /** @test */
+  public function selectVisibleWhenHiddenShouldBePresent() {
+    $this->assertXpathContentContains('//select[contains(@name, "VisibleWhenHidden")]/optgroup[contains(@label, "Division bann")]/option[@value="8"]', 'Boite recherche');
+  }
 }