/* ==========================================================================
   Escales du Monde — services
   Feuille de style globale : tokens, reset, header, footer, accueil.

   Palette issue de la charte : bleu #0055DD dominant, marine #091E31,
   or #BDA577 en accent DÉCORATIF uniquement (contraste 2.4:1 sur blanc —
   jamais utilisé pour du texte).
   ========================================================================== */

:root {
  /* Couleurs de marque */
  --blue:        #0055dd;
  --blue-deep:   #0026a0;
  --blue-soft:   #e8f0ff;
  --blue-tint:   #f2f6ff;
  --navy:        #091e31;
  --navy-soft:   #122539;

  /* Accent rouge saumon — réservé au badge « Meilleur prix » / « Promo »
     (voir « badges » dans js/catalog.js), jamais utilisé comme couleur de
     marque courante ni sur le prix lui-même, qui reste dans le bleu de
     marque : le badge suffit à signaler l'offre. Texte blanc dessus par
     choix du client, malgré un contraste mesuré (≈ 2,8:1, sous les 4,5:1
     recommandés par WCAG AA) — accepté sciemment pour ce badge court et
     décoratif, où ce n'est pas un texte essentiel à la compréhension.      */
  --salmon: #ff6b5b;

  /* Violet « événement » — HORS CHARTE, ajouté à la demande du client pour
     le badge des offres bâties autour d'un événement daté (Canton Fair…).
     Les quatre couleurs de marque étaient déjà prises : bleu = « Combiné »,
     marine = « Bientôt disponible », saumon = « Meilleur prix » et
     « Places limitées », vert = WhatsApp.

     Ce violet a été retenu parce qu'il tient le blanc : contraste 7,1:1,
     bien au-delà des 4,5:1 exigés — c'est ce que l'or de la charte ne
     permettait pas (2,4:1 en texte, et seulement 7,2:1 à condition d'y
     poser du marine, refusé par le client). Il reste voisin du bleu sur la
     roue chromatique, donc il tranche sans jurer avec le reste du site.    */
  --event: #6d28d9;

  /* Neutres */
  --bg:          #f5f7fb;
  --surface:     #ffffff;
  --border:      #e2e8f2;
  --border-soft: #eef2f8;
  --text:        #0b1a2b;
  --text-muted:  #5a6473;

  /* États */
  --whatsapp:    #25d366;
  --whatsapp-dk: #128c7e;
  --warn-bg:     #fff8e6;
  --warn-border: #f0d9a0;
  --warn-text:   #7a5a12;

  /* Mesures */
  --header-h:          76px;  /* hauteur au repos, en haut de page */
  --header-h-scrolled: 64px;  /* hauteur une fois le seuil de scroll dépassé */
  /* Hauteur commune à tous les boutons de l'en-tête (retour, téléphone,
     WhatsApp, langue, Services) — évite que chacun tire sa propre hauteur
     de son padding + icône, ce qui les désalignait légèrement entre eux. */
  --header-btn-h:      36px;
  --radius:      14px;
  --radius-lg:   20px;
  --shadow-sm:   0 1px 2px rgba(9, 30, 49, .06), 0 1px 3px rgba(9, 30, 49, .08);
  --shadow-md:   0 4px 12px rgba(9, 30, 49, .08), 0 2px 4px rgba(9, 30, 49, .06);
  --shadow-lg:   0 12px 32px rgba(9, 30, 49, .14);
  --maxw:        1120px;

  --font-title:  'Playfair Display', Georgia, 'Times New Roman', serif;
  --font-body:   'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
}

/* Accessibilité : respect de prefers-reduced-motion (règle imposée au projet) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------- Écriture droite-gauche */
/* Typographie arabe : Cairo (SIL OFL) pour TOUT, titres comme texte, chargé
   uniquement par les pages /ar/ (voir leur balise Google Fonts).

   Un premier essai confiait les titres à Amiri (naskh éditorial, pour tenir
   le rôle de Playfair Display) : écarté à la relecture du client, qui
   préfère la même police partout. Les titres se distinguent donc par la
   GRAISSE et non par la fonte — d'où le 800 ci-dessous, plus épais que le
   600 des titres latins, parce qu'un titre arabe en 600 ne se détachait pas
   assez du corps de texte.

   Inter reste dans la pile derrière Cairo : il sert aux fragments qui
   restent en caractères latins même sur le site arabe — le nom de l'agence,
   « WhatsApp », les codes IATA (ALG, IST) et les noms d'aéroports que la
   base OurAirports ne fournit qu'en anglais.                              */
[dir="rtl"] {
  --font-title: 'Cairo', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-body:  'Cairo', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
}
/* « .svc-title » est un <span>, pas un titre au sens HTML, mais c'est bien un
   titre à l'écran (le nom du service sur sa carte) : sans lui, les cartes
   de l'accueil resteraient en 600 pendant que tout le reste passe en 800.
   Les autres éléments en police de titre sont des PRIX (déjà en 700) : on
   les laisse tels quels, ce sont des chiffres, pas des titres.            */
[dir="rtl"] h1,
[dir="rtl"] h2,
[dir="rtl"] h3,
[dir="rtl"] .svc-title { font-weight: 800; }

/* Suites latines dans un texte arabe (numéros, adresse, e-mail, nom de
   l'agence). L'algorithme bidi d'Unicode traite chiffres, « + » et espaces
   comme des caractères FAIBLES : dans un paragraphe de droite à gauche, il
   réordonnait les groupes, et « +213 5 50 73 18 16 » s'affichait
   « 16 18 73 50 5 213+ ». Le HTML, lui, était correct.

   <bdi> isole la suite ; les navigateurs lui appliquent déjà
   « unicode-bidi: isolate » par leur feuille par défaut, mais on l'écrit
   explicitement — c'est le comportement sur lequel repose l'affichage de
   toutes les coordonnées de l'agence, il ne doit pas dépendre d'un défaut.  */
bdi { unicode-bidi: isolate; }

