/* ==========================================================================
   viachiangmai · feuille de style de référence
   Direction : Lanna (montagnes du Nord, feuille d'or, teck, safran)
   ========================================================================== */

/* --- 1. Tokens ---------------------------------------------------------- */
:root {
  /* Palette de 5 couleurs */
  --c-primary:      #0F3D3E;  /* Vert Doi     · principale */
  --c-secondary:    #C68B2C;  /* Or Lanna     · secondaire */
  --c-bg:           #F2F5F1;  /* Brume du Ping · fond */
  --c-text:         #16211D;  /* Teck         · texte */
  --c-cta:          #D14208;  /* Safran       · accent CTA */

  /* Neutres de support */
  --c-surface:      #FFFFFF;
  --c-muted:        #5C6B64;
  --c-border:       #DCE4DD;
  --c-cta-hover:    #B03706;
  --c-primary-soft: #E3EDE5;
  --c-primary-deep: #0A2B2C;
  /* L'or Lanna est une couleur de surface : à 2,9:1 sur blanc et 2,7:1 sur la
     brume du Ping, il porte un aplat, un filet ou un liseré, mais pas du petit
     texte. Cette version encrée tient 5,0:1 sur #FFFFFF et 4,5:1 sur #F2F5F1.
     Elle ne sert donc qu'aux libellés et pictogrammes de petite taille posés
     sur fond clair ; l'or reste l'or partout ailleurs. */
  --c-secondary-ink: #96660F;
  /* L'or éclairci, pour le petit texte posé sur le vert Doi ou sur une photo
     sombre : l'or Lanna n'y tient que 4,1:1, celui-ci environ 7,3:1. Il servait
     déjà aux surtitres des héros photo ; il a maintenant un nom. */
  --c-secondary-light: #EFC46E;

  /* Typographie */
  --font-display: "Fraunces", "Noto Sans Thai", Georgia, "Times New Roman", serif;
  --font-body:    "Karla", "Noto Sans Thai", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Rythme */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 72px; --sp-9: 104px;

  /* Formes */
  --r-card: 14px;
  --r-btn: 10px;
  --r-pill: 999px;
  --shadow-card:  0 1px 2px rgba(22,33,29,.06), 0 12px 28px -18px rgba(22,33,29,.35);
  --shadow-hover: 0 2px 4px rgba(22,33,29,.08), 0 22px 40px -20px rgba(22,33,29,.45);
  --shadow-float: 0 4px 10px rgba(22,33,29,.06), 0 26px 50px -24px rgba(22,33,29,.5);

  /* La coquille porte les grilles de cartes et les bandes photo, pas le texte :
     à 1920 px, 1200 n'utilisait que 63 % de l'écran pour une grille qui n'a
     aucune raison d'être étroite. La largeur de lecture, elle, reste à 68
     caractères (.prose) — entre 50 et 75, l'intervalle où l'oeil retrouve le
     début de la ligne suivante. Élargir le texte serait une régression. */
  --container: 1320px;
  --gutter: 24px;
}

/* --- 2. Base ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

/* Les ancres de page (sommaire du guide, sous-navigation des excursions)
   glissent au lieu de sauter, sauf réglage système contraire. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  text-wrap: balance;
  margin: 0;
}
h1 { font-size: clamp(2.4rem, 5.2vw, 4rem); font-variation-settings: "opsz" 144; line-height: 1.04; }
h2 { font-size: clamp(1.8rem, 3vw, 2.6rem); }
h3 { font-size: 1.2rem; font-variation-settings: "opsz" 24; }
p  { margin: 0; max-width: 68ch; }
a  { color: inherit; }

img { max-width: 100%; display: block; }

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

/* Le lien d'évitement : premier arrêt du clavier sur chaque page, masqué au
   repos (pas display:none, qui le sortirait de la tabulation), posé en haut à
   gauche au focus, au-dessus du header collant et du panneau du menu. Il prend
   le vert Doi des pastilles actives plutôt que le safran, réservé à la
   réservation. */
.skip-link {
  position: fixed;
  top: var(--sp-2);
  left: var(--sp-2);
  z-index: 100;
  padding: 0;
  border-radius: var(--r-btn);
  background: var(--c-primary);
  color: #fff;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.5;
  text-decoration: none;
  box-shadow: var(--shadow-float);
  clip-path: inset(50%);
  width: 1px;
  height: 1px;
  overflow: hidden;
  white-space: nowrap;
}
.skip-link:focus {
  clip-path: none;
  width: auto;
  height: auto;
  padding: var(--sp-2) var(--sp-4);
  overflow: visible;
}
/* La cible du lien d'évitement reçoit le focus (tabindex="-1") : pas d'anneau
   autour de toute la page, la tabulation suivante montre le sien. Sa marge de
   défilement couvre le header collant, pour que rien ne passe dessous. */
#main:focus { outline: none; }
#main { scroll-margin-top: 80px; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0;
}

.section { padding-block: var(--sp-9); }
.section--tight { padding-block: var(--sp-8); }
.section--alt { background: var(--c-surface); }

/* --- Rythme vertical resserré --------------------------------------------
   Par défaut, deux sections voisines mettent 208 px entre leur dernière et
   leur première ligne (104 + 104). Sur une page qui enchaîne des blocs courts
   — une grille de cartes, une bande de renvois, une FAQ — cet écart n'est plus
   du rythme, c'est un trou : le lecteur croit la page finie. Il passe ici à
   96 px entre deux sections et 80 px de part et d'autre d'un bloc serré, un
   peu plus de la moitié.

   Porté par l'accueil, le hub des excursions et les pages du guide. Les pages
   catégorie, les fiches et les articles gardent le rythme par défaut : leur
   contenu est d'un seul tenant, l'air y sépare des choses différentes. */
.page-tight .section { padding-block: var(--sp-7); }
.page-tight .section--tight { padding-block: var(--sp-6); }

/* Deux bandes teintées qui se suivent ne sont qu'une seule bande à l'oeil :
   doubler le rembourrage à leur jonction creuse un vide au milieu d'un aplat
   continu, ce qui se lit comme un défaut et pas comme une séparation. */
.section--alt + .section--alt { padding-top: 0; }

.section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-7);
}

/* --- 3. Boutons --------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 44px;
  padding: 0 var(--sp-5);
  border: 0;
  border-radius: var(--r-btn);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.btn--cta {
  background: var(--c-cta);
  color: #fff;
  box-shadow: 0 8px 18px -10px rgba(209,66,8,.9);
}
.btn--cta:hover { background: var(--c-cta-hover); transform: translateY(-1px); }
.btn--ghost {
  background: transparent;
  color: var(--c-primary);
  border: 1.5px solid var(--c-border);
}
.btn--ghost:hover { border-color: var(--c-primary); background: var(--c-primary-soft); }
/* Le meme appel a l'action, en contour. Sur l'accueil les cartes d'excursion
   alignaient trois aplats orange a la suite, ce qui usait la couleur d'accent
   pour le reste de la page : ici le filet suffit, la surface de clic ne bouge
   pas, et l'aplat au survol dit que c'est bien le meme bouton. */
.btn--cta-line {
  background: transparent;
  color: var(--c-cta);
  border: 1.5px solid var(--c-cta);
}
.btn--cta-line:hover { background: var(--c-cta); color: #fff; transform: translateY(-1px); }
/* L'appui. Un téléphone n'a pas de survol : sans cet état, rien ne confirmait
   le toucher avant le chargement de la page suivante. */
.btn:active, .hero__paths a:active { transform: translateY(1px); transition-duration: .05s; }

/* --- 4. Barre d'annonce + header --------------------------------------- */
.announce {
  background: var(--c-primary-deep);
  color: #D8E4DC;
  font-size: 13px;
  text-align: center;
  padding: var(--sp-2) var(--gutter);
}
.announce b { color: var(--c-secondary); font-weight: 700; }

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,255,255,.92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--c-border);
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  min-height: 72px;
}
.logo {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.25rem;
  letter-spacing: -.02em;
  color: var(--c-primary);
  text-decoration: none;
  white-space: nowrap;
}
.logo span { color: var(--c-secondary); }
/* Sur le fond blanc du header, l'or Lanna ne tient que 2,9:1 : le logo y prend
   l'or encré (5,0:1). Le pied de page, vert profond, garde l'or Lanna (5,1:1). */
.site-header .logo span { color: var(--c-secondary-ink); }

.nav { margin-left: auto; }
.nav__list { display: flex; gap: var(--sp-5); list-style: none; margin: 0; padding: 0; }
.nav__item { position: relative; }
.nav__link {
  display: inline-block;
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
  color: var(--c-text);
  padding-block: var(--sp-2);
  border-bottom: 2px solid transparent;
}
.nav__link:hover { color: var(--c-primary); border-bottom-color: var(--c-secondary); }

/* --- 4a bis. Sous-menus du header (desktop) -------------------------------- */
/* Un silo déplie quatre à six liens vers des pages et des ancres qui existent
   déjà. Ce n'est pas un mega-menu : une colonne, la largeur d'une carte, la même
   ombre que le reste du site.

   Ouverture au survol ET au focus clavier : `:focus-within` suffit, aucun script
   n'est nécessaire. Le nom du silo reste un lien vers sa page, on peut donc
   cliquer « Temples » sans jamais ouvrir le panneau, exactement comme avant.

   Le panneau reste dans le flux d'un parent `position: relative` et remonte de
   quelques pixels : la zone entre le nom et la liste ne se traverse jamais à
   découvert, sans quoi le panneau se refermerait sous la souris. */
.nav__item::after {
  content: "";
  position: absolute;
  inset: 100% 0 auto 0;
  height: 14px;              /* le pont entre le nom et le panneau */
  display: none;
}
.nav__item:hover::after, .nav__item:focus-within::after { display: block; }
.nav__sub {
  position: absolute;
  top: calc(100% + 12px);
  left: -14px;
  z-index: 70;
  /* Assez large pour que chaque libellé tienne sur une ligne dans les deux
     langues : un item replié sur deux lignes casse le rythme de la colonne,
     et le français est plus long à sens égal. */
  min-width: 284px;
  list-style: none;
  margin: 0;
  padding: var(--sp-2);
  background: #fff;
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-float);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity .14s ease, transform .14s ease, visibility .14s;
}
.nav__item:hover > .nav__sub,
.nav__item:focus-within > .nav__sub {
  opacity: 1;
  visibility: visible;
  transform: none;
}
/* Échap referme le panneau sans déplacer le focus (site.js pose data-shut). Le
   survol passe devant : revenir à la souris rouvre, comme on s'y attend. */
.nav__item[data-shut]:not(:hover) > .nav__sub {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
}
.nav__sub a {
  display: block;
  padding: 9px var(--sp-3);
  border-radius: 8px;
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.35;
  text-decoration: none;
  color: var(--c-text);
}
.nav__sub a:hover, .nav__sub a:focus-visible { background: var(--c-primary-soft); color: var(--c-primary); }
/* Le premier lien est la page du silo elle-même : il porte le nom, pas un détail. */
.nav__sub li:first-child a { font-weight: 700; }
.nav__sub li:first-child { border-bottom: 1px solid var(--c-border); margin-bottom: var(--sp-1); padding-bottom: var(--sp-1); }

/* --- 4a ter. Un silo sans page : « À voir, à faire » ----------------------- */
/* Son nom est un <button> et non un lien : il n'a pas de page où mener. Il
   prend l'allure exacte des autres noms de silo, seul le curseur le distingue.

   Sans script, il s'ouvre comme les autres, au survol et au focus. Avec
   script, site.js pose data-ready sur le silo et lui donne aria-expanded :
   c'est alors cet état, et lui seul, qui ouvre le panneau. Le focus ne
   l'ouvre plus de lui-même, pour qu'un lecteur d'écran n'entende jamais
   « réduit » devant une liste affichée. Le survol à la souris passe par le
   script, qui met l'état à jour avant d'ouvrir. */
.nav__trigger {
  font-family: inherit;
  line-height: inherit;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  padding-inline: 0;
  cursor: pointer;
}
.nav__trigger[aria-expanded="true"] { border-bottom-color: var(--c-secondary); }
.nav__item[data-ready]:hover > .nav__sub,
.nav__item[data-ready]:focus-within > .nav__sub {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
}
.nav__item[data-ready] > .nav__trigger[aria-expanded="true"] + .nav__sub {
  opacity: 1;
  visibility: visible;
  transform: none;
}
/* Ici le premier lien n'est pas la page du silo : c'est un lieu comme les
   autres, sans graisse ni filet. */
.nav__item--group .nav__sub li:first-child a { font-weight: 500; }
.nav__item--group .nav__sub li:first-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 0; }

.header-actions { display: flex; align-items: center; gap: var(--sp-3); margin-left: var(--sp-4); }

/* Sélecteur de langue : pointe toujours vers la page équivalente, jamais vers l'accueil */
.langswitch {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--c-border);
  border-radius: var(--r-pill);
  overflow: hidden;
  background: var(--c-surface);
  font-size: 13px;
  font-weight: 700;
}
.langswitch a, .langswitch span {
  padding: 6px 13px;
  text-decoration: none;
  color: var(--c-muted);
  line-height: 1.4;
}
.langswitch [aria-current="true"] { background: var(--c-primary); color: #fff; }
.langswitch a:hover { background: var(--c-primary-soft); color: var(--c-primary); }

/* --- 4a. Menu mobile ------------------------------------------------------ */
/* Le même menu que la nav du haut, replié dans un <details> : ouverture au
   clic et au clavier, état annoncé aux lecteurs d'écran, zéro JavaScript.
   Masqué à partir de 1200 px, où la nav horizontale est visible. */
.menu { display: none; position: relative; }
.menu__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 14px 9px 12px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  color: var(--c-text);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  list-style: none;              /* pas de triangle */
  -webkit-tap-highlight-color: transparent;
}
.menu__btn::-webkit-details-marker { display: none; }
.menu__btn:focus-visible { outline: 3px solid var(--c-secondary); outline-offset: 2px; }
/* Trois barres dessinées en CSS : rien à charger. */
.menu__icon {
  position: relative;
  width: 18px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}
.menu__icon::before, .menu__icon::after {
  content: "";
  position: absolute;
  left: 0;
  width: 18px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}
.menu__icon::before { top: -6px; }
.menu__icon::after  { top: 6px; }
/* Ouvert, les trois barres deviennent une croix : l'état est visible. */
.menu[open] .menu__icon { background: transparent; }
.menu[open] .menu__icon::before { top: 0; transform: rotate(45deg); }
.menu[open] .menu__icon::after  { top: 0; transform: rotate(-45deg); }
.menu[open] .menu__btn { background: var(--c-primary); border-color: var(--c-primary); color: #fff; }
/* Voile plein écran : c'est un pseudo-élément du <summary>, donc un appui à
   côté du panneau referme le menu, sans une ligne de JavaScript. */
.menu[open] .menu__btn::after {
  content: "";
  position: fixed;
  inset: 60px 0 0 0;   /* la barre du header reste lisible */
  z-index: 60;
  background: rgba(10,43,44,.38);
}

.menu__panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 70;
  width: min(78vw, 300px);
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sp-3);
  background: #fff;
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  box-shadow: 0 18px 44px rgba(10,43,44,.22);
}
.menu__list { list-style: none; margin: 0; padding: 0; }
.menu__list a {
  display: block;
  padding: 13px var(--sp-3);
  border-radius: 10px;
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  color: var(--c-text);
}
.menu__list > li + li { border-top: 1px solid var(--c-border); }
.menu__list a:hover, .menu__list a:focus-visible { background: var(--c-primary-soft); color: var(--c-primary); }

/* Un silo du menu mobile tient sur une ligne en deux zones : le nom, qui navigue
   comme avant, et un chevron de 44 px qui déplie les sous-liens.

   Le chevron est un <summary> : ouverture au doigt, à Entrée et à Espace, état
   annoncé aux lecteurs d'écran, zéro JavaScript. La liste qu'il commande est sa
   voisine et non son contenu, parce qu'un <details> fermé cache tous ses enfants
   sauf le résumé : le nom du silo, lui, doit rester cliquable fermé. Le sélecteur
   `[open] ~` fait la liaison, et il est supporté partout depuis toujours. */
.menu__item { display: grid; grid-template-columns: 1fr auto; align-items: center; }
.menu__main { grid-column: 1; }
.menu__disc { grid-column: 2; }
.menu__chev {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  cursor: pointer;
  list-style: none;
  color: var(--c-muted);
  -webkit-tap-highlight-color: transparent;
}
.menu__chev::-webkit-details-marker { display: none; }
.menu__chev:hover { background: var(--c-primary-soft); color: var(--c-primary); }
.menu__chev:focus-visible { outline: 3px solid var(--c-secondary); outline-offset: -3px; }
/* Le chevron : deux traits, dessinés en CSS, qui pivotent à l'ouverture. */
.menu__arrow {
  width: 9px;
  height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform .18s ease;
}
.menu__disc[open] .menu__arrow { transform: translateY(2px) rotate(-135deg); }
.menu__disc[open] .menu__chev { color: var(--c-primary); }
.menu__sublist {
  grid-column: 1 / -1;
  display: none;
  list-style: none;
  margin: 0 0 var(--sp-2);
  padding: 0 0 0 var(--sp-3);
  border-left: 2px solid var(--c-border);
}
.menu__disc[open] ~ .menu__sublist { display: block; }
.menu__sublist a { padding: 10px var(--sp-3); font-size: 15px; font-weight: 500; color: var(--c-muted); }
.menu__sublist a:hover, .menu__sublist a:focus-visible { color: var(--c-primary); }
/* Un silo sans page : toute sa ligne est le <summary>. Le nom et le chevron
   s'alignent sur ceux des autres lignes, et l'état ouvert ou fermé est annoncé
   nativement, comme sur les chevrons. */
