/* =====================================================================
   Resaskill - Barre de reservation collante
   Portage de la maquette validee le 23/09/2026
   (C:\Users\milov\Desktop\maquette-barre-reservation.html).

   TROIS CHOSES A SAVOIR AVANT D'Y TOUCHER
   ---------------------------------------
   1. La barre est DEPLACEE SUR <body> par le JS. Un `position: fixed`
      place dans un widget Elementor se recale sur le premier ancetre
      porteur d'un transform / filter / will-change - et Elementor en
      pose un des qu'une animation d'entree est activee. La barre se
      retrouverait alors coincee dans la colonne au lieu de longer le
      bas de l'ecran.
   2. Consequence de (1) : la barre ne vit plus sous la racine du
      widget, donc TOUT var(--rsk-br-*) porte une VALEUR DE REPLI. Le JS
      recopie bien les tokens sur la barre, mais un token oublie sans
      repli rendrait le bouton transparent - texte blanc sur fond blanc,
      parcours mort, aucune erreur. Lecon payee deux fois (2.4.96,
      2.4.197).
   3. Ici les paliers @media sont LEGITIMES : la barre occupe toute la
      largeur de la fenetre, pas une colonne. C'est le seul cas de nos
      composants ou la fenetre est bien la bonne unite de mesure.
   ===================================================================== */

/* Hote laisse DANS LE FLUX : il porte les tokens et sert de repere au
   JS. Il ne contient qu'un element en `position: fixed`, donc il ne
   prend aucune hauteur.
   Surtout, il n'est PAS en `display:none` : sans JS la barre doit
   rester visible et cliquable (contrat ws-fx-js). Un hote masque
   rendrait le JS obligatoire pour voir quoi que ce soit. */
.rsk-br-hote { margin: 0; padding: 0; line-height: 0; }

/* box-sizing pose SUR TOUT ce que contient la barre, jamais herite du
   theme du site. Sans lui, le bouton mobile en `width:100%` ajoute ses
   36 px de remplissage par-dessus les 100 % : mesure a 390 px de large,
   bouton de 394 px dans un conteneur de 358 - il deborde d'une barre en
   `overflow` implicite, donc il se fait trancher sans un mot.
   Notre CSS public doit tenir seul. */
.rsk-br,
.rsk-br *,
.rsk-br *::before,
.rsk-br *::after { box-sizing: border-box; }