/* La mise en miroir de la MISE EN PAGE ne se fait pas ici : tout le reste de
   la feuille utilise des propriétés logiques (inset-inline-start,
   padding-inline, text-align: start…), qui s'inversent d'elles-mêmes dès que
   <html dir="rtl"> est posé. Une seule feuille sert donc les deux sens.

   Ce bloc ne traite QUE ce qu'une propriété logique ne peut pas exprimer :
   des dessins qui pointent dans une direction.

   Les icônes NON directionnelles (téléphone, WhatsApp, horloge, épingle,
   coche, croix, loupe, image, hamburger, chevron vers le bas) ne sont
   volontairement PAS retournées : une loupe miroir reste une loupe, mais
   une flèche miroir ment sur ce qu'elle fait.                              */
[dir="rtl"] .header-back svg,      /* flèche « Accueil »                    */
[dir="rtl"] .hc-arrow svg,         /* flèches du hero                       */
[dir="rtl"] .svc-nav svg,          /* flèches du carrousel de services      */
[dir="rtl"] .svc-foot svg,         /* flèche « Voir les offres »            */
[dir="rtl"] .ho-all svg,           /* flèche « Voir tous les voyages »      */
[dir="rtl"] .item-chevron,         /* chevron de fin de carte catalogue     */
[dir="rtl"] .voy-nav svg,          /* flèches du carrousel d'une fiche      */
[dir="rtl"] .photo-zoom-nav svg,     /* flèches de la photo d'hôtel agrandie  */
[dir="rtl"] .cal-nav svg,          /* mois précédent / suivant              */
[dir="rtl"] .block-link svg,       /* « En savoir plus »                    */
[dir="rtl"] .hotel-chevron,        /* accordéon des hôtels, replié          */
[dir="rtl"] .flight-line svg {     /* avion du trajet                       */
  transform: scaleX(-1);
}
/* Une fois déplié, le chevron pointe vers le bas dans les deux sens
   d'écriture — ce n'est plus une indication de sens, mais d'état. La règle
   .hotel-row[aria-expanded='true'] .hotel-chevron (deux classes + un
   attribut) est plus spécifique que le miroir RTL ci-dessus (un attribut +
   une classe) : elle l'emporte donc même en arabe, sans règle dupliquée.   */

/* Le petit décalage de la flèche au survol doit partir du bon côté. */
[dir="rtl"] .svc-card:hover .svc-foot svg { transform: scaleX(-1) translateX(3px); }

/* Vidéos de fond du hero : retournées en arabe.
   Les quatre vidéos sont cadrées avec leur sujet (plage, avion, passeports,
   bateau) du côté OPPOSÉ au texte, qui est à gauche en français. En arabe le
   texte passe à droite : sans ce miroir, le sujet se retrouverait derrière le
   texte au lieu de lui faire face.
   Le miroir porte aussi sur l'image « poster » affichée pendant le
   chargement, puisqu'elle appartient au même élément <video>.              */
[dir="rtl"] .hc-video { transform: scaleX(-1); }

/* Même raison pour les photos des bandeaux de section : elles ont été
   recadrées avec leur sujet à droite pour faire face au texte français, qui
   est à gauche. En arabe, sans miroir, l'avion de /vols/ se retrouvait
   littéralement DERRIÈRE le titre.
   On recompose avec le zoom de .sec-hero-photo au lieu de l'écraser, sinon
   une page qui forcerait « --hero-zoom » perdrait son réglage.            */
[dir="rtl"] .sec-hero-photo { transform: scaleX(-1) scale(var(--hero-zoom, 1)); }

/* ---------------------------------------------------------------- Reset -- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; display: block; }
button { font: inherit; color: inherit; }
a { color: var(--blue); }

h1, h2, h3 {
  font-family: var(--font-title);
  font-weight: 600;
  line-height: 1.2;
  margin: 0;
  letter-spacing: -.01em;
}

:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 2px;
  border-radius: 4px;
}

.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: 20px; }

.skip-link {
  position: absolute; inset-inline-start: 8px; top: -60px; z-index: 200;
  background: var(--surface); color: var(--blue);
  padding: 10px 16px; border-radius: 8px; font-weight: 600;
  text-decoration: none; transition: top .18s ease;
}
.skip-link:focus { top: 8px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------- Header -- */
/* Hauteur, fond et logo évoluent ensemble au scroll, avec une hystérésis
   gérée en JS (activée à 64 px, désactivée sous 24 px, classe .is-scrolled)
   pour éviter l'oscillation autour d'un seuil unique — voir initHeaderScroll
   dans js/chrome.js (aucune logique JS supplémentaire : tout le mouvement
   passe par transition CSS sur cette seule classe). Une ancienne version
   gardait la hauteur strictement constante (un changement brutal avait fait
   « sursauter » le contenu) ; la transition ci-dessous est volontairement
   douce (.25s ease) pour éviter de reproduire ce problème.                 */

/* Fond CLAIR, dans l'esprit d'intrepidtravel.com — le bleu de marque passe
   du fond du bandeau au logo et aux accents. Fond blanc plein en
   permanence, au repos comme au scroll — un essai de « verre flouté »
   (fond translucide + backdrop-filter) au scroll a été retiré à la
   demande du client, qui n'aimait pas la transparence. Seule la HAUTEUR
   continue de rétrécir au scroll, avec une ombre légère qui apparaît pour
   détacher le bandeau du contenu qui défile dessous.                      */
.site-header {
  position: sticky; top: 0; z-index: 90;
  height: var(--header-h);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  transition: height .25s ease, border-color .25s ease, box-shadow .25s ease;
}
.site-header.is-scrolled {
  height: var(--header-h-scrolled);
  border-bottom-color: transparent;
  box-shadow: 0 2px 16px rgba(9, 30, 49, .1);
}

/* Bug corrigé : sur un écran bas (téléphone en mode PAYSAGE), le
   rétrécissement de l'en-tête déplace le contenu qui suit de quelques
   pixels — assez pour repasser sous le seuil de désactivation (24px) et
   redéclencher aussitôt le seuil d'activation (64px), qui déplace le
   contenu à nouveau, etc. Boucle infinie, écran qui « sursaute » sans
   arrêt. Sous 560px de hauteur, le rétrécissement ne changerait de toute
   façon presque rien à l'espace disponible : on le désactive simplement.

   Ce média-query n'est que le filet de sécurité visuel : la bascule
   elle-même (la classe « is-scrolled ») est désormais gelée directement
   dans initHeaderScroll() (js/chrome.js) dès que la fenêtre est courte —
   sinon la classe continuait à s'ajouter/se retirer à chaque micro-rebond
   de défilement, et l'ombre + le filet transparent, qui ONT chacun leur
   transition, clignotaient en boucle même sans changement de hauteur :
   perçu comme un tremblement. Seuil aligné avec celui du JS (560px), avec
   de la marge au-dessus des ~460px max d'un téléphone en paysage, pour
   qu'aucun des deux seuils ne puisse lui-même osciller pendant l'animation
   de la barre d'adresse du navigateur.                                    */
