/********** Template CSS **********/

/* Polices variables auto-hebergees (sous-ensemble latin de Google Fonts, licence
   SIL OFL). Un seul fichier par famille couvre toutes les graisses. */
@font-face {
    font-family: "Rubik";
    font-style: normal;
    font-weight: 300 900;
    font-display: swap;
    src: url(../fonts/rubik-latin.woff2) format("woff2");
}

@font-face {
    font-family: "Nunito";
    font-style: normal;
    font-weight: 200 1000;
    font-display: swap;
    src: url(../fonts/nunito-latin.woff2) format("woff2");
}

/* Palette de marque InfinityCom, relevee sur le logo (static/logo.png, logo1.png).
   --secondary sert aux aplats decoratifs : son contraste avec le blanc n'est que
   de 2,81:1. Pour du texte ou un bouton vert, utiliser --secondary-dark (5,36:1). */
:root {
    --primary: #2B6FB5;        /* bleu du logo - blanc dessus : 5,19:1 (WCAG AA) */
    --primary-light: #8AB0D6;  /* teinte claire - sur banniere sombre : 5,9:1 */
    --secondary: #7FA651;      /* vert du logo - aplats uniquement */
    --secondary-dark: #4F7530; /* vert assombri - blanc dessus : 5,36:1 (WCAG AA) */
    --light: #EFF4FA;
    --dark: #091E3E;
    --darker: #061429;         /* bandeau de pied de page */
    --rayon: .5rem;
    --ombre: 0 10px 30px rgba(9, 30, 62, .12);
}

/* Rayon unique pour tout ce qui est arrondi (cartes, vignettes, champs). */
.rounded {
    border-radius: var(--rayon) !important;
}


/*** Apparition au defilement ***/
/* main.js ne pose .reveal-attente que sur les blocs encore hors de l'ecran : le
   contenu reste visible sans JavaScript, et rien de ce qui s'affiche au
   chargement n'est masque puis reaffiche. */
.reveal {
    transition: opacity .6s ease-out, transform .6s ease-out;
}

.reveal-attente {
    opacity: 0;
    transform: translateY(24px);
}

@media (prefers-reduced-motion: reduce) {
    .reveal {
        transition: none;
    }

    .reveal-attente {
        opacity: 1;
        transform: none;
    }
}

/* Cartes en cascade : main.js donne a chacune un --cascade croissant. Les
   proprietes translate / scale / rotate s'ajoutent au transform des effets 3D
   sans l'ecraser. */
.reveal-attente .carte-3d,
.reveal-attente .team-item {
    opacity: 0;
    translate: 0 40px;
}

.team-item {
    transition: opacity .7s ease-out var(--cascade, 0s), translate .7s cubic-bezier(.2, .8, .2, 1) var(--cascade, 0s);
}

/* L'icone du service eclot une fois sa carte arrivee. */
.reveal-attente .service-item .service-icon {
    scale: 0;
    rotate: -180deg;
}


/*** Titres animes ***/
/* .titre-anime n'est pose que par main.js (hors prefers-reduced-motion) : sans
   lui, les titres s'affichent normalement. */
.titre-anime .mot {
    display: inline-block;
    opacity: 0;
    translate: 0 .5em;
    transition: opacity .5s ease-out, translate .6s cubic-bezier(.2, .8, .2, 1);
    transition-delay: calc(var(--rang) * 60ms + .1s);
}

.titre-anime > p.h5,
.titre-anime > nav {
    opacity: 0;
    transition: opacity .6s ease-out;
}

.titre-anime > nav {
    transition-delay: .4s;
}

.titre-joue .mot {
    opacity: 1;
    translate: 0;
}

.titre-joue > p.h5,
.titre-joue > nav {
    opacity: 1;
}

/* Le trait se trace depuis son point d'ancrage, puis le curseur blanc demarre. */
.section-title-1.titre-anime::before {
    scale: 0 1;
    transform-origin: left;
    transition: scale .8s cubic-bezier(.2, .8, .2, 1) .3s;
}

.section-title-1.text-center.titre-anime::before {
    transform-origin: center;
}

.section-title-1.titre-anime::after {
    opacity: 0;
    transition: opacity .3s 1s;
}