.rsk-br {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9998;
  background: var(--rsk-br-surface, #FFFFFF);
  border-top: 1px solid var(--rsk-br-line, #E4E8EF);
  box-shadow: 0 -6px 28px rgba(9, 20, 40, .10);
  padding: 10px max(16px, env(safe-area-inset-left))
           calc(10px + env(safe-area-inset-bottom))
           max(16px, env(safe-area-inset-right));
  box-sizing: border-box;

  /* Etat visible PAR DEFAUT. L'etat cache n'existe que si le JS l'a
     pose (.rsk-br-js) - contrat ws-fx-js du socle. Une barre invisible
     a vie serait bien pire qu'une barre toujours affichee. */
  transform: translateY(0);
  opacity: 1;
  transition: transform .26s cubic-bezier(.22, .78, .3, 1), opacity .2s ease;
}

/* Variante « en haut de page » : meme barre, ancrage inverse. */
.rsk-br.est-haut {
  bottom: auto;
  top: 0;
  border-top: 0;
  border-bottom: 1px solid var(--rsk-br-line, #E4E8EF);
  box-shadow: 0 6px 28px rgba(9, 20, 40, .10);
  padding: calc(10px + env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
           10px max(16px, env(safe-area-inset-left));
}

.rsk-br.rsk-br-js { transform: translateY(110%); opacity: 0; pointer-events: none; }
.rsk-br.rsk-br-js.est-haut { transform: translateY(-110%); }
.rsk-br.rsk-br-js.est-visible { transform: translateY(0); opacity: 1; pointer-events: auto; }

/* Disposition en FLEX et non en grille, volontairement : la photo, le
   prix et la ligne de detail sont chacun desactivables par reglage. Une
   grille a pistes nommees aurait demande des cellules fantomes pour ne
   pas se decaler - et sur mobile, ou la grille n'a que deux pistes, une
   cellule fantome poussait le bouton hors de sa rangee. Le flex se
   referme tout seul sur les elements presents. */
.rsk-br-inner {
  max-width: var(--rsk-br-max, 1120px);
  margin: 0 auto;
  min-height: var(--rsk-br-h, 56px);
  display: flex;
  align-items: center;
  gap: 14px;
}

.rsk-br-photo {
  width: 48px;
  height: 48px;
  border-radius: 10px;
  overflow: hidden;
  background: #DCE3EC;
  flex: none;
}
.rsk-br-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Le seul element elastique de la barre : tout le reste garde sa taille,
   c'est le bloc de texte qui absorbe la place restante et tronque. */
.rsk-br-infos { flex: 1 1 auto; min-width: 0; }

.rsk-br-nom {
  font-family: 'Bricolage Grotesque', Georgia, serif;
  font-size: 17px;
  font-weight: 800;
  color: var(--rsk-br-ink, #12336B);
  line-height: 1.2;
  margin: 0 0 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rsk-br-meta {
  font-size: 12.5px;
  color: var(--rsk-br-muted, #6B7A93);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* =====================================================================
   LE MESSAGE (2.4.233)
   ---------------------------------------------------------------------
   Une ligne AU-DESSUS de la rangee, dans la barre : la meme annonce que
   le bandeau du formulaire (promotion, facilite de paiement, information
   pratique...). Statique : tronquee proprement. Defilante : le texte est
   double, et chaque copie porte son espace de queue, de sorte que le
   decalage de -50 % tombe PILE sur le raccord (avec un `gap` il manquait
   la moitie de l'ecart).
   Sans texte, la ligne n'existe pas : la barre garde sa hauteur d'origine.
   Tous les var() portent une valeur de repli : la barre vit sur <body>.
   ===================================================================== */
.rsk-br-msg {
  /* 2.4.247 : la ligne prend la largeur de SON TEXTE (plafonnee), alignee sur
     le bord gauche du contenu de la barre. « Toute la largeur » reste un
     reglage (classe .msg-pleine). */
  width: fit-content;
  max-width: min(100%, var(--rsk-br-msg-max, var(--rsk-br-max, 1120px)));
  margin: 0 auto 8px max(0px, calc((100% - var(--rsk-br-max, 1120px)) / 2));
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: min(var(--rsk-br-r, 10px), 12px);
  background: #F5EFE2;
  background: var(--rsk-br-msg-bg, color-mix(in srgb, var(--rsk-br-accent, #B28E4B) 14%, #FFFFFF));
  color: var(--rsk-br-msg-fg, var(--rsk-br-ink, #12336B));
  font-family: 'Hanken Grotesk', system-ui, sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: normal;
  text-transform: none;
  overflow: hidden;
}
.rsk-br-msg[hidden] { display: none; }
.rsk-br.msg-centre .rsk-br-msg { margin-left: auto; margin-right: auto; }
.rsk-br.msg-droite .rsk-br-msg { margin-left: auto; margin-right: max(0px, calc((100% - var(--rsk-br-max, 1120px)) / 2)); }
.rsk-br.msg-pleine .rsk-br-msg { width: auto; max-width: var(--rsk-br-max, 1120px); margin-left: auto; margin-right: auto; }
/* Un theme qui met `div { text-transform: uppercase }` ou un espacement de
   lettres sur les blocs ne doit pas atteindre le texte : on le neutralise
   sur tout ce que contient la ligne. */
.rsk-br-msg * { text-transform: none; letter-spacing: normal; }
.rsk-br-msg-ico { flex: none; display: inline-flex; line-height: 0; opacity: .85; }
.rsk-br-msg-txt { flex: 1 1 auto; min-width: 0; overflow: hidden; }

/* Statique : une ligne, tronquee si elle ne tient pas. */
.rsk-br-msg-run { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Defilant. */
.rsk-br-msg[data-mode="defile"] .rsk-br-msg-run {
  display: flex;
  width: max-content;
  overflow: visible;
  text-overflow: clip;
  animation: rsk-br-defile var(--rsk-br-msg-vitesse, 18s) linear infinite;
}
.rsk-br-msg[data-mode="defile"] .rsk-br-msg-run > span { flex: none; padding-right: 60px; }
.rsk-br-msg[data-mode="defile"]:hover .rsk-br-msg-run { animation-play-state: paused; }
@keyframes rsk-br-defile { from { transform: translateX(0); } to { transform: translateX(-50%); } }

@media (max-width: 560px) {
  .rsk-br-msg { margin-bottom: 6px; padding: 5px 10px; font-size: 12px; }
}

/* Mouvement reduit : pas de defilement, le texte reste lisible (tronque). */
@media (prefers-reduced-motion: reduce) {
  .rsk-br-msg[data-mode="defile"] .rsk-br-msg-run {
    display: block; width: auto; overflow: hidden; text-overflow: ellipsis; animation: none;
  }
  .rsk-br-msg[data-mode="defile"] .rsk-br-msg-run > span { padding-right: 0; }
  .rsk-br-msg-run > span + span { display: none; }
}

/* =====================================================================
   PLUSIEURS PRESTATIONS : le rail de choix
   ---------------------------------------------------------------------
   Un rail qui DEFILE horizontalement, jamais une pile qui grandit : la
   hauteur de la barre ne doit dependre ni du nombre de prestations, ni
   de la variante choisie. Trois prestations ou onze, 77 px.
   ===================================================================== */
.rsk-br-rail { position: relative; flex: 1 1 auto; min-width: 0; }

.rsk-br-choix {
  display: flex;
  align-items: center;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  padding: 2px 0;
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* anciens Edge */
}
.rsk-br-choix::-webkit-scrollbar { display: none; }

/* Voile au bord droit : il dit « ca continue » sans barre de defilement
   visible. Pose par le JS, et SEULEMENT si le rail deborde vraiment -
   un voile permanent laisserait croire a un contenu cache qui n'existe
   pas. Il se fond dans le fond de la barre, reglable. */
.rsk-br-rail.deborde::after {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 28px;
  pointer-events: none;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), var(--rsk-br-surface, #FFFFFF));
}

/* ── Variante « pastille » : vignette + nom + prix ── */
.rsk-br-chip {
  flex: none;
  scroll-snap-align: start;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  max-width: 230px;
  padding: 6px 12px 6px 6px;
  border: 1px solid var(--rsk-br-line, #E4E8EF);
  border-radius: 12px;
  background: #FFFFFF;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.rsk-br-chip:hover { border-color: #C8CFDC; }
.rsk-br-chip:focus-visible { outline: 2px solid var(--rsk-br-ink, #12336B); outline-offset: 2px; }

.rsk-br-chip-vig {
  width: 34px; height: 34px;
  border-radius: 8px;
  overflow: hidden;
  background: #DCE3EC;
  flex: none;
}
.rsk-br-chip-vig img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* `display: block` sur les deux lignes, et ce n'est pas cosmetique : un
   <span> reste INLINE, donc le nom et le prix se suivaient sur la meme
   ligne et se chevauchaient (« Seance de suivi55,00 € »). Rien n'etait
   casse, c'etait juste illisible. Mesure le 24/09/2026. */
.rsk-br-chip-txt { display: block; min-width: 0; }
.rsk-br-chip-nom {
  display: block;
  font-size: 13.5px; font-weight: 700;
  color: var(--rsk-br-ink, #12336B);
  line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rsk-br-chip-prix {
  display: block;
  font-size: 12px;
  color: var(--rsk-br-muted, #6B7A93);
  line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* L'etat retenu se voit par la BORDURE et un fond tres pale, jamais par
   un aplat de couleur : le nom doit rester lisible quelle que soit la
   teinte d'accent choisie par le site. */
.rsk-br-chip[aria-pressed="true"] {
  border-color: var(--rsk-br-accent, #B28E4B);
  box-shadow: inset 0 0 0 1px var(--rsk-br-accent, #B28E4B);
  background: color-mix(in srgb, var(--rsk-br-accent, #B28E4B) 7%, #FFFFFF);
}
@supports not (background: color-mix(in srgb, red 5%, white)) {
  .rsk-br-chip[aria-pressed="true"] { background: #FAF7F1; }
}
.rsk-br-chip[aria-pressed="true"] .rsk-br-chip-prix {
  color: var(--rsk-br-ink, #12336B);
  font-weight: 600;
}

/* ── Variante « carre » : photo + prix incruste ──
   52 et non 56 : avec les 2 px de respiration du rail, un carre de 56
   poussait la barre a 81 px alors que la barre a une seule prestation
   en fait 77. */
.rsk-br-carre {
  flex: none;
  scroll-snap-align: start;
  position: relative;
  width: 52px; height: 52px;
  padding: 0;
  border: 1px solid var(--rsk-br-line, #E4E8EF);
  border-radius: 12px;
  overflow: hidden;
  background: #DCE3EC;
  cursor: pointer;
  transition: border-color .15s ease, transform .1s ease;
}
.rsk-br-carre img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rsk-br-carre-prix {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: rgba(9, 20, 40, .62);
  color: #FFFFFF;
  font-size: 10.5px; font-weight: 700; line-height: 1;
  padding: 3px 0;
  text-align: center;
}
.rsk-br-carre[aria-pressed="true"] {
  border-color: var(--rsk-br-accent, #B28E4B);
  box-shadow: 0 0 0 2px var(--rsk-br-accent, #B28E4B);
}
.rsk-br-carre:focus-visible { outline: 2px solid var(--rsk-br-ink, #12336B); outline-offset: 3px; }

/* Le carre ne porte pas le nom : il est rappele a gauche du rail, sinon
   on choisit a l'aveugle entre des photos qui se ressemblent. */
.rsk-br-carre-nom {
  flex: none;
  max-width: 190px;
  padding-right: 4px;
  font-family: 'Bricolage Grotesque', Georgia, serif;
  font-size: 15px; font-weight: 800;
  color: var(--rsk-br-ink, #12336B);
  line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.rsk-br-prix { flex: none; text-align: right; white-space: nowrap; padding-right: 4px; }
.rsk-br-prix b {
  display: block;
  font-size: 21px;
  font-weight: 800;
  color: var(--rsk-br-ink, #12336B);
  line-height: 1;
}
.rsk-br-prix span { font-size: 11.5px; color: var(--rsk-br-muted, #6B7A93); }

/* Colonne du bouton en `auto` : le libelle est configurable, une largeur
   fixe finit toujours par le tronquer (piege paye en 2.4.182). */
.rsk-br-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 24px;
  border: none;
  border-radius: var(--rsk-br-r, 11px);
  background: var(--rsk-br-accent, #B28E4B);
  color: var(--rsk-br-btn-fg, #FFFFFF);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: filter .15s ease, transform .1s ease;
}
.rsk-br-btn:hover  { filter: brightness(1.07); color: var(--rsk-br-btn-fg, #FFFFFF); }
.rsk-br-btn:active { transform: scale(.98); }
.rsk-br-btn:focus-visible { outline: 2px solid var(--rsk-br-ink, #12336B); outline-offset: 3px; }

/* ── Tablette : on resserre, on garde tout ── */
@media (max-width: 900px) {
  .rsk-br-inner { min-height: var(--rsk-br-h-t, 52px); }
  .rsk-br-nom { font-size: 16px; }
  .rsk-br-btn { padding: 13px 20px; font-size: 14.5px; }
  .rsk-br-chip { max-width: 190px; }
  .rsk-br-carre-nom { max-width: 150px; font-size: 14px; }
}

/* ── Mobile : la photo sort, le bouton prend toute la largeur ──
   Sur 360 px ce qui compte est le PRIX et le BOUTON. La photo est
   decorative : elle cede la premiere, jamais le bouton.
   Deux rangees assumees (nom + prix, puis bouton) : 328 px de bouton
   sous le pouce valent mieux qu'une rangee unique ou il tombe a 120 px.
   `flex: 1 0 100%` sur le bouton est ce qui le fait passer a la ligne
   ET occuper toute la largeur : sans la base a 100 %, il resterait
   coince a cote du prix. */
@media (max-width: 560px) {
  .rsk-br-inner {
    min-height: var(--rsk-br-h-m, 44px);
    flex-wrap: wrap;
    gap: 8px 10px;
  }
  .rsk-br-photo { display: none; }
  .rsk-br-prix { text-align: right; padding: 0; }
  .rsk-br-prix b { font-size: 19px; }
  .rsk-br-prix span { display: none; }
  .rsk-br-nom { font-size: 15px; margin-bottom: 1px; }
  /* La ligne de detail sort : sur deux rangees elle coutait 16 px de
     hauteur (105 px de barre au lieu de 89) pour une information deja
     lue dans la page. */
  .rsk-br-meta { display: none; }
  .rsk-br-btn { flex: 1 0 100%; width: 100%; padding: 13px 18px; font-size: 15px; }

  /* Avec un rail de choix, la barre tient sur DEUX rangees, jamais
     trois : rangee 1 = le rail (il defile), rangee 2 = prix + bouton.
     `flex: 1 0 100%` donne la rangee entiere au rail. */
  .rsk-br-rail { flex: 1 0 100%; }
  /* Classe posee par le PHP, pas un `:has()` : Firefox ne l'a supporte
     qu'a partir de la 121 et Safari de la 15.4. Une regle qui ne
     s'applique pas chez une partie des visiteurs est pire qu'une
     classe explicite. */
  .rsk-br.a-choix .rsk-br-btn { flex: 1 1 auto; width: auto; }
  /* Chaque pixel du rail est un pixel pris a la page : on resserre le
     choix, jamais le bouton. Mesure : 121 px de barre avant, 116 apres. */
  .rsk-br-chip { max-width: 190px; padding: 5px 10px 5px 5px; gap: 8px; }
  .rsk-br-chip-vig { width: 30px; height: 30px; border-radius: 7px; }
  .rsk-br-chip-nom { font-size: 13px; }
  .rsk-br-chip-prix { font-size: 11.5px; }
  .rsk-br-carre { width: 46px; height: 46px; }
  .rsk-br-carre-prix { font-size: 9.5px; padding: 2px 0; }
  .rsk-br-carre-nom { display: none; }
}

/* Masquage par palier (reglages « Afficher sur ... »). Le selecteur
   porte la classe sur la barre elle-meme, qui vit sur <body>. */
@media (min-width: 1025px) { .rsk-br.sans-ordinateur { display: none; } }
@media (min-width: 561px) and (max-width: 1024px) { .rsk-br.sans-tablette { display: none; } }
@media (max-width: 560px) { .rsk-br.sans-mobile { display: none; } }

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

/* =====================================================================
   LA FENETRE — le tunnel de reservation ouvert sur place
   ---------------------------------------------------------------------
   Meme precaution que la barre : elle vit sur <body> (le JS l'y deplace),
   donc chaque var(--rsk-br-*) porte une valeur de repli.
   ===================================================================== */
.rsk-br-modale[hidden] { display: none; }

.rsk-br-modale {
  position: fixed;
  inset: 0;
  z-index: 9999;            /* au-dessus de la barre (9998) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
  box-sizing: border-box;
}

.rsk-br-voile {
  position: absolute;
  inset: 0;
  background: rgba(9, 20, 40, .55);
  /* Pas de fermeture au clic : voir la croix ci-dessous. */
}

.rsk-br-fenetre {
  position: relative;
  width: min(980px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--rsk-br-surface, #FFFFFF);
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(9, 20, 40, .28);
  overflow: hidden;
  box-sizing: border-box;
}

/* 🔴 EXACTEMENT UN enfant en `flex:1 1 auto; overflow-y:auto` dans une
   colonne flex a hauteur bornee. Ici c'est le corps ; la croix est en
   position absolue, elle ne compte pas dans la colonne. Sans cela, le
   tunnel deborde d'un conteneur en `overflow:hidden` et son bouton de
   validation devient inatteignable, sans barre de defilement pour s'en
   sortir (piege paye en 2.4.196). */
.rsk-br-corps {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.rsk-br-croix {
  position: absolute;
  top: 10px; right: 12px;
  z-index: 2;
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: 1px solid var(--rsk-br-line, #E4E8EF);
  border-radius: 50%;
  background: var(--rsk-br-surface, #FFFFFF);
  color: var(--rsk-br-ink, #12336B);
  font-size: 22px; line-height: 1;
  cursor: pointer;
  padding: 0;
}
.rsk-br-croix:hover { background: #F1F5F9; }
.rsk-br-croix:focus-visible { outline: 2px solid var(--rsk-br-ink, #12336B); outline-offset: 2px; }

/* La page derriere ne defile plus tant que la fenetre est ouverte. */
html.rsk-br-fige, html.rsk-br-fige body { overflow: hidden; }

/* Note reservee aux administrateurs (reglage manquant). Elle reste dans
   le flux de la page, pas dans la barre. */
.rsk-br-note {
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid #F0C36D;
  background: #FFF8E6;
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
  color: #6B5316;
}