@media (max-height: 560px) {
  .site-header.is-scrolled { height: var(--header-h); }
  .site-header.is-scrolled .brand img { height: 40px; }
}

.site-header .wrap {
  position: relative;   /* ancre l'overlay de recherche mobile, ci-dessous */
  height: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}

.brand { display: flex; align-items: center; text-decoration: none; flex: none; }
/* 40px dans un en-tête de 76px : il reste 18px d'air au-dessus et en
   dessous. Monter plus haut collerait le logo aux bords.                  */
.brand img { height: 40px; width: auto; transition: height .25s ease; }
.site-header.is-scrolled .brand img { height: 34px; }

.header-actions { display: flex; align-items: center; gap: 10px; min-width: 0; }

/* Une seule hauteur pour TOUS les boutons de l'en-tête (retour, téléphone,
   WhatsApp, langue, Services) — voir --header-btn-h dans les tokens en
   tête de fichier : avant, chacun tirait sa hauteur de son propre padding
   + icône, et ces tailles ne tombaient jamais tout à fait d'accord
   (32 / 27 / 35 px selon le bouton) — d'où des icônes qui semblaient mal
   alignées sur mobile.                                                    */

.header-back {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  height: var(--header-btn-h); box-sizing: border-box;
  color: var(--blue); text-decoration: none;
  font-size: 14px; font-weight: 500;
  padding: 0 12px; border-radius: 999px;
  background: var(--blue-soft);
  transition: background .16s ease;
}
.header-back:hover { background: var(--blue-tint); }
.header-back svg { width: 16px; height: 16px; flex: none; stroke: currentColor; fill: none; stroke-width: 2; }
/* Sur un bandeau étroit, le libellé « Accueil » se réduit à la seule
   flèche — la recherche qui justifiait ça à l'origine a été retirée,
   mais le bandeau reste plus confortable sans texte en dessous de 720px
   (logo + WhatsApp y prennent déjà pas mal de place).                    */
.header-back span { display: none; }
@media (min-width: 720px) { .header-back span { display: inline; } }

.header-wa {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  height: var(--header-btn-h); box-sizing: border-box;
  background: var(--whatsapp); color: #fff;
  text-decoration: none; font-weight: 600; font-size: 14px;
  padding: 0 15px; border-radius: 999px;
  transition: background .16s ease;
}
.header-wa:hover { background: var(--whatsapp-dk); }
.header-wa svg { width: 17px; height: 17px; fill: currentColor; flex: none; }
.header-wa .label { display: none; }
@media (min-width: 560px) { .header-wa .label { display: inline; } }

/* ------------------------------------------------ Menu Services (en-tête) */
/* Remplace la recherche retirée : permet de rejoindre une autre section
   sans repasser par l'accueil. Mêmes colonnes que le pied de page (voir
   groupedSections dans chrome.js). Dernier bouton de l'en-tête (demande
   client : les « 3 barres » à l'extrémité, sans chevron à côté — l'état
   ouvert/fermé reste porté par aria-expanded pour les lecteurs d'écran).
   Le panneau s'ancre par la droite — « .site-header .wrap » est déjà
   positionné (voir plus haut) — juste sous ce bouton, maintenant qu'il
   est lui-même à l'extrémité.                                            */
.header-nav-toggle {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  height: var(--header-btn-h); box-sizing: border-box;
  color: var(--text); text-decoration: none; background: none;
  border: 0; font: inherit; font-size: 14px; font-weight: 500; cursor: pointer;
  padding: 0 10px; border-radius: 999px;
  transition: background .16s ease;
}
.header-nav-toggle:hover { background: var(--bg); }
.header-nav-toggle svg { width: 18px; height: 18px; flex: none; stroke: currentColor; fill: none; stroke-width: 2; }
.header-nav-toggle span { display: none; }
@media (min-width: 860px) { .header-nav-toggle span { display: inline; } }

.header-nav-panel {
  position: absolute; top: calc(100% + 10px); inset-inline-end: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 20px;
  min-width: 520px;
  z-index: 95;
}
.header-nav-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.header-nav-col h3 {
  font-family: var(--font-body); font-size: 12px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-muted); margin: 0 0 10px;
}
.header-nav-col ul { list-style: none; margin: 0; padding: 0; }
.header-nav-col li { margin-bottom: 7px; }
.header-nav-col a { font-size: 14px; color: var(--text); text-decoration: none; }
.header-nav-col a:hover { color: var(--blue); text-decoration: underline; }

/* Badge « Bientôt disponible » — voir « soon » dans js/sections.js. Même
   teinte que .tag.is-soon / .poster-badge.is-soon dans css/section.css :
   un seul vocabulaire de couleur pour « pas encore prêt ».

   Uniquement sur les cartes de l'accueil, superposé à la photo : le client
   l'a retiré du menu Services et du pied de page, où il alourdissait deux
   listes qui doivent rester des listes de liens.                          */
.soon-badge {
  position: absolute; top: 10px; inset-inline-start: 10px; z-index: 1;
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
  padding: 4px 10px; border-radius: 999px;
  background: var(--navy); color: #fff;
  box-shadow: 0 1px 4px rgba(9, 30, 49, .18);
}

/* --------------------------------------------------- Sélecteur de langue */
/* Trois drapeaux plutôt qu'un menu déroulant : à trois entrées, un menu
   coûterait un clic de plus pour rien. La langue courante n'est pas un
   lien — elle est déjà là, cerclée de bleu plutôt que fond plein (le
   drapeau porte déjà sa propre couleur, un aplat derrière l'étoufferait).
   Volontairement TRÈS compact (drapeau seul, sans le code FR/EN/ع) :
   c'est ce qui permet de le garder visible sur mobile, voir plus bas.     */