.menu__disc--group { grid-column: 1 / -1; }
.menu__group {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  padding-left: var(--sp-3);
  border-radius: 10px;
  font-size: 16px;
  font-weight: 600;
  color: var(--c-text);
  cursor: pointer;
  list-style: none;
  -webkit-tap-highlight-color: transparent;
}
.menu__group::-webkit-details-marker { display: none; }
/* Le survol seulement là où il existe : au doigt, un :hover resté collé après
   le toucher peindrait la ligne ouverte comme une ligne sélectionnée. */
@media (hover: hover) {
  .menu__group:hover { background: var(--c-primary-soft); color: var(--c-primary); }
}
.menu__group .menu__chev { background: transparent; }
.menu__group:focus-visible { outline: 3px solid var(--c-secondary); outline-offset: -3px; }
/* La ligne garde la hauteur des autres (53 px) : le chevron de 44 px plus le
   retrait vertical que les liens tiennent de leur padding. */
.menu__group { padding-block: 4.5px; }
.menu__cta { display: block; width: 100%; margin-top: var(--sp-3); text-align: center; }
.menu__hint {
  margin: var(--sp-2) 0 4px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--c-muted);
  text-align: center;
}

/* --- 4b. Header en surimpression (accueil) ------------------------------- */
/* Zéro JavaScript sur ce site : un header collant ne peut pas repasser en blanc
   au défilement, donc en surimpression il défile avec la photo. */
.site-header--overlay {
  position: absolute;
  top: 0;
  inset-inline: 0;
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
}
/* Voile court sous le menu : le haut de la photo peut être un ciel clair. */
.site-header--overlay::before {
  content: "";
  position: absolute;
  inset: 0 0 -40% 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(10,43,44,.58) 0%, rgba(10,43,44,0) 100%);
}
.site-header--overlay .logo { color: #fff; }
/* Sur la photo voilée, c'est l'or encré qui manquerait de contraste. */
.site-header--overlay .logo span { color: var(--c-secondary); }
.site-header--overlay .nav__link { color: #fff; }
.site-header--overlay .nav__link:hover { color: #fff; border-bottom-color: var(--c-secondary); }
.site-header--overlay .langswitch {
  background: rgba(255,255,255,.12);
  border-color: rgba(255,255,255,.38);
}
.site-header--overlay .langswitch a, .site-header--overlay .langswitch span { color: #EAF2ED; }
.site-header--overlay .langswitch [aria-current="true"] { background: #fff; color: var(--c-primary); }
.site-header--overlay .langswitch a:hover { background: rgba(255,255,255,.22); color: #fff; }

/* Bannière « ce site existe aussi en … » : jamais de redirection automatique */
.lang-hint {
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-size: 14px;
  text-align: center;
  padding: var(--sp-2) var(--gutter);
}
.lang-hint a { font-weight: 700; }

/* --- 5. Hero ------------------------------------------------------------ */
.hero {
  position: relative;
  min-height: 78vh;
  display: flex;
  align-items: flex-end;
  padding-block: var(--sp-9) var(--sp-8);
  color: #fff;
  isolation: isolate;
  overflow: hidden;
}
/* Dégradé de repli : utilisé par les heros de pages intérieures, et visible
   le temps que la photo du hero d'accueil se charge. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(120% 80% at 20% 15%, #2C6B5A 0%, transparent 60%),
    radial-gradient(90% 70% at 85% 10%,  #C68B2C 0%, transparent 55%),
    linear-gradient(160deg, #17514A 0%, #0F3D3E 45%, #0A2B2C 100%);
}
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(10,43,44,0) 0%, rgba(10,43,44,.4) 45%, rgba(10,43,44,.82) 100%);
}
/* --- 5b. Hero avec vraie photo (accueil) -------------------------------- */
/* Le header passe par-dessus la photo : le hero remonte sous lui et gagne la
   hauteur du menu, sinon le titre serait poussé hors de l'écran.

   La hauteur est calée sur le contenu réel — en-tête compensée, eyebrow, H1,
   sous-titre, bouton et preuves — et pas sur une fraction ronde de l'écran. À
   88vh l'accueil se lisait comme une couverture de magazine : rien ne disait
   qu'il y avait une page en dessous. À 78vh le début de la section suivante
   apparaît avec son eyebrow et son H2, pas seulement sa marge. Le rembourrage
   haut garde les 72 px du header en surimpression et lui ajoute une respiration
   d'un cran plus courte, ce qui rend au bas du hero la place que le bouton
   « Commencer ici » lui prend. */
.hero--photo {
  background-color: var(--c-primary);
  min-height: 78vh;
  padding-top: calc(72px + var(--sp-8));
  padding-bottom: var(--sp-7);
}
.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* La photo remplace le dégradé de repli, et le voile est renforcé : sur une
   image claire, le texte blanc ne tient pas avec le voile d'origine.
   Le Wat Chiang Man est clair et coloré : le voile vertical est allégé au
   milieu pour rendre au chedi son or, et c'est le voile latéral, plus dense à
   gauche, qui porte le contraste sous le titre. */
.hero--photo::before { content: none; }
.hero--photo::after {
  background:
    linear-gradient(180deg, rgba(10,43,44,.34) 0%, rgba(10,43,44,.30) 40%, rgba(10,43,44,.86) 100%),
    linear-gradient(90deg, rgba(10,43,44,.72) 0%, rgba(10,43,44,.4) 38%, rgba(10,43,44,0) 62%);
}
/* Sur tablette, le bloc de texte occupe plus de la moitié de la largeur et le
   surtitre passe devant le ciel : le voile latéral y est un peu plus dense et
   plus large. Le haut et le milieu de la photo gardent leurs valeurs. */
@media (min-width: 640px) and (max-width: 899px) {
  .hero--photo::after {
    background:
      linear-gradient(180deg, rgba(10,43,44,.34) 0%, rgba(10,43,44,.30) 40%, rgba(10,43,44,.86) 100%),
      linear-gradient(90deg, rgba(10,43,44,.80) 0%, rgba(10,43,44,.55) 45%, rgba(10,43,44,0) 75%);
  }
}

.hero .eyebrow { color: var(--c-secondary); }
/* L'or Lanna plein tient sur le dégradé des heros intérieurs, pas sur une vraie
   photo : mesuré sur le rendu, il tombait à 3,7:1 en bas de l'image en grand
   écran et à 1,5:1 sur mobile, où le bloc de texte remonte dans le ciel clair.
   Cette teinte plus claire du même or repasse au-dessus de 4,5:1 des deux côtés
   (environ 6,5:1 en grand écran, 4,5:1 sur mobile avec le voile renforcé plus
   bas) sans toucher aux eyebrow du reste du site ni aux autres heros. */
.hero--photo .eyebrow { color: var(--c-secondary-light); }
/* Sur les passages clairs de la photo (ciel, pignon doré), l'or perd du
   contraste : une ombre courte et un halo discret le détachent sans changer sa
   teinte. */
.hero--photo .eyebrow { text-shadow: 0 1px 2px rgba(10,43,44,.6), 0 0 10px rgba(10,43,44,.5); }
/* Le français est plus long à sens égal : à 14ch le titre passait sur trois
   lignes en grand écran, et « regret. » ou « CATALOGUE » restaient seuls. Les
   mots ne changent pas, seules les coupures. */
:lang(fr) .hero--photo h1 { text-wrap: balance; }
/* « Chiang Mai, expliquée » tient sur une ligne dès la tablette ; à 14ch le
   titre passait sur trois lignes et remontait le surtitre dans le ciel. */
@media (min-width: 768px) { :lang(fr) .hero--photo h1 { max-width: 20ch; } }
:lang(fr) .hero--photo .hero__sub,
:lang(fr) .hero--photo .eyebrow { text-wrap: pretty; }
.hero h1 { color: #fff; max-width: 14ch; margin-block: var(--sp-4) var(--sp-5); font-weight: 900; }
/* Le sous-titre du hero est écrit pour tenir sur deux lignes dans les deux
   langues (60 à 116 caractères). La hauteur des deux lignes est réservée : le
   français est plus long à sens égal, et sans cette réserve un hero anglais et
   son équivalent français ne feraient pas la même hauteur. */
.hero__sub {
  font-size: 19px; color: #DCE7E0; max-width: 52ch;
  line-height: 1.55;
  min-height: 3.1em;
}

/* Les raccourcis sous le sous-titre : six pages qui répondent aux questions qu'on
   arrive avec. Des pastilles sur verre fumé, lisibles sur la photo, et une
   cible de 44 px. Sur téléphone la rangée défile de côté au lieu de s'empiler
   sur trois lignes, comme la barre de section de « Commencer ici ». */
.hero__paths {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: center;
  margin-top: var(--sp-5);
}
.hero__paths span { font-size: 14px; font-weight: 700; color: #DCE7E0; margin-right: var(--sp-2); }
.hero__paths a {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 var(--sp-4);
  border: 1.5px solid rgba(255,255,255,.42);
  border-radius: var(--r-pill);
  background: rgba(10,43,44,.38);
  backdrop-filter: blur(6px);
  color: #fff; font-size: 15px; font-weight: 700;
  text-decoration: none; white-space: nowrap;
  transition: background-color .18s ease, border-color .18s ease;
}
.hero__paths a:hover { background: rgba(10,43,44,.6); border-color: #fff; }
@media (max-width: 639px) {
  .hero__paths {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter);
  }
  .hero__paths::-webkit-scrollbar { display: none; }
  .hero__paths span { display: none; }
}

/* Le rendez-vous de saison : une carte sur le même verre fumé que les
   raccourcis, filet et titre dans l'or du hero, pour qu'on la voie sans la
   prendre pour une publicité. Elle mène à un article du site, pas à une
   réservation, et reste seconde : sous les raccourcis jusqu'à 1023 px, puis
   dans le vide à droite du titre. Là, le hero passe en deux colonnes, mais le
   bouton et les raccourcis gardent toute la largeur : rien de ce qui existait
   ne change de place. */
.hero__season {
  display: inline-flex; flex-direction: column; gap: 2px;
  max-width: 100%;
  margin-top: var(--sp-5);
  padding: var(--sp-3) var(--sp-5);
  border: 1.5px solid rgba(239,196,110,.6);
  border-radius: var(--r-card);
  background: rgba(10,43,44,.5);
  backdrop-filter: blur(6px);
  color: #fff; text-decoration: none;
  transition: background-color .18s ease, border-color .18s ease;
}
.hero__season:hover { background: rgba(10,43,44,.7); border-color: #EFC46E; }
.hero__season-k {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.15rem; line-height: 1.25; color: #EFC46E;
}
/* La date et l'action ne se coupent jamais en leur milieu : si la ligne ne
   tient pas, elle passe à la ligne après le point, pas au milieu de
   « Préparer vos soirées ». */
.hero__season-p { font-size: 15px; font-weight: 700; line-height: 1.4; }
.hero__season-p > span { white-space: nowrap; }
@media (max-width: 639px) {
  .hero__season { padding: var(--sp-3) var(--sp-4); }
  .hero__season-p { font-size: 14px; }
}
@media (min-width: 1024px) {
  .hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--sp-7);
  }
  .hero__grid > * { grid-column: 1; }
  .hero__grid > .hero__paths { grid-column: 1 / -1; }
  .hero__grid > .hero__season {
    grid-column: 2; grid-row: 1 / 4;
    align-self: end; margin-top: 0;
  }
}

/* Les deux promesses du site, descendues du hero dans la présentation de la
   ville : elles appuient l'argument au lieu de concurrencer le bouton. */
.proofs { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.proofs li { display: flex; gap: var(--sp-2); font-weight: 500; color: var(--c-primary); }
.proofs li::before { content: "\2713"; color: var(--c-secondary-ink); font-weight: 700; }

/* --- 6. Barre de recherche (chevauche le hero) -------------------------- */
.searchbar-wrap { margin-top: calc(var(--sp-7) * -1); position: relative; z-index: 10; }
.searchbar {
  background: var(--c-surface);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-float);
  padding: var(--sp-4);
  display: grid;
  grid-template-columns: 2.2fr 1fr 1fr auto;
  gap: var(--sp-3);
  align-items: center;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-btn);
  background: var(--c-bg);
  min-height: 56px;
  justify-content: center;
}
.field label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-muted);
}
.field input, .field select {
  border: 0;
  background: transparent;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--c-text);
  padding: 0;
  width: 100%;
}
.field input:focus, .field select:focus { outline: none; }
.field:focus-within { box-shadow: inset 0 0 0 2px var(--c-primary); }

.searchbar .btn--cta { height: 56px; }

.quick-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
  font-size: 14px;
  color: var(--c-muted);
}
.quick-links a {
  text-decoration: none;
  color: var(--c-primary);
  font-weight: 700;
  padding: 4px 12px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-pill);
  background: var(--c-surface);
}
.quick-links a:hover { border-color: var(--c-primary); background: var(--c-primary-soft); }

/* --- 7. Chiffres clés --------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-5);
  padding-block: var(--sp-8);
  border-bottom: 1px solid var(--c-border);
}
.stat__n {
  font-family: var(--font-display);
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--c-primary);
  font-variant-numeric: tabular-nums;
}
.stat__l { font-size: 14px; color: var(--c-muted); }

/* --- 8. Grille + carte d'excursion -------------------------------------- */
.grid-tours {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-5);
}

.tour-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: transform .22s ease, box-shadow .22s ease;
}
.tour-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); }

