body.fond {
    background-image: url('../images/fond.jpg');
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    background-attachment: fixed;    /* reste en place quand on scrolle */
    min-height: 100vh; /* pour s'assurer que le body occupe tout l'écran */
}

/* Gabarit fixe : header et footer restent en place, seul <main> défile.
   Colonne flex qui occupe exactement la hauteur de la fenêtre : header et footer gardent leur hauteur
   naturelle (qui varie : menu replié, formulaire de connexion), main prend le reste et défile.
   Aucune hauteur codée en dur, aucun position: fixed, donc rien ne passe sous le header.
   La hauteur du body vient de la chaîne html > body en 100%, plutôt que de 100vh / 100dvh : en pourcentage, elle suit la zone
   réellement visible du navigateur (sur mobile, 100vh ignore la barre d'adresse et peut cacher le footer). */
html {
    height: 100%;
}
body.gabarit-fixe {
    height: 100%;
    min-height: 0; /* annule le min-height: 100vh de body.fond, qui l'emporterait sur height et dépasserait l'écran sur mobile */
    margin: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden; /* le body ne défile jamais, c'est main qui défile */
}
body.gabarit-fixe > header,
body.gabarit-fixe > footer {
    flex: 0 0 auto;
}
body.gabarit-fixe > main {
    flex: 1 1 auto;
    min-height: 0; /* indispensable : sans ça, un enfant flex refuse de rétrécir sous la hauteur de son contenu et rien ne défile */
    overflow: auto; /* tout débordement (vertical ou horizontal) reste confiné dans main */
    scrollbar-gutter: stable; /* la place de la barre de défilement est réservée : pas de décalage quand elle apparaît */
    overscroll-behavior: contain; /* atteindre le bout de main ne fait pas rebondir la page entière, ne rafraîchit pas accidentellement (perte d'un formulaire en cours) et ne déclenche pas de navigation par balayage (mobile) */
}

/* Menu principal replié (sous md) : déroulé par-dessus main au lieu de repousser le contenu.
   Sorti du flux en absolu, le header garde donc sa hauteur; au-dessus de md le menu est en ligne, rien ne change.
   Le bloc conteneur est .navbar (position: relative dans Bootstrap), qui ne fait que la largeur du bouton hamburger :
   d'où la largeur au contenu plutôt que left/right 0, qui donnerait un menu aussi étroit que le bouton. */
@media (max-width: 767.98px) { /* = sous le point de rupture md de Bootstrap (navbar-expand-md) */
    body.gabarit-fixe > header .navbar-collapse {
        position: absolute;
        top: 100%;
        left: 0; /* aligné sous le bouton hamburger */
        width: max-content; /* aussi large que l'option la plus longue */
        max-width: calc(100vw - 1rem); /* sans jamais dépasser l'écran */
        z-index: 1030; /* au-dessus du contenu de main et du message flash (sticky-top = 1020), sous les modales (1055) */
        padding: 0.5rem;
        background-color: rgba(var(--bs-dark-rgb), 0.5); /* fond sombre léger, le flou fait le reste pour la lisibilité */
        backdrop-filter: blur(6px); /* floute le contenu derrière; ignoré sans dommage si non supporté */
        -webkit-backdrop-filter: blur(6px);
        border-radius: 0 0 var(--bs-border-radius) var(--bs-border-radius);
        box-shadow: var(--bs-box-shadow);
    }
}

/* Message flash : le conteneur ne prend aucune hauteur dans main, l'alerte déborde par-dessus le contenu
   (sticky-top de Bootstrap fournit position: sticky, top: 0 et le z-index) */
.bref-message {
    height: 0;
    overflow: visible;
}

#navbarNav > ul > li.nav-item > a:hover,
#navbarNav > ul > li.nav-item > a.active {
    background-color: var(--coul-accent); /* couleur d'accent de Config\Theme, définie dans gabarit/head.php */
    color: var(--coul-texte-fond-accent) !important; /* texte lisible sur fond d'accent, aussi de Config\Theme */
}

/* Zones du header (gabarit/principal.php) : menu principal, menu secondaire, connexion.
   Sous md : hamburger et connexion sur la première ligne, menu secondaire seul sur la deuxième, pleine largeur.
   À partir de md : les deux menus empilés à gauche, la connexion à droite, centrée sur leur hauteur.
   Une zone vide (pas de menu secondaire, non connecté) ne prend aucune place. */