.header-lang { display: inline-flex; align-items: center; flex: none; gap: 3px; }
.header-lang a,
.header-lang .header-lang-on {
  display: inline-flex; line-height: 0; padding: 2px; border-radius: 5px;
}
.header-lang img {
  display: block; width: 21px; height: 15px; border-radius: 3px;
  object-fit: cover; border: 1px solid rgba(9, 30, 49, .18);
}
.header-lang a:hover { background: var(--blue-soft); }
.header-lang .header-lang-on { box-shadow: 0 0 0 2px var(--blue); }

/* La copie du pied de page : même composant, posé sous les liens Agence.
   Jamais remplacée par la version compacte ci-dessous : le pied de page a
   toute la place voulue, pas de recoin à préserver comme dans l'en-tête. */
.footer-col .header-lang { margin-top: 14px; }

/* ---------------------------------------- Sélecteur compact (en-tête, mobile) */
/* Sous 560px, les trois drapeaux de .header-lang laissaient l'en-tête un
   peu chargé à côté du logo, du téléphone et de WhatsApp (déjà réduits à
   leur icône à cette largeur). Un seul drapeau (la langue courante) qui
   ouvre un petit menu pour les deux autres — important de le garder
   visible plutôt que de le renvoyer au pied de page (public algérien,
   bascule fréquente FR ↔ AR), mais sans élargir la structure.            */
.header-lang-compact { display: none; }
@media (max-width: 559px) {
  .header-actions > .header-lang { display: none; }
  .header-actions .header-lang-compact { display: block; position: relative; }
}
.header-lang-toggle {
  display: inline-flex; align-items: center; gap: 3px;
  height: var(--header-btn-h); box-sizing: border-box;
  padding: 0 6px; border-radius: 7px; border: 1px solid var(--border);
  background: var(--surface); cursor: pointer;
}
.header-lang-toggle:hover { background: var(--bg); }
.header-lang-toggle img {
  display: block; width: 20px; height: 14px; border-radius: 3px;
  object-fit: cover; border: 1px solid rgba(9, 30, 49, .18);
}
.header-lang-toggle svg {
  width: 13px; height: 13px; stroke: var(--text-muted); stroke-width: 2.5;
  fill: none; flex: none; transition: transform .16s ease;
}
.header-lang-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.header-lang-panel {
  position: absolute; top: calc(100% + 8px); inset-inline-end: 0; z-index: 40;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-lg); padding: 6px; min-width: 168px;
}
.header-lang-panel a,
.header-lang-panel .is-current {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 10px; border-radius: 8px;
  font-size: 14px; text-decoration: none; color: var(--text);
  white-space: nowrap;
}
.header-lang-panel a:hover { background: var(--blue-soft); color: var(--blue); }
.header-lang-panel .is-current { font-weight: 700; color: var(--blue); background: var(--blue-soft); }
.header-lang-panel img {
  display: block; width: 21px; height: 15px; border-radius: 3px; flex: none;
  object-fit: cover; border: 1px solid rgba(9, 30, 49, .18);
}

/* Sous 640px, le panneau ne se love plus sous le bouton (il n'y a pas la
   place) : il devient une feuille pleine largeur, ancrée sous tout
   l'en-tête plutôt que sous le seul déclencheur. « top »/« max-height »
   suivent la hauteur RÉELLE du header (position: fixed ne peut pas utiliser
   100% comme le ferait un absolu) — d'où la variante .is-scrolled ci-après,
   qui bascule sur --header-h-scrolled une fois le header rétréci.         */
@media (max-width: 639px) {
  .header-nav-panel {
    position: fixed; top: var(--header-h); inset-inline: 0;
    min-width: 0; width: 100%;
    border-radius: 0; border: 0; border-top: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    max-height: calc(100vh - var(--header-h));
    overflow-y: auto;
  }
  .site-header.is-scrolled .header-nav-panel {
    top: var(--header-h-scrolled);
    max-height: calc(100vh - var(--header-h-scrolled));
  }
  .header-nav-cols { grid-template-columns: 1fr; gap: 20px; }
}

/* ------------------------------------------------------- Téléphone fixe -- */
.header-phone {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  height: var(--header-btn-h); box-sizing: border-box;
  color: var(--text); text-decoration: none;
  font-size: 14px; font-weight: 500;
  padding: 0 10px; border-radius: 999px;
  transition: background .16s ease;
}
.header-phone:hover { background: var(--bg); }
.header-phone svg { width: 16px; height: 16px; flex: none; fill: currentColor; }
.header-phone .label { display: none; }
@media (min-width: 640px) { .header-phone .label { display: inline; } }

/* --------------------------------------------------------------- Footer -- */
/* Règle client : logo seul, aucun texte de marque à côté.
   Pas de silhouette de dunes — explicitement rejetée par le client.        */

/* Pied de page CLAIR. Le marine est réservé au dégradé des bandeaux :
   employé ici sur toute la largeur, il alourdissait le bas de page.
   Pas de filet doré au-dessus (retiré à la demande du client) — le
   passage bleu → blanc se fait directement, sans transition décorative.   */
.site-footer {
  background-color: var(--surface);
  color: var(--text-muted);
  margin-top: 64px;
  padding: 44px 0 24px;
  font-size: 14.5px;
  /* Motif de la charte, en filigrane dans le coin — pas un aplat texturé,
     un seul motif posé une fois, très pâle (opacité déjà réduite dans le
     fichier lui-même, voir assets/pattern/). Choisi ici car c'est un fond
     UNI, sans photo : contrairement aux héros (.sec-hero), rien ne risque
     d'entrer en conflit avec lui. Coin haut, là où logo + colonnes
     laissent le plus de vide sur grand écran.                            */
  background-image: url('../assets/pattern/motif-charte-subtle.webp');
  background-repeat: no-repeat;
  /* Décalages POSITIFS : le motif reste entièrement dans le cadre — un
     décalage négatif ici le pousse hors du bord (donc invisible), piège
     déjà rencontré en le posant la première fois.                       */
  background-position: right 10px top 10px;
  background-size: 360px auto;
}
/* Miroir RTL : le motif suit le coin qui reste vide, pas un côté fixe. */
[dir="rtl"] .site-footer { background-position: left 10px top 10px; }