.tour-card__media {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: linear-gradient(150deg, #2C6B5A, #0F3D3E);
}
/* Remplit son conteneur, quel qu'il soit : carte d'excursion ou carte de catégorie. */
.ph {
  position: absolute;
  inset: 0;
  transition: transform .5s ease;
}
.tour-card:hover .ph { transform: scale(1.06); }

/* La photo de la vignette : posée sur le dégradé, qui reste visible tant qu'elle
   n'est pas chargée, et qui zoome avec elle au survol. */
.tour-card__shot {
  position: absolute;
  inset: 0;
  transition: transform .5s ease;
}
.tour-card__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.tour-card:hover .tour-card__shot { transform: scale(1.06); }
.ph--inthanon { background: linear-gradient(155deg,#3D7F63 0%,#14514B 55%,#0A2B2C 100%); }
.ph--elephant { background: linear-gradient(155deg,#7A9A5E 0%,#2E6248 60%,#12332C 100%); }
.ph--cuisine  { background: linear-gradient(155deg,#D9A343 0%,#B0662A 55%,#5C3316 100%); }

.badge {
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  background: var(--c-secondary);
  color: #21160A;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: var(--r-pill);
}
.fav {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255,255,255,.9);
  color: var(--c-primary);
  cursor: pointer;
}
.duration {
  position: absolute;
  bottom: var(--sp-3);
  right: var(--sp-3);
  background: rgba(10,43,44,.72);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  padding: 5px 11px;
  border-radius: var(--r-pill);
}

/* La micro-étiquette d'une carte : « notre préférée », « la meilleure
   demi-journée ». Quatre excursions sur dix-neuf en portent une. En haut à
   gauche de la photo, la durée restant en bas à droite. */
.tour-tag {
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: 1;
  background: var(--c-secondary);
  /* Du blanc sur l'or tenait 2,9:1 ; le brun du badge en tient 6:1. */
  color: #21160A;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: var(--r-pill);
  box-shadow: 0 2px 8px rgba(10,43,44,.28);
}

/* « Pour qui » et « à éviter si ». Deux lignes qui font le tri à la place du
   lecteur, et surtout la seconde : dire à qui une sortie ne convient pas est ce
   qui sépare une sélection d'un catalogue. */
.tour-fit { margin: 0; font-size: 13.5px; line-height: 1.45; }
.fit__row { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-2); }
.fit__row + .fit__row { margin-top: var(--sp-1); }
.tour-fit dt {
  font-weight: 700;
  color: var(--c-primary);
  white-space: nowrap;
}
.fit__row--skipif dt { color: var(--c-muted); }
.tour-fit dd { margin: 0; color: var(--c-muted); }

.tour-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  flex: 1;
}
.tour-card__title {
  font-size: 1.2rem;
  min-height: 2.6em;                 /* réserve 2 lignes → grille alignée */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tour-card__title a { text-decoration: none; }
.tour-card__title a::after { content: ""; position: absolute; inset: 0; } /* carte cliquable */

.rating { display: flex; align-items: center; gap: var(--sp-2); font-size: 14px; }
.rating .stars { color: var(--c-secondary); letter-spacing: 1px; }
.rating b { font-variant-numeric: tabular-nums; }
.rating span { color: var(--c-muted); }

.perks { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: 14px; color: var(--c-muted); }
.perks li::before { content: "✓ "; color: var(--c-primary); font-weight: 700; }

.tour-card__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-top: auto;
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
  border-top: 1px solid var(--c-border);
}
.price__from { font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--c-muted); }
.price__n {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.price__eur { font-size: 14px; color: var(--c-muted); font-weight: 500; }
.price__free { font-size: 12px; color: var(--c-primary); font-weight: 700; }
.tour-card__foot .btn { position: relative; z-index: 2; } /* passe au-dessus de l'overlay */

/* --- 9. Réassurance ----------------------------------------------------- */
.reassure { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-5); }
.reassure__item { display: grid; gap: var(--sp-3); }
.reassure__icon {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: 12px;
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-size: 20px;
}
.reassure h3 { font-size: 1.05rem; }
.reassure p { font-size: 15px; color: var(--c-muted); }

/* --- 10. Bandeau éthique ------------------------------------------------ */
.ethic {
  background: var(--c-primary);
  color: #E6EFE9;
  border-radius: var(--r-card);
  padding: var(--sp-8) var(--sp-7);
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: var(--sp-7);
  align-items: center;
}
.ethic h2 { color: #fff; }
.ethic p { color: #C9DAD1; }
/* Le surtitre de la bande : de l'or clair, lisible en petit sur le vert. */
.ethic .eyebrow { color: var(--c-secondary-light); }

/* --- 11. Étapes --------------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-6); counter-reset: step; }
.step { display: grid; gap: var(--sp-3); }
.step__n {
  counter-increment: step;
  font-family: var(--font-display);
  font-size: 2.4rem;
  font-weight: 900;
  color: var(--c-secondary);
  line-height: 1;
}
.step__n::before { content: counter(step, decimal-leading-zero); }

/* --- 12. Avis ----------------------------------------------------------- */
.reviews { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); }
.review {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  padding: var(--sp-5);
  display: grid;
  gap: var(--sp-3);
}
.review blockquote { margin: 0; font-size: 16px; }
.review footer { font-size: 14px; color: var(--c-muted); }

/* --- 13. Footer --------------------------------------------------------- */
.site-footer { background: var(--c-primary-deep); color: #B9CCC3; padding-block: var(--sp-8) var(--sp-6); }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: var(--sp-6); }
.footer-col__title { color: #fff; font-size: 1rem; margin-bottom: var(--sp-3);
  font-family: var(--font-display); font-weight: 700; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); font-size: 15px; }
.site-footer a { color: #B9CCC3; text-decoration: none; }
.site-footer a:hover { color: var(--c-secondary); }
.footer-legal {
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid rgba(255,255,255,.12);
  font-size: 13px;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  justify-content: space-between;
}

/* --- 15. Responsive ----------------------------------------------------- */
/* Le header passe au bouton Menu sous 1200 px, et non sous 1024 comme le
   reste de la mise en page : avec « Préparer le voyage » en tête, six entrées,
   le sélecteur de langue et le bouton orange ne tiennent plus sur une ligne
   entre 1024 et 1200 px (en français, chaque libellé se repliait sur deux). */
@media (max-width: 1199px) {
  /* La nav disparaît : c'est elle qui portait le margin-left:auto. Le bouton
     menu la remplace, à droite du sélecteur de langue. */
  .nav { display: none; }
  .header-actions { margin-left: auto; gap: var(--sp-2); }
  .menu { display: block; }
  /* Sur mobile le header ne survole plus la photo : il reste collé en haut,
     sur fond plein, pour que le menu soit atteignable depuis n'importe quel
     endroit de la page. Sans JavaScript un header transparent ne peut pas
     redevenir lisible au défilement. */
  .site-header__inner { min-height: 60px; gap: var(--sp-3); }
  /* Les deux commandes du header tactile : au doigt, elles faisaient 34 px et
     32 px de haut. Un plancher de 44 px les met à la taille de cible
     recommandée sans toucher aux marges intérieures, donc sans les élargir ;
     la barre garde ses 60 px, et le clavier comme la souris ne voient rien. */
  .menu__btn { min-height: 44px; }
  .langswitch a, .langswitch span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
  }
  /* Pas de backdrop-filter sur mobile : la propriété crée un bloc contenant
     pour les éléments en position fixed, et le voile plein écran du menu ne
     couvrirait plus que la barre du header. Fond plein, même lisibilité. */
  .site-header { background: var(--c-surface); backdrop-filter: none; }
  .site-header--overlay {
    position: sticky;
    background: var(--c-surface);
    backdrop-filter: none;
    border-bottom-color: var(--c-border);
  }
  .site-header--overlay::before { content: none; }
  .site-header--overlay .logo { color: var(--c-primary); }
  .site-header--overlay .logo span { color: var(--c-secondary-ink); }
  .site-header--overlay .langswitch { background: var(--c-surface); border-color: var(--c-border); }
  .site-header--overlay .langswitch a, .site-header--overlay .langswitch span { color: var(--c-muted); }
  .site-header--overlay .langswitch [aria-current="true"] { background: var(--c-primary); color: #fff; }
  /* Le hero n'a plus de header à compenser au-dessus de lui. */
  .hero--photo { padding-top: var(--sp-8); min-height: 72vh; }
}
/* Entre 1200 et 1279 px, sept entrées, le sélecteur de langue et le bouton
   orange ne tiennent sur une ligne en français qu'à condition de resserrer
   l'espace entre les entrées. Au-delà, l'espacement d'origine revient. */
@media (min-width: 1200px) and (max-width: 1279px) {
  .nav__list { gap: var(--sp-4); }
}
@media (max-width: 1023px) {
  .grid-tours, .reassure, .reviews, .steps { grid-template-columns: repeat(2, 1fr); }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .searchbar { grid-template-columns: 1fr 1fr; }
  .searchbar .btn--cta { grid-column: 1 / -1; }
  .ethic, .footer-grid { grid-template-columns: 1fr; }
}
@media (min-width: 640px) and (max-width: 1199px) {
  /* Le header garde son bouton orange à cette largeur : inutile de le répéter
     au bas du menu. */
  .menu__cta, .menu__hint { display: none; }
}
@media (max-width: 639px) {
  .grid-tours, .reassure, .reviews, .steps, .searchbar { grid-template-columns: 1fr; }
  .hero { min-height: 68vh; }
  .hero--photo { min-height: 70vh; padding-top: var(--sp-7); }
  /* Les paliers du voile sont des pourcentages de la hauteur du hero : calés
     sur le grand écran, où le texte occupe la moitié basse de l'image. Sur
     mobile le même texte occupe presque toute la hauteur et sa première ligne
     se retrouve dans le ciel, là où le voile ne fait encore que 34 %. Le haut
     est donc assombri ici, et ici seulement, dès 15 %, là où commence le
     surtitre : au-dessus, le voile s'allège pour laisser voir le ciel et la
     flèche du chedi. */
  /* Le chedi est aux deux tiers de la photo : sur un écran étroit, le cadrage
     centré ne garderait que les arbres entre les deux bâtiments. */
  .hero--photo .hero__media img { object-position: 70% center; }
  .hero--photo::after {
    background:
      linear-gradient(180deg, rgba(10,43,44,.36) 0%, rgba(10,43,44,.66) 15%, rgba(10,43,44,.72) 30%, rgba(10,43,44,.92) 100%),
      linear-gradient(90deg, rgba(10,43,44,.58) 0%, rgba(10,43,44,0) 62%);
  }
  /* Le bouton du header passait sur deux lignes et rognait le sélecteur de
     langue : le menu porte le même appel, en bas de son panneau. */
  .header-actions > .btn--cta { display: none; }
  /* Sur un écran de 360 px, le logo, les langues et le menu tiennent sur une
     ligne à condition de serrer un peu. */
  .logo { font-size: 1.12rem; }
  .menu__btn { padding: 8px 12px 8px 10px; font-size: 13px; }
  .menu__icon, .menu__icon::before, .menu__icon::after { width: 16px; }
  .langswitch a, .langswitch span { padding: 6px 11px; }
  .section { padding-block: var(--sp-8); }
  .tour-card__foot { flex-direction: column; align-items: stretch; }
  .tour-card__foot .btn { width: 100%; }
  .menu__panel { width: min(86vw, 320px); }
}

/* --- 16. Mouvement réduit ----------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .tour-card:hover { transform: none; }
  .tour-card:hover .ph, .cat-card:hover .ph { transform: none; }
  .tour-card:hover .tour-card__shot { transform: none; }
  .cat-card:hover .cat-card__shot { transform: none; }
}

/* ==========================================================================
   Ajouts : pages catégorie, hub, et dégradés par thème
   ========================================================================== */

/* Dégradés par catégorie : fond de chargement sous la photo de la case,
   et repli complet pour une catégorie qui n'en a pas encore. */
.ph--nature    { background: linear-gradient(155deg,#4E8F73 0%,#17564C 55%,#0A2B2C 100%); }
.ph--adventure { background: linear-gradient(155deg,#B4703A 0%,#6E4326 55%,#2A1B12 100%); }
.ph--temple    { background: linear-gradient(155deg,#E2E6E4 0%,#9BB4C9 45%,#3B5B72 100%); }

/* --- Hero compact des pages intérieures -------------------------------- */
.hero--page { min-height: 44vh; padding-block: var(--sp-8) var(--sp-7); }
.hero--page h1 { max-width: 20ch; }
/* Un itinéraire est un outil, pas une page de présentation : on vient y chercher
   le premier jour, pas une image. Son hero garde le même dessin, la même
   typographie et le même dégradé, sur un cinquième de hauteur en moins, ce qui
   remonte le bandeau de faits et l'aperçu dans le premier écran. */
.hero--itin { min-height: 34vh; padding-block: var(--sp-7) var(--sp-6); }

/* --- Fil d'Ariane ------------------------------------------------------- */
.crumbs { font-size: 14px; color: var(--c-muted); padding-block: var(--sp-4); }
.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.crumbs li::after { content: "›"; margin-left: var(--sp-2); color: var(--c-border); }
.crumbs li:last-child::after { content: ""; }
.crumbs a { color: var(--c-primary); text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.crumbs [aria-current="page"] { color: var(--c-muted); }

/* Le fil d'Ariane crée déjà une respiration : la section qui suit n'a pas besoin
   du plein padding haut, sinon le haut de page part en blanc. */
.crumbs + .section, .crumbs + .section--tight { padding-top: var(--sp-6); }

/* --- Corps de texte éditorial ------------------------------------------ */
.prose { display: grid; gap: var(--sp-4); max-width: 68ch; margin-inline: 0; }
.prose p { font-size: 17px; }
.prose strong { color: var(--c-primary); font-weight: 700; }

/* --- Grille de catégories (hub) ---------------------------------------- */
.cat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); }
/* Une seule case : elle ne se tasse plus dans le premier tiers d'une grille à
   trois colonnes, avec deux tiers de vide à sa droite. Elle prend la largeur
   d'une colonne de lecture, en format horizontal. Sans :has(), la grille garde
   son format habituel : la case reste une carte verticale, rien ne casse. */
@supports selector(:has(*)) {
  @media (min-width: 768px) {
    .cat-grid:has(> .cat-card:only-child) { grid-template-columns: minmax(0, 860px); }
    .cat-grid:has(> .cat-card:only-child) > .cat-card { flex-direction: row; }
    .cat-grid:has(> .cat-card:only-child) > .cat-card .cat-card__media { flex: 0 0 42%; aspect-ratio: auto; min-height: 220px; }
    .cat-grid:has(> .cat-card:only-child) > .cat-card .cat-card__body { align-self: center; }
  }
}
.cat-card {
  position: relative;
  display: flex; flex-direction: column;
  border: 1px solid var(--c-border); border-radius: var(--r-card);
  background: var(--c-surface); overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: transform .22s ease, box-shadow .22s ease;
}
.cat-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); }
.cat-card__media { aspect-ratio: 16/9; position: relative; overflow: hidden; }
.cat-card:hover .ph { transform: scale(1.04); }
/* La photo de la case : posée sur le dégradé, qui reste visible tant qu'elle
   n'est pas chargée. object-fit la recadre au format du panneau — 16/9 pour les
   trois premières cases, 21/9 pour les deux dernières au-delà de 1024 px. */
.cat-card__shot { position: absolute; inset: 0; transition: transform .5s ease; }
.cat-card__shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cat-card:hover .cat-card__shot { transform: scale(1.04); }
.cat-card__body { padding: var(--sp-5); display: grid; gap: var(--sp-2); }
.cat-card__body h3 a { text-decoration: none; }
.cat-card__body h3 a::after { content: ""; position: absolute; inset: 0; }
.cat-card__count { font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--c-secondary); }
.cat-card__body p { font-size: 15px; color: var(--c-muted); }

/* --- Titre d'une liste de cartes ---------------------------------------- */
/* Une liste de cartes n'a pas le droit de commencer aux h3 sans intitule : le
   niveau saute, et la liste n'est annoncee a personne. Le titre reste discret,
   il nomme la liste, il ne rouvre pas une section. */
.list-title {
  font-size: 1.35rem;
  margin: var(--sp-7) 0 var(--sp-5);
}

/* --- Pied de carte : un seul CTA pleine largeur ------------------------- */
.tour-card__foot--single { display: block; }
.tour-card__foot--single .btn { width: 100%; }
.tour-card__note { font-size: 12px; color: var(--c-muted); text-align: center; margin-top: var(--sp-2); }

/* Le prix de départ, au-dessus du bouton. Le surtitre et le nombre reprennent
   .price__from et .price__n, écrits pour le pied à deux colonnes d'origine :
   la ligne s'aligne donc d'elle-même sur le prix du hero d'une fiche. */
.tour-card__price {
  display: flex; align-items: baseline; gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}
.tour-card__price .price__n { font-size: 1.35rem; }

/* --- FAQ ---------------------------------------------------------------- */
.faq { display: grid; gap: var(--sp-3); max-width: 78ch; }
.faq details {
  border: 1px solid var(--c-border); border-radius: var(--r-card);
  background: var(--c-surface); padding: var(--sp-4) var(--sp-5);
}
.faq summary {
  cursor: pointer; font-family: var(--font-display); font-weight: 700;
  font-size: 1.05rem; list-style: none; display: flex; justify-content: space-between; gap: var(--sp-4);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; color: var(--c-secondary); font-size: 1.3rem; line-height: 1;
  transition: transform .25s cubic-bezier(.2,.7,.2,1);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq summary:hover { color: var(--c-cta); }
.faq details[open] summary { margin-bottom: var(--sp-3); }
.faq p { font-size: 15px; color: var(--c-muted); }

/* Renvoi d'une page categorie vers la page du guide qui la cite. */
.cat-guide a {
  font-weight: 700; color: var(--c-primary); text-decoration: none;
  border-bottom: 2px solid var(--c-secondary);
}
.cat-guide a:hover { color: var(--c-cta); }
/* « À lire ensuite » au-dessus du titre visé, sur sa propre ligne : un tiret
   entre les deux était la seule liaison possible sur une ligne, et le titre
   porte souvent ses propres deux-points. */
.cat-guide__k {
  display: block; margin-bottom: var(--sp-1);
  font-size: 13px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--c-muted);
}

/* --- Divulgation d'affiliation ----------------------------------------- */
/* La bande éthique de l'accueil : le bouton vers les sorties, et sous lui le
   renvoi vers la page qui explique la règle. Deux poids, deux rôles. */
.ethic__acts { display: grid; gap: var(--sp-3); justify-items: start; }
.ethic__more { font-size: 14px; font-weight: 700; color: var(--c-secondary-light); text-decoration: none; }
.ethic__more:hover { text-decoration: underline; }

.disclosure {
  font-size: 13px; color: var(--c-muted);
  border-left: 3px solid var(--c-secondary);
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-4);
  max-width: 68ch;
}

/* Cinq cartes dans une grille de trois colonnes laissaient une case morte de
   368 x 420 px en bas à droite. Au-delà de 1024 px, sur une base de six
   colonnes, les trois premières cartes en prennent deux et les deux dernières
   en prennent trois : les deux rangées sont pleines. Une carte moitié plus
   large garderait une vignette en 16/9 moitié plus haute, qui écraserait la
   première rangée : elle passe en 21/9, et les rangées finissent à la même
   hauteur. En dessous de 1024 px la grille reprend le comportement commun à
   tout le site, deux colonnes puis une. La classe n'est posée que s'il y a
   bien cinq cartes, c'est build_home qui le vérifie. */
@media (min-width: 1024px) {
  .cat-grid--fill { grid-template-columns: repeat(6, 1fr); }
  .cat-grid--fill > * { grid-column: span 2; }
  .cat-grid--fill > :nth-last-child(-n+2) { grid-column: span 3; }
  .cat-grid--fill > :nth-last-child(-n+2) .cat-card__media { aspect-ratio: 21 / 9; }
}

/* Le bloc blog : deux articles, deux colonnes. */
.cat-grid--2 { grid-template-columns: repeat(2, 1fr); }

@media (max-width: 1023px) {
  .cat-grid { grid-template-columns: repeat(2, 1fr); }
  .callout__head { grid-template-columns: 1fr; }
}
@media (max-width: 639px)  {
  .cat-grid, .cat-grid--2 { grid-template-columns: 1fr; }
  .hero--page { min-height: auto; }
}

/* ==========================================================================
   Silo guide : pages piliers, blog, blocs éditoriaux de l'accueil
   ========================================================================== */

/* --- Intro d'une page catégorie : orientation + texte -------------------- */
/* Le texte seul laissait 441 px de vide à sa droite. Le panneau les occupe
   avec ce qu'un guide dit d'un lieu — où, combien de temps, quand — sans
   élargir d'un pixel la colonne de lecture. */
.cat-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr);
  gap: var(--sp-7);
  align-items: start;
}
.factbox { border-left: 3px solid var(--c-secondary); padding-left: var(--sp-5); }
.factbox dl { margin: 0; }
.factbox dt {
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--c-muted); margin-top: var(--sp-4);
}
.factbox dt:first-child { margin-top: 0; }
.factbox dd {
  margin: 4px 0 0; font-size: 15px; line-height: 1.5; color: var(--c-text); max-width: 34ch;
}
/* Le budget ferme le panneau, en petit et en gris : c'est un repère avant de
   descendre dans les cartes, pas un argument. */
.factbox__budget { font-size: 14px; color: var(--c-muted); }

@media (max-width: 1023px) {
  .cat-intro { grid-template-columns: 1fr; gap: var(--sp-5); }
  .factbox { order: 2; }
  .factbox dd { max-width: none; }
}

/* --- Accueil : bloc d'introduction en deux colonnes ---------------------- */
.intro-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
  gap: var(--sp-7);
  align-items: start;
}
.intro-split > div:first-child h2 { margin-top: var(--sp-2); }

/* --- Accueil : encart « à lire avant de réserver » ----------------------- */
.callout {
  background: var(--c-primary);
  color: #fff;
  border-radius: var(--r-card);
  padding: var(--sp-7);
  max-width: 78ch;
}
.callout h2 { color: #fff; margin-block: var(--sp-2) var(--sp-4); }
.callout p { color: #DCE7E0; }
.callout .eyebrow { color: var(--c-secondary-light); }
.callout .btn--ghost { color: #fff; border-color: rgba(255,255,255,.45); }
.callout .btn--ghost:hover { background: rgba(255,255,255,.12); border-color: #fff; }

/* --- La frise des douze mois -------------------------------------------
   Le bloc "quand venir" portait le même patron que les autres panneaux : un
   surtitre, un titre, un paragraphe. La frise en fait un objet d'information.
   Les couleurs viennent de la palette du site, et comme la couleur seule ne
   dit rien à un lecteur d'écran, chaque case porte aussi le nom de sa saison
   en texte masqué à l'oeil. */
.u-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* Le panneau des saisons prend toute la largeur : à 78ch il laissait 356 px
   de vide à sa droite, et la frise des douze mois n'y tenait qu'à l'étroit.
   Le titre et le texte se répartissent en deux colonnes, la frise passe
   dessous sur toute la largeur. */
.callout--season { max-width: none; }
.callout__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-5) var(--sp-7);
  align-items: start;
}
/* Le bouton reste sous le titre : sinon la colonne de gauche, deux lignes de
   titre face à sept lignes de texte, se creusait de 130 px. */
.callout__aside { display: grid; gap: var(--sp-4); justify-items: start; align-content: start; }
.callout__aside h2 { margin-bottom: var(--sp-1); }
.season { margin-top: var(--sp-7); }
.season__title {
  font-size: 12px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--c-secondary); margin-bottom: var(--sp-3);
}
.season__bar {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(12, 1fr); gap: 5px;
}
/* Le mois est écrit au-dessus de sa couleur, jamais dessus : un libellé posé
   sur un aplat oblige à choisir une couleur de texte qui tienne sur les
   quatre saisons, et février, qui est à cheval, n'en a aucune. */
.season__m {
  display: grid; gap: var(--sp-2); text-align: center;
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--c-muted);
}
.season__m::after { content: ""; height: 10px; border-radius: 3px; background: var(--season-c, #7FA98F); }
.is-best  { --season-c: var(--c-secondary); }
.is-green { --season-c: #7FA98F; }
.is-hot   { --season-c: #C9DAD1; }
.is-smoke { --season-c: #8C8577; }
/* Février est à cheval : les brûlis commencent vers le milieu du mois. */
.is-best-smoke { --season-c: linear-gradient(90deg, var(--c-secondary) 0 50%, #8C8577 50% 100%); }
.season__key {
  list-style: none; margin: var(--sp-4) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-5);
  font-size: 13px; color: var(--c-muted);
}
.season__key li { display: flex; align-items: center; }
.season__key b { display: inline-block; width: 14px; height: 14px; border-radius: 4px; margin-right: 8px; background: var(--season-c); }
/* La frise est nee dans le panneau sombre de l'accueil, et elle en portait les
   couleurs partout : sur le fond clair de /start-here/, #DCE7E0 tombait a
   1,15:1, soit un libelle qu'on devine plutot qu'on ne le lit. Le cas courant
   est donc le fond clair, avec le gris de texte secondaire du site (5,11:1,
   celui des libelles .fact__k), et le panneau sombre garde sa teinte claire. */
.callout .season__m,
.callout .season__key { color: #DCE7E0; }

/* --- Page guide : sommaire collant + colonne de texte -------------------- */
.guide {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: var(--sp-8);
  align-items: start;
  /* Plafonné sous la coquille : le texte est déjà bridé à 68 caractères, une
     coquille plus large ne ferait qu'agrandir le vide à sa droite. Les bandes
     de cartes de la même page, elles, profitent bien des 1320 px. */
  max-width: 1152px;
}
/* Le sommaire vit dans un <details>. En grand écran il est ouvert (site.js
   l'ouvre), son résumé est masqué et c'est l'enveloppe qui colle : rien ne
   change à l'œil. Sur téléphone il se replie en une ligne, sans quoi ses six à
   neuf liens remplissaient le premier écran avant la première phrase. */
.guide__fold {
  position: sticky;
  top: 96px;
  /* Jamais plus haut que l'écran sous le header : un long sommaire défile
     dans son cadre, et ses derniers liens restent atteignables. Un sommaire
     court n'atteint pas la limite et ne change pas. */
  max-height: calc(100vh - 96px - var(--sp-4));
  overflow-y: auto;
  overscroll-behavior: contain;
}
.guide__sum { display: none; }
.guide__toc {
  font-size: 15px;
  border-left: 2px solid var(--c-border);
  padding-left: var(--sp-4);
}
.guide__toc-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-muted);
  margin-bottom: var(--sp-3);
}
.guide__toc ol { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.guide__toc a { color: var(--c-text); text-decoration: none; }
.guide__toc a:hover { color: var(--c-primary); text-decoration: underline; }
/* Les lieux d'une section, sous son titre : plus petits, en retrait, pour que
   la liste des sections reste lisible d'un coup d'œil. */
.guide__toc .guide__toc-sub {
  margin: var(--sp-2) 0 var(--sp-1);
  padding-left: var(--sp-3);
  gap: var(--sp-1);
  font-size: 14px;
  border-left: 1px solid var(--c-border);
}
.guide__toc-sub a { color: var(--c-muted); }

.prose h2 {
  font-size: clamp(1.5rem, 2.4vw, 1.95rem);
  margin-block: var(--sp-8) var(--sp-4);
  scroll-margin-top: 96px;
}
.prose h2:first-child { margin-top: 0; }
.prose .lede { font-size: 19px; color: var(--c-text); }

/* --- Photo éditoriale dans le corps d'une page guide --------------------- */
/* Aucun rapport n'est imposé : l'image garde le cadrage du fichier, et ce sont
   les attributs width/height qui réservent sa place avant qu'elle n'arrive.
   Imposer un 16/9 ici aurait rogné les photos verticales jusqu'au paysage. */
.media { margin: var(--sp-2) 0; }
/* Plafonnée à la largeur du fichier le plus large servi en simple densité : au
   delà, le navigateur agrandirait une source de 720 px pour remplir la colonne,
   c'est-à-dire vendrait du flou pour de la netteté. */
.media--full { max-width: 720px; }
.media__shot { display: block; }
.media__shot img {
  display: block; width: 100%; height: auto;
  border-radius: var(--r-card); background: var(--c-border);
}
/* Le médaillon : la réponse aux photos verticales. Servie sur toute la colonne,
   une 9/16 fait défiler l'écran entier sur une seule image ; bridée ici, elle
   garde son cadrage et laisse le texte respirer à côté d'elle. */
.media--inset { max-width: 320px; }
.media__cap { margin-top: var(--sp-2); font-size: 14px; color: var(--c-muted); }

/* --- Sources repliées en fin d'article ----------------------------------- */
/* Une ligne sous un filet, en texte secondaire : la référence est là pour qui
   veut vérifier, sans carte ni titre qui la ferait passer pour un chapitre.
   Le « + » reprend celui de la FAQ, en or encré pour tenir le contraste à
   cette taille. Le contenu est dans le HTML, replié ou non. */
.src-note { border-top: 1px solid var(--c-border); padding-top: var(--sp-1); color: var(--c-muted); font-size: 15px; }
.src-note__sum {
  list-style: none; cursor: pointer; min-height: 44px; padding-block: var(--sp-2);
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  font-weight: 700;
}
.src-note__sum::-webkit-details-marker { display: none; }
/* Sources puis crédits : deux lignes d'une même bande, sans l'écart de la colonne. */
.src-note + .src-note { margin-top: calc(-1 * var(--sp-4)); }
.src-note__sum::after {
  content: "+"; flex: none; color: var(--c-secondary-ink); font-size: 1.25rem; line-height: 1;
  transition: transform .25s cubic-bezier(.2,.7,.2,1);
}
.src-note[open] .src-note__sum::after { transform: rotate(45deg); }
.src-note__sum:hover { color: var(--c-text); }
.src-note__body { display: grid; gap: var(--sp-3); padding-bottom: var(--sp-4); }
.src-note__body p { margin: 0; font-size: 15px; max-width: none; }
.src-note__list { margin: 0; padding-left: 1.1em; display: grid; gap: var(--sp-2); line-height: 1.55; }
.src-note a { color: inherit; text-underline-offset: 2px; overflow-wrap: anywhere; }
.src-note a:hover { color: var(--c-text); }
@media (prefers-reduced-motion: reduce) { .src-note__sum::after { transition: none; } }
@media (max-width: 639px) {
  /* Sur mobile la colonne fait toute la largeur : sans plafond, une verticale
     occuperait plus d'un écran de haut à elle seule. */
  .media--inset { max-width: 260px; margin-inline: auto; }
}

/* --- Fiches lieu (temples, quartiers, modes de transport) ---------------- */
.place-list { display: grid; gap: var(--sp-5); margin-block: var(--sp-5) var(--sp-6); }
/* Une carte est une cible d'ancre : le header collant ne doit pas la recouvrir. */
.place[id] { scroll-margin-top: 96px; }
.place {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  padding: var(--sp-5) var(--sp-6);
}
.place h3 { font-size: 1.2rem; margin: 0; }
.place__meta {
  font-size: 14px;
  font-weight: 700;
  color: var(--c-primary);
  margin-block: 4px var(--sp-3);
}
.place p:last-child { margin-bottom: 0; }
/* L'offre sortante d'une carte : de l'air au-dessus du bouton, et sur
   téléphone un rembourrage plus court pour que le libellé tienne sur une
   ligne. Seules les cartes à offre portent ce bouton. */
.place .btn--cta-line { margin-top: var(--sp-4); }
@media (max-width: 639px) {
  .place .btn--cta-line { padding-inline: var(--sp-4); }
}
/* Une fiche avec photo : la photo au-dessus sur mobile, en vignette à gauche
   au-delà. Toujours en 16/9, quelle que soit la longueur du texte : les cartes
   d'une même liste gardent la même image, et la place est réservée avant
   l'arrivée du fichier. */
.place--shot { display: grid; gap: var(--sp-4) var(--sp-5); align-items: start; }
.place__shot { display: block; }
.place__shot img {
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 9;
  object-fit: cover; border-radius: var(--r-btn); background: var(--c-border);
}
@media (min-width: 640px) {
  .place--shot { grid-template-columns: 240px minmax(0, 1fr); }
}

/* --- Tableau des saisons ------------------------------------------------- */
.table-wrap { overflow-x: auto; margin-block: var(--sp-5) var(--sp-6); }
.data-table { width: 100%; border-collapse: collapse; font-size: 16px; }
.data-table th, .data-table td {
  text-align: left;
  vertical-align: top;
  padding: var(--sp-4) var(--sp-4) var(--sp-4) 0;
  border-bottom: 1px solid var(--c-border);
}
.data-table th { width: 11rem; color: var(--c-primary); font-weight: 700; white-space: nowrap; }

/* --- Tableau comparatif -------------------------------------------------- */
/* Le .data-table d'à côté est fait pour deux colonnes, un intitulé et sa valeur.
   Celui-ci croise des sujets et des critères : sept quartiers, cinq colonnes.

   Il reste un vrai tableau, avec ses en-têtes de ligne et de colonne, parce que
   c'est ce qui le rend lisible à la voix. Les rôles ARIA sont écrits en clair
   dans le HTML : sous 640 px la mise en page passe en blocs empilés, et un
   display: block sur un <tr> effacerait sinon la sémantique du tableau. */
.compare-table {
  width: 100%;
  /* Il vit dans la colonne de lecture, bridée à 68 caractères : le tableau tient
     dedans en laissant les valeurs se replier, plutôt que de glisser sous une
     colonne coupée. Le plancher ne sert qu'aux largeurs intermédiaires, où la
     colonne se resserre pour de bon. */
  min-width: 600px;
  border-collapse: collapse;
  font-size: 14.5px;
}
.compare-table th, .compare-table td {
  border-bottom: 1px solid var(--c-border);
  padding: 11px var(--sp-3) 11px 0;
  text-align: left;
  vertical-align: top;
  line-height: 1.4;
}
.compare-table thead th {
  color: var(--c-primary);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
  border-bottom-width: 2px;
}
.compare-table tbody th { font-weight: 700; color: var(--c-text); }
/* Sans repartition, la mise en page automatique donnait tout l'espace libre a la
   premiere colonne et serrait « Best for », qui est la colonne qu'on lit. */
.compare-table thead th:first-child { width: 19%; }
.compare-table thead th:nth-child(2) { width: 27%; }
.compare-table thead th:nth-child(3) { width: 14%; }
.compare-table thead th:nth-child(4) { width: 17%; }
.compare-table thead th:nth-child(5) { width: 11%; }
.compare-table thead th:nth-child(6) { width: 12%; }
.compare-table tbody th a { color: var(--c-primary); text-decoration: none; border-bottom: 1px solid var(--c-border); }
.compare-table tbody th a:hover { border-bottom-color: var(--c-secondary); }
.compare-table tbody tr:last-child th, .compare-table tbody tr:last-child td { border-bottom: 0; }

/* --- Bloc « choisir son quartier » --------------------------------------- */
/* Quatre cas de figure, quatre réponses, chacune vers la fiche qui la détaille.
   C'est la réponse courte pour qui ne lira pas les sept descriptions. */
.picks {
  margin-block: var(--sp-6);
  padding: var(--sp-5);
  background: var(--c-primary-soft);
  border-radius: var(--r-card);
}
.picks__title { margin: 0 0 var(--sp-4); font-size: 1.15rem; }
.pick-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-4);
}
.pick {
  padding: var(--sp-4);
  background: var(--c-surface);
  border-radius: 10px;
}
.pick__q { margin: 0; font-size: 13px; font-weight: 700; color: var(--c-muted); text-transform: uppercase; letter-spacing: .03em; }
.pick__a { margin: var(--sp-1) 0 var(--sp-2); font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; }
.pick__a a { color: var(--c-primary); text-decoration: none; border-bottom: 2px solid var(--c-secondary); }
.pick__a a:hover { color: var(--c-cta); }
.pick__p { margin: 0; font-size: 14.5px; line-height: 1.5; color: var(--c-muted); }
/* La réponse courte de « que réserver » : un verdict par carte, et sous lui les
   lignes qui le composent, chacune menant à la section qui la justifie. La
   carte, sa grille et son titre viennent du bloc ci-dessus ; seule la liste
   manquait, et le titre y remplace le lien unique par une icône. */
.pick__a svg { vertical-align: -3px; margin-right: 7px; color: var(--c-secondary-ink); }
.pick__items { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.pick__items li { font-size: 14.5px; line-height: 1.45; color: var(--c-muted); }
.pick__items a { color: var(--c-primary); font-weight: 700; text-decoration: none; }
.pick__items a:hover, .pick__items a:focus-visible {
  text-decoration: underline;
  text-decoration-color: var(--c-secondary);
  text-underline-offset: 3px;
}

/* Sous 640 px le tableau s'empile : une carte par sujet, chaque valeur précédée
   de l'intitulé de sa colonne. Six colonnes qui glissent horizontalement sur
   360 px ne se lisent pas. Les rôles ARIA du HTML gardent la sémantique du
   tableau, que ces display: block effaceraient sinon.

   Ce bloc vit ici, et pas dans le @media du haut de la feuille : celui-là est
   antérieur au composant, et à spécificité égale c'est la dernière règle qui
   gagne. Le min-width du tableau y survivait à l'empilement et débordait de la
   page de vingt-neuf pixels. */
@media (max-width: 639px) {
  .pick-list { grid-template-columns: 1fr; }
  .compare-table, .compare-table tbody, .compare-table tr,
  .compare-table thead th, .compare-table tbody th, .compare-table td { display: block; }
  .compare-table { min-width: 0; }
  .compare-table thead { display: none; }
  .compare-table tr {
    margin-bottom: var(--sp-4);
    padding: var(--sp-4);
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-card);
  }
  .compare-table tbody th {
    padding: 0 0 var(--sp-3);
    font-family: var(--font-display);
    font-size: 1.1rem;
    white-space: normal;
    border-bottom: 1px solid var(--c-border);
  }
  .compare-table td { padding: var(--sp-2) 0 0; border: 0; }
  .compare-table td::before {
    content: attr(data-col);
    display: block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--c-muted);
  }
}

/* --- « Vérifié en … » ---------------------------------------------------- */
/* Une note de service, pas une section : sur les pages pratiques et
   commerciales, elle dit quand le contenu a été relu. La date est écrite à la
   main dans le JSON de la page, jamais déduite de la date de génération. */
.last-checked {
  margin: var(--sp-6) 0 0;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--c-border);
  font-size: 13px;
  color: var(--c-muted);
}

/* --- Widget de disponibilité GetYourGuide (fin d'article) ---------------- */
/* Le widget est rendu par un iframe chargé après coup : sans hauteur réservée,
   la page saute au moment où il s'insère (mauvais CLS, et le lecteur perd sa
   ligne). Le fond gris tient la place en attendant. */
.gyg-embed {
  margin-block: var(--sp-5) var(--sp-4);
  min-height: 220px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  padding: var(--sp-4);
}
.gyg-embed > div { max-width: 100%; }
.gyg-embed span { font-size: 13px; color: var(--c-muted); }
.gyg-embed a { color: var(--c-primary); }

/* --- Accueil : bandes piliers ------------------------------------------
   Trois cartes de deux lignes ne faisaient pas le poids face aux excursions.
   La bande prend la largeur du conteneur : le guide à gauche, ce qu'il y a
   dedans à droite. Le fond alterne d'une bande à l'autre pour qu'on lise
   trois blocs et non une liste. */
.pillars { display: grid; gap: var(--sp-4); }
.pillar {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: var(--sp-7);
  align-items: start;
  padding: var(--sp-6) var(--sp-7);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  background: var(--c-surface);
}
.pillar:nth-child(even) { background: var(--c-bg); }
.pillar { overflow: hidden; }
.pillar__side { display: grid; gap: var(--sp-3); }
/* La photo du guide. Empilée, elle court d'un bord à l'autre de la bande en
   haut ; en grand écran elle devient une colonne pleine hauteur à gauche. Elle
   a remplacé le médaillon : trois bandes de texte d'affilée faisaient défiler
   six écrans de téléphone avant la première image de l'accueil. */
.pillar__photo {
  display: block;
  margin: calc(var(--sp-5) * -1) calc(var(--sp-5) * -1) 0;
}
.pillar__photo img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 9; object-fit: cover;
  background: var(--c-border);
}
.pillar__title { font-size: clamp(1.5rem, 2.2vw, 1.9rem); font-variation-settings: "opsz" 60; }
.pillar__title a { text-decoration: none; }
.pillar__title a:hover { color: var(--c-cta); }
.pillar__lede { color: var(--c-muted); font-size: 16px; max-width: 56ch; }
.pillar__go { margin-top: var(--sp-2); }
.pillar__inside {
  /* Centrée plutôt que calée en haut : la liste est plus courte que le
     chapeau, et le vide se voyait tout entier en bas à droite de la bande. */
  align-self: center;
  padding-left: var(--sp-6);
  border-left: 1px solid var(--c-border);
}
.pillar__label {
  font-size: 12px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--c-secondary-ink);
  margin-bottom: var(--sp-3);
}
.pillar__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.pillar__list li { border-top: 1px solid var(--c-border); padding-top: var(--sp-2); }
.pillar__list li:first-child { border-top: 0; padding-top: 0; }
.pillar__list a {
  text-decoration: none; font-weight: 700; font-size: 15px;
  color: var(--c-primary); display: inline-flex; gap: var(--sp-2);
}
.pillar__list a::before { content: "\203A"; color: var(--c-secondary-ink); }
.pillar__list a:hover { color: var(--c-cta); }

/* --- Accueil : bandes piliers, grand écran ------------------------------
   Empilée, la bande tient déjà : tout ce bloc ne concerne que le grand écran,
   où elle était haute et creuse. La photo du guide prend une colonne de
   280 px pleine hauteur à gauche. Les deux colonnes de texte se resserrent
   (1,1 contre 1 au lieu de 1,25) pour que le chapeau cesse de s'arrêter au
   milieu de sa colonne. La droite devient un rail pleine hauteur : le filet
   court du haut au bas de la bande, le libellé se cale sur le surtitre de
   gauche, et les trois entrées se partagent la hauteur restante
   au lieu de flotter au centre avec du vide au-dessus et au-dessous. Le
   bouton, enfin, prend le filet vert plutôt que le filet gris : c'est la
   sortie de la bande, elle ne se lisait pas comme telle. */
@media (min-width: 1024px) {
  .pillar {
    grid-template-columns: 280px minmax(0, 1.1fr) minmax(0, 1fr);
    gap: var(--sp-7);
    padding: 0 var(--sp-6) 0 0;
  }
  .pillar__photo { margin: 0; position: relative; align-self: stretch; }
  .pillar__photo img { position: absolute; inset: 0; height: 100%; aspect-ratio: auto; }
  .pillar__side { row-gap: var(--sp-2); padding-block: var(--sp-6); }
  .pillar__title { margin-top: var(--sp-1); letter-spacing: -.005em; }
  .pillar__lede { max-width: 58ch; }
  .pillar__go { margin-top: var(--sp-3); }
  /* Le filet gris du bouton se confondait avec ceux du rail. */
  .pillar__go .btn { border-color: var(--c-primary); }

  .pillar__inside {
    align-self: stretch;
    display: flex;
    flex-direction: column;
    padding-left: var(--sp-6);
    padding-block: var(--sp-6);
  }
  /* Le libellé se cale sur le surtitre de la colonne voisine : les deux
     colonnes partent de la même ligne. */
  .pillar__label { margin-bottom: var(--sp-2); }
  .pillar__list { flex: 1; display: flex; flex-direction: column; gap: 0; }
  .pillar__list li {
    flex: 1;
    display: flex; align-items: center;
    border-top: 1px solid var(--c-border);
    padding-block: var(--sp-3);
  }
  .pillar__list li:first-child { padding-top: var(--sp-3); }
  /* L'entrée prend toute la largeur du rail, le chevron passe à droite : trois
     lignes pleines se lisent comme un sommaire, trois lignes courtes non. */
  .pillar__list a {
    width: 100%;
    justify-content: space-between;
    align-items: center;
    gap: var(--sp-4);
    font-size: 16px;
    transition: color .18s ease;
  }
  .pillar__list a::before { content: none; }
  .pillar__list a::after {
    content: "\203A";
    color: var(--c-secondary-ink);
    transition: transform .18s ease;
  }
  .pillar__list a:hover::after { transform: translateX(3px); }
}

/* --- Accueil : sous-bloc d'une section ----------------------------------
   Les excursions tiennent maintenant dans une seule section : la sélection et
   le bandeau éthique en sont des sous-blocs, séparés par du rythme plutôt que
   par un nouveau fond pleine largeur. */
.subblock { margin-top: var(--sp-8); }
.section__head--sub { margin-bottom: var(--sp-6); }
.h-sub { font-size: clamp(1.5rem, 2.4vw, 2.1rem); font-variation-settings: "opsz" 72; }
.ethic--in { margin-top: var(--sp-8); }
.ethic h3 { color: #fff; }

/* --- Carte de page guide (accueil et blog) ------------------------------- */
.cat-grid--3 { grid-template-columns: repeat(3, 1fr); }
.cat-card--guide .cat-card__body { padding-top: var(--sp-6); }
.cat-card--guide h3 { font-size: 1.35rem; }
.cat-grid--posts { margin-top: var(--sp-6); }

/* Catégorie d'un article : une pastille verte au-dessus de la date. Elle ne
   cherche pas le clic (il n'y a pas de page par catégorie), elle sert à
   classer d'un coup d'oeil une liste qui va s'allonger. */
.cat-card__body .post-card__cat {
  justify-self: start;
  margin: 0 0 var(--sp-2);
  padding: 3px var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* Photo d'une carte d'article : en tête de carte, d'un bord à l'autre, comme
   sur les cartes d'excursion. Posée entre le titre et le chapeau, elle coupait
   le texte et tombait à une hauteur différente sur chaque carte, selon que le
   titre prenait une, deux ou trois lignes. */
.post-card__photo { display: block; }
.post-card__photo img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16/10; object-fit: cover;
  background: var(--c-border);
}
/* Article sans photo : même emprise que la photo, avec le dégradé de repli des
   heros intérieurs. Décoratif, masqué aux lecteurs d'écran. */
.post-card__photo--none {
  aspect-ratio: 16/10;
  background:
    radial-gradient(120% 80% at 20% 15%, #2C6B5A 0%, transparent 60%),
    radial-gradient(90% 70% at 85% 10%,  #C68B2C 0%, transparent 55%),
    linear-gradient(160deg, #17514A 0%, #0F3D3E 45%, #0A2B2C 100%);
}

/* --- Blog : filtre par catégorie ----------------------------------------
   Deux articles aujourd'hui, deux catégories, et une liste qui n'a vocation
   qu'à s'allonger : le tri se fait sur place, en haut de la liste, plutôt que
   par une page par catégorie — à ce volume ces pages seraient presque vides et
   Google n'aurait aucune raison de les indexer.

   C'est un groupe de boutons radio : clic, clavier (flèches entre les
   pastilles), état coché annoncé aux lecteurs d'écran. Le tri lui-même est
   dans assets/js/site.js.

   Il était en CSS : une règle `:has()` par catégorie, numérotées de un à huit,
   que la feuille et le générateur devaient tenir à l'identique — le blog était
   plafonné à huit rayons et le filtre disparaissait entièrement sans `:has()`.
   Une ligne de comparaison en JavaScript remplace les huit règles, sans
   plafond.

   Le HTML livre le bloc `hidden` et c'est le script qui le montre : sans lui,
   la liste entière, et aucune pastille qui promettrait un tri qui n'aurait pas
   lieu. C'est aussi ce que voit un robot d'indexation. */
.post-filter { margin: 0; padding: 0; border: 0; min-inline-size: 0; }
.post-filter__legend {
  padding: 0; margin-bottom: var(--sp-2);
  font-size: 12px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--c-muted);
}
.post-filter__chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* Le bouton radio reste focusable — il est déplacé hors de l'écran, pas
   masqué : `display: none` le retirerait de l'ordre de tabulation et le
   groupe deviendrait inatteignable au clavier. C'est sa pastille qui porte
   l'anneau de focus. */
.post-filter__radio {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%);
}
.post-filter__chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 36px; padding: 0 var(--sp-4);
  border: 1.5px solid var(--c-border); border-radius: var(--r-pill);
  background: var(--c-surface); color: var(--c-primary);
  font-size: 13px; font-weight: 700; letter-spacing: .04em;
  cursor: pointer;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
.post-filter__chip:hover { border-color: var(--c-primary); background: var(--c-primary-soft); }
.post-filter__n { font-weight: 400; color: var(--c-muted); font-variant-numeric: tabular-nums; }
.post-filter__radio:checked + .post-filter__chip {
  background: var(--c-primary); border-color: var(--c-primary); color: #fff;
}
.post-filter__radio:checked + .post-filter__chip .post-filter__n { color: #A8C2B2; }
.post-filter__radio:focus-visible + .post-filter__chip {
  outline: 2px solid var(--c-cta); outline-offset: 3px;
}

/* La carte écartée est masquée par l'attribut `hidden`, que le script pose et
   retire : elle sort de l'affichage et de l'arbre d'accessibilité d'un coup.
   La règle est nécessaire — `.cat-card` déclare `display: flex`, qui gagnerait
   sinon contre le `display: none` par défaut de `[hidden]`. */
.post-card[hidden] { display: none; }

/* ==========================================================================
   Page d'expérience : une page par excursion, sous sa catégorie
   ==========================================================================
   Le principe de mise en page : une colonne de lecture et une carte de
   réservation collante à sa droite. Le prix et le bouton restent sous les yeux
   pendant toute la lecture, et la page cesse d'être une pile de sections
   pleine largeur qu'il faut dérouler jusqu'au bout pour réserver.
   Zéro JavaScript, comme le reste du site : le collant, les ancres, les
   glissières et les accordéons sont tous en CSS. */

/* Hero resserré : sur une fiche produit, la ligne de faits et le bouton
   doivent tenir dans le premier écran avec le titre. */
.hero--tour { min-height: 62vh; padding-block: var(--sp-9) var(--sp-8); }
.hero--tour h1 { max-width: 20ch; margin-block: var(--sp-3) var(--sp-4); font-size: clamp(2rem, 3.8vw, 3.2rem); }
.hero--tour .hero__sub { max-width: 56ch; }

/* Entrée : la photo se révèle, puis le texte monte ligne par ligne. Tout est
   en transform et opacity, rien qui fasse recalculer la mise en page, et rien
   du tout si le système demande moins d'animation. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
  @keyframes reveal-img { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: none; } }
  .hero--tour .hero__media { animation: reveal-img 1.4s cubic-bezier(.2,.7,.2,1) both; }
  .hero--tour .eyebrow,
  .hero--tour h1,
  .hero--tour .hero__sub,
  .hero--tour .tour-meta,
  .hero--tour .tour-actions { animation: rise .7s cubic-bezier(.2,.7,.2,1) both; }
  .hero--tour .eyebrow      { animation-delay: .10s; }
  .hero--tour h1            { animation-delay: .18s; }
  .hero--tour .hero__sub    { animation-delay: .30s; }
  .hero--tour .tour-meta    { animation-delay: .40s; }
  .hero--tour .tour-actions { animation-delay: .48s; }
}

.tour-meta { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-6); margin-top: var(--sp-5); }
.tour-meta__item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 15px;
  color: #DCE7E0;
}
.tour-meta__item b { color: #fff; font-weight: 700; }
.tour-meta svg, .incl svg, .rail__list svg, .fact__k svg { flex: none; }
.tour-meta svg { color: var(--c-secondary); }
.hero .tour-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-6); }
/* Le bouton fantôme est vert sur fond clair : sur le hero sombre il disparaît. */
.hero .btn--ghost { color: #fff; border-color: rgba(255,255,255,.45); }
.hero .btn--ghost:hover { background: rgba(255,255,255,.12); border-color: #fff; }

/* Hero avec photo : le header n'est pas en surimpression ici, donc pas de
   padding supplémentaire, seulement le voile renforcé. */
.hero--shot::before { content: none; }
/* Même or éclairci que sur l'accueil : l'or plein ne tient pas 4,5:1 sur une
   photo, même sous le voile. */
.hero--shot .eyebrow { color: var(--c-secondary-light); }
.hero--shot::after {
  background:
    linear-gradient(180deg, rgba(10,43,44,.36) 0%, rgba(10,43,44,.55) 45%, rgba(10,43,44,.92) 100%),
    linear-gradient(90deg, rgba(10,43,44,.72) 0%, rgba(10,43,44,.32) 45%, rgba(10,43,44,0) 70%);
}
/* Voile allégé (clé "shade": "soft") : pour une photo dont le sujet est en
   bas de l'image. Le bas n'est plus éteint à 92 % ; c'est le voile latéral,
   un peu plus dense sous le texte, qui porte le contraste du titre. */
.hero--shot-soft::after {
  background:
    linear-gradient(180deg, rgba(10,43,44,.30) 0%, rgba(10,43,44,.34) 50%, rgba(10,43,44,.62) 100%),
    linear-gradient(90deg, rgba(10,43,44,.78) 0%, rgba(10,43,44,.48) 42%, rgba(10,43,44,0) 74%);
}
/* Sur téléphone, le texte occupe toute la largeur, coin clair compris : le
   voile latéral n'y suffit plus, c'est un voile vertical uniforme qui le
   remplace, assez léger pour laisser voir les toits en bas. */
@media (max-width: 767px) {
  .hero--shot-soft::after {
    background: linear-gradient(180deg, rgba(10,43,44,.66) 0%, rgba(10,43,44,.56) 55%, rgba(10,43,44,.7) 100%);
  }
}

/* L'offre d'ouverture d'un article : un renvoi discret dans le hero, à droite
   du titre sur grand écran, sous le sous-titre sur mobile. Le titre reste le
   premier plan : le bloc est petit, en texte courant, et son bouton est en
   contour, un cran sous le bouton plein de la carte plus bas dans l'article.
   Le côté droit de la photo est le plus clair (le voile latéral s'y arrête) :
   le bloc porte son propre fond sombre, sinon ni le texte blanc ni le filet
   safran ne tiendraient sur les lanternes. Ni collant, ni flottant. */
.hero-offer {
  margin-top: var(--sp-5);
  max-width: 34rem;
  padding: var(--sp-5);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: var(--r-card);
  background: rgba(10,43,44,.78);
  backdrop-filter: blur(6px);
}
.hero-offer__t {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.2rem; font-weight: 700; line-height: 1.2;
  font-variation-settings: "opsz" 24;
  color: #fff;
  text-wrap: balance;
}
.hero-offer__p { margin: var(--sp-2) 0 var(--sp-4); font-size: 15px; line-height: 1.5; color: #DCE7E0; }
/* Contour safran, fond transparent, texte blanc : le filet tient 3:1 sur le
   fond du bloc, le texte blanc bien au-delà. Il se remplit au survol, comme
   le bouton en contour du reste du site. Le libellé peut passer sur deux
   lignes plutôt que déborder du bloc. */
.hero-offer__btn {
  width: 100%;
  padding-inline: var(--sp-4);
  border: 1.5px solid var(--c-cta);
  background: transparent;
  color: #fff;
  text-align: center;
}
.hero-offer__btn:hover { background: var(--c-cta); transform: translateY(-1px); }
/* L'anneau de focus du site est safran : contre un filet safran il ne se voit
   pas. L'or clair, celui des menus, le détache sur le fond sombre. */
.hero-offer__btn:focus-visible { outline-color: var(--c-secondary-light); }
.hero-offer__note { margin: var(--sp-3) 0 0; font-size: 13px; color: #B9CCC3; }
@media (min-width: 1024px) {
  .hero__split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--sp-7);
    align-items: end;
  }
  .hero-offer { margin-top: 0; max-width: none; }
}

/* Sous-navigation collante : elle se pose sous le header et donne les six
   points de la page. Sans elle, la seule façon d'atteindre la FAQ est le
   défilement. Sur mobile elle glisse horizontalement. */
.tour-nav {
  position: sticky;
  top: 71px;
  z-index: 40;
  background: rgba(255,255,255,.94);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--c-border);
}
/* Sous 1200 px le header passe au bouton Menu et mesure 60 px : la barre se
   recale dessous. Déclaré après la règle de base, sinon ses 71 px l'emportent. */
@media (max-width: 1199px) {
  .tour-nav { top: 59px; }
}
.tour-nav ul {
  display: flex;
  gap: var(--sp-6);
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.tour-nav ul::-webkit-scrollbar { display: none; }
/* Sur un téléphone, la barre déborde et rien ne le disait : le dernier lien
   était coupé net et pouvait passer pour la fin de la liste.

   Un voile de la couleur de la barre couvre le bord droit tant qu'il reste à
   faire défiler, et s'efface une fois au bout. C'est son opacité qui s'anime,
   sur la position de défilement de la liste : `animation-timeline`, déjà utilisé
   par la barre de progression de lecture et par les révélations au défilement.
   Une barre qui tient en entier n'a pas de défilement, donc pas de chronologie,
   donc pas de voile, sans qu'aucune mesure ait été faite.

   L'opacité s'anime nativement, contrairement à une longueur glissée dans un
   `mask-image` : là, le `var()` du dégradé se fige à la première résolution et
   le voile ne repart jamais. Le voile est posé sur la coquille et non sur la
   liste, sinon il défilerait avec elle.

   Là où `timeline-scope` manque, il n'y a simplement pas de voile : c'est le
   comportement d'avant, et rien ne se casse. */
@supports (animation-timeline: scroll()) and (timeline-scope: --x) {
  .tour-nav { timeline-scope: --nav-scroll; }
  .tour-nav ul { scroll-timeline: --nav-scroll inline; }
  .tour-nav > .container { position: relative; }
  .tour-nav > .container::after {
    content: "";
    position: absolute;
    inset-block: 0;
    right: var(--gutter);
    width: 44px;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(255,255,255,0), #fff 78%);
    /* Le repos est « pas de voile ». Une barre qui tient en entier n'a pas de
       défilement : sa chronologie est inactive, l'animation ne s'applique pas,
       et c'est cette valeur de base qui reste. */
    opacity: 0;
    animation: nav-more linear both;
    animation-timeline: --nav-scroll;
  }
  @keyframes nav-more {
    0%, 82% { opacity: 1; }
    100%    { opacity: 0; }
  }
}
.tour-nav a {
  display: block;
  padding: var(--sp-4) 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--c-muted);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.tour-nav a:hover { color: var(--c-primary); border-bottom-color: var(--c-secondary); }
/* La section en cours de lecture. Aucune règle CSS ne peut la connaître : c'est
   assets/js/site.js qui pose `aria-current`, et le même attribut porte le repère
   visuel et l'annonce aux lecteurs d'écran. Sans le script, la barre reste ce
   qu'elle était — six liens qui marchent, sans repère de position. */
.tour-nav a[aria-current] { color: var(--c-primary); border-bottom-color: var(--c-primary); }
/* Les ancres doivent s'arrêter sous le header et sa sous-navigation. */
.tour-page [id] { scroll-margin-top: 132px; }
/* Hub des excursions : chaque catégorie est une cible de la barre collante,
   elle s'arrête donc sous le header et la barre, pas derrière. */
.hub-cat { scroll-margin-top: 124px; }
/* Le nombre d'excursions d'une catégorie, à côté de son nom dans la barre. */
.tour-nav__n { font-weight: 500; color: var(--c-muted); font-variant-numeric: tabular-nums; margin-left: 2px; }

/* Tuiles de faits : les quatre questions qu'on se pose avant de lire quoi que
   ce soit, répondues sans défiler. */
.facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); margin-top: var(--sp-6); }
.fact {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  padding: var(--sp-4) var(--sp-5);
}
.fact__k {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--c-muted);
}
.fact__k svg { color: var(--c-secondary-ink); }
.fact__v { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; color: var(--c-primary); margin-top: 6px; }

/* Colonne de lecture + rail de réservation. Le rail est premier dans le code :
   sur mobile, où la grille retombe sur une colonne, le prix et le bouton
   arrivent donc juste sous les faits, pas au bout de la page. */
.tour-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 348px;
  gap: var(--sp-8);
  align-items: start;
  margin-top: var(--sp-7);
}
.tour-body { grid-column: 1; grid-row: 1; }
.tour-rail {
  grid-column: 2; grid-row: 1;
  position: sticky;
  top: 132px;
  max-height: calc(100vh - 152px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Les blocs de la colonne de lecture sont séparés par un filet, pas par cent
   pixels de vide : c'est ce qui raccourcit vraiment la page. */
.tour-block { padding-block: var(--sp-7); border-top: 1px solid var(--c-border); }
.tour-block:first-child { border-top: 0; padding-top: 0; }
.tour-block > h2 { font-size: clamp(1.5rem, 2.2vw, 2rem); margin-bottom: var(--sp-5); }
.tour-block .prose p + p { margin-top: var(--sp-4); }
.tour-block .prose p { font-size: 17px; }

/* Le verdict, en tête de « L'expérience » : une recommandation, pas une
   bannière. Un aplat vert très pâle sans ombre ni bordure, le texte courant du
   site, et rien qui rivalise avec le bouton de réservation. Libellé à gauche
   dès qu'il y a la place, au-dessus sur mobile. */
.tour-verdict {
  margin: 0 0 var(--sp-6);
  padding: var(--sp-4) var(--sp-5);
  background: var(--c-primary-soft);
  border-radius: var(--r-btn);
  max-width: 68ch;
  font-size: 16px;
  line-height: 1.55;
}
.verdict__row { display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); gap: var(--sp-4); }
.verdict__row + .verdict__row { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--c-border); }
.tour-verdict dt { font-weight: 700; color: var(--c-primary); }
.verdict__row--not dt { color: var(--c-muted); }
.tour-verdict dd { margin: 0; color: var(--c-text); }
@media (max-width: 639px) {
  .tour-verdict { padding: var(--sp-4); }
  .verdict__row { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}

/* "Lire la suite" : le troisième paragraphe se déplie. Le texte est dans le
   HTML, donc indexé, mais il ne coûte pas un écran de défilement à qui veut
   seulement savoir ce que c'est. */
.more { margin-top: var(--sp-4); }
.more summary {
  cursor: pointer; list-style: none;
  font-size: 14px; font-weight: 700; color: var(--c-primary);
  display: inline-flex; align-items: center; gap: var(--sp-2);
}
.more summary::-webkit-details-marker { display: none; }
.more summary::after { content: "\25BE"; transition: transform .2s ease; }
.more[open] summary::after { transform: rotate(180deg); }
.more[open] summary { margin-bottom: var(--sp-4); }
.more summary:hover { color: var(--c-cta); }

/* Itinéraire : des bandes alternées, un panneau numéroté d'un côté, le texte
   de l'autre. C'est la partie qui doit donner l'impression d'avancer dans la
   journée, pas de lire une liste. */
.trip { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-6); }
.trip__step {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: var(--sp-6);
  align-items: center;
}
/* Une ligne sur deux inverse les colonnes. Le gabarit est inversé en même
   temps que l'ordre, sinon le panneau hériterait de la colonne large et
   changerait de taille d'une étape à l'autre. */
.trip__step:nth-child(even) { grid-template-columns: minmax(0, 1fr) 260px; }
.trip__step:nth-child(even) .trip__media { order: 2; }
.trip__media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-card);
  overflow: hidden;
  display: grid;
  place-items: center;
  transition: transform .35s cubic-bezier(.2,.7,.2,1);
}
.trip__step:hover .trip__media { transform: translateY(-3px) scale(1.012); }
/* Quand l'étape a une photo, elle remplit le panneau et le numéro passe en
   bas à gauche sur un voile, pour rester lisible quelle que soit l'image. */
.trip__media picture, .trip__media img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform .5s cubic-bezier(.2,.7,.2,1);
}
.trip__step:hover .trip__media--shot img { transform: scale(1.04); }
.trip__media--shot::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(200deg, rgba(10,43,44,0) 35%, rgba(10,43,44,.75) 100%);
}
.trip__media--shot .trip__n {
  position: absolute; left: var(--sp-4); bottom: var(--sp-3);
  font-size: 2.4rem; z-index: 1;
}
.trip__n {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 3.2rem;
  line-height: 1;
  color: #fff;
  text-shadow: 0 2px 20px rgba(10,43,44,.45);
  letter-spacing: -.02em;
}
.trip__text h3 { font-size: 1.25rem; }
.trip__text p { font-size: 15.5px; color: var(--c-muted); margin-top: var(--sp-3); }

