/*************************************************************
 MISE EN PAGE PLEINE HAUTEUR
 Remplace le calcul JS de fitToBottom (sidebars.js) par du flex.

 Principe : le body est une colonne flex haute de 100vh. La barre de
 navigation y prend sa hauteur naturelle (sticky = dans le flux, plus besoin
 de compenser en JS), le bandeau de titre aussi, et #contentRow occupe tout
 le reste. Les elements .fitToBottom deviennent des items flex qui prennent
 l'espace restant de leur colonne, au lieu de recevoir une hauteur en pixels.

 Pour revenir en arriere : retirer le <link> de ce fichier dans base.html et
 restaurer le corps de updateBottomFitting()/fitToBottom() dans sidebars.js.
*************************************************************/

/*************
 SQUELETTE
*************/

body {
  height: 100vh;
  padding-top: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* dans le flux : la barre reserve sa place elle-meme */
#navbars {
  position: sticky;
  top: 0;
  right: auto;
  left: auto;
  z-index: 1030;
  flex: 0 0 auto;
}

/* tout ce qui entoure #contentRow garde sa hauteur naturelle.
   Le bandeau de titre est enveloppe dans #topContent parce que les pages y
   posent souvent une classe de grille bootstrap (col-sm-12 = flex: 0 0 100%),
   qui, appliquee a un enfant direct du body, lui ferait reclamer toute la
   hauteur de la fenetre et ecraserait #contentRow. */
body>* {
  flex: 0 0 auto;
}

#topContent {
  flex: 0 0 auto;
}

/* la ligne colonne gauche | contenu | colonne droite */
#contentRow {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

#leftSidebar,
#rightSidebar {
  float: none;
  flex: 0 0 auto;
  height: auto;
  min-height: 0;
}

#leftSidebar {
  order: 1;
}

#mainContainer {
  order: 2;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  overflow: auto;
}

#rightSidebar {
  order: 3;
}

/*************
 INTERIEUR DES COLONNES
 (poignee de redimensionnement, barre de boutons, contenu)
*************/

.leftsidebar,
.rightsidebar {
  display: flex;
}

.leftsidebar .sidebuttonbar {
  order: 1;
}

.leftsidebar #leftSidebarContent,
.leftsidebar .minimizedsidebar {
  order: 2;
}

.leftsidebar .splitbar {
  order: 3;
}

.rightsidebar .splitbar {
  order: 1;
}

.rightsidebar #rightSidebarContent,
.rightsidebar .minimizedsidebar {
  order: 2;
}

.rightsidebar .sidebuttonbar {
  order: 3;
}

#leftSidebar .sidebuttonbar,
#rightSidebar .sidebuttonbar,
.leftsidebar .splitbar,
.rightsidebar .splitbar,
.minimizedsidebar {
  float: none;
  flex: 0 0 auto;
}

#leftSidebarContent,
#rightSidebarContent {
  height: auto;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
}

/*************
 .fitToBottom / .fitToBottomIfNecessary

 Tout conteneur qui heberge un .fitToBottom devient une colonne flex, sauf
 s'il est deja une ligne horizontale (row, d-flex, input-group...) : dans ce
 cas les enfants sont etires en hauteur par le align-items: stretch par
 defaut, il suffit de les laisser retrecir.

 min-height: 0 partout : sans lui un item flex refuse de descendre sous la
 hauteur de son contenu, et les .yscroller internes cessent de scroller.
*************/

.fitToBottom,
.fitToBottomIfNecessary {
  min-height: 0;
}

:has(> .fitToBottom, > .fitToBottomIfNecessary):where(:not(body, #contentRow, .row, .d-flex, .form-row, .input-group, .btn-group, .nav, .navbar, .list-group-horizontal)):where(:not(:has(> .float-left, > .float-right))) {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

:has(> .fitToBottom, > .fitToBottomIfNecessary):where(:not(body, #contentRow, .row, .d-flex, .form-row, .input-group, .btn-group, .nav, .navbar, .list-group-horizontal)):where(:not(:has(> .float-left, > .float-right)))>.fitToBottom {
  flex: 1 1 0;
}

:has(> .fitToBottom, > .fitToBottomIfNecessary):where(:not(body, #contentRow, .row, .d-flex, .form-row, .input-group, .btn-group, .nav, .navbar, .list-group-horizontal)):where(:not(:has(> .float-left, > .float-right)))>.fitToBottomIfNecessary {
  flex: 0 1 auto;
}

/* .fitToBottom dans un .row : la ligne est exclue du passage en colonne, et
   l'etirement implicite (align-items: stretch) ne donne pas une hauteur
   exploitable comme conteneur de defilement -- .row porte flex-wrap: wrap, ce
   qui fait dependre la hauteur de la ligne du contenu. On la fixe donc
   explicitement : le .row a bien une hauteur definie (flex: 1 1 0 dans sa
   colonne parente), donc le pourcentage se resout. */
.row>.fitToBottom,
.row>.fitToBottomIfNecessary {
  height: 100%;
}

/* Conteneur qui melange flottants et .fitToBottom (colonnes cote a cote des
   vues etudiantes) : passer en colonne flex casserait la mise en page, on se
   contente donc d'etirer les enfants en hauteur. */
:has(> .fitToBottom, > .fitToBottomIfNecessary):has(> .float-left, > .float-right)>.fitToBottom {
  height: 100%;
}

:has(> .fitToBottom, > .fitToBottomIfNecessary):has(> .float-left, > .float-right)>.fitToBottomIfNecessary {
  max-height: 100%;
}

/* colonne flex declaree a la main dans une page : les enfants suivent */
.d-flex.flex-column>.fitToBottom {
  flex: 1 1 0;
}

.d-flex.flex-column>.fitToBottomIfNecessary {
  flex: 0 1 auto;
}

/* Meme piege que pour #topContent, un cran plus bas : une classe de grille
   bootstrap posee hors d'un .row vaut flex: 0 0 100%, soit toute la hauteur
   de la colonne. On la ramene a sa hauteur naturelle. */
body>[class*="col-"] {
  flex: 0 0 auto;
}

:has(> .fitToBottom, > .fitToBottomIfNecessary):where(:not(body, #contentRow, .row, .d-flex, .form-row, .input-group, .btn-group, .nav, .navbar, .list-group-horizontal)):where(:not(:has(> .float-left, > .float-right)))>[class*="col-"] {
  flex: 0 0 auto;
  max-width: 100%;
}