/* Sous 640px, les colonnes s'empilent en pleine largeur : il n'y a plus de
   coin vide, le motif se retrouve à cheval sur le texte « Billetterie ».
   Pas de coin vide à combler ici → on le retire, plutôt que de forcer
   une taille minuscule qui le rendrait juste confus.                    */
@media (max-width: 640px) { .site-footer { background-image: none; } }
.site-footer a { color: var(--text); text-decoration: none; }
.site-footer a:hover { color: var(--blue); text-decoration: underline; }

/* ---------------------------------------------------------- 1. En-tête -- */
/* Marque + réseaux sociaux, sur une seule ligne fine — le logo n'est plus
   qu'une signature (règle client : très petit, sans texte à côté), les
   réseaux sociaux n'ont plus à partager la barre du bas avec le copyright.
   clamp() pour rester proportionné sur les petits écrans.                 */
.footer-top {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 16px;
  margin-bottom: 36px;
}
.footer-brand { flex: none; }
.footer-brand img { height: clamp(20px, 2.6vw, 26px); width: auto; }

/* Icônes pleines plutôt que des cercles clairs : un bloc affirmé à côté
   de la signature, dans l'esprit du bas de page de la référence.         */
.footer-social { display: flex; gap: 10px; flex: none; }
.footer-social a {
  width: 36px; height: 36px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--navy);
  transition: background .16s ease;
}
.footer-social a:hover { background: var(--blue); }
.footer-social svg { width: 17px; height: 17px; fill: #fff; }
/* Filet de sécurité si un lien social redevenait vide un jour (config.js) :
   icône affichée quand même, mais en <span> inerte plutôt qu'en <a> vers
   une URL inventée — voir renderFooter() dans chrome.js.                  */
.footer-social-pending {
  width: 36px; height: 36px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--navy); opacity: .45; cursor: default;
}
.footer-social-pending svg { width: 17px; height: 17px; fill: #fff; }

.footer-divider { height: 1px; background: var(--border); margin: 28px 0; }

/* ------------------------------------------------------------ Colonnes -- */
/* Un thème par colonne, un lien par ligne. « Nos services » est éclaté en
   plusieurs colonnes par affinité (Billetterie, Hébergements et voyages,
   Autres services) plutôt qu'une seule longue liste de 10 liens — voir
   footerGroup dans sections.js. Pas de « Company »/« Purpose » à
   l'anglo-saxonne : une agence locale n'a ni page carrières ni certification à afficher,
   les inventer serait mentir sur ce qu'elle est.
   auto-fit plutôt qu'un nombre de colonnes fixe : le nombre de colonnes de
   service peut changer si on ajoute un footerGroup, sans casser la mise
   en page.                                                               */
.footer-cols {
  display: grid; gap: 28px 24px;
  grid-template-columns: 1fr;
}
@media (min-width: 560px) {
  .footer-cols { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}

.footer-col h3 {
  font-family: var(--font-body); font-size: 12.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--text); margin-bottom: 12px;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 8px; }

/* « Nous joindre » : libellé du service au-dessus du numéro plutôt que les
   deux bout à bout — 4 lignes de contact (billetterie/commercial/visa/
   direction) sur la même ligne qu'un numéro provoquait un retour à la
   ligne en plein milieu d'un numéro de téléphone.                        */
.footer-tel-label { display: block; font-size: 11.5px; color: var(--text-muted); margin-bottom: 1px; }
.footer-tel-num { display: block; }

/* ------------------------------------------------------ 3. Barre légale */
/* Tout en bas, séparée du reste par .footer-divider : copyright à gauche,
   liens juridiques à droite — seule « Mentions légales » existe aujourd'hui,
   mais la liste est prête à accueillir CGU/plan du site sans rien changer
   à la structure (voir renderFooter() dans chrome.js).                   */
.footer-legal {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 20px;
  font-size: 13px; color: var(--text-muted);
}
.footer-legal-links { display: flex; flex-wrap: wrap; gap: 4px 20px; list-style: none; margin: 0; padding: 0; }
.footer-legal-links a { color: var(--text-muted); }
.footer-legal-links a:hover { color: var(--blue); }

/* ------------------------------------------------- Hero carrousel accueil */
/* Plusieurs diapositives, navigation MANUELLE uniquement (flèches, points,
   clavier) — pas de défilement automatique, voir js/hero-carousel.js.
   Habillage (photo par diapositive) à faire dans une prochaine passe :
   pour l'instant, chaque diapositive reprend le même dégradé bleu que le
   reste du site — c'est la mécanique qui est posée ici, pas le rendu final.
   Inspiré d'intrepidtravel.com (bandeau blanc + hero en dessous).         */

/* TEST 2 — pleine largeur, collé sous l'en-tête (retour à la version
   d'origine, comparée un temps à la carte inset ci-dessous en commentaire).
   Le fond de la page ne doit plus apparaître autour du hero : plus de
   marge ni de coins arrondis, la photo/vidéo touche les deux bords.       */
.hero-carousel-wrap {
  max-width: none;
  margin-inline: 0;
  padding-inline: 0;
  padding-top: 0;
}

.hero-carousel {
  position: relative;
  background: linear-gradient(160deg, var(--blue) 0%, var(--blue-deep) 100%);
  overflow: hidden;
  border-radius: 0;
}

/* TEST 1 (comparaison) — carte inset à bords arrondis, façon
   intrepidtravel.com. Pour revenir à cette version : commenter le bloc
   TEST 2 ci-dessus et décommenter celui-ci.
.hero-carousel-wrap {
  max-width: calc(var(--maxw) + 32px);
  margin-inline: auto;
  padding-inline: 16px;
  padding-top: 20px;
}
.hero-carousel {
  position: relative;
  background: linear-gradient(160deg, var(--blue) 0%, var(--blue-deep) 100%);
  overflow: hidden;
  border-radius: var(--radius-lg);
}
*/
/* Les 4 diapositives partagent la MÊME cellule de grille (grid-area 1/1) :
   elles se superposent, mais chacune contribue quand même au calcul de la
   hauteur de la ligne — la piste s'ajuste donc automatiquement à la plus
   haute d'entre elles. C'est délibéré plutôt qu'une hauteur fixe devinée :
   un bouton qui passe sur deux lignes à 320px (« Découvrir nos services »)
   avait fait déborder le contenu hors d'un min-height codé en dur lors des
   tests — la grille absorbe ce genre de cas sans qu'on ait à le prévoir.  */
.hc-viewport { position: relative; display: grid; }

.hc-slide {
  position: relative;
  grid-area: 1 / 1;
  display: flex; align-items: center;
  opacity: 0; visibility: hidden;
  transition: opacity .3s ease, visibility .3s ease;
  pointer-events: none;
}
.hc-slide.is-active {
  opacity: 1; visibility: visible;
  pointer-events: auto;
}

/* Vidéo de fond — TEST sur la diapositive 1 uniquement (voir index.html).
   « display:none » sous reduced-motion : le dégradé bleu de .hero-carousel,
   juste derrière, prend le relais tout seul, aucun repli à coder à part.  */
.hc-video {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover;
}
/* L'avion, dans cette vidéo, vole haut dans le tiers supérieur d'un cadre
   1280×720 très ciel — bien depuis le passage du hero en pleine largeur
   (plus de carte, voir plus haut) : sur un écran large, la carte est
   beaucoup plus large que haute, donc « object-fit: cover » ne rogne QUE
   verticalement (jamais horizontalement, la largeur colle exactement à
   celle de la carte). Avec le centrage par défaut, ce rognage vertical
   partait quasiment du haut de l'image et coupait l'avion. On décale donc
   la fenêtre visible plus haut dans l'image source — l'axe horizontal
   n'est pas concerné (voir ci-dessus) : la vidéo redevient normalement
   cadrée sur téléphone/tablette (rognage horizontal cette fois, où « 28% »
   sur l'axe vertical n'a aucun effet puisqu'il n'y a alors aucun rognage
   vertical à positionner).                                                */
.hc-video-avion { object-position: center 28%; }
/* Le voile bleu uniforme (ex-.hc-video-overlay, en mix-blend-mode: multiply
   sur toute la vidéo) a été retiré à la demande du client : la photo/vidéo
   doit se voir dans ses vraies couleurs. Seul le dégradé DIRECTIONNEL du
   côté du texte reste — voir .hc-slide::after juste en dessous — c'est lui
   qui garantit la lisibilité du texte blanc, pas un filtre sur toute
   l'image.                                                                */
@media (prefers-reduced-motion: reduce) {
  .hc-video { display: none; }
}

/* Pas de max-width ici : .wrap fixe déjà 1120px, et h1/p ci-dessous ont
   leur propre largeur en « ch ». En ajouter une ici entrerait en conflit
   avec celle de .wrap (même spécificité, la dernière déclarée gagnerait)
   et recentrerait tout le bloc au lieu de le garder aligné à gauche.      */
/* Même principe que .sec-hero::after : on assombrit le côté du texte, pas
   toute la vidéo — seul dégradé restant sur le hero depuis le retrait du
   voile bleu uniforme (voir la note au-dessus de .hc-video). z-index 1,
   .hc-inner est à 2 : le texte reste au-dessus du dégradé.               */
.hc-slide::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to right,
    rgba(9, 30, 49, .60) 0%,
    rgba(9, 30, 49, .34) 42%,
    rgba(9, 30, 49, 0) 72%);
  pointer-events: none;
}
[dir="rtl"] .hc-slide::after { transform: scaleX(-1); }