.section-title-1.titre-joue::before {
    scale: 1;
}

.section-title-1.titre-joue::after {
    opacity: 1;
}


/*** Transitions entre pages ***/
/* View Transitions entre documents (Chrome, Edge, Safari 18+) : les autres
   navigateurs changent de page normalement. La navbar reste en place, le
   contenu glisse en fondu, et la vignette d'une realisation se deploie
   jusqu'a l'image de sa page detail (meme view-transition-name). */
@media (prefers-reduced-motion: no-preference) {
    @view-transition {
        navigation: auto;
    }
}

.navbar {
    view-transition-name: navbar;
}

.bg-header h1 {
    view-transition-name: titre-page;
}

::view-transition-old(root) {
    animation: page-sortie .25s ease-in both;
}

::view-transition-new(root) {
    animation: page-entree .45s cubic-bezier(.2, .8, .2, 1) both;
}

::view-transition-group(*) {
    animation-duration: .45s;
    animation-timing-function: cubic-bezier(.2, .8, .2, 1);
}

@keyframes page-sortie {
    to { opacity: 0; translate: 0 -12px; }
}

@keyframes page-entree {
    from { opacity: 0; translate: 0 24px; }
}


/*** Heading ***/
/* p.h5 / li.h5 : sur-titres et listes qui etaient des <h5> ; ils en gardent la graisse. */
h1,
h2,
.fw-bold {
    font-weight: 800 !important;
}

h3,
h4,
.fw-semi-bold {
    font-weight: 700 !important;
}

h5,
h6,
p.h5,
li.h5,
.fw-medium {
    font-weight: 600 !important;
}


/*** Button ***/
.btn {
    font-family: 'Nunito', sans-serif;
    font-weight: 600;
    transition: .3s;
}

.btn-primary {
    color: #FFFFFF;
    box-shadow: inset 0 0 0 50px transparent;
}

.btn-primary:hover {
    box-shadow: inset 0 0 0 0 var(--primary);
}

.btn-square {
    width: 36px;
    height: 36px;
}

.btn-sm-square {
    width: 30px;
    height: 30px;
}

.btn-lg-square {
    width: 48px;
    height: 48px;
}

.btn-square,
.btn-sm-square,
.btn-lg-square {
    padding-left: 0;
    padding-right: 0;
    text-align: center;
}


/*** Navbar ***/
.navbar-light .navbar-nav .nav-link {
    font-family: 'Nunito', sans-serif;
    position: relative;
    margin-left: 25px;
    padding: 35px 0;
    color: #FFFFFF !important;
    font-size: 18px;
    font-weight: 600;
    outline: none;
    transition: .3s;
}

.sticky-top.navbar-light .navbar-nav .nav-link {
    padding: 20px 0;
    color: var(--dark) !important;
}

.navbar-light .navbar-nav .nav-link:hover,
.navbar-light .navbar-nav .nav-link.active {
    /* Navbar transparente, posee sur un visuel sombre : le bleu de marque n'y
       donne que 2,6:1. La teinte claire monte a 5,9:1. La navbar collee, elle,
       est blanche et reprend --primary (voir la regle suivante). */
    color: var(--primary-light) !important;
}

.sticky-top.navbar-light .navbar-nav .nav-link:hover,
.sticky-top.navbar-light .navbar-nav .nav-link.active {
    color: var(--primary) !important;
}

.navbar-light .navbar-brand img {
    max-height: 60px;
    transition: .3s;
}

.sticky-top.navbar-light .navbar-brand img {
    max-height: 45px;
}

@media (max-width: 991.98px) {
    .sticky-top.navbar-light {
        position: relative;
        background: #FFFFFF;
    }

    .navbar-light .navbar-collapse {
        margin-top: 15px;
        border-top: 1px solid #DDDDDD;
    }

    .navbar-light .navbar-nav .nav-link,
    .sticky-top.navbar-light .navbar-nav .nav-link {
        padding: 10px 0;
        margin-left: 0;
        color: var(--dark) !important;
    }

    /* Menu deroule sur fond blanc : on revient au bleu de marque. */
    .navbar-light .navbar-nav .nav-link:hover,
    .navbar-light .navbar-nav .nav-link.active {
        color: var(--primary) !important;
    }

    .navbar-light .navbar-brand img {
        max-height: 45px;
    }
}