/* Citation : la respiration entre le récit et l'itinéraire. Elle déborde de la
   colonne de lecture, ce qui casse la succession de blocs identiques. */
.pull {
  margin: var(--sp-7) calc(-1 * var(--sp-5)) 0;
  padding: var(--sp-6) var(--sp-6) var(--sp-6) var(--sp-7);
  background: var(--c-primary-soft);
  border-radius: var(--r-card);
  position: relative;
}
.pull::before {
  content: "";
  position: absolute;
  left: var(--sp-5); top: var(--sp-6); bottom: var(--sp-6);
  width: 3px; border-radius: 3px;
  background: var(--c-secondary);
}
.pull blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.9vw, 1.5rem);
  font-weight: 700;
  line-height: 1.35;
  color: var(--c-primary);
  text-wrap: balance;
}

/* Points forts : numérotés, deux colonnes, un filet or qui se déploie au
   survol. Le contenu ne change pas, sa présentation cesse d'être une liste. */
.hl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-6) var(--sp-7); }
.hl__item { position: relative; padding-top: var(--sp-4); border-top: 1px solid var(--c-border); }
.hl__item::after {
  content: "";
  position: absolute; left: 0; top: -1px; height: 2px; width: 0;
  background: var(--c-secondary);
  transition: width .4s cubic-bezier(.2,.7,.2,1);
}
.hl__item:hover::after { width: 56px; }
.hl__n {
  display: flex; align-items: center; gap: var(--sp-3);
  color: var(--c-secondary);
  margin-bottom: var(--sp-3);
}
.hl__n span {
  font-family: var(--font-display); font-weight: 900; font-size: 1.1rem;
  letter-spacing: .04em;
}
.hl h3 { font-size: 1.05rem; }
.hl p { font-size: 14.5px; color: var(--c-muted); margin-top: var(--sp-2); }