.hc-inner {
  position: relative; z-index: 2;
  padding-top: 56px;
  padding-bottom: 64px;   /* dégage la place des points, positionnés en absolu sous le texte */
  /* Place pour les deux flèches, à gauche comme à droite, sans qu'elles
     ne passent sur le texte (piège trouvé en testant : la flèche
     précédente chevauchait le paragraphe sans ce padding-left).          */
  padding-inline-start: 62px;
  padding-inline-end: 62px;
  color: #fff;
}
@media (min-width: 720px) { .hc-inner { padding-inline-start: 76px; padding-inline-end: 76px; } }
/* Ombres portées : même raison que sur .sec-hero (voir section.css) — le
   voile a été allégé deux fois, l'ombre prend le relais sans assombrir la
   vidéo.                                                                  */
/* h1 sur la 1re diapositive, h2 sur les 3 suivantes (une seule diapositive
   affichée à la fois : un seul h1 par page, exigé pour le SEO — voir
   A-REMPLIR.md/README.md) : même style pour les deux balises, le rendu ne
   doit pas changer selon celle utilisée.                                  */
.hc-inner h1, .hc-inner h2 {
  font-size: clamp(28px, 6.4vw, 44px);
  max-width: 16ch;
  margin: 8px 0 14px;
  text-shadow: 0 1px 14px rgba(9, 30, 49, .5), 0 1px 2px rgba(9, 30, 49, .35);
}
/* Blanc pur, comme .sec-hero p : sur une vidéo, les 12 % de transparence
   coûtaient trop de contraste. La hiérarchie tient à la taille.          */
.hc-inner p {
  font-size: clamp(15px, 3.4vw, 17px);
  color: #fff;
  max-width: 52ch; margin: 0 0 22px;
  text-shadow: 0 1px 10px rgba(9, 30, 49, .6), 0 1px 2px rgba(9, 30, 49, .45);
}

.hero-eyebrow {
  display: inline-block;
  font-size: 12.5px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255, 255, 255, .8);
}

/* ------------------------------------- Apparition du texte, en cascade -- */
/* Sobre : un léger glissement vers le haut plutôt qu'un effet voyant.
   « both » : invisible avant le départ, reste au repos une fois arrivé —
   sans ça l'élément réapparaîtrait à son état de base une fois l'animation
   finie. Ne s'applique qu'à la diapositive ACTIVE : .hc-slide bascule
   .is-active par un simple toggle de classe (hero-carousel.js), donc
   retirer puis remettre la classe relance l'animation à chaque fois qu'on
   revient sur une diapositive — pas besoin de JS pour ça.
   Respecte prefers-reduced-motion via la règle globale déjà en place tout
   en haut de ce fichier (animation-duration ramenée à .001ms).            */