@media (min-width: 992px) {
    .navbar-light {
        position: absolute;
        width: 100%;
        top: 0;
        left: 0;
        border-bottom: 1px solid rgba(256, 256, 256, .1);
        z-index: 999;
    }
    
    .sticky-top.navbar-light {
        position: fixed;
        background: #FFFFFF;
    }

    .navbar-light .navbar-nav .nav-link::before {
        position: absolute;
        content: "";
        width: 0;
        height: 2px;
        bottom: -1px;
        left: 50%;
        background: var(--primary);
        transition: .3s;
    }

    .navbar-light .navbar-nav .nav-link:hover::before,
    .navbar-light .navbar-nav .nav-link.active::before {
        width: 100%;
        left: 0;
    }
}


/*** Carousel ***/
/* <picture> est un element inline : sans cela, une diapositive dont l'image est
   enveloppee s'effondre a une hauteur nulle (et emporte sa legende avec elle).
   display:contents rend l'enveloppe totalement transparente a la mise en page,
   l'<img> se comportant exactement comme si <picture> n'existait pas. */
picture {
    display: contents;
}

/* Les diapositives sont en 3:2 : affichees telles quelles, elles occuperaient
   plus qu'un ecran d'ordinateur et trop peu sur mobile pour loger la legende.
   Hauteur bornee, image recadree plutot que deformee. */
.hero-image {
    height: clamp(520px, 85vh, 830px);
    object-fit: cover;
}

/* En portrait (mobile, tablette), seule la moitie de la largeur reste visible :
   on garde la zone ou se trouvent les personnages plutot que le centre. */
.hero-image.cadrage-slide1 {
    object-position: 35% center;
}

.hero-image.cadrage-slide2 {
    object-position: 60% center;
}

/* Sur tablette, le cadre reprend le format 3:2 des photos : image entiere.
   Sur telephone, 4:3 laisse juste assez de hauteur a la legende (~90 % visible). */
@media (max-width: 991.98px) {
    .hero-image {
        height: auto;
        aspect-ratio: 3 / 2;
    }
}

@media (max-width: 575.98px) {
    .hero-image {
        aspect-ratio: 4 / 3;
    }
}

.carousel-caption {
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(9, 30, 62, .7);
    z-index: 1;
}

@media (max-width: 576px) {
    .carousel-caption .h5 {
        font-size: 14px;
        font-weight: 500 !important;
    }

    .carousel-caption h1,
    .carousel-caption h2 {
        font-size: 26px;
        font-weight: 600 !important;
    }
}

/* Scene 3D de l'accueil (hero-3d.js) : le canvas est place dans la legende de
   la diapositive active, entre le voile sombre et le texte. */
.hero-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 1.5s ease;
}

.carousel-caption .legende-hero {
    position: relative;
    z-index: 1;
}

.hero-canvas.visible {
    opacity: .9;
}

.carousel-control-prev,
.carousel-control-next {
    width: 10%;
}

.carousel-control-prev-icon,
.carousel-control-next-icon {
    width: 3rem;
    height: 3rem;
}


/*** Section Title ***/
.section-title-1::before {
    position: absolute;
    content: "";
    width: 150px;
    height: 5px;
    left: 0;
    bottom: 0;
    background: var(--primary);
    border-radius: 2px;
}

.section-title-1.text-center::before {
    left: 50%;
    margin-left: -75px;
}

.section-title-1.section-title-sm::before {
    width: 90px;
    height: 3px;
}

.section-title-1::after {
    position: absolute;
    content: "";
    width: 6px;
    height: 5px;
    bottom: 0px;
    background: #FFFFFF;
    -webkit-animation: section-title-run 5s infinite linear;
    animation: section-title-run 5s infinite linear;
}

.section-title-1.section-title-sm::after {
    width: 4px;
    height: 3px;
}

.section-title-1.text-center::after {
    -webkit-animation: section-title-run-center 5s infinite linear;
    animation: section-title-run-center 5s infinite linear;
}