.entete-zones {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas:
        "nav connexion"
        "sous-nav sous-nav";
    align-items: center;
}
.entete-nav {
    grid-area: nav;
}
.entete-sous-nav {
    grid-area: sous-nav;
}
.entete-connexion {
    grid-area: connexion;
    justify-self: end;
}
@media (min-width: 768px) { /* = à partir du point de rupture md de Bootstrap */
    .entete-zones {
        grid-template-areas:
            "nav connexion"
            "sous-nav connexion";
    }
}

/* Footer (gabarit/footer.php) : copyright et bloc de l'hébergeur. Sous md, deux colonnes : le copyright est centré dans l'espace
   que le logo laisse libre. À partir de md, trois colonnes dont les deux extrêmes sont égales : le copyright, dans celle du milieu,
   est centré sur l'écran, et l'hébergeur est au bout de la troisième (la première reste vide). */
.pied-zones {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 0.5rem;
}
.pied-copyright {
    text-align: center;
}
@media (min-width: 768px) { /* = à partir du point de rupture md de Bootstrap */
    .pied-zones {
        grid-template-columns: 1fr auto 1fr;
    }
    .pied-copyright {
        grid-column: 2;
    }
    .pied-hebergeur {
        grid-column: 3;
        justify-self: end;
    }
}

/* Menu secondaire (gabarit/nav_secondaire.php) : nav-underline de Bootstrap, resserré. Même logique que le menu principal,
   mais l'élément survolé ou actif est souligné de la couleur d'accent au lieu d'en prendre le fond ; le texte garde la couleur de Config\Theme (classe posée dans la vue) */
.sous-nav {
    --bs-nav-link-padding-y: 0.125rem;
    --bs-nav-underline-gap: 1.25rem; /* même écart entre les libellés que dans le menu principal */
    row-gap: 0; /* si le menu passe sur deux lignes (petit écran), elles restent serrées */
}
.sous-nav .nav-link:hover,
.sous-nav .nav-link:focus,
.sous-nav .nav-link.active {
    border-bottom-color: var(--coul-accent);
}
.sous-nav .nav-link.active {
    font-weight: inherit; /* Bootstrap met l'élément actif en gras : pas ici, comme dans le menu principal */
}

/* Bouton plein de la couleur d'accent qui s'inverse au survol et à l'appui : fond transparent, bordure et contenu de la couleur d'accent
   (variables de Bootstrap 5.3 ; à poser par classes_suppl des helpers bouton_*, ou classes_suppl_bouton de form_pill_un_input) */
.btn-survol-inverse {
    --bs-btn-hover-bg: transparent;
    --bs-btn-hover-color: var(--coul-accent);
    --bs-btn-hover-border-color: var(--coul-accent);
    --bs-btn-active-bg: transparent;
    --bs-btn-active-color: var(--coul-accent);
    --bs-btn-active-border-color: var(--coul-accent);
}

/* Bouton qui garde son apparence au survol : pour un bouton à deux états (contour / plein, fleur de Vieilles dépouilles), dont le survol
   de Bootstrap ferait passer un état pour l'autre. L'appui garde son effet. À poser par classes_suppl des helpers bouton_* */
.btn-survol-stable {
    --bs-btn-hover-bg: var(--bs-btn-bg);
    --bs-btn-hover-color: var(--bs-btn-color);
    --bs-btn-hover-border-color: var(--bs-btn-border-color);
}

/* Pagination (Pager/simongrenier_full.php) : fond transparent sur la photo, numéros et chevrons de la couleur du texte de Config\Theme,
   survol en couleur d'accent ; variables de Bootstrap 5.3, pour ne pas réécrire ses règles. La page active garde text-bg-* (couleur d'accent), posé dans la vue */
.pagination {
    --bs-pagination-bg: transparent;
    --bs-pagination-color: var(--coul-texte);
    --bs-pagination-focus-bg: transparent;
    --bs-pagination-focus-color: var(--coul-texte);
    --bs-pagination-hover-color: var(--coul-texte-fond-accent);
    --bs-pagination-hover-bg: var(--coul-accent);
    --bs-pagination-hover-border-color: var(--coul-accent);
    --bs-pagination-active-border-color: var(--coul-accent); /* page active : bordure de la couleur de son fond, donc invisible */
}

/* Marge interne verticale d'une demi-unité (0.125rem), la moitié de py-1 / px-1 : Bootstrap n'a rien entre py-0 et py-1.
   Rangées des listes de la section Listes : leurs boutons de contrôle ne touchent plus les bordures haute et basse, avec la
   moitié de l'espace qui les sépare de la bordure droite (px-1). */
.py-demi {
    padding-top: 0.125rem;
    padding-bottom: 0.125rem;
}