@keyframes hc-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
.hc-inner .hero-eyebrow,
.hc-inner h1,
.hc-inner h2,
.hc-inner p,
.hc-inner .hc-cta {
  opacity: 0;
}
.hc-slide.is-active .hc-inner .hero-eyebrow  { animation: hc-rise .7s cubic-bezier(.16, 1, .3, 1) .05s both; }
.hc-slide.is-active .hc-inner h1,
.hc-slide.is-active .hc-inner h2             { animation: hc-rise .7s cubic-bezier(.16, 1, .3, 1) .15s both; }
.hc-slide.is-active .hc-inner p              { animation: hc-rise .7s cubic-bezier(.16, 1, .3, 1) .26s both; }
.hc-slide.is-active .hc-inner .hc-cta        { animation: hc-rise .7s cubic-bezier(.16, 1, .3, 1) .37s both; }

.hc-cta {
  display: inline-flex; align-items: center;
  background: #fff; color: var(--blue);
  font-weight: 700; font-size: 15px;
  padding: 12px 22px; border-radius: 999px;
  text-decoration: none;
  transition: transform .16s ease, box-shadow .16s ease;
}
.hc-cta:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0, 0, 0, .18); }

.hc-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 38px; height: 38px; border-radius: 50%;
  background: #fff; border: 0; cursor: pointer;
  display: grid; place-items: center;
  box-shadow: 0 4px 14px rgba(9, 30, 49, .22);
  transition: background .16s ease;
}
.hc-arrow:hover { background: var(--blue-soft); }
.hc-prev { inset-inline-start: 10px; }
.hc-next { inset-inline-end: 10px; }
.hc-arrow svg { width: 19px; height: 19px; stroke: var(--blue); fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
@media (min-width: 720px) {
  .hc-arrow { width: 44px; height: 44px; }
  .hc-prev { inset-inline-start: 20px; }
  .hc-next { inset-inline-end: 20px; }
}

.hc-dots {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 3;
  display: flex; gap: 8px;
}
.hc-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: rgba(255, 255, 255, .4); border: 0; padding: 0; cursor: pointer;
  transition: background .16s ease, width .16s ease;
}
.hc-dot:hover { background: rgba(255, 255, 255, .65); }
.hc-dot.is-active { background: #fff; width: 22px; border-radius: 999px; }

/* -------------------------------------------------- Grille des services -- */

.services { padding: 44px 0 8px; }

.section-title { font-size: clamp(23px, 5vw, 30px); margin-bottom: 6px; }
.section-lede  { color: var(--text-muted); margin: 0 0 28px; max-width: 60ch; }

/* ------------------------------------------ Nos meilleures offres (accueil) */
/* Voir js/home-offers.js. Même apparence que les cartes « affiche » de la
   page Voyages organisés (.poster-card dans section.css), recopiée ici en
   version courte : l'accueil ne charge pas section.css. Grille de 4 sur
   ordinateur, 2 sur tablette ; sur téléphone, bande qui défile au doigt
   (comme le carrousel de services juste au-dessus). Contenu visible dès le
   chargement : pas d'apparition au défilement.                            */
.home-offers { margin-top: 48px; }
.home-offers[hidden] { display: none; }
.ho-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; }
.ho-head .section-lede { margin-bottom: 22px; }
.ho-all {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  margin-bottom: 22px; font-weight: 600; font-size: 14.5px; color: var(--blue); text-decoration: none;
}
.ho-all:hover { color: var(--blue-deep); }
.ho-all svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.ho-grid {
  list-style: none; margin: 0; padding: 4px 4px 8px;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px;
}
.ho-grid > li { display: flex; }
.ho-card {
  width: 100%; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; color: var(--text); text-decoration: none; box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.ho-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--blue); }