.section-title-1.section-title-sm::after {
    -webkit-animation: section-title-run-sm 5s infinite linear;
    animation: section-title-run-sm 5s infinite linear;
}

@keyframes section-title-run {
    0% {left: 0; } 50% { left : 145px; } 100% { left: 0; }
}

@keyframes section-title-run-center {
    0% { left: 50%; margin-left: -75px; } 50% { left : 50%; margin-left: 70px; } 100% { left: 50%; margin-left: -75px; }
}

@keyframes section-title-run-sm {
    0% {left: 0; } 50% { left : 85px; } 100% { left: 0; }
}


/*** Service ***/
.service-item {
    position: relative;
    min-height: 300px;
    height: 100%;
    padding: 40px 30px;
    transition: .3s;
}

.service-item:hover {
    --leve: -4px;
    box-shadow: var(--ombre);
}

.service-item .service-icon {
    margin-bottom: 30px;
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--primary);
    border-radius: 2px;
    transform: rotate(-45deg);
}

.service-item .service-icon i {
    transform: rotate(45deg);
}

/* Ecrans tactiles : l'eclosion de l'icone sans l'effet 3D du survol. */
.service-item .service-icon {
    transition: scale .6s cubic-bezier(.34, 1.56, .64, 1) calc(var(--cascade, 0s) + .35s),
        rotate .6s cubic-bezier(.34, 1.56, .64, 1) calc(var(--cascade, 0s) + .35s);
}

/*** Testimonial ***/
/* Defilement horizontal natif : 1 carte en mobile, 2 en tablette, 3 au-dela.
   La largeur des colonnes retranche les gouttieres pour que chaque carte
   tombe pile sur un point d'accroche. */
.defilement-piste {
    --gouttiere: 24px;
    --par-vue: 1;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - (var(--par-vue) - 1) * var(--gouttiere)) / var(--par-vue));
    gap: var(--gouttiere);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}

.defilement-piste::-webkit-scrollbar {
    display: none;
}

.defilement-piste:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 4px;
}

@media (min-width: 768px) {
    .defilement-piste {
        --par-vue: 2;
    }
}

@media (min-width: 992px) {
    .defilement-piste {
        --par-vue: 3;
    }
}

.defilement-element {
    scroll-snap-align: start;
}

.defilement-element .testimonial-item {
    height: calc(100% - 3rem);
}

.defilement-nav {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 15px;
}


/*** Team ***/
.team-item {
    transition: .3s;
}

.team-social {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: .3s;
}

.team-social a.btn {
    position: relative;
    margin: 0 3px;
    margin-top: 100px;
    opacity: 0;
}

.team-item:hover {
    box-shadow: 0 0 30px #DDDDDD;
}

.team-item:hover .team-social {
    background: rgba(9, 30, 62, .7);
}

.team-item:hover .team-social a.btn:first-child {
    opacity: 1;
    margin-top: 0;
    transition: .3s 0s;
}

.team-item:hover .team-social a.btn:nth-child(2) {
    opacity: 1;
    margin-top: 0;
    transition: .3s .05s;
}

.team-item:hover .team-social a.btn:nth-child(3) {
    opacity: 1;
    margin-top: 0;
    transition: .3s .1s;
}

.team-item:hover .team-social a.btn:nth-child(4) {
    opacity: 1;
    margin-top: 0;
    transition: .3s .15s;
}

.team-item .team-img img {
    transition: .3s;
}

.team-item:hover .team-img img {
    transform: scale(1.15);
}


/*** Project Portfolio ***/
.portfolio-item {
    margin-bottom: 60px;
}

.portfolio-img img {
    /* Reserve la place avant chargement (evite le decalage de mise en page)
       et uniformise une grille alimentee par des photos de formats varies. */
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    transition: .3s;
}

.portfolio-item:hover .portfolio-img img {
    transform: scale(1.2);
}

.portfolio-title {
    position: absolute;
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 120px;
    padding: 0 30px;
    right: 30px;
    left: 30px;
    bottom: -60px;
    background: #FFFFFF;
    box-shadow: 0 0 30px rgba(0, 0, 0, .1);
    transition: .3s;
    z-index: 3;
}