/* Inclus / non inclus. Le signe porte l'information autant que la couleur :
   un lecteur daltonien doit pouvoir lire les deux colonnes. */
.incl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-6); }
.incl h3 { font-size: .95rem; margin-bottom: var(--sp-4); }
.incl ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.incl li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: var(--sp-3); align-items: start; font-size: 15px; }
.incl svg { margin-top: 2px; }
.incl--yes svg { color: #2E6248; }
.incl--no svg { color: #A2472A; }
.incl--no li { color: var(--c-muted); }

/* Le rail de réservation. Il porte le prix, le widget GetYourGuide, le lien de
   secours et la mention de qui encaisse. */
.rail {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  padding: var(--sp-5);
}
.rail__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-2); }
.rail__price b { font-family: var(--font-display); font-size: 2rem; font-weight: 900; color: var(--c-primary); line-height: 1; }
.rail__price span { font-size: 13px; color: var(--c-muted); }
.rail__free { font-size: 14px; color: var(--c-muted); }
.rail .gyg-embed { border: 0; padding: 0; background: transparent; margin-block: var(--sp-4) 0; min-height: 180px; }
.rail .btn--cta { width: 100%; margin-top: var(--sp-4); }
.rail__list {
  list-style: none; margin: var(--sp-5) 0 0; padding: var(--sp-5) 0 0;
  border-top: 1px solid var(--c-border);
  display: grid; gap: var(--sp-3); font-size: 14px; color: var(--c-muted);
}
.rail__list li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: var(--sp-3); align-items: start; }
.rail__list svg { color: var(--c-primary); margin-top: 1px; }
.rail__note { font-size: 12.5px; color: var(--c-muted); margin-top: var(--sp-4); }