/* Champs de saisie resserrés, partout dans le site (à l'origine ceux de la liste des versements) : marge interne de px-1 py-0
   (0 en hauteur, 0.25rem sur les côtés) pour les champs, les menus déroulants et les étiquettes de groupe ($, %).
   Le padding seul ne suffit pas : Bootstrap garde une hauteur minimale (1.5em + 0.75rem + bordures) qui laisserait du vide
   au-dessus et au-dessous du texte ; on la réduit aussi. Les sélecteurs « .input-group > » couvrent input-group-sm et -lg,
   dont les règles sont plus précises que .form-control. */
.form-control,
.form-select,
.input-group-text,
.input-group > .form-control,
.input-group > .form-select,
.input-group > .input-group-text {
    padding-top: 0;
    padding-bottom: 0;
    padding-left: 0.25rem;
    min-height: calc(1.5em + 0.25rem + calc(var(--bs-border-width) * 2));
}
/* un menu déroulant garde sa marge droite, où Bootstrap dessine sa flèche ; un champ en erreur aussi, pour son icône */
.form-control,
.input-group-text,
.input-group > .form-control:not(.is-invalid),
.input-group > .input-group-text {
    padding-right: 0.25rem;
}
/* Champs au plus serré en hauteur, dans un conteneur qui porte .champs-serres (tableau des listes de tâches) : la hauteur minimale
   n'est plus que celle de la ligne de texte et des bordures, sans le 0.25rem de jeu de la règle générale */
.champs-serres .form-control,
.champs-serres .form-select {
    min-height: calc(1.5em + calc(var(--bs-border-width) * 2));
}
/* champs de filtre des en-têtes : hauteur prévue pour la bordure épaisse d'un filtre en vigueur (border-2), pour qu'un champ filtré ne
   soit pas plus haut que ses voisins ; comme dans les en-têtes des transactions des dépenses, où le jeu de la règle générale l'absorbe */
.champs-serres thead .form-control,
.champs-serres thead .form-select {
    min-height: calc(1.5em + calc(var(--bs-border-width) * 4));
}
/* les boutons de contrôle du même conteneur sont réduits à la hauteur de leur icône (1em + bordures, au lieu de 1.5em), pour laisser
   place à une marge verticale (my-1 dans la vue) sans hausser la ligne. Par variable plutôt que par une classe passée en classes_suppl :
   ce paramètre resterait en mémoire pour les boutons suivants de la page (Config\View::$saveData) */
.champs-serres .btn {
    --bs-btn-line-height: 1;
    /* en bloc : un bouton en ligne se place sur la ligne de texte de son formulaire, qui devient plus haut que lui et le décentre */
    display: block;
    /* carré : sans marge sur les côtés non plus (l'icône fait 1em de large) ; !important pour passer devant le px-1 du composant */
    padding-left: 0 !important;
    padding-right: 0 !important;
}
/* Bootstrap Icons descend chaque icône de 0.125em pour l'asseoir sur une ligne de texte : dans un bouton de la hauteur de l'icône,
   elle déborderait vers le bas et paraîtrait décentrée */
.champs-serres .btn .bi::before {
    vertical-align: top;
}
/* Menu déroulant ou champ de date à l'apparence d'un texte ordinaire, à poser avec form-control-plaintext (lignes du tableau des
   listes de tâches) : sans flèche ni icône de calendrier, mais avec son comportement d'origine */
select.champ-nu {
    appearance: none; /* retire la flèche du navigateur */
    cursor: pointer;
}
/* la liste déroulée ne doit pas hériter du texte clair sur fond transparent du champ : couleurs du thème Bootstrap */
select.champ-nu option {
    color: var(--bs-body-color);
    background-color: var(--bs-body-bg);
}
/* l'icône du calendrier, invisible, est étirée sur tout le champ : un clic n'importe où ouvre le calendrier (la saisie au clavier
   reste possible). Navigateurs à moteur Chromium et Safari ; ailleurs, l'icône du navigateur demeure */
input[type="date"].champ-nu {
    position: relative;
    cursor: pointer;
}
input[type="date"].champ-nu::-webkit-calendar-picker-indicator {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    opacity: 0;
    cursor: pointer;
}

@keyframes glisser_bas {
    0% {
        top: -600px;
        opacity: 0;
    }
    100% {
        top: 0;
        opacity: 1;
    }
}
.texte_descendant {
    position: relative;
    animation: glisser_bas 0.4s;
    animation-name: glisser_bas;
    animation-duration: 1s;
    animation-timing-function: ease;
    animation-delay: 0s;
    animation-iteration-count: 1;
    animation-direction: normal;
    animation-fill-mode: none;
    animation-play-state: running;
}