.portfolio-item:hover .portfolio-title {
    bottom: -45px;
}

.portfolio-btn {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: .3s;
    z-index: 2;
    opacity: 0;
}

.portfolio-item:hover .portfolio-btn {
    opacity: 1;
}

.portfolio-btn a {
    transition: .3s;
}

.portfolio-item:hover .portfolio-btn a {
    margin-top: -60px;
}

.portfolio-box::after {
    position: absolute;
    content: "";
    width: 100%;
    height: 0;
    left: 0;
    bottom: 0;
    border-radius: 2px;
    background: rgba(9, 30, 62, .7);
    transition: .3s;
    z-index: 1;
}

.portfolio-item:hover .portfolio-box::after {
    height: 100%;
}

/* Galerie de la fiche projet (carrousel Bootstrap) et visionneuse. */
.galerie-projet img {
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

.galerie-nav {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 30px;
}

.visionneuse .modal-content {
    box-shadow: none;
}

.visionneuse-image {
    max-height: 85vh;
}

.visionneuse-fermer {
    position: absolute;
    top: -2.5rem;
    right: 0;
    opacity: 1;
}

.visionneuse-precedent,
.visionneuse-suivant {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

.visionneuse-precedent {
    left: 10px;
}

.visionneuse-suivant {
    right: 10px;
}


/*** Work Process ***/
.process-icon {
    width: 75px;
    height: 75px;
}

.process-item .position-relative::after {
    position: absolute;
    content: "\f101";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 50px;
    color: #DDDDDD;
    top: 0;
    right: -45px;
    -webkit-animation: process-item-icon 3s infinite linear;
    animation: process-item-icon 3s infinite linear;
}

@keyframes process-item-icon {
    0% {right: -30px; } 50% { right: -45px; } 100% { right: -30px; }
}

.process-item:last-child .position-relative::after {
    display: none;
}

@media (max-width: 992px) {
    .process-item:nth-child(2) .position-relative::after {
        display: none;
    }
}

@media (max-width: 768px) {
    .process-item .position-relative::after {
        display: none;
    }
}


/*** Accessibilite ***/
/* Focus clavier visible et aux couleurs de marque (le contour par defaut
   disparait sur les boutons bleus). */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--primary-light);
    outline-offset: 2px;
    box-shadow: none;
}

.lien-evitement:focus {
    position: fixed;
    top: 10px;
    left: 10px;
    z-index: 100000;
    padding: .75rem 1.25rem;
    color: #FFFFFF;
    background: var(--dark);
    border-radius: var(--rayon);
}

main:focus {
    outline: none;
}

/* Ecrans tactiles et clavier : les actions reservees au survol (agrandir une
   image, reseaux sociaux d'un membre) restent accessibles. */
@media (hover: none) {
    .portfolio-btn,
    .team-social a.btn {
        opacity: 1;
    }

    .portfolio-btn {
        align-items: flex-start;
        justify-content: flex-end;
        padding: 12px;
    }

    .portfolio-btn .display-1 {
        font-size: 1.5rem;
        padding: 12px;
        background: rgba(9, 30, 62, .7);
        border-radius: 50%;
    }

    .team-social {
        align-items: flex-end;
        padding-bottom: 15px;
    }

    .team-social a.btn {
        margin-top: 0;
    }

    .btn-square,
    .btn-sm-square {
        width: 44px;
        height: 44px;
    }
}

.portfolio-item:focus-within .portfolio-btn,
.team-item:focus-within .team-social a.btn {
    opacity: 1;
    margin-top: 0;
}

.team-item:focus-within .team-social {
    background: rgba(9, 30, 62, .7);
}


/*** Forfaits ***/
.forfait-vedette {
    z-index: 1;
    outline: 2px solid var(--primary);
}

.forfait-badge {
    position: absolute;
    top: 1.25rem;
    right: 1.25rem;
    padding: .45em .8em;
    font-family: 'Nunito', sans-serif;
    letter-spacing: .03em;
    text-transform: uppercase;
}

@media (min-width: 992px) {
    .forfait-vedette.carte-3d {
        --echelle: 1.03;
    }
}