/* Le pratique : une grille de specs. Neuf lignes de tableau, c'est un mur ;
   deux colonnes de fiches, cela se balaie du regard. */
.specs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4) var(--sp-6); margin: 0; }
.spec { border-top: 1px solid var(--c-border); padding-top: var(--sp-4); }
.spec dt { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--c-primary); }
.spec dd { margin: var(--sp-2) 0 0; font-size: 15px; color: var(--c-muted); }
.specs + p { margin-top: var(--sp-6); }

/* CTA intercalaire : après les points forts, au moment où l'envie se décide,
   sans attendre le bas de page. */
.inline-cta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
  padding: var(--sp-5) var(--sp-6);
  background: var(--c-primary-soft);
  border-radius: var(--r-card);
}
.inline-cta p { font-weight: 700; color: var(--c-primary); font-size: 15px; }

/* Bande de fin, pleine largeur : la dernière occasion de réserver avant les
   autres sorties, dans le vert du site. */
.endcta { background: var(--c-primary); color: #fff; padding-block: var(--sp-8); }
.endcta h2 { color: #fff; margin-block: var(--sp-2) var(--sp-4); max-width: 18ch; }
.endcta .eyebrow { color: var(--c-secondary-light); }
.endcta__p { color: #DCE7E0; max-width: 58ch; }
.endcta__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-5); margin-top: var(--sp-6); }
.endcta__price { font-size: 15px; color: #DCE7E0; }
.endcta__price b { font-family: var(--font-display); font-size: 1.5rem; color: #fff; }

/* Barre de progression de lecture, sous la sous-navigation. Elle suit le
   défilement du document, sans une ligne de JavaScript. */
.progress { height: 2px; background: transparent; }
@supports (animation-timeline: scroll()) {
  .progress {
    background: var(--c-secondary);
    transform-origin: 0 50%;
    animation: progress linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}

/* Révélations au défilement : chaque bloc monte en entrant dans le cadre.

   L'animation ne touche que transform, jamais opacity, et c'est délibéré : une
   fenêtre plus haute que le document rend la timeline inactive, l'animation
   reste alors sur son image de départ. Avec un fondu, la page se retrouverait
   vide dans ce cas, et c'est précisément ainsi que le moteur de rendu de Google
   voit une page, en allongeant la fenêtre à la hauteur du document. Un décalage
   de quelques pixels, lui, ne cache rien à personne.

   Sur un navigateur qui ne connaît pas les animations liées au défilement,
   rien ne bouge et la page reste exactement lisible. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .tour-block > h2, .trip__step, .hl__item, .spec, .pull, .inline-cta, .fact {
      animation: rise-in linear both;
      animation-timeline: view();
      animation-range: entry 5% cover 24%;
    }
    @keyframes rise-in {
      from { transform: translateY(20px); }
      to { transform: none; }
    }
  }
}

/* À l'impression, aucune animation : une feuille imprimée n'a pas de défilement. */
/* --- 14 bis. Pages itinéraire -------------------------------------------- */
/* Une page itinéraire se lit debout, sur un téléphone, pendant le voyage. Elle
   emprunte tout ce qui existe déjà : la barre collante `.tour-nav` des fiches
   avec sa section courante, le bandeau `.facts`, les boutons, les couleurs. Ce
   bloc n'ajoute que ce qu'aucun composant du site ne savait faire : un aperçu
   qui tient en trois lignes, une journée découpée en moments, et une option qui
   se compare à trois autres. */

/* Les ancres passent sous le header collant ET sous la barre des jours, comme
   sur une fiche. */
.itinerary [id] { scroll-margin-top: 132px; }

/* La page n'a pas de colonne latérale, contrairement aux pages guide : dans une
   coquille de 1320 px, le texte s'arrêtait à sa mesure de lecture et laissait
   quatre cents pixels de vide à droite. La page entière se resserre donc, barre
   des jours comprise pour qu'elles restent alignées. */
.itinerary > .container, .itinerary .tour-nav > .container { max-width: 1040px; }

/* Cinq tuiles au lieu de quatre : « idéal pour, rythme, scooter, excursions,
   à payer » se lisent d'un coup et répondent à la question avant le texte. */
.facts--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }

.itin-block { padding-block: var(--sp-7); border-top: 1px solid var(--c-border); }
.itin-block > h2 { font-size: clamp(1.4rem, 2.2vw, 1.9rem); margin-bottom: var(--sp-4); }
.itin-block__lede { color: var(--c-muted); max-width: 62ch; margin-bottom: var(--sp-5); }

/* --- L'aperçu ------------------------------------------------------------- */
/* `.trip` existait déjà pour le parcours d'une fiche, mais il réclame une photo
   par étape et une colonne de 260 px. Ici l'aperçu doit se lire en cinq
   secondes, pas s'illustrer : une pastille de jour, un titre, une ligne. */
.plan { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-4); }
.plan__step {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: baseline;
  padding: var(--sp-4) var(--sp-5);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
}
.plan__n {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.05rem;
  color: var(--c-primary);
}
.plan__text h3 { font-size: 1.1rem; margin: 0; }
.plan__text p { margin: 6px 0 0; font-size: 15.5px; color: var(--c-muted); line-height: 1.5; }

/* --- Une journée ---------------------------------------------------------- */
/* Le repère au défilement, c'est l'en-tête : un numéro en or, un titre, une
   ligne d'intention. Sans lui, cinq journées d'affilée deviennent un mur. */
.day { padding-block: var(--sp-7); border-top: 1px solid var(--c-border); }
.day__head { margin-bottom: var(--sp-5); }
.day__n {
  margin: 0 0 var(--sp-2);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--c-secondary-ink);
}
.day__head h2 { font-size: clamp(1.4rem, 2.2vw, 1.9rem); margin: 0; }
.day__lede { margin: var(--sp-3) 0 0; font-size: 17px; color: var(--c-muted); max-width: 64ch; }

/* Le moment de la journée à gauche, ce qu'on y fait à droite. La colonne de
   gauche est étroite et ne bouge pas : c'est elle qui rend la journée
   parcourable sans la lire. */
.slot {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr);
  gap: var(--sp-5);
  padding-block: var(--sp-4);
  border-top: 1px solid var(--c-border);
}
.slot:first-of-type { border-top: 0; padding-top: 0; }
.slot__k {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--c-primary);
  padding-top: 3px;
}
.slot__v { max-width: 64ch; }
.slot__v p { margin: 0; font-size: 16.5px; line-height: 1.65; }
.slot__v p + p { margin-top: var(--sp-3); }
/* La note pratique : l'ordre, le transport, la chaleur, l'heure. Elle se
   distingue du récit parce qu'elle se lit seule. */
.slot__note {
  margin-top: var(--sp-3) !important;
  padding-left: var(--sp-4);
  border-left: 2px solid var(--c-secondary);
  font-size: 15px !important;
  color: var(--c-muted);
}
.day__link { margin: var(--sp-5) 0 0; font-size: 15px; }
.day__link a { color: var(--c-primary); font-weight: 700; text-decoration: none; border-bottom: 2px solid var(--c-secondary); }
.day__link a:hover { color: var(--c-cta); }
.day__link::before { content: "\2192"; color: var(--c-secondary-ink); font-weight: 700; margin-right: var(--sp-2); }