.ho-card:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; }
.ho-media {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden;
  background: linear-gradient(160deg, var(--blue-soft) 0%, var(--blue-tint) 100%);
}
.ho-media > img:first-child { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .4s ease; }
.ho-card:hover .ho-media > img:first-child { transform: scale(1.04); }
.ho-flag {
  position: absolute; inset-inline-start: 12px; bottom: 12px;
  width: 26px; height: 19.5px; border-radius: 4px; object-fit: cover;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .9), 0 2px 6px rgba(9, 30, 49, .3);
}
.ho-badge {
  position: absolute; top: 12px; inset-inline-start: 12px;
  padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: .02em;
  background: rgba(255, 255, 255, .92); color: var(--text); box-shadow: 0 1px 4px rgba(9, 30, 49, .18);
}
.ho-badge.is-promo, .ho-badge.is-limited { background: var(--salmon); color: #fff; }
.ho-badge.is-combo { background: var(--blue); color: #fff; }
.ho-badge.is-event { background: var(--event); color: #fff; }
.ho-badge.is-soon  { background: var(--navy); color: #fff; }
.ho-body { padding: 14px 16px 16px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.ho-title { font-family: var(--font-title); font-size: 18px; font-weight: 700; line-height: 1.25; }
.ho-sub { font-size: 13.5px; color: var(--text-muted); line-height: 1.45; }
.ho-meta { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text-muted); }
.ho-meta svg { width: 14px; height: 14px; stroke: var(--blue); fill: none; stroke-width: 2; flex: none; }
.ho-price { margin-top: auto; padding-top: 8px; display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 6px; }
.ho-from { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.ho-old { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; }
.ho-amount { font-family: var(--font-title); font-size: 17px; font-weight: 700; color: var(--blue); white-space: nowrap; }
.ho-per { font-size: 12px; color: var(--text-muted); }

@media (max-width: 960px) {
  .ho-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .ho-head { display: block; }
  .ho-all { margin: -12px 0 16px; }
  .ho-grid {
    display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .ho-grid::-webkit-scrollbar { display: none; }
  .ho-grid > li { flex: none; width: 78%; scroll-snap-align: start; }
}

/* ------------------------------------------------- Carrousel de services -- */
/* TEST — inspiré des cartes de voyage d'intrepidtravel.com (photo en haut,
   métadonnées + prix en bas, flèche de défilement qui chevauche la carte).
   Défilement horizontal NATIF (overflow-x + scroll-snap), pas un carrousel
   à index comme le hero : plus robuste au doigt, la flèche ne fait que
   déclencher un scrollBy() sur ce qui existe déjà, elle ne réinvente pas
   la navigation. Toujours manuel — pas de défilement automatique.

   Chaque carte a encore une zone d'icône à la place d'une photo :
   l'habillage (photo par service) viendra dans une prochaine passe, comme
   pour le hero.                                                          */

.services-carousel { position: relative; }

.svc-track {
  display: flex; gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  list-style: none; margin: 0; padding: 4px 4px 8px;
}
.svc-track::-webkit-scrollbar { display: none; }

.svc-item {
  flex: 0 0 auto;
  width: min(78vw, 280px);
  scroll-snap-align: start;
}
@media (min-width: 620px)  { .svc-item { width: 260px; } }
@media (min-width: 980px)  { .svc-item { width: 280px; } }

.svc-card {
  height: 100%;
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none; color: inherit;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .18s ease, transform .18s ease;
}
.svc-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }

/* Fond teinté + icône tant qu'aucune photo n'est renseignée (voir « photo »
   dans sections.js) — l'œil comprend déjà « ici il y aura une image ».
   Le voile bleu essayé un temps par-dessus les photos a été retiré : les
   9 générées par IA partagent déjà le même style (invite commune, voir
   IMAGE-CREDITS.md), un filtre en plus les rendait juste plus ternes sans
   vraiment ajouter de cohérence. Un léger zoom au survol à la place —
   même geste que les cartes-affiches de voyages/ (.poster-photo).        */
.svc-media {
  position: relative; overflow: hidden;
  height: 128px; flex: none;
  display: grid; place-items: center;
  background: linear-gradient(160deg, var(--blue-soft) 0%, var(--blue-tint) 100%);
}
.svc-media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform .4s ease;
}
.svc-card:hover .svc-media img { transform: scale(1.04); }
.svc-media svg {
  position: relative; z-index: 1;
  width: 38px; height: 38px;
  stroke: var(--blue); fill: none; stroke-width: 1.4;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: .85;
}

.svc-body {
  flex: 1;
  display: flex; flex-direction: column;
  padding: 16px 18px 18px;
}
.svc-title {
  font-family: var(--font-title); font-size: 17.5px; font-weight: 600;
  line-height: 1.3; margin-bottom: 6px;
}
.svc-desc {
  flex: 1;
  font-size: 13.5px; line-height: 1.5; color: var(--text-muted);
  margin: 0 0 14px;
}

.svc-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
}
.svc-cta { font-size: 13.5px; font-weight: 600; color: var(--blue); }
.svc-foot svg {
  width: 15px; height: 15px; flex: none;
  stroke: var(--blue); fill: none; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  transition: transform .16s ease;
}
.svc-card:hover .svc-foot svg { transform: translateX(3px); }

/* Flèches de défilement : même traitement visuel que celles du hero
   (cercle blanc, ombre, chevron bleu) — cohérence entre les deux
   carrousels du site.                                                    */
.svc-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 40px; height: 40px; border-radius: 50%;
  background: #fff; border: 0; cursor: pointer;
  display: grid; place-items: center;
  box-shadow: 0 4px 14px rgba(9, 30, 49, .18);
  transition: background .16s ease, opacity .16s ease;
}
.svc-nav:hover { background: var(--blue-soft); }
.svc-nav svg { width: 19px; height: 19px; stroke: var(--blue); fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.svc-nav[hidden] { display: none; }
.svc-prev { inset-inline-start: -6px; }
.svc-next { inset-inline-end: -6px; }
@media (min-width: 720px) {
  .svc-prev { inset-inline-start: -14px; }
  .svc-next { inset-inline-end: -14px; }
}

/* -------------------------------------------------------- Bande contact -- */

.contact-band {
  margin-top: 52px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px 24px;
  display: grid; gap: 20px;
}
@media (min-width: 800px) {
  .contact-band { grid-template-columns: 1fr auto; align-items: center; }
}
.contact-band h2 { font-size: 24px; margin-bottom: 6px; }
.contact-band p { margin: 0; color: var(--text-muted); }

.btn-wa {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  background: var(--whatsapp); color: #fff;
  font-weight: 600; font-size: 16px;
  padding: 14px 24px; border-radius: 999px;
  text-decoration: none; border: 0; cursor: pointer;
  box-shadow: 0 4px 14px rgba(37, 211, 102, .3);
  transition: background .16s ease, transform .16s ease;
}
.btn-wa:hover { background: var(--whatsapp-dk); transform: translateY(-1px); }
.btn-wa[disabled], .btn-wa[aria-disabled='true'] {
  background: #b9c2ce; box-shadow: none; cursor: not-allowed; transform: none;
}
.btn-wa svg { width: 20px; height: 20px; fill: currentColor; flex: none; }

/* -------------------------------------------------------- Page légale --- */
/* mentions-legales.html. Colonne de lecture volontairement plus étroite que
   le reste du site (760px, pas 1120px) : un texte juridique se lit mieux
   sur une ligne courte. Combiner .wrap et .legal-content sur le même
   élément fonctionne parce qu'aucune autre propriété ne s'y oppose — la
   déclaration la plus tardive (ici .legal-content) l'emporte pour
   max-width, exactement comme voulu.                                     */
.legal-content { max-width: 760px; padding: 44px 0 88px; }

.legal-content h2 {
  font-size: 21px; margin: 40px 0 14px;
  padding-top: 28px; border-top: 1px solid var(--border-soft);
}
.legal-content h2:first-of-type { margin-top: 28px; padding-top: 0; border-top: 0; }
.legal-content p { margin: 0 0 14px; line-height: 1.7; }
.legal-content ul { margin: 0 0 14px; padding-inline-start: 22px; }
.legal-content li { margin-bottom: 7px; line-height: 1.6; }
.legal-content code {
  font-family: ui-monospace, Consolas, monospace; font-size: .92em;
  background: var(--blue-tint); padding: 1px 5px; border-radius: 4px;
}
.legal-content .hint { font-size: 13px; color: var(--text-muted); margin: -6px 0 14px; }
.legal-content .notice { margin: 0 0 8px; }

.legal-content dl.detail-pairs { margin: 0 0 14px; }

/* -------------------------------------------------------------- Reveal --- */
/* Apparition par ANIMATION avec animation-fill-mode: backwards, jamais par
   transition : une transition laisse « transform: none » sur l'élément et
   tue ensuite l'effet de survol des cartes (piège connu du projet).        */

.js-reveal [data-reveal] { opacity: 0; }
.js-reveal [data-reveal].is-in {
  animation: reveal-up .5s cubic-bezier(.22, .61, .36, 1) backwards;
  opacity: 1;
}
@keyframes reveal-up {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