/*** Effets 3D ***/
/* main.js fait suivre le pointeur a --rx / --ry (inclinaison) et --mx / --my
   (reflet), uniquement avec une souris et hors prefers-reduced-motion. Sans
   JS, les cartes restent a plat : seules les variables par defaut s'appliquent. */
.carte-3d {
    --rx: 0deg;
    --ry: 0deg;
    --leve: 0px;
    --echelle: 1;
    transform: perspective(1000px) translateY(var(--leve)) rotateX(var(--rx)) rotateY(var(--ry)) scale(var(--echelle));
    transform-style: preserve-3d;
    transition: transform .5s cubic-bezier(.2, .8, .2, 1), box-shadow .3s,
        opacity .7s ease-out var(--cascade, 0s), translate .7s cubic-bezier(.2, .8, .2, 1) var(--cascade, 0s);
}

/* Pendant le survol, l'inclinaison suit le pointeur sans retard. */
.carte-3d.carte-active {
    transition: transform .12s linear, box-shadow .3s;
}

.carte-3d::before {
    position: absolute;
    inset: 0;
    content: "";
    border-radius: inherit;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, .35), transparent 55%);
    opacity: 0;
    pointer-events: none;
    transition: opacity .3s;
    z-index: 4;
}

.carte-3d.carte-active::before {
    opacity: 1;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    /* Les elements en avant-plan se detachent de la carte inclinee. */
    .service-item.carte-3d .service-icon,
    .service-item.carte-3d h3,
    .forfait.carte-3d .h2,
    .forfait.carte-3d .btn,
    .portfolio-box.carte-3d .portfolio-title {
        transition: transform .5s cubic-bezier(.2, .8, .2, 1), bottom .3s;
    }

    .service-item.carte-3d:hover h3,
    .forfait.carte-3d:hover .h2,
    .forfait.carte-3d:hover .btn {
        transform: translateZ(30px);
    }

    .portfolio-box.carte-3d:hover .portfolio-title {
        transform: translateZ(50px);
    }

    /* Le losange de l'icone fait un tour complet sur lui-meme. */
    .service-item.carte-3d .service-icon {
        transition: transform .8s cubic-bezier(.2, .8, .2, 1),
            scale .6s cubic-bezier(.34, 1.56, .64, 1) calc(var(--cascade, 0s) + .35s),
            rotate .6s cubic-bezier(.34, 1.56, .64, 1) calc(var(--cascade, 0s) + .35s);
    }

    .service-item.carte-3d:hover .service-icon {
        transform: translateZ(50px) rotateY(360deg) rotate(-45deg);
    }
}

/* Legende du carrousel d'accueil : legere rotation qui suit la souris. */
.hero-3d {
    transform: perspective(1200px) rotateX(var(--hero-rx, 0deg)) rotateY(var(--hero-ry, 0deg));
    transition: transform .6s cubic-bezier(.2, .8, .2, 1);
}

@media (prefers-reduced-motion: reduce) {
    .carte-3d,
    .hero-3d {
        transform: none;
    }

    .forfait-vedette {
        transform: scale(var(--echelle));
    }
}


/*** Miscellaneous ***/
/* Classes utilitaires : remplacent les styles en ligne repetes dans les templates. */
.titre-section {
    max-width: 600px;
}

.legende-hero {
    max-width: 900px;
}

.icone-carree {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
}

.icone-carree-sm {
    width: 45px;
    height: 45px;
}

/* Absente de Bootstrap 5.0 (arrivee en 5.3). */
.object-fit-cover {
    object-fit: cover;
}

.photo-apropos {
    min-height: 500px;
}

.photo-membre {
    height: 450px;
    object-fit: cover;
}

.photo-temoin {
    width: 60px;
    height: 60px;
    object-fit: cover;
}

.prix-periode {
    font-size: 16px;
    line-height: 40px;
}

.back-to-top {
    position: fixed;
    display: flex;
    align-items: center;
    justify-content: center;
    right: 45px;
    bottom: 45px;
    z-index: 99;
    opacity: 0;
    visibility: hidden;
    transition: opacity .3s, visibility 0s linear .3s;
}

.back-to-top.visible {
    opacity: 1;
    visibility: visible;
    transition: opacity .3s;
}