/* --- La journée qui se choisit -------------------------------------------- */
.opt-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5); }
/* Deux colonnes conviennent à une journée qui offre quatre options. Une page qui
   recommande n'en aligne pas toujours un nombre pair : l'option seule prend la
   largeur entière plutôt que la moitié, et la dernière d'un nombre impair fait
   de même, sans quoi la grille se termine sur un trou. */
.opt-list--solo { grid-template-columns: minmax(0, 1fr); }
.opt-list--odd > .opt:last-child { grid-column: 1 / -1; }
.opt {
  display: flex;
  flex-direction: column;
  padding: var(--sp-5);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
}
/* La photo de l'option, entre le bord haut de la carte et le titre. Elle garde
   les proportions 16/9 des autres médias du site et le rayon des cartes, comme
   la photo d'une carte d'article : intégrée à la carte, pas un hero posé
   dessus. Le fichier reste en 4/3 comme toute la famille des étapes — c'est
   object-fit qui rogne le haut et le bas, jamais un étirement — et la hauteur
   est donc la même d'une option à l'autre, en deux colonnes comme en une. */
.opt__shot { display: block; flex: none; margin: 0 0 var(--sp-4); }
.opt__shot img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16/9; object-fit: cover; object-position: center;
  border-radius: var(--r-card); background: var(--c-border);
}
.opt > h3 { font-size: 1.2rem; margin: 0; }
/* L'avis, juste sous le titre. C'est la phrase pour laquelle la carte existe :
   elle se lit avant les critères, pas après. */
.opt__take { margin: var(--sp-3) 0 var(--sp-4); font-size: 15.5px; line-height: 1.55; }
.opt__take b { color: var(--c-primary); }
/* La contrainte de réservation, seulement là où elle apprend quelque chose. */
.opt__note {
  margin: var(--sp-4) 0 0;
  padding-left: var(--sp-4);
  border-left: 2px solid var(--c-secondary);
  font-size: 14px;
  line-height: 1.5;
  color: var(--c-muted);
}
.opt__rows { margin: 0; display: grid; gap: var(--sp-3); }
.opt__row { display: grid; grid-template-columns: 6.6rem minmax(0, 1fr); gap: var(--sp-3); }
.opt__row dt { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--c-muted); padding-top: 3px; }
.opt__row dd { margin: 0; font-size: 15.5px; line-height: 1.5; }

.opt__more { margin: var(--sp-4) 0 0; font-size: 14.5px; }
.opt__more a { color: var(--c-primary); font-weight: 700; text-decoration: none; border-bottom: 1px solid var(--c-border); }
.opt__more a:hover { border-bottom-color: var(--c-secondary); }
/* L'excursion vient après l'avis, jamais avant, et elle est visiblement une
   conséquence de ce qui précède : un filet, pas une carte de plus. */
.opt__book {
  margin-top: auto;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--c-border);
}
/* Le bouton garde sa largeur naturelle : deux aplats orange pleine largeur côte
   à côte pèseraient plus que l'avis qu'ils suivent. */
.opt__book .btn { margin-top: var(--sp-3); }
.opt__tour { margin: var(--sp-4) 0 0; font-size: 14.5px; font-weight: 700; }
.opt__price { color: var(--c-muted); font-weight: 500; white-space: nowrap; }
/* L'option qui ne se réserve pas le dit : c'est la moitié du propos de la page. */
.opt__none {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: auto 0 0;
  padding-top: var(--sp-5);
  font-size: 14px;
  font-weight: 700;
  color: var(--c-muted);
}
.opt__none svg { color: var(--c-primary); flex: none; }

/* --- La page de décision (/start-here/) ----------------------------------- */
/* Elle n'apporte aucune forme nouvelle : la barre collante, le bandeau de faits,
   les cartes, la frise des saisons, le bloc « choisir » et l'aperçu numéroté
   viennent tous d'ailleurs. Ne restent ici que la phrase de réponse — ce pour
   quoi la page existe — et le corps de texte qui la justifie. */
.answer {
  margin: 0 0 var(--sp-4);
  max-width: 42ch;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.1rem, 1.7vw, 1.32rem);
  line-height: 1.35;
  color: var(--c-primary);
}
.decide__p { max-width: 64ch; font-size: 16.5px; line-height: 1.65; color: var(--c-muted); }
.decide__p + .decide__p { margin-top: var(--sp-3); }
/* Le composant qui suit respire, la réponse et ses raisons restent serrées. */
.decide__p:last-of-type, .answer:last-child { margin-bottom: var(--sp-5); }
.decide__cta { margin-top: var(--sp-5); }
/* Le renvoi d'une étape de l'aperçu : même flèche que celui d'une journée, à
   l'échelle de la ligne qu'il suit. */
.plan__text .day__link { margin-top: var(--sp-2); font-size: 14.5px; }

/* --- Les renvois de fin --------------------------------------------------- */
.plink { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.plink li {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: baseline;
  padding-block: var(--sp-3);
  border-top: 1px solid var(--c-border);
}
.plink li:first-child { border-top: 0; }
.plink a { color: var(--c-primary); font-weight: 700; text-decoration: none; border-bottom: 2px solid transparent; }
.plink a:hover { border-bottom-color: var(--c-secondary); }
.plink span { font-size: 15px; color: var(--c-muted); line-height: 1.5; }

/* --- La bande « choisir son itinéraire » de l'accueil ---------------------- */
/* Une carte ou deux, sans mise en page transitoire. À deux, deux colonnes
   égales. À une seule, la carte prend la largeur de la bande et se met à plat :
   le texte à gauche, le bouton à droite. C'est une bannière assumée plutôt
   qu'une colonne veuve à côté d'un vide, et le jour où le second itinéraire
   arrive, rien n'est à refaire. */
.plan-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--sp-5);
  max-width: 940px;
}
/* Trois cartes : « commencer ici », puis les deux durées. Dans 940 px la
   troisième serait passée à la ligne toute seule, ce qui aurait fait lire un
   choix en deux temps là où il s'en présente trois. */
.plan-cards--3 { max-width: 1180px; }
/* À deux, les cartes ont des textes de longueur différente. Le corps doit
   remplir la carte pour qu'une rangée élastique existe avant le bouton, sans
   quoi les deux boutons ne se retrouvent pas à la même hauteur. */
.plan-cards .cat-card { display: flex; flex-direction: column; }
.plan-cards .cat-card__body { flex: 1; }
.plan-cards .cat-card:not(:only-child) .cat-card__body { grid-template-rows: auto auto 1fr auto; }
.plan-cards .cat-card:only-child .cat-card__body {
  /* La grille des rangées est déclarée, sinon `grid-row: 1 / -1` ne désigne que
     la première : sans grille explicite, la ligne -1 n'existe pas. */
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: repeat(3, auto);
  align-items: center;
  column-gap: var(--sp-7);
}
.plan-cards .cat-card:only-child .cat-card__body > * { grid-column: 1; }
.plan-cards .cat-card:only-child .cat-card__body > :last-child {
  grid-column: 2;
  grid-row: 1 / -1;
  margin: 0;
}

@media (max-width: 1023px) {
  .facts--5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .itinerary [id] { scroll-margin-top: 118px; }
  .opt-list { grid-template-columns: 1fr; }
}

@media (max-width: 639px) {
  /* Sur un téléphone, le moment de la journée passe au-dessus de son contenu :
     deux colonnes sur 360 px laisseraient huit caractères au texte. */
  .plan__step, .slot { grid-template-columns: 1fr; gap: var(--sp-2); }
  .plan__step { gap: var(--sp-1); }
  .slot { padding-block: var(--sp-4); }
  .slot__k { padding-top: 0; }
  /* Sur un téléphone, l'intitulé passe dans la ligne au lieu de la précéder :
     à trois critères par carte et quatre cartes, la colonne d'étiquettes coûtait
     douze lignes pour douze mots. Le deux-points suffit à les séparer. */
  .opt__row { display: block; }
  .opt__row dt { display: inline; font-size: 15px; letter-spacing: 0; text-transform: none;
                 color: var(--c-primary); }
  /* Le générateur n'écrit aucune espace entre </dt> et <dd> : elle se pose ici,
     sinon l'intitulé et sa valeur se collent. */
  .opt__row dt::after { content: ":"; margin-inline-end: .35em; }
  .opt__row dd { display: inline; }
  .opt { padding: var(--sp-4); }
  .plink li { grid-template-columns: 1fr; gap: var(--sp-1); }
  .itin-block > h2, .day__head h2 { font-size: 1.35rem; }
}

@media print {
  *, *::before, *::after { animation: none !important; transform: none !important; opacity: 1 !important; }
}

/* Accordéon : la flèche pivote et le contenu se déplie au lieu de sauter. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .faq details::details-content {
    block-size: 0; overflow: clip;
    transition: block-size .32s cubic-bezier(.2,.7,.2,1), content-visibility .32s allow-discrete;
  }
  .faq details[open]::details-content { block-size: auto; }
}

/* Sorties similaires : une glissière plutôt qu'une grille, pour que la fin de
   page tienne en un écran. */
.snap-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(290px, 1fr);
  gap: var(--sp-5);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: var(--sp-4);
}
.snap-row > * { scroll-snap-align: start; }
/* Dans la glissière, la carte est plus étroite que dans une grille : deux
   lignes coupent la plupart des titres. Quatre au plus, trois réservées. */
.snap-row .tour-card__title {
  -webkit-line-clamp: 4;
  min-height: 3.9em;
}

@media (max-width: 1023px) {
  /* Le header mobile mesure 60 px : la sous-navigation se recale dessous,
     sinon le texte défile dans l'interstice. */
  .tour-nav { top: 59px; }
  .tour-page [id] { scroll-margin-top: 118px; }
  /* Une colonne, et le rail remonte : dans le code il est avant le corps, donc
     le prix et le widget arrivent juste après les faits, pas au bout de la page. */
  .tour-layout { grid-template-columns: 1fr; gap: var(--sp-6); margin-top: var(--sp-6); }
  .tour-body, .tour-rail { grid-column: 1; grid-row: auto; }
  .tour-rail { position: static; max-height: none; overflow: visible; }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hl, .specs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .trip__step { grid-template-columns: 180px minmax(0, 1fr); gap: var(--sp-5); }
  .trip__step:nth-child(even) { grid-template-columns: minmax(0, 1fr) 180px; }
  .guide { grid-template-columns: 1fr; gap: var(--sp-5); }
  .guide__fold {
    position: static;
    max-height: none;
    overflow: visible;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-card);
  }
  .guide__sum {
    display: flex; align-items: center; gap: var(--sp-2);
    min-height: 52px; padding: 0 var(--sp-4);
    list-style: none; cursor: pointer;
    font-weight: 700; font-size: 15px; color: var(--c-primary);
  }
  .guide__sum::-webkit-details-marker { display: none; }
  .guide__sum::after {
    content: "+"; margin-left: auto;
    font-size: 20px; line-height: 1; color: var(--c-secondary-ink);
  }
  .guide__fold[open] .guide__sum::after { content: "\2212"; }
  .guide__sum-n {
    font-weight: 500; color: var(--c-muted);
    font-variant-numeric: tabular-nums;
  }
  .guide__fold .guide__toc { border-left: 0; padding: 0 var(--sp-4) var(--sp-4); }
  .guide__fold .guide__toc-title { display: none; }
  .intro-split { grid-template-columns: 1fr; gap: var(--sp-5); }
  .cat-grid--3 { grid-template-columns: repeat(2, 1fr); }
  .pillar { grid-template-columns: 1fr; gap: var(--sp-5); padding: var(--sp-5); }
  .pillar__inside { padding-left: 0; border-left: 0; border-top: 1px solid var(--c-border); padding-top: var(--sp-4); }
}
@media (max-width: 639px) {
  .cat-grid--3 { grid-template-columns: 1fr; }
  .incl, .hl, .specs { grid-template-columns: 1fr; gap: var(--sp-5); }
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
  .fact { padding: var(--sp-3) var(--sp-4); }
  .fact__v { font-size: .95rem; }
  .hero--tour { min-height: 0; padding-block: var(--sp-8) var(--sp-7); }
  .hero--tour h1 { max-width: none; }
  .tour-nav ul { gap: var(--sp-5); }
  /* La sous-navigation glisse : le dégradé de bord dit qu'il y a une suite. */
  .tour-nav ul { mask-image: linear-gradient(90deg, #000 82%, transparent 100%); }
  /* Là où la chronologie de défilement existe, le voile animé prend le relais :
     il s'efface une fois la barre au bout, ce que ce dégradé fixe ne sait pas
     faire. Ailleurs, ce dégradé reste, et le comportement est celui d'avant. */
  @supports (animation-timeline: scroll()) and (timeline-scope: --x) {
    .tour-nav ul { mask-image: none; }
  }
  /* L'étape passe en pile, le numéro se pose sur le panneau. */
  .trip__step, .trip__step:nth-child(even) { grid-template-columns: 1fr; gap: var(--sp-4); }
  .trip__step:nth-child(even) .trip__media { order: 0; }
  .trip__media { aspect-ratio: 16 / 7; }
  .trip__n { font-size: 2.4rem; }
  .pull { margin-inline: 0; padding: var(--sp-5) var(--sp-5) var(--sp-5) var(--sp-6); }
  .inline-cta { flex-direction: column; align-items: stretch; text-align: center; }
  .endcta__actions { flex-direction: column; align-items: stretch; }
  .callout { padding: var(--sp-5); }
  /* Six mois par ligne plutôt que douze colonnes de 24 px. */
  .season__bar { grid-template-columns: repeat(6, 1fr); }
  .data-table th { width: auto; white-space: normal; }
}

/* ==========================================================================
   19. La carte — /chiang-mai-map/ et /fr/carte-chiang-mai/
   ==========================================================================
   Ces règles ne servent qu'à deux pages sur soixante-sept. Elles restent
   pourtant dans la feuille commune : deux kilo-octets de plus dans un fichier
   déjà en cache pour un an valent mieux qu'une requête de plus sur la page qui
   porte déjà le plus de poids.

   Sans JavaScript, rien de ce bloc ne s'applique à autre chose qu'une liste de
   fiches .place ordinaire — la coquille de carte et la barre de filtres sortent
   `hidden` du générateur. */

.prose--wide { max-width: 72ch; }

/* --- La coquille ---------------------------------------------------------- */
.mapwrap { margin-top: var(--sp-6); }

.maplayout { display: grid; gap: var(--sp-5); }
/* Deux colonnes seulement quand il y a la place : la carte prend les deux tiers,
   la décision le tiers restant. En dessous, la liste passe sous la carte. */
@media (min-width: 1024px) {
  .maplayout { grid-template-columns: 1.9fr 1fr; align-items: start; }
  .mapside {
    position: sticky; top: 96px;
    max-height: calc(100vh - 120px);
    overflow-y: auto;
    padding-right: var(--sp-2);
  }
}

/* Leaflet numérote ses propres couches de 200 à 1000 : les tuiles à 200, les
   repères à 600, ses boutons de zoom à 1000. Le site, lui, tient tout entier
   entre 40 et 70 — le header à 50, ses sous-menus à 70. La carte passait donc
   au-dessus du menu déroulant, et pas seulement à l'oeil : les liens du menu
   n'étaient plus cliquables au-dessus d'elle.

   `z-index: 0` sur le conteneur crée un contexte d'empilement : les mille de
   Leaflet se règlent désormais à l'intérieur de cette boîte, et la boîte entière
   se range à zéro, sous tout ce que le header pose. Une seule ligne, et rien à
   surenchérir ailleurs — c'est le header qui doit gagner, pas la carte. */
.mapcanvas { position: relative; z-index: 0; }
.map {
  height: 60vh; min-height: 380px; max-height: 620px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-card);
  background: var(--c-primary-soft);
  overflow: hidden;
}
@media (min-width: 1024px) { .map { height: calc(100vh - 200px); max-height: 720px; } }

/* Le message d'échec : il ne remplace pas la liste, il explique pourquoi la
   carte manque, au-dessus d'une page qui reste entière. */
.map__fail {
  margin: var(--sp-3) 0 0;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--c-border);
  border-left: 3px solid var(--c-secondary);
  border-radius: var(--r-btn);
  background: var(--c-surface);
  font-size: 15px; color: var(--c-muted);
}
.mapwrap:not(.has-map) .map { display: none; }

/* --- La barre : quelle carte, puis quelles catégories ---------------------- */
/* Un sélecteur de classe l'emporte sur la règle [hidden] du navigateur : sans
   cette ligne, la barre de filtres s'affichait quand même sans JavaScript, et
   proposait un tri qui n'aurait pas lieu. C'est exactement ce que le générateur
   cherche à éviter en la posant `hidden`. La règle vaut pour toutes les parties
   de la page que le script révèle. */
.mapbar[hidden], .mview[hidden], .mapcanvas[hidden], .mapcard[hidden],
.map__fail[hidden] { display: none !important; }

.mapbar {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  gap: var(--sp-4) var(--sp-5);
  margin-bottom: var(--sp-4);
}
/* Un <fieldset> se dimensionne sur son contenu et ne se laisse pas rétrécir :
   à 360 px il poussait la page à 745 px de large. Le défilement appartient donc
   à un conteneur intérieur, et le fieldset accepte de descendre sous sa largeur
   naturelle (min-width: 0, ce qu'un élément de flex ne fait pas tout seul). */
.mapbar fieldset {
  border: 0; margin: 0; padding: 0;
  display: block; min-width: 0; max-width: 100%;
}
.mapbar__pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); min-width: 0; }
.mapbar__legend {
  display: block; float: none; width: auto;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--c-muted); margin-bottom: var(--sp-2); padding: 0;
}
.mfilter__pill, .mscope__pill { position: relative; display: inline-flex; }
.mfilter__pill input, .mscope__pill input {
  position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer;
}
.mfilter__pill span, .mscope__pill span {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--c-border);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  font-size: 14px; font-weight: 500; color: var(--c-text);
  white-space: nowrap; transition: background .15s, border-color .15s, color .15s;
}
/* Le rappel de couleur sur la pastille : un point, avant le libellé, de la
   teinte du repère. La pastille elle-même ne change pas — ni son fond, ni son
   état actif, ni « Tous », ni le choix du cadre, qui ne sont pas des
   catégories. Le point double le nom, il ne le remplace pas : `aria-hidden`
   par construction, puisque c'est un pseudo-élément décoratif. */
.mfilter__pill input[value="temples"] + span::before,
.mfilter__pill input[value="neighbourhoods"] + span::before,
.mfilter__pill input[value="markets"] + span::before,
.mfilter__pill input[value="landmarks"] + span::before,
.mfilter__pill input[value="shopping"] + span::before {
  content: ""; flex: none; align-self: center;
  width: 8px; height: 8px; margin-right: 1px;
  border-radius: 50%;
  background: var(--dot-color, var(--c-muted));
}
.mfilter__pill input[value="temples"] + span        { --dot-color: var(--cat-temples); }
.mfilter__pill input[value="neighbourhoods"] + span { --dot-color: var(--cat-neighbourhoods); }
.mfilter__pill input[value="markets"] + span        { --dot-color: var(--cat-markets); }
.mfilter__pill input[value="landmarks"] + span      { --dot-color: var(--cat-landmarks); }
.mfilter__pill input[value="shopping"] + span       { --dot-color: var(--cat-shopping); }
/* Sur fond vert la pastille cochée noierait son point : il passe en blanc
   plutôt que de faire une tache sombre sur un aplat sombre. Idem grisée. */
.mfilter__pill input:checked + span::before { background: rgba(255, 255, 255, .85); }
.mfilter__pill.is-empty span::before { opacity: .35; }

.mfilter__pill b, .mscope__pill b {
  font-size: 12px; font-weight: 700; color: var(--c-muted);
  font-variant-numeric: tabular-nums;
}
.mfilter__pill input:hover + span, .mscope__pill input:hover + span { border-color: var(--c-primary); }
.mfilter__pill input:checked + span, .mscope__pill input:checked + span {
  background: var(--c-primary); border-color: var(--c-primary); color: #fff;
}
.mfilter__pill input:checked + span b, .mscope__pill input:checked + span b { color: #cfe0d4; }
.mfilter__pill input:focus-visible + span, .mscope__pill input:focus-visible + span {
  outline: 2px solid var(--c-secondary); outline-offset: 2px;
}
/* Le choix du cadre n'est pas un filtre de plus : il change ce que la carte
   montre, pas ce qu'elle contient. Un trait le sépare des catégories. */
.mscope { padding-right: var(--sp-5) !important; border-right: 1px solid var(--c-border) !important; }
@media (max-width: 767px) { .mscope { padding-right: 0 !important; border-right: 0 !important; } }

/* --- Carte | Liste, sur mobile seulement ---------------------------------- */
.mview { display: none; }
@media (max-width: 1023px) {
  .mview {
    display: inline-flex; align-self: flex-start; width: max-content;
    border: 1px solid var(--c-primary); border-radius: var(--r-pill); overflow: hidden;
  }
  .mview__btn {
    appearance: none; border: 0; background: transparent; cursor: pointer;
    font-family: var(--font-body); font-size: 14px; font-weight: 700;
    color: var(--c-primary); padding: 7px 18px;
  }
  .mview__btn.is-on { background: var(--c-primary); color: #fff; }
  .mview__btn:focus-visible { outline: 2px solid var(--c-secondary); outline-offset: -2px; }
  .mapwrap.has-map.show-list .mapcanvas { display: none; }
  .mapwrap.has-map:not(.show-list) .map-list,
  .mapwrap.has-map:not(.show-list) #map-list-title { display: none; }
}

/* --- Les repères ---------------------------------------------------------- */
/* Une seule forme pour toutes les catégories — aucun pictogramme dans le
   repère : une carte éditoriale, pas un jeu d'icônes. La teinte distingue la
   catégorie, la forme distingue le lieu du quartier, et la sélection change
   aussi la taille : un état qui ne tiendrait qu'à la couleur ne se verrait pas
   de tout le monde. Le nom de la catégorie reste écrit dans la pastille, la
   fiche et la carte de décision ; la couleur ne porte jamais seule le sens. */
:root {
  --cat-temples:        #0F3D3E;  /* vert Doi */
  --cat-neighbourhoods: #B08A1E;  /* ocre */
  --cat-markets:        #9B4A2F;  /* terre cuite */
  --cat-landmarks:      #4A5C6A;  /* ardoise */
  --cat-shopping:       #6B4A6E;  /* prune */
}
.pin-wrap { background: none; border: 0; }
.pin {
  display: block; width: 22px; height: 22px; margin: 5px 0 0 6px;
  background: var(--pin-color, var(--c-primary));
  border: 2px solid #fff;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  box-shadow: 0 2px 5px rgba(22, 33, 29, .38);
  transition: transform .12s ease, background .12s ease;
}
.pin.is-on {
  background: var(--c-cta);
  transform: rotate(-45deg) scale(1.32);
  box-shadow: 0 3px 9px rgba(22, 33, 29, .5);
}
/* Un quartier n'est pas un lieu : rond, pas de pointe, et posé au centre de sa
   zone plutôt que sur un point. La forme dit la différence avant la couleur. */
.pin--area {
  width: 16px; height: 16px; margin: 8px 0 0 9px;
  border-radius: 50%;
  background: var(--pin-color, var(--c-secondary));
  transform: none;
}
.pin--area.is-on { background: var(--c-cta); transform: scale(1.35); }
/* La catégorie ne pose qu'une variable : l'état `is-on` écrit son fond en
   dur, il l'emporte donc sur toutes les teintes sans qu'aucune règle de
   sélection ait à être écrite cinq fois. Un seul rouge sélectionné, partout. */
.pin--temples        { --pin-color: var(--cat-temples); }
.pin--neighbourhoods { --pin-color: var(--cat-neighbourhoods); }
.pin--markets        { --pin-color: var(--cat-markets); }
.pin--landmarks      { --pin-color: var(--cat-landmarks); }
.pin--shopping       { --pin-color: var(--cat-shopping); }
.leaflet-marker-icon:focus-visible .pin,
.leaflet-marker-icon:focus .pin { outline: 3px solid var(--c-secondary); outline-offset: 3px; }

/* --- La carte de décision -------------------------------------------------- */
.mapcard {
  position: relative;
  border: 1px solid var(--c-border);
  border-left: 3px solid var(--c-cta);
  border-radius: var(--r-card);
  background: var(--c-surface);
  padding: var(--sp-4) var(--sp-5);
  margin-bottom: var(--sp-5);
  box-shadow: var(--shadow-card);
}
.mapcard__name { font-family: var(--font-display); font-size: 1.15rem; margin: 0 2rem 2px 0; }
.mapcard__meta { font-size: 13px; font-weight: 700; color: var(--c-primary); margin: 0 0 var(--sp-3); }
.mapcard__take { font-size: 15px; margin: 0 0 var(--sp-2); }
.mapcard__area { font-size: 13px; font-style: italic; color: var(--c-muted); margin: 0 0 var(--sp-2); }
.mapcard__link { font-weight: 700; color: var(--c-cta); text-decoration: none; }
.mapcard__link:hover { text-decoration: underline; }
.mapcard p:last-child { margin-bottom: 0; }
.mapcard__close {
  position: absolute; top: 8px; right: 8px;
  width: 32px; height: 32px; line-height: 1;
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font-size: 22px; color: var(--c-muted); border-radius: 50%;
}
.mapcard__close:hover { background: var(--c-bg); color: var(--c-text); }

/* Sur mobile la fiche se pose sous la carte plutôt que par-dessus : elle ne
   masque donc jamais ce qu'elle décrit, et il n'y a pas de panneau glissant à
   apprendre. La carte est raccourcie pour que les deux tiennent dans l'écran. */
@media (max-width: 1023px) {
  .mapwrap.has-map:not(.show-list) .mapcard {
    margin-top: var(--sp-3);
    box-shadow: var(--shadow-float);
  }
}

/* --- La liste -------------------------------------------------------------- */
/* Ailleurs sur le site, .place-list est un <div> : ici c'est une vraie <ul>,
   parce que vingt-sept lieux sont une liste et qu'un lecteur d'écran doit
   l'annoncer comme telle. Elle a donc besoin de sa propre remise à zéro. */
.map-list { margin-top: var(--sp-4); list-style: none; padding-left: 0; }
.map-list > li::marker { content: none; }
.map-place { cursor: pointer; }
.map-place:hover { border-color: var(--c-primary); }
.map-place[aria-current] {
  border-color: var(--c-cta);
  box-shadow: inset 3px 0 0 var(--c-cta);
}
.map-place h3 { border-radius: 3px; }
.map-place h3:focus-visible { outline: 2px solid var(--c-secondary); outline-offset: 3px; }
.place__take { margin: 0 0 var(--sp-3); }
.place__area, .place__note {
  font-size: 13.5px; font-style: italic; color: var(--c-muted);
  margin: calc(var(--sp-3) * -1) 0 var(--sp-3);
}
.place__link { font-weight: 700; color: var(--c-cta); text-decoration: none; }
.place__link:hover { text-decoration: underline; }

/* L'en-tête de groupe : un repère de catégorie au-dessus des lieux qui en
   relèvent, pas une nouvelle fiche. Le premier n'a pas besoin de marge
   au-dessus, les suivants si, pour se détacher du groupe précédent. */
.place-group-heading { cursor: default; }
.place-group-heading:not(:first-child) { margin-top: var(--sp-5); }
.place-group__title {
  font-size: 1rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--c-muted); margin: 0;
}
.place-group__link { font-size: 14px; margin: var(--sp-2) 0 0; }

/* --- Le crédit, hors de la carte ------------------------------------------- */
/* La mention d'attribution est aussi dans le contrôle de Leaflet, en bas de la
   carte. Celle-ci vit dans le HTML : elle reste lisible si la carte ne se
   charge pas, ce qui est exactement le cas où l'on ne peut pas s'en passer. */
.map__credit { font-size: 12.5px; color: var(--c-muted); margin: var(--sp-5) 0 0; }
.map__credit a { color: var(--c-muted); }

/* Leaflet pose ses propres couleurs et sa propre police : on les ramène à
   celles du site, sinon la page porte deux typographies. */
.leaflet-container { font-family: var(--font-body); background: var(--c-primary-soft); }
.leaflet-control-attribution {
  background: rgba(255, 255, 255, .86) !important;
  font-size: 11px !important; color: var(--c-muted) !important;
  padding: 2px 7px !important;
}
.leaflet-control-attribution a { color: var(--c-muted) !important; }
.leaflet-bar a {
  color: var(--c-primary) !important;
  border-bottom-color: var(--c-border) !important;
}
.leaflet-bar a:hover { background: var(--c-primary-soft) !important; }
.leaflet-touch .leaflet-bar a:first-child { border-radius: var(--r-btn) var(--r-btn) 0 0 !important; }
.leaflet-touch .leaflet-bar a:last-child { border-radius: 0 0 var(--r-btn) var(--r-btn) !important; }

/* --- Le renvoi de fin de section (pages guide et articles) ------------------ */
.sec__link { margin: var(--sp-4) 0 var(--sp-5); font-weight: 700; }

/* --- 360 px ---------------------------------------------------------------- */
/* La barre de filtres glisse dans son propre conteneur : la page, elle, ne
   déborde jamais horizontalement. */
@media (max-width: 639px) {
  .mapbar { flex-direction: column; align-items: stretch; gap: var(--sp-3); }
  /* Les pastilles glissent dans leur propre boîte. La page, elle, ne déborde
     jamais : c'est ce conteneur qui coupe, pas le document. */
  .mapbar__pills {
    flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px;
    scrollbar-width: thin; -webkit-overflow-scrolling: touch;
  }
  /* Un fondu au bord droit dit qu'il reste des filtres hors de l'écran. Il ne
     porte que sur la rangée des catégories : à 360 px elle mesure 628 px pour
     312 px de place, elle déborde donc toujours, alors que les deux pastilles
     de « quelle carte » tiennent (312 px sur 312). Un fondu sur une rangée qui
     ne glisse pas serait une promesse fausse.

     Pas de flèche, pas de script : le dégradé est posé sur le <fieldset>, qui
     ne défile pas, et laisse passer les clics. */
  .mfilter { position: relative; }
  .mfilter::after {
    content: ""; position: absolute; top: 0; right: 0; bottom: 4px; width: 30px;
    background: linear-gradient(to left, var(--c-bg), rgba(242, 245, 241, 0));
    pointer-events: none;
  }
  .mfilter__pill span, .mscope__pill span { padding: 8px 13px; font-size: 13.5px; }
  .map { height: 46vh; min-height: 280px; }
  .mapcard { padding: var(--sp-4); }
}

/* La note de vérification des coordonnées : elle vit sous la liste plutôt qu'au-
   dessus de la carte, pour que la carte arrive plus haut sur une page dont c'est
   l'outil principal. Elle reste au contact des lieux qu'elle concerne. */
.map__note {
  font-size: 14px; color: var(--c-muted);
  margin: var(--sp-6) 0 0; padding-top: var(--sp-4);
  border-top: 1px solid var(--c-border);
}

/* Une catégorie sans aucun lieu dans le cadre choisi : lisible, mais pas
   cochable. Cocher un filtre qui ne peut rien montrer n'est pas un choix. */
.mfilter__pill.is-empty span { opacity: .45; }
.mfilter__pill.is-empty input { cursor: default; }

/* --- 16. Le lien de confidentialité du bandeau légal ---------------------- */
/* Ce bloc portait une bannière de consentement. Elle a disparu avec les cookies
   qu'elle demandait : la mesure d'audience est désormais agrégée, ne pose aucun
   cookie et ne crée aucun identifiant, il n'y a donc plus de choix à proposer.
   Ne reste qu'un lien vers la page qui explique ce qui est mesuré. */
.footer-legal__link { text-decoration: none; }
.footer-legal__link:hover { color: var(--c-secondary); }
/* Le groupe « À propos · Confidentialité » : deux liens qui comptent pour un
   seul bloc du bandeau, pour que space-between ne les écarte pas l'un de
   l'autre. */
.footer-legal__links { display: inline-flex; flex-wrap: wrap; gap: var(--sp-4); }

/* --- 17. La page « À propos » --------------------------------------------- */
/* La seule page à la première personne. Elle se lit comme une page de carnet :
   un portrait, la présentation à côté, puis deux souvenirs posés comme des
   tirages, et le reste dans la colonne de lecture habituelle.

   Le tirage : la photo sur un passe-partout blanc, la légende dessous, dans la
   même surface. Aucune image n'est recadrée — width/height du fichier
   réservent la place, la photo garde son cadrage, les visages restent
   entiers. */
.about { display: grid; gap: var(--sp-8); }
.about__intro {
  display: grid; gap: var(--sp-7); align-items: start;
  grid-template-columns: minmax(0, 340px) minmax(0, 68ch);
}
.about__print {
  margin: 0; padding: var(--sp-3) var(--sp-3) var(--sp-2);
  background: var(--c-surface); border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}
.about__print img {
  display: block; width: 100%; height: auto;
  border-radius: 4px; background: var(--c-border);
}
.about__cap {
  margin-top: var(--sp-2); padding-inline: var(--sp-1);
  font-family: var(--font-display); font-weight: 500;
  font-variation-settings: "opsz" 14;
  font-size: 15px; line-height: 1.4; color: var(--c-muted);
}
.about__text { padding-top: var(--sp-2); }

/* Les deux souvenirs, à la même hauteur sans rognure : chaque tirage grandit
   en proportion du rapport largeur/hauteur de sa photo (--ar, posé par
   build.py). Une paysage et une portrait s'alignent ainsi d'elles-mêmes, à
   toutes les largeurs où elles sont côte à côte. */
.about__mems {
  display: flex; gap: var(--sp-5); align-items: flex-start;
  max-width: calc(340px + var(--sp-7) + 68ch);
}
.about__print--mem { flex: var(--ar) 1 calc(var(--sp-3) * 2); min-width: 0; }

.about__body { padding-top: 0; }
.about__body h2:first-child { margin-top: 0; }
/* La photo de l'université, dans le fil du récit : un tirage à la largeur de
   la colonne de texte, posé entre deux paragraphes. */
.about__print--inline { margin-block: var(--sp-2); }

/* Le mot de la fin et son clin d'œil : le texte à gauche, la photo de
   Tomorrowland à droite, alignés sur leur milieu. Empilés sur téléphone. */
.about__end {
  display: grid; gap: var(--sp-7); align-items: center;
  grid-template-columns: minmax(0, 52ch) minmax(0, 460px);
  padding-top: var(--sp-6); border-top: 1px solid var(--c-border);
  max-width: calc(52ch + var(--sp-7) + 460px);
}
.about__closing {
  margin: 0;
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.15rem, 1.6vw, 1.3rem); line-height: 1.5;
  color: var(--c-primary);
}

@media (max-width: 1023px) {
  .about__intro { grid-template-columns: minmax(0, 280px) minmax(0, 1fr); gap: var(--sp-6); }
}
@media (max-width: 767px) {
  .about { gap: var(--sp-7); }
  .about__intro { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }
  .about__print--portrait { max-width: 360px; }
  .about__text { padding-top: 0; }
  /* Sur téléphone, côte à côte, la photo verticale tomberait sous les cent
     pixels de large. Les deux tirages s'empilent ; la verticale est bridée
     pour ne pas occuper plus d'un écran à elle seule. */
  .about__mems { flex-direction: column; gap: var(--sp-5); }
  .about__print--mem { flex: none; width: 100%; }
  .about__print--mem:last-child { max-width: 300px; }
  .about__end { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }
}