/* Bouton WhatsApp flottant. A gauche, pour ne pas recouvrir le retour en haut,
   qui occupe le coin droit. Vert de marque WhatsApp, non modifiable. */
.bouton-whatsapp {
    position: fixed;
    left: 25px;
    bottom: 25px;
    z-index: 99;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: #25D366;
    color: #FFFFFF;
    font-size: 30px;
    box-shadow: 0 4px 14px rgba(9, 30, 62, .3);
    transition: .3s;
}

.bouton-whatsapp:hover,
.bouton-whatsapp:focus {
    background: #1DA851;
    color: #FFFFFF;
    transform: scale(1.08);
}

@media (max-width: 575.98px) {
    .bouton-whatsapp {
        left: 16px;
        bottom: 16px;
        width: 48px;
        height: 48px;
        font-size: 26px;
    }
}

/* Banniere de tete des pages interieures (partial _banniere.html).
   Deux declarations : la premiere sert de repli, la seconde prend le dessus
   sur les navigateurs qui gerent image-set() et sert alors le WebP. */
.bg-header {
    margin-bottom: 90px;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    background-image: linear-gradient(rgba(9, 30, 62, .7), rgba(9, 30, 62, .7)),
                      url(../img-opt/banniere.jpg);
    background-image: linear-gradient(rgba(9, 30, 62, .7), rgba(9, 30, 62, .7)),
                      image-set(url(../img-opt/banniere.webp) type("image/webp"),
                                url(../img-opt/banniere.jpg) type("image/jpeg"));
}

/* Sur mobile, la variante 768 px suffit (32 Ko au lieu de 127). */
@media (max-width: 767.98px) {
    .bg-header {
        background-image: linear-gradient(rgba(9, 30, 62, .7), rgba(9, 30, 62, .7)),
                          image-set(url(../img-opt/banniere-768.webp) type("image/webp"),
                                    url(../img-opt/banniere.jpg) type("image/jpeg"));
    }
}

.bg-copyright {
    background: var(--darker);
}

@media (max-width: 575.98px) {
    .bg-copyright {
        padding-bottom: 64px;
    }
}

.navbar-brand img {
    width: auto;
}

.link-animated a {
    transition: .3s;
}

.link-animated a:hover {
    padding-left: 10px;
}

/* Champ leurre anti-robots : hors de l'ecran, mais present dans le DOM et
   accessible aux lecteurs d'ecran (qui liront son libelle « laisser vide »). */
.champ-leurre {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Formulaires poses sur un aplat de marque (devis, commande, contact).
   Sans cela, les libelles heritent de la couleur du corps de texte (#6B6A75),
   soit 1,03:1 sur le bleu : illisibles. Les champs eux-memes restent blancs
   avec un texte sombre, donc rien a y changer. */
.bg-primary .form-label,
.bg-primary .form-check-label,
.bg-primary legend,
.bg-primary .asteriskField {
    color: #FFFFFF;
}

/* Legerement attenue pour la hierarchie, mais pas au point de passer
   sous le seuil AA : .85 donnait 3,88:1, .92 donne 4,67:1. */
.bg-primary .form-text {
    color: rgba(255, 255, 255, .92);
}

/* Le rouge d'erreur de Bootstrap (#dc3545) tombe a 1,15:1 sur ce bleu. L'eclaircir
   assez pour atteindre le seuil AA le rendrait presque blanc, donc indistinguable
   des libelles : on pose plutot le message sur une pastille claire, ou le rouge
   sombre ressort a 7,7:1 et se lit sans ambiguite comme une erreur. */
.bg-primary .invalid-feedback,
.bg-primary .errorlist {
    color: #8A1C1C;
    background: #FFE3E3;
    border-radius: 2px;
    padding: .35rem .6rem;
    margin-top: .35rem;
}

.bg-primary .errorlist {
    list-style: none;
    margin-bottom: .75rem;
}

.bg-primary .errorlist li {
    color: inherit;
}

@media (min-width: 767.98px) {
    .footer-about {
        margin-bottom: -75px;
    }
}

.footer-logo {
    width: 100%;
    max-width: 260px;
    height: auto;
}
