@charset "utf-8";
/* ==========================================================================
   BELVÉDÈRE — contemporain clair et minéral.

   Ce thème consomme EXACTEMENT le même modèle de données que les quatre
   autres. Il n'invente aucun champ. Ce qui change :

     — le hero est un ÉCRAN PARTAGÉ : l'image tient une moitié pleine de
       la fenêtre, du haut au bas ; le texte tient l'autre, cadré sur la
       grille. Rien n'est posé sur la photo (comptoir), rien n'est monté
       sur marge (atelier) ;
     — les hébergements sont des RANGÉES ALTERNÉES pleine largeur, une
       par unité, le côté de l'image changeant à chaque fois ;
     — la galerie est une PLANCHE CONTACT à fond perdu, carrés jointifs
       d'un bord de l'écran à l'autre ;
     — les informations pratiques et l'accès partagent une TABLE DE
       RELEVÉ : intitulé en monospace à gauche, texte à droite, un filet
       entre chaque ;
     — le lieu tient en une colonne de texte FIXE pendant que la pile
       d'images défile à côté ;
     — l'en-tête est un rail opaque, avec son filet dès le premier pixel.

   LE PARTI PRIS : l'image n'a ni cadre, ni filet, ni marge, ni ombre.
   La profondeur vient de l'écart de valeur et du blanc, jamais d'un
   contour ni d'un flou. Rayon de bordure : ZÉRO partout, sans exception.

   Six gabarits de section sont redéfinis. Les cinq autres retombent sur
   core/ — et sont habillés ici, plus bas.
   ========================================================================== */

/* ---------- 1. Polices auto-hébergées ----------------------------------- */
/* Jost — géométrique de lignée Futura — porte TOUT le discours, en trois
   graisses. IBM Plex Mono ne sert qu'à ce qui se compte : numéros de
   rangée, mesures, étiquettes de formulaire, prix. Cette division du
   travail est l'identité typographique du thème : une seule voix pour
   lire, une seule voix pour compter. */

@font-face {
  font-family: 'Jost'; font-style: normal; font-weight: 300;
  font-display: swap; src: url('../../../assets/fonts/jost-300.woff2') format('woff2');
}
@font-face {
  font-family: 'Jost'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('../../../assets/fonts/jost-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Jost'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('../../../assets/fonts/jost-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Plex Mono'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('../../../assets/fonts/plexmono-400.woff2') format('woff2');
}

/* ---------- 2. Jetons ---------------------------------------------------- */

:root {
  /* Aucun blanc pur : le fond est un calcaire, pas une feuille. */
  --calcaire:   #F2F1EC;
  --calcaire-2: #FAFAF8;   /* surface haute : bandes, champs */
  --graphite:   #191B1D;   /* l'encre */
  --graphite-2: #55595E;   /* texte secondaire — 5,9:1 sur calcaire */
  --filet:      #D8D7D0;   /* séparations décoratives : hors seuil, assumé */
  --filet-fort: #9C9A92;   /* bord des champs — 3,0:1, seuil interface tenu */
  --ardoise:    #35505E;   /* l'accent : 7,7:1 sur calcaire, conforme AA */
  --alerte:     #8A3A2E;

  --geo:   'Jost', 'Jost repli', 'Century Gothic', Avenir, sans-serif;
  --mono:  'Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  --t-display: clamp(2.9rem, 7.2vw, 6.4rem);
  --t-h2:      clamp(1.7rem, 3.2vw, 2.8rem);
  --t-h3:      clamp(1.35rem, 2.1vw, 1.9rem);
  --t-lead:    clamp(1.05rem, 1.4vw, 1.28rem);
  --t-body:    1.0625rem;
  --t-petit:   0.875rem;
  --t-mesure:  0.6875rem;

  --gouttiere: clamp(20px, 4vw, 56px);
  --large:     1440px;
  --section-y: clamp(64px, 10vh, 136px);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --survol: 180ms;
  --apparition: 640ms;
  --h-entete: 64px;
}

/* Repli métrique : Jost a une hauteur d'x moyenne et une chasse étroite.
   Century Gothic et Avenir sont ses voisins les plus proches sur les
   machines qui les ont ; ailleurs on ajuste la substitution pour que le
   texte ne saute pas au chargement. */
@font-face {
  font-family: 'Jost repli';
  src: local('Century Gothic'), local('Avenir Next'), local('Avenir'), local('Arial');
  size-adjust: 94%; ascent-override: 100%; descent-override: 26%; line-gap-override: 0%;
}

/* ---------- 3. Remise à plat --------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* =========================================================================
   L'ATTERRISSAGE DES ANCRES
   =========================================================================
   Une ancre doit s'arrêter SOUS l'en-tête, et le titre visé doit être
   entier. Deux quantités le décident, et une seule des deux appartient au
   thème :

   « --ancre-haut » — ce que l'en-tête collé occupe en haut de la fenêtre,
   filet compris, plus l'air qu'on veut sous la barre. Posé par
   « scroll-padding-top » sur <html>, il vaut pour TOUTES les ancres de la
   page : le menu, les boutons du hero, ceux des hébergements et des
   offres, le lien du bandeau, « Aller au contenu », et le champ qu'une
   erreur de formulaire ramène sous les yeux. Une règle, pas une par
   famille de cible — c'est ainsi qu'aucune n'est oubliée.

   « --ancre-retrait » — le padding HAUT de la section visée, remonté par
   « scroll-margin-top » pour que ce soit le TITRE qui s'immobilise, et non
   le bord haut du <section>, qui est invisible. Sans lui le titre atterrit
   une respiration trop bas, avec la fin de la section précédente encore
   visible sous la barre.

   LA HAUTEUR EST MESURÉE, PAS SUPPOSÉE.
   Relevé de 320 à 1920 px, avec et sans bandeau : 64 px de barre
   et 1 px de filet, sans jamais varier — cet en-tête ne se replie pas au
   défilement et sa hauteur ne dépend pas de la largeur. Sans script, en
   dessous de 900 px, la feuille de <noscript> le sort du flux collant : il
   n'occulte alors plus rien, et 65 px reste une réserve large.

   LE BANDEAU D'INFORMATION N'ENTRE PAS DANS CE COMPTE, et ce n'est pas un
   oubli : posé au-dessus de l'en-tête il s'en va au défilement, et
   descendu dans <main> il n'occulte rien. Dans les deux cas ce qui reste
   collé en haut est la barre, et elle seule. Vérifié aux deux longueurs de
   message, d'une ligne et de deux.

   tools/verifier-ancres.mjs mesure tout cela dans un navigateur, sur les
   cinq thèmes, à quatre largeurs, sur deux moteurs, avec et sans script.
   ========================================================================= */
html {
  --ancre-air: 20px;
  --ancre-haut: calc(65px + var(--ancre-air));
  scroll-padding-top: var(--ancre-haut);
}

body {
  margin: 0;
  background: var(--calcaire);
  color: var(--graphite);
  font-family: var(--geo);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

img, picture, svg { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3, p, ul, ol, dl, dd, figure, blockquote, address { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }

/* Rayon nul partout, champs et boutons compris. C'est un parti, pas un
   oubli : ce thème ne pose aucune courbe. */
input, textarea, button, select { border-radius: 0; }

:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 3px; }
::selection { background: var(--ardoise); color: var(--calcaire-2); }

.defs { position: absolute; width: 0; height: 0; overflow: hidden; }
body.bloque { overflow: hidden; }

.evitement {
  position: absolute; left: -9999px; z-index: 100;
  background: var(--graphite); color: var(--calcaire);
  padding: 0.8em 1.2em;
  font-family: var(--mono); font-size: var(--t-mesure);
  text-transform: uppercase; letter-spacing: 0.12em; text-decoration: none;
}
.evitement:focus { left: 1rem; top: 1rem; }

/* ---------- 4. Typographie ----------------------------------------------- */

/* Le monospace : la seule autre voix du thème. Tout ce qui se compte,
   se mesure ou s'étiquette passe par lui, et rien d'autre. */
.mesure {
  font-family: var(--mono);
  font-size: var(--t-mesure);
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--graphite-2);
  font-variant-numeric: tabular-nums;
}

.titre2 {
  font-size: var(--t-h2);
  font-weight: 300;
  line-height: 1.06;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.chapeau {
  margin-top: 0.9em;
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--graphite-2);
  max-width: 46ch;
  text-wrap: pretty;
}

.corps { margin-top: 1.1em; max-width: 62ch; }
.corps + .corps { margin-top: 0.9em; }
em { font-style: italic; }

.lien, .sec__texte a, .corps a {
  text-decoration: underline;
  text-decoration-color: var(--filet-fort);
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
  transition: text-decoration-color var(--survol) var(--ease);
}
.lien:hover, .corps a:hover { text-decoration-color: var(--ardoise); }

/* Le glyphe ★ ne figure pas dans le sous-ensemble : il est dessiné. */
.etoiles { display: inline-flex; gap: 0.16em; vertical-align: baseline; }
.etoiles svg { width: 0.66em; height: 0.66em; fill: currentColor; }
.etoiles--corps svg { width: 0.58em; height: 0.58em; }

.aconfirmer { background: none; color: var(--alerte); border-bottom: 1px dotted var(--alerte); }

/* ---------- 5. Trame ----------------------------------------------------- */

.sec {
  max-width: var(--large);
  margin-inline: auto;
  padding: var(--section-y) var(--gouttiere);
  /* Le TITRE s'immobilise sous l'en-tête, pas le bord haut du <section>,
     qui est invisible. « --ancre-retrait » vaut le padding haut de la
     section et se déclare À CÔTÉ de lui : toute règle qui change ce padding
     doit reposer les deux, sans quoi la cible remonte d'une respiration
     entière. La réserve sous l'en-tête, elle, est posée une fois pour
     toutes par « scroll-padding-top » sur <html> — voir la note là-haut. */
  --ancre-retrait: var(--section-y);
  scroll-margin-top: calc(0px - var(--ancre-retrait));
}

/* L'en-tête d'une section : le numéro, le titre, le chapô. Le filet sous
   le titre court sur toute la largeur utile — c'est la seule ligne
   décorative du thème, et elle sert à caler l'œil sur la grille. */
.sec__entete { padding-bottom: clamp(18px, 2vw, 28px); border-bottom: 1px solid var(--filet); }

/* NOTE, pour les blocs qui vivent dans une section à fond perdu —
   galerie, réserver : on leur donne une LARGEUR, jamais un padding. Le
   filet sous un titre est une bordure, et une bordure court sur la boîte
   de padding : avec un padding, le trait sortait jusqu'aux bords de la
   fenêtre alors que le titre, lui, restait cadré. Vu à la première
   capture. */
.sec__rang, .lieu__rang { display: block; margin-bottom: 1.4em; color: var(--ardoise); }

/* ---------- 6. En-tête : un rail opaque ---------------------------------- */
/* Opaque dès le premier pixel, et c'est voulu : le hero de ce thème pose
   une image à MI-LARGEUR, sous le côté droit de la barre. Un en-tête
   transparent y rendrait le menu illisible une fois sur deux, selon la
   photo. L'atelier peut flotter — sa planche est en retrait ; le
   comptoir peut se voiler — son image est sombre. Pas ici. */

.entete {
  position: sticky; top: 0; z-index: 40;
  background: var(--calcaire);
  border-bottom: 1px solid var(--filet);
}
/* Au défilement, le filet se fonce : la barre se détache de la page sans
   qu'aucune ombre n'apparaisse. */
.entete--pose { border-bottom-color: var(--filet-fort); }

.entete__barre {
  max-width: var(--large);
  margin-inline: auto;
  min-height: var(--h-entete);
  padding-inline: var(--gouttiere);
  display: flex; align-items: center; gap: 1.5rem;
}

.entete__marque {
  display: inline-flex; align-items: center; gap: 0.7em;
  margin-right: auto;
  font-family: var(--mono);
  font-size: var(--t-mesure);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

/* L'emblème vient de l'instance : ce thème ne règle que sa taille, sur
   les seules proportions du dessin. Aucune couleur — il hérite de
   l'encre, donc du thème. */
.entete__embleme { flex: none; width: auto; }
.entete__embleme--carre { height: 2.1em; }
.entete__embleme--haut  { height: 3em; translate: 0 0.1em; }
/* Un mot dessine — le logo que la proprietaire a depose depuis son
   ordinateur, souvent quatre fois plus large que haut. A la toise d'un
   monogramme il occuperait la moitie de la barre et pousserait le menu a
   la ligne : il se lit sur sa LARGEUR, il lui faut donc moins de hauteur.
   Le garde-fou est la pour le cas extreme d'une banniere tres etiree, sur
   un telephone : le dessin retrecit, il ne se deforme pas. */
.entete__embleme--large { height: 1.5em; max-width: 40vw; }


.menu { display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2rem); }
.menu__liste { display: flex; align-items: center; gap: clamp(1rem, 2.2vw, 2rem); }
/* Un mot de menu ne se coupe pas. L'appel a l'action vit maintenant DANS
   la liste — il n'y a qu'un seul ordre de menu, celui de la page — donc
   la liste porte un element de plus, et elle peut deborder la barre le
   temps que la police definitive arrive. Sans ces deux lignes, le
   navigateur retasse les mots puis les remet : un decalage de mise en
   page mesure a 0,154 sur atelier, a 1920 px. */
.menu__liste { flex-wrap: nowrap; }
.menu__liste a, .menu__action { white-space: nowrap; }

.menu a {
  font-family: var(--mono);
  font-size: var(--t-mesure);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--graphite-2);
  padding-block: 0.4em;
  border-bottom: 1px solid transparent;
  transition: color var(--survol) var(--ease), border-color var(--survol) var(--ease);
}
.menu a:hover { color: var(--graphite); border-bottom-color: var(--ardoise); }
/* CE QUI LE DISTINGUE EST SA GRAISSE, PAS UN SOULIGNE. Le filet sous le
   mot n'a jamais paru : `.menu a` pose `border-bottom: 1px solid transparent`
   et l'emporte en specificite. Un trait aurait de toute facon dit « lien
   souligne » dans une rangee ou aucune autre entree n'en porte. C'est donc
   la graisse qui le detache, comme sur atelier et veillee. Bruyere et
   comptoir n'ont pas cette regle : leur appel a l'action est encadre. */
.menu__action { color: var(--graphite); font-weight: 700; }

.entete__bascule { display: none; background: none; border: 0; padding: 0.6rem; cursor: pointer; }
.entete__trait2 {
  display: block; width: 22px; height: 1px;
  background: var(--graphite);
  transition: transform var(--survol) var(--ease), opacity var(--survol) var(--ease);
}
.entete__trait2 + .entete__trait2 { margin-top: 6px; }
.entete__bascule[aria-expanded="true"] .entete__trait2:first-child { transform: translateY(3.5px) rotate(45deg); }
.entete__bascule[aria-expanded="true"] .entete__trait2:last-child  { transform: translateY(-3.5px) rotate(-45deg); }

/* ---------- 7. Boutons ---------------------------------------------------- */

.bouton, .sec__bouton {
  display: inline-block;
  font-family: var(--mono);
  font-size: var(--t-mesure);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 1.05em 1.9em;
  background: var(--graphite);
  color: var(--calcaire);
  border: 1px solid var(--graphite);
  cursor: pointer;
  transition: background var(--survol) var(--ease), color var(--survol) var(--ease);
}
.bouton:hover, .sec__bouton:hover { background: transparent; color: var(--graphite); }
.bouton--nu, .sec__bouton--doux { background: transparent; color: var(--graphite); }
.bouton--nu:hover, .sec__bouton--doux:hover { background: var(--graphite); color: var(--calcaire); }
.bouton[aria-busy="true"] { cursor: progress; opacity: 0.7; }

/* ---------- 8. HERO — écran partagé --------------------------------------- */

/* Le hero n'a pas de respiration haute : son retrait d'ancre est donc nul.
   Sans cette ligne, une ancre qui le viserait remonterait d'un --section-y
   entier. Voir la note de .sec. */
.sec--hero { max-width: none; padding: 0; --ancre-retrait: 0px; }

.hero__vue { background: var(--calcaire-2); }
.hero__vue img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }

.hero__mot {
  padding: clamp(36px, 6vh, 72px) var(--gouttiere) clamp(44px, 7vh, 88px);
}

.hero__reference { display: block; margin-bottom: 1.6em; color: var(--ardoise); }

.hero__titre {
  font-size: var(--t-display);
  font-weight: 300;
  line-height: 0.94;
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.hero__devise {
  margin-top: 0.7em;
  font-size: var(--t-lead);
  color: var(--graphite-2);
  max-width: 32ch;
}
.hero__chapo {
  margin-top: 1.6em;
  max-width: 46ch;
  color: var(--graphite-2);
  text-wrap: pretty;
}
.hero__chapo + .hero__chapo { margin-top: 0.9em; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 2.2em; }

@media (min-width: 900px) {
  /* Deux blocs, une seule rangée. La colonne de droite va jusqu'au bord
     de la fenêtre ; celle de gauche est calée EXACTEMENT sur le bord des
     autres sections, grâce au décalage de centrage repris en padding.
     Aucune unité de fenêtre n'entre là-dedans : 100 % se résout sur la
     largeur réelle du <main>, barre de défilement déduite.

     L'ÉCRAN N'EST PARTAGÉ QUE S'IL Y A UNE PHOTO. Sans elle, la moitié
     droite restait vide et le titre se serrait dans la gauche : le hero
     redevient alors un bloc de texte cadré comme les autres sections.
     Un navigateur qui ignore :has() jette la règle et obtient le même
     repli. */
  .sec--hero:has(.hero__vue) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 50%);
    align-items: stretch;
    min-height: min(calc(100svh - var(--h-entete)), 900px);
    padding-left: max(0px, calc((100% - var(--large)) / 2));
  }
  .sec--hero:not(:has(.hero__vue)) .hero__mot {
    max-width: var(--large);
    margin-inline: auto;
    padding-block: clamp(56px, 12vh, 140px);
    padding-inline: var(--gouttiere);
  }
  /* L'ANCRE D'AGRANDISSEMENT FAIT PARTIE DE LA CHAÎNE DES HAUTEURS.
     Depuis que toute photo du socle s'agrandit, un <a class="vue"> se
     tient entre la figure et le <picture>. Sa hauteur restait
     automatique, et « height: 100% » ne se résout pas contre un parent
     qui n'en a pas : l'image reprenait ses proportions naturelles — un
     1200 × 703 dans une colonne de 900 de haut — et laissait le bas de
     l'écran partagé en blanc. Le défaut ne se voyait pas en aperçu :
     l'instance de recette portait le moteur d'avant l'ancre.
     Chaque maillon doit donc porter sa hauteur, l'ancre comprise. */
  .hero__vue { grid-column: 2; grid-row: 1; height: 100%; }
  .hero__vue > .vue, .hero__vue picture { display: block; height: 100%; }
  .hero__vue img { height: 100%; aspect-ratio: auto; }
  .hero__mot {
    grid-column: 1; grid-row: 1;
    display: flex; flex-direction: column; justify-content: center;
    padding-block: clamp(48px, 8vh, 110px);
    padding-inline: var(--gouttiere) clamp(32px, 4vw, 72px);
  }
}

/* ---------- 9. LE LIEU — colonne fixe, images qui défilent ---------------- */

.lieu { display: grid; gap: clamp(28px, 4vw, 52px); }
.lieu__mot .titre2 { margin-top: 0; }

.releve { margin-top: 2em; border-top: 1px solid var(--filet); }
.releve__ligne {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1.5rem;
  padding-block: 0.85em;
  border-bottom: 1px solid var(--filet);
}
.releve__valeur { font-size: var(--t-h3); font-weight: 300; line-height: 1; font-variant-numeric: tabular-nums; }
.releve__mot { text-align: right; }

.lieu__vues { display: grid; gap: 2px; }
.lieu__vues img { width: 100%; }
.vue { display: block; text-decoration: none; cursor: zoom-in; }
.vue img { transition: opacity var(--survol) var(--ease); }
.vue:hover img { opacity: 0.88; }
.vue__legende { margin-top: 0.7em; }

@media (min-width: 900px) {
  /* PAS DE PHOTOS, PAS DE COLONNE. La colonne de 36 % n'a de sens que
     s'il y a une pile d'images à côté ; seule, elle serrait tout le
     texte dans un tiers de la page. Le lieu sans photo redevient un
     bloc de lecture pleine largeur — et rien à faire pour un navigateur
     sans :has(), qui obtient déjà ce repli. */
  .lieu:has(.lieu__vues) {
    grid-template-columns: minmax(0, 36%) minmax(0, 1fr);
    column-gap: clamp(32px, 4vw, 80px);
    align-items: start;
  }
  /* Le texte ne bouge pas pendant qu'on parcourt les photos : c'est le
     geste d'un dossier d'architecture, et c'est ce qui distingue cette
     section de la planche + texte de l'atelier, alignés côte à côte sur
     la même hauteur. Sans photos, rien à suivre : pas de sticky. */
  .lieu:has(.lieu__vues) .lieu__mot {
    position: sticky; top: calc(var(--h-entete) + clamp(24px, 5vh, 64px));
  }
}

/* ---------- 10. HÉBERGEMENTS — rangées alternées -------------------------- */

.rangees { display: grid; gap: clamp(56px, 9vw, 132px); margin-top: clamp(36px, 5vw, 72px); }
.rangee { display: grid; gap: clamp(20px, 3vw, 40px); }

.rangee__vues { display: grid; gap: 2px; }
.rangee__vues > .vue img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.rangee__vignettes { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 2px; }
.rangee__vignettes img { width: 100%; aspect-ratio: 1; object-fit: cover; }

.rangee__mot { display: flex; flex-direction: column; }
.rangee__rang { display: block; margin-bottom: 1.3em; }
.rangee__nom { font-size: var(--t-h3); font-weight: 400; line-height: 1.15; letter-spacing: -0.015em; }
.rangee__accroche { margin-top: 0.35em; color: var(--graphite-2); }

.fiche-technique { margin-top: 1.4em; border-top: 1px solid var(--filet); }
.fiche-technique__ligne {
  display: flex; align-items: baseline; gap: 0.9rem;
  padding-block: 0.55em;
  border-bottom: 1px solid var(--filet);
  font-size: var(--t-petit);
}
.fiche-technique__ligne dt { color: var(--ardoise); }
.fiche-technique__ligne dd { margin: 0; }

.rangee__equipements { display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem; margin-top: 1.1em; }

.rangee__pied { display: flex; flex-wrap: wrap; align-items: center; gap: 1.2rem; margin-top: 1.8em; }
.rangee__prix { color: var(--ardoise); }

@media (min-width: 900px) {
  /* Une rangée sans photo ne garde pas la colonne de l'image : son
     texte reprend la largeur, au lieu de tenir dans 56 % en laissant le
     reste blanc. Une fiche incomplète reste propre — c'est la même
     règle que dans le gabarit, qui ne rend pas de cadre vide. */
  .rangee:has(.rangee__vues) {
    grid-template-columns: minmax(0, 56%) minmax(0, 1fr);
    column-gap: clamp(32px, 4vw, 76px);
    align-items: center;
  }
  /* LE ZIGZAG. Une rangée sur deux renvoie son image à droite : le
     regard descend en lacets au lieu de suivre une colonne. Aucun
     réglage ne le déclare — c'est le rang qui décide. */
  .rangee:nth-child(even) .rangee__vues { order: 2; }
}

/* ---------- 11. GALERIE — planche contact à fond perdu -------------------- */

.sec--gallery { max-width: none; padding-inline: 0; }
.sec--gallery .sec__entete {
  width: calc(min(var(--large), 100%) - 2 * var(--gouttiere));
  margin-inline: auto;
}

/* ---------------------------------------------------------------------
   CE QUE LE MODELE PORTAIT ET QUE CE THEME NE DESSINAIT PAS.

   La couverture de la galerie, les intertitres de categorie, le resume
   d'un hebergement, et surtout LES LEGENDES SOUS LES VUES — ce theme
   n'en posait aucune, au motif qu'elles vivent dans la visionneuse. Or
   sans script il n'y a pas de visionneuse, et l'administration propose
   ce champ a tout le monde. Elles sont donc la, en surimpression au bas
   de la vue, et rendues au flux quand le pointeur est grossier.
   --------------------------------------------------------------------- */

/* La galerie de ce theme est A FOND PERDU — « .sec--gallery » retire la
   gouttiere. La couverture en profite ; sa LEGENDE, elle, doit revenir
   dans la colonne de texte, sinon elle se colle au bord de l'ecran. */
.galerie__couverture { margin-top: clamp(28px, 4vw, 52px); }
.galerie__couverture img { width: 100%; aspect-ratio: 21 / 9; object-fit: cover; }
.galerie__couverture .legende {
  width: calc(min(var(--large), 100%) - 2 * var(--gouttiere));
  margin: 0.7em auto 0;
}

/* L'intertitre d'une serie. La section est a fond perdu : il faut lui
   rendre la gouttiere, sans quoi il se colle au bord de l'ecran. */
.galerie__categorie {
  width: calc(min(var(--large), 100%) - 2 * var(--gouttiere));
  margin: clamp(30px, 4vw, 52px) auto clamp(8px, 1vw, 14px);
  font-family: var(--mono);
  font-size: var(--t-mesure);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--graphite-2);
}

.rangee__resume { margin-top: 0.8em; }
/* L'intitule d'une serie de vues — « Interieur », « Exterieur ». Il
   coiffe les categories : plus d'air au-dessus, l'encre pleine plutot
   que le gris des sous-titres. */
.rangee__intitule { margin-top: 2em; color: var(--graphite); }
.rangee__categorie { margin-top: 1.1em; }
.rangee__legende { margin-top: 0.45em; font-size: 0.8125rem; line-height: 1.35; text-wrap: pretty; }

/* La planche contact reste jointive : la legende s'y pose SUR la vue,
   revelee au survol et au focus, plutot que d'ouvrir des gouttieres
   entre les cases. C'est le seul thème du socle où la légende ne prend
   aucune hauteur dans le flux — et c'est pour cela que ses rangées se
   touchent. */
.galerie-mosaique figure { position: relative; display: block; }
.galerie-mosaique__legende {
  position: absolute;
  inset: auto 0 0 0;
  margin: 0;
  padding: 0.7em 0.8em 0.6em;
  background: linear-gradient(to top, rgb(0 0 0 / 0.72), rgb(0 0 0 / 0));
  color: #fff;
  font-size: 0.8125rem;
  line-height: 1.3;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--survol) var(--ease), transform var(--survol) var(--ease);
  pointer-events: none;
}
.galerie-mosaique figure:hover .galerie-mosaique__legende,
.galerie-mosaique .vue:focus-visible + .galerie-mosaique__legende {
  opacity: 1;
  transform: none;
}
/* Au doigt, il n'y a pas de survol : la legende revient dans le flux,
   sous sa vue, plutot que de rester invisible. */
@media (hover: none) {
  .galerie-mosaique figure { position: static; }
  .galerie-mosaique__legende {
    position: static;
    opacity: 1;
    transform: none;
    padding: 0.5em 0 0;
    background: none;
    color: var(--graphite-2);
  }
}

/* =====================================================================
   LA GALERIE — L'INVARIANT DU SOCLE. Le même dans les cinq thèmes.
   =====================================================================
   « La galerie est une mosaïque de vignettes rectangulaires, toutes
   exactement de la même taille. »

   Ce bloc est IDENTIQUE d'un thème à l'autre, au caractère près. Il l'est
   à dessein, et il n'est pas dans une feuille commune : une TROISIÈME
   feuille bloquante fait perdre au socle son décalage de mise en page à
   zéro. Mesuré, sur la démonstration complète à 768 px, douze
   chargements : 0,00 avec deux feuilles, 0,17 sur deux chargements sur
   douze avec trois — l'en-tête est en `position: fixed`, et une page
   peinte avant que toutes les feuilles soient là pousse `main` de la
   hauteur de l'en-tête, puis le reprend.

   Ce qui garantit que les cinq copies ne divergent pas n'est donc pas
   leur origine commune, c'est tools/verifier-galerie.mjs : il MESURE les
   rectangles rendus dans deux moteurs, sur tous les thèmes présents dans
   le dossier, avec 1, 2, 3, 5, 7 et 25 photos. Un thème ajouté demain y
   passe sans qu'on l'inscrive nulle part.

   Ce que le thème règle, plus bas : --galerie-rapport, --galerie-colonnes,
   --galerie-ecart, --galerie-rayon, --galerie-fond. Rien d'autre.
   ===================================================================== */

.galerie-mosaique {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* LE NOMBRE DE COLONNES EST FIXE, ET C'EST TOUT LE SUJET.
     `auto-fit` efface les pistes vides : quand il reste moins de photos
     que de colonnes, il donne toute la largeur aux survivantes — une
     photo seule devenait un bandeau de 1920 px. `auto-fill` garde les
     pistes mais laisse le compte au hasard de la largeur, et tombait à
     UNE colonne sur téléphone. Un compte franc, par palier, tient la
     promesse aux deux bouts. */
  grid-template-columns: repeat(var(--galerie-colonnes, 2), minmax(0, 1fr));
  /* Un seul `gap` : l'écart est le même dans les deux sens par
     construction, et non par coïncidence. */
  gap: var(--galerie-ecart, 16px);
}

/* `min-width: 0` : sans lui, une légende longue impose sa largeur
   minimale à sa cellule et fait déborder la grille de son cadre. */
.galerie-mosaique > li { margin: 0; min-width: 0; }

/* La chaîne figure > a > picture > img est en ligne par défaut. Une
   image en largeur 100 % dans un conteneur en ligne ne remplit pas sa
   cellule : la mosaïque sortait en une colonne d'images centrées, ce qui
   ressemble à un défaut de grille alors que c'en est un d'affichage. */
.galerie-mosaique figure,
.galerie-mosaique a,
.galerie-mosaique picture { display: block; margin: 0; }

.galerie-mosaique img {
  display: block;
  width: 100%;
  height: auto;
  /* LE RECADRAGE, ET SON PRIX. `cover` remplit le cadre en rognant ce
     qui dépasse ; il ne déforme jamais. Le prix est payé par les
     portraits : un 3:4 dans un 4:3 perd 44 % de sa hauteur. C'est
     pourquoi aucun thème ne va au-delà de 16:10 — plus large coûterait
     une tête. Et c'est `aspect-ratio` qui réserve la place AVANT le
     chargement : le décalage de mise en page reste à zéro. */
  aspect-ratio: var(--galerie-rapport, 4 / 3);
  object-fit: cover;
  border-radius: var(--galerie-rayon, 0);
  /* Vu le temps du décodage seulement : évite un trou clair sur un fond
     sombre. */
  background: var(--galerie-fond, transparent);
}
/* ================= fin de l'invariant de galerie ===================== */

/* ---------------------------------------------------------------------
   AUTO-FIT ETAIT LE BUG, PAS LA SOUPLESSE.

   La planche etait en `repeat(auto-fit, minmax(16rem, 1fr))`. Le
   raisonnement d'alors : avec un nombre fixe de colonnes, une serie de
   trois photos laisse des cases vides au bout de sa rangee, et sur une
   planche jointive un trou se voit. auto-fit efface les pistes
   inoccupees, donc trois photos remplissent la largeur.

   Elles la remplissent TROP. Mesure au navigateur : une galerie d'UNE
   photo la donnait a voir sur 1920 px — 100 % du cadre a toutes les
   largeurs. Sept photos a 375 px : une par rangee, pleine largeur.
   Ce que auto-fit repare au bout d'une rangee, il le casse au debut.

   Le compte est donc franc, par palier. Une derniere rangee incomplete
   s'aligne a gauche et garde la taille de ses vues : c'est le prix, il
   est bien plus petit que celui d'une photo en bandeau.

   ET DES RECTANGLES, PLUS DES CARRES. Le 3:2 est le format du 24x36 :
   sur une planche contact, c'est le seul cadre qui ne soit pas une
   citation approximative.
   --------------------------------------------------------------------- */
.galerie-mosaique {
  --galerie-rapport: 3 / 2;
  --galerie-ecart: 2px;               /* jointif : la signature du theme */
  --galerie-fond: var(--calcaire-2);
  --galerie-colonnes: 2;
  margin-top: clamp(28px, 4vw, 56px);
}
@media (min-width:  520px) { .galerie-mosaique { --galerie-colonnes: 3; } }
@media (min-width:  760px) { .galerie-mosaique { --galerie-colonnes: 4; } }
@media (min-width: 1100px) { .galerie-mosaique { --galerie-colonnes: 5; } }
@media (min-width: 1500px) { .galerie-mosaique { --galerie-colonnes: 6; } }

/* La variante : les memes photos, en portraits. Le rapport change, la
   regle non — cellules egales, colonnes franches, aucune pleine
   largeur. Moins de colonnes, parce qu'un portrait est plus haut. */
.galerie-mosaique--colonnes { --galerie-rapport: 3 / 4; --galerie-colonnes: 2; }
@media (min-width:  760px) { .galerie-mosaique--colonnes { --galerie-colonnes: 3; } }
@media (min-width: 1100px) { .galerie-mosaique--colonnes { --galerie-colonnes: 4; } }
@media (min-width: 1500px) { .galerie-mosaique--colonnes { --galerie-colonnes: 5; } }

/* ---------- 12. TABLE DE RELEVÉ — séjour et accès ------------------------- */
/* Le même objet sert deux sections, et c'est le point : dans ce thème,
   « informations pratiques » et « accès » se lisent comme une seule
   famille de données. */

.table-releve { margin-top: clamp(28px, 4vw, 52px); border-top: 1px solid var(--filet); }
.table-releve__ligne {
  display: grid;
  gap: 0.4em;
  padding-block: clamp(16px, 2vw, 26px);
  border-bottom: 1px solid var(--filet);
}
.table-releve__mot { padding-top: 0.35em; color: var(--graphite); }
.table-releve__detail { margin: 0; max-width: 68ch; }
.table-releve__detail .corps:first-child { margin-top: 0; }

@media (min-width: 760px) {
  .table-releve__ligne { grid-template-columns: minmax(0, 24%) minmax(0, 1fr); column-gap: clamp(24px, 4vw, 72px); }
}

.acces { display: grid; gap: 0; }
.acces__plaque {
  font-size: var(--t-h3);
  font-weight: 300;
  font-style: normal;
  line-height: 1.3;
  margin-top: clamp(24px, 3vw, 40px);
}
.acces__carte {
  display: inline-flex; align-items: center; gap: 0.6em;
  margin-top: 2em;
  text-decoration: none;
  color: var(--ardoise);
}
.acces__carte span {
  text-decoration: underline; text-underline-offset: 0.25em;
  text-decoration-thickness: 1px; text-decoration-color: var(--filet-fort);
  transition: text-decoration-color var(--survol) var(--ease);
}
.acces__carte:hover span { text-decoration-color: var(--ardoise); }
.acces__pin { width: 1.35em; height: 1.35em; flex: none; }

/* ---------- 13. Les sections servies par core/ ----------------------------
   « Services », « qui vous accueille », « aux alentours » et « avis »
   n'ont pas de gabarit ici : ils retombent sur ceux du socle, dont le
   vocabulaire de classes est celui de core/. On les habille au
   vocabulaire de ce thème — filets, monospace, images sans cadre.

   AUCUN VIS-À-VIS : les sections s'empilent, pleine largeur. C'est un
   choix, pas un manque — l'atelier met « accueil » et « accès » côte à
   côte, ce thème préfère laisser respirer.
   ------------------------------------------------------------------------- */

.sec__titre { font-size: var(--t-h2); font-weight: 300; line-height: 1.06; letter-spacing: -0.022em; }
.sec__intro { margin-top: 0.9em; font-size: var(--t-lead); color: var(--graphite-2); max-width: 46ch; }
.sec__texte { margin-top: 1.1em; max-width: 62ch; }
.sec__texte + .sec__texte { margin-top: 0.9em; }
.sec__corps { margin-top: clamp(28px, 4vw, 52px); }

/* --- Services : une grille typographique, pictogramme en tête ------------ */
.sec__services {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: clamp(20px, 2.6vw, 36px);
  margin-top: clamp(28px, 4vw, 52px);
}
.sec__services > li { padding-top: 0.9em; border-top: 1px solid var(--filet); }
/* Sous le filet et au-dessus du nom : la colonne de ce thème s'ouvre par
   un trait horizontal, et un dessin posé juste dessous en prolonge la
   lecture. L'ardoise, l'accent du thème, et rien d'écrit dans le SVG. */
.service__pictogramme {
  display: block;
  width: 22px; height: 22px;
  margin-bottom: 0.7em;
  color: var(--ardoise);
}
/* UNE ENTRÉE SANS ICÔNE GARDE LA PLACE DE CELLE QU'ELLE N'A PAS. Sans
   cela son nom remonte à la hauteur des dessins voisins et la rangée part
   en escalier — une liste où l'on n'a rempli que la moitié des icônes est
   le cas ordinaire, pas le cas limite. La réserve ne se pose que si la
   liste porte au moins un dessin : celle qui n'en a aucun n'a rien à
   aligner, et ne gagne pas un pixel de vide. */
.sec__services:has(.service__pictogramme) > li:not(:has(.service__pictogramme))::before {
  content: ""; display: block; height: 22px; margin-bottom: 0.7em;
}
.service__nom { display: block; font-size: var(--t-petit); font-weight: 500; letter-spacing: 0.01em; }
.service__detail { display: block; margin-top: 0.35em; font-size: var(--t-petit); color: var(--graphite-2); }
.sec__categorie {
  margin-top: 2.4em;
  font-family: var(--mono); font-size: var(--t-mesure);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ardoise);
}

/* --- Qui vous accueille : portrait en colonne, texte à côté ------------- */
.sec--about__portrait { margin: 0; }
.sec--about__portrait img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.sec--about__gens { display: flex; flex-wrap: wrap; gap: 2rem; margin-top: 1.8em; }
.sec--about__gens img { width: 120px; aspect-ratio: 1; object-fit: cover; }
.gens__nom { margin-top: 0.6em; font-size: var(--t-petit); font-weight: 500; }
.gens__role { font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.1em; text-transform: uppercase; color: var(--graphite-2); }
.sec--about__histoire { margin-top: 1.4em; max-width: 62ch; color: var(--graphite-2); }

@media (min-width: 820px) {
  /* LA GRILLE N'EXISTE QUE S'IL Y A UN PORTRAIT.
     Sans lui, le texte était le seul enfant de la grille : il tombait
     dans la colonne étroite réservée à l'image, et la moitié droite de
     la section restait vide. Le portrait est facultatif — l'atelier
     rend souvent cette section sans photo —, la grille doit donc l'être
     aussi. Un navigateur qui ignore :has() jette la règle : le texte
     reprend la largeur, ce qui est exactement le repli voulu. */
  .sec--about .sec__corps:has(.sec--about__portrait) {
    display: grid;
    grid-template-columns: minmax(200px, 280px) minmax(0, 1fr);
    column-gap: clamp(28px, 4vw, 72px);
    align-items: start;
  }
  /* Le portrait tient la première colonne, TOUT le reste la seconde.
     Sans ce calage, le placement automatique renvoyait le deuxième
     paragraphe sous le portrait, dans la colonne étroite.

     Et le portrait court sur toutes les rangées : sinon sa hauteur
     imposait celle de la première, et le paragraphe suivant repartait
     350 px plus bas. On ne connaît pas d'avance le nombre de blocs de
     la colonne de texte — corps, gens, histoire —, d'où un span large ;
     les rangées vides ne coûtent rien, l'écart de rangée étant nul. */
  .sec--about .sec__corps > .sec--about__portrait { grid-column: 1; grid-row: 1 / span 30; }
  .sec--about .sec__corps > :not(.sec--about__portrait) { grid-column: 2; }
  /* Le premier bloc de chaque colonne part du haut : avec portrait c'est
     le portrait et le texte d'à côté, sans portrait c'est le texte seul. */
  .sec--about .sec__corps > :first-child,
  .sec--about .sec__corps > .sec--about__portrait + * { margin-top: 0; }
}
@media (max-width: 819px) { .sec--about__portrait { max-width: 260px; } }

/* --- Aux alentours : des cartes sans carte ------------------------------ */
.sec__grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  gap: clamp(24px, 3vw, 44px);
  margin-top: clamp(28px, 4vw, 52px);
}
.carte { display: flex; flex-direction: column; }
.carte img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.carte__nom { margin-top: 0.9em; font-size: var(--t-petit); font-weight: 500; }
.carte__type, .carte__distance {
  margin-top: 0.3em;
  font-family: var(--mono); font-size: var(--t-mesure);
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--graphite-2);
}
.carte__texte, .carte__resume, .carte__accroche { margin-top: 0.7em; font-size: var(--t-petit); color: var(--graphite-2); }
.carte__faits, .carte__equipements { display: flex; flex-wrap: wrap; gap: 0.3rem 1rem; margin-top: 0.8em; font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.1em; text-transform: uppercase; color: var(--graphite-2); }
.carte__action { margin-top: 0.9em; font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.1em; text-transform: uppercase; }

/* --- Avis : un filet à gauche, rien d'autre ----------------------------- */
.sec__avis {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
  gap: clamp(24px, 3vw, 48px);
  margin-top: clamp(28px, 4vw, 52px);
}
.avis { border-left: 1px solid var(--filet-fort); padding-left: 1.2rem; }
.avis__texte { font-size: var(--t-petit); line-height: 1.6; }
.avis__source { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.1em; font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.1em; text-transform: uppercase; color: var(--graphite-2); }
.avis__auteur { color: var(--graphite); }
.avis__note { color: var(--ardoise); }
.avis__origine, .avis__date { color: var(--graphite-2); }

/* --- Ce que d'autres gabarits du socle posent encore -------------------- */
.sec__points { margin-top: 1.6em; }
.sec__points li { padding-top: 0.7em; margin-top: 0.7em; border-top: 1px solid var(--filet); font-size: var(--t-petit); }
.sec__chiffres { display: flex; flex-wrap: wrap; gap: 2.4rem; margin-top: 2em; }
.sec__medias { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr)); gap: 2px; margin-top: 2.2em; }
.sec__medias img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.sec__rubriques { margin-top: 2em; border-top: 1px solid var(--filet); }
.rubrique { border-bottom: 1px solid var(--filet); }
.rubrique__ligne { cursor: pointer; padding: 1em 0; list-style: none; }
.rubrique__ligne::-webkit-details-marker { display: none; }
.rubrique__nom { display: inline; font-size: var(--t-petit); font-weight: 500; }
.rubrique__detail { padding-bottom: 1.4em; }
.sec--access__adresse { margin-top: 1.2em; font-style: normal; }
.sec--access__reperes { margin-top: 1.6em; }
.sec--access__carte { font-family: var(--mono); font-size: var(--t-mesure); text-transform: uppercase; letter-spacing: 0.1em; }
.galerie__vue, .planche__lien { display: block; text-decoration: none; }

/* ---------- 14. RÉSERVER — bande claire, grille stricte ------------------- */
/* L'atelier pose le formulaire en deux colonnes avec son titre collant à
   gauche ; le comptoir l'enferme dans une colonne centrée sur fond
   sombre. Ici : une bande claire pleine largeur, le titre et son filet
   d'un bord à l'autre, et le formulaire cadré à gauche sur la grille. */

.sec--booking {
  max-width: none;
  background: var(--calcaire-2);
  border-top: 1px solid var(--filet);
}
.sec--booking .sec__entete,
.sec--booking .sec__corps {
  width: calc(min(var(--large), 100%) - 2 * var(--gouttiere));
  margin-inline: auto;
}
.formulaire { display: grid; gap: 0; max-width: 62rem; }
.formulaire[hidden] { display: none; }

.champs { display: grid; gap: clamp(18px, 2vw, 26px); }
@media (min-width: 640px) {
  .champs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .champ { grid-column: 1 / -1; }
  .champ--moitie { grid-column: auto; }
}
@media (min-width: 1080px) {
  .champs { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .champ--moitie { grid-column: span 2; }
}

.champ { display: flex; flex-direction: column; }

.etiquette {
  display: flex; align-items: baseline; gap: 0.6em;
  font-family: var(--mono); font-size: var(--t-mesure);
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--graphite-2);
  margin-bottom: 0.7em;
}
.etiquette__note { text-transform: none; letter-spacing: 0; opacity: 0.8; }

/* Le champ n'est pas une boîte : c'est une ligne. Un seul filet, en bas. */
.controle {
  background: transparent;
  border: 0; border-bottom: 1px solid var(--filet-fort);
  padding: 0.6em 0;
  width: 100%;
  min-height: 44px;                       /* cible tactile confortable */
  transition: border-color var(--survol) var(--ease);
}
.controle:hover { border-bottom-color: var(--graphite-2); }
.controle:focus { border-bottom-color: var(--ardoise); outline: none; }
.controle:focus-visible { outline: 2px solid var(--ardoise); outline-offset: 3px; }
.controle--zone { resize: vertical; min-height: 7em; line-height: 1.55; }
.controle::placeholder { color: var(--graphite-2); opacity: 0.7; }
.controle[aria-invalid="true"] { border-bottom-color: var(--alerte); border-bottom-width: 2px; }

.erreur, .indication {
  display: none;
  margin-top: 0.5em;
  font-family: var(--mono); font-size: var(--t-mesure);
  letter-spacing: 0.06em;
  color: var(--alerte);
}
.erreur--visible, .indication--visible { display: block; }

/* UNE INDICATION N'EST PAS UNE ERREUR : la demande part quand meme, et la
   couleur d'alerte lui ferait dire le contraire. */
.indication { color: var(--graphite-2); }

/* Le groupe de logements : des cases empilees, pas un champ isole.
   Elles reprennent le dessin de la case de consentement — meme .case,
   meme .case__etiquette — et ne corrigent que ce qui n'a de sens que
   pour une case seule : la marge qui l'ecartait du champ precedent, et
   le cadre que le navigateur pose sur tout fieldset. */
.champ--hebergements { border: 0; padding: 0; margin: 0; gap: 0.4em; }
.champ--hebergements > .etiquette { padding-inline: 0; }
.champ--hebergements .champ--case { margin-top: 0; }

.champ--case { flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: 0.75em; margin-top: 1.8em; }
.case {
  appearance: none; -webkit-appearance: none;
  flex: none; width: 1.1em; height: 1.1em; margin-top: 0.3em;
  border: 1px solid var(--filet-fort); background: transparent;
  display: grid; place-content: center; cursor: pointer;
  transition: border-color var(--survol) var(--ease);
}
.case::after { content: ""; width: 0.52em; height: 0.52em; background: var(--ardoise); transform: scale(0); transition: transform var(--survol) var(--ease); }
.case:checked::after { transform: scale(1); }
.case:checked { border-color: var(--ardoise); }
.case[aria-invalid="true"] { border-color: var(--alerte); }
.case__etiquette { flex: 1; min-width: 14ch; cursor: pointer; font-size: var(--t-petit); line-height: 1.5; }
.champ--case .erreur { flex-basis: 100%; }

/* Piège à robots : hors écran, jamais display:none, hors tabulation. */
.appat { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.envoi { margin-top: 2.2em; }
.secours { margin-top: 1.8em; font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.06em; color: var(--graphite-2); }
.secours .lien { text-transform: none; letter-spacing: 0; }

.confirme { border-top: 1px solid var(--graphite); padding-top: clamp(24px, 3vw, 40px); }
.confirme__titre { font-size: var(--t-h3); font-weight: 300; }
.confirme__rappel { display: grid; grid-template-columns: auto 1fr; gap: 0.4em 1.6em; margin-top: 1.4em; font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.08em; }
.confirme__pistes { margin-top: 0.9em; padding-left: 1.1em; list-style: disc; font-size: var(--t-petit); }
.confirme__pistes li { margin-bottom: 0.35em; }
.confirme__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1.2rem; margin-top: 1.8em; }
.confirme__actions .lien { background: none; border: 0; cursor: pointer; font-family: var(--mono); font-size: var(--t-mesure); text-transform: uppercase; letter-spacing: 0.1em; }
.confirme__echec { margin-top: 1em; max-width: 52ch; color: var(--alerte); }

/* ---------- 15. Pages légales --------------------------------------------- */

.sec--legal { max-width: 70ch; }
.sec--legal .sec__titre { font-size: var(--t-h2); }
.sec--legal__mentions { margin-top: 1.6em; border-top: 1px solid var(--filet); }
.sec--legal__mentions dt {
  padding-top: 0.9em; margin-top: 0.9em; border-top: 1px solid var(--filet);
  font-family: var(--mono); font-size: var(--t-mesure);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--graphite-2);
}
.sec--legal__mentions dd { margin: 0.35em 0 0; }
.sec--legal__retour { margin-top: 3em; font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.1em; text-transform: uppercase; }

/* ---------- 16. Pied ------------------------------------------------------ */

.pied {
  border-top: 1px solid var(--filet);
  padding: clamp(40px, 6vh, 80px) var(--gouttiere);
  font-family: var(--mono);
  font-size: var(--t-mesure);
  letter-spacing: 0.08em;
  line-height: 2;
  color: var(--graphite-2);
}
/* ---------------------------------------------------------------------
   LA SIGNATURE DU PIED — le nom, la devise, la presentation.

   Le pied n'etait qu'une grille de paragraphes de meme poids : le nom de
   la maison y pesait autant que l'annee. Il s'ouvre desormais sur une
   signature, puis range le reste en colonnes. Trois champs du modele y
   trouvent enfin un toit : la devise, la description longue et les
   quatre adresses de reseaux sociaux, qu'AUCUN gabarit ne lisait.
   --------------------------------------------------------------------- */

.pied__signature {
  max-width: var(--large);
  margin-inline: auto;
  padding-bottom: clamp(24px, 3vw, 40px);
  margin-bottom: clamp(24px, 3vw, 40px);
  border-bottom: 1px solid var(--filet);
}
.pied__devise {
  margin-top: 0.35em;
  font-family: var(--geo);
  font-size: var(--t-body);
  letter-spacing: 0;
  color: var(--graphite);
}
/* La presentation garde une mesure de lecture : un paragraphe de six
   lignes etale sur 1360 px ne se lit pas. */
.pied__mot {
  max-width: 58ch;
  margin-top: 1.1em;
  font-family: var(--geo);
  font-size: var(--t-petit);
  letter-spacing: 0;
  line-height: 1.7;
}
.pied__mot + .pied__mot { margin-top: 0.9em; }

.pied__adresse, .pied__contacts, .pied__mention { font-style: normal; }

/* Les reseaux sont des MOTS, pas des logos : le socle ne dessine aucune
   marque, et un logo approximatif se remarque plus qu'il ne sert. */
.pied__intitule {
  margin-bottom: 0.4em;
  font-size: var(--t-mesure);
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.pied__reseaux ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3em 1.1em;
}

/* Une photo du socle qui s'agrandit : le curseur dit ce que le clic fait. */
.sec__agrandir { display: block; cursor: zoom-in; text-decoration: none; }
.sec__agrandir img { transition: opacity var(--survol) var(--ease); }
.sec__agrandir:hover img { opacity: 0.88; }

.pied__grille { max-width: var(--large); margin-inline: auto; display: grid; gap: 1.6rem; }
.pied__nom { color: var(--graphite); letter-spacing: 0.2em; text-transform: uppercase; }
.pied a { text-decoration: none; border-bottom: 1px solid var(--filet); }
.pied a:hover { border-bottom-color: var(--ardoise); }
.pied__legal, .pied__annee { font-variant-numeric: tabular-nums; }
@media (min-width: 760px) {
  .pied__grille { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}

/* ---------- 17. Visionneuse ----------------------------------------------- */
/* Construite par assets/js/commun.js. Rien n'est écrit dans le HTML :
   sans script, une vignette est un lien vers la grande image. */

.visionneuse {
  position: fixed; inset: 0;
  border: 0; padding: 0; margin: 0;
  width: 100vw; max-width: none;
  height: 100dvh; max-height: none;
  background: var(--calcaire);
  color: var(--graphite);
  overscroll-behavior: contain;
}
.visionneuse[open] { display: flex; flex-direction: column; }
.visionneuse::backdrop { background: rgb(25 27 29 / 0.92); }
.visionneuse__scene {
  flex: 1; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  padding-block: clamp(14px, 3vmin, 30px);
  padding-inline: clamp(58px, 9vmin, 104px);
}
.visionneuse__scene picture { display: contents; }
.visionneuse__vue { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; -webkit-user-select: none; user-select: none; }
.visionneuse__pied {
  flex: none; text-align: center;
  font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: 0.08em;
  color: var(--graphite-2);
  padding: 0 clamp(58px, 9vmin, 104px) clamp(16px, 3vmin, 28px);
}
.visionneuse__legende { max-width: 68ch; margin-inline: auto; }
.visionneuse__compteur { margin-top: 0.5em; font-variant-numeric: tabular-nums; }
.visionneuse__commande {
  position: absolute;
  width: 44px; height: 44px;
  background: var(--calcaire-2);
  border: 1px solid var(--filet-fort);
  color: var(--graphite);
  display: grid; place-items: center; cursor: pointer;
  transition: border-color var(--survol) var(--ease);
}
.visionneuse__commande:hover { border-color: var(--ardoise); }
.visionneuse__commande[hidden] { display: none; }
.visionneuse__precedente { left: 2vmin; top: 50%; transform: translateY(-50%); }
.visionneuse__suivante   { right: 2vmin; top: 50%; transform: translateY(-50%); }
.visionneuse__fermer     { right: 2vmin; top: 2vmin; }
.visionneuse__chevron { width: 10px; height: 10px; border-left: 1px solid currentColor; border-bottom: 1px solid currentColor; }
.visionneuse__chevron--gauche { transform: rotate(45deg); }
.visionneuse__chevron--droite { transform: rotate(-135deg); }
.visionneuse__croix { position: relative; width: 14px; height: 14px; }
.visionneuse__croix::before, .visionneuse__croix::after {
  content: ""; position: absolute; inset: 50% 0 auto; height: 1px; background: currentColor;
}
.visionneuse__croix::before { transform: rotate(45deg); }
.visionneuse__croix::after  { transform: rotate(-45deg); }
@media (max-width: 699px) {
  .visionneuse__scene { padding-inline: 10px; }
  .visionneuse__pied  { padding-inline: 16px; }
  .visionneuse__precedente { left: 10px; }
  .visionneuse__suivante   { right: 10px; }
}

/* ---------- 18. Apparition au défilement ---------------------------------- */
/* Un seul mouvement : une remontée de quelques pixels. Aucun effet, aucun
   flou, aucune échelle. */

.js .reveal { opacity: 0; transform: translateY(12px); }
.js .reveal--vu {
  opacity: 1; transform: none;
  transition: opacity var(--apparition) var(--ease), transform var(--apparition) var(--ease);
}

/* ---------- 19. Menu sur petit écran -------------------------------------- */

@media (max-width: 899px) {
  .entete__bascule { display: block; }
  .entete__marque, .entete__bascule { position: relative; z-index: 1; }

  /* LE PANNEAU PART DU BAS DE LA BARRE, OÙ QU'ELLE SOIT.

     `var(--h-entete)` suppose la barre en haut de la fenêtre. Dès qu'un
     bandeau d'information la précède, elle descend d'autant, et le
     panneau, lui, ne bougeait pas : ses premières entrées passaient sous
     l'enseigne et sous la bascule. Mesuré à 375 px, bandeau d'une ligne :
     enseigne 90 → 113, première entrée 106 → 158.

     `--entete-decalage` est la distance mesurée entre le haut de la
     fenêtre et le haut de la barre. Le script la pose à l'ouverture du
     menu — le défilement est bloqué pendant ce temps, elle ne bouge
     plus. SANS BANDEAU ELLE VAUT ZÉRO, et le repli aussi : ni le rendu ni
     la feuille sans script ne changent d'un pixel. */
  .menu {
    position: fixed; inset: calc(var(--entete-decalage, 0px) + var(--h-entete)) 0 0;
    background: var(--calcaire);
    border-top: 1px solid var(--filet);
    flex-direction: column; align-items: flex-start; justify-content: flex-start;
    gap: 0;
    padding: clamp(24px, 5vh, 56px) var(--gouttiere);
    /* ET IL DÉFILE S'IL LE FAUT. Le panneau part du bas de la barre :
       un bandeau de deux lignes sur un petit écran lui prend jusqu'à
       cent trente pixels, et la dernière entrée du menu passait sous le
       bord de la fenêtre. Mesuré à 320 px, onze sections allumées :
       « Réserver » se terminait 27 px trop bas. Rien ne défile tant que
       tout tient. */
    overflow-y: auto;
    overscroll-behavior: contain;
    opacity: 0; visibility: hidden;
    transition: opacity var(--survol) var(--ease), visibility 0s linear var(--survol);
  }
  .menu--ouvert { opacity: 1; visibility: visible; transition: opacity var(--survol) var(--ease), visibility 0s; }
  .menu__liste { flex-direction: column; align-items: flex-start; gap: 0; width: 100%; }
  .menu__liste li { width: 100%; }
  .js .menu a {
    display: flex; align-items: center;
    width: 100%; min-height: 52px;
    font-size: 0.8125rem; letter-spacing: 0.14em;
    border-bottom: 1px solid var(--filet);
  }
  .js .menu__action { color: var(--graphite); }

  /* SANS SCRIPT, LE MENU DOIT RESTER ATTEIGNABLE — et ces règles-là ont
     quitté cette feuille pour css/sans-js.css, servie par <noscript>.
     Ici, elles s'appliquaient à la première peinture PUIS disparaissaient
     quand le script différé posait « js » : l'en-tête changeait de
     hauteur et toute la page sautait. La note en tête de sans-js.css
     porte la mesure. */
}

/* ---------- 20. Mouvement réduit ------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }
  .js .reveal, .js .reveal--vu { opacity: 1; transform: none; }
  .vue:hover img { opacity: 1; }
}

/* --- Ce que les gabarits du socle posent en plus ------------------------
   La couverture de la galerie, les series d'un hebergement, les vues
   legendees. Ces classes viennent de core/templates : ce theme ne
   redefinit pas toutes les sections, et celles qu'il laisse au socle
   doivent etre habillees comme les siennes. */

.sec--gallery__couverture {
  margin: 0 0 clamp(24px, 3vw, 40px);
}
.sec--gallery__couverture img {
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
  background: var(--calcaire-2);
}
.sec--gallery__couverture figcaption {
  margin-top: .5rem;
  font-size: var(--t-petit);
  color: var(--graphite-2);
}

.carte__photo { margin: 0 0 .8rem; }
.carte__photo img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.carte__photo figcaption,
.carte__vues figcaption {
  margin-top: .35rem;
  font-size: var(--t-petit);
  color: var(--graphite-2);
}
.carte__intitule,
.carte__categorie {
  margin: 1rem 0 .4rem;
  font-family: var(--mono);
  font-size: var(--t-mesure);
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--graphite-2);
}
.carte__vues {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: .4rem;
}
.carte__vues img { width: 4rem; height: 3rem; object-fit: cover; }
.carte__vues figcaption { max-width: 4rem; }

/* =========================================================================
   LE BANDEAU D'INFORMATION — une ligne de releve

   Ce theme numerote et met en monospace tout ce qui se compte. Le bandeau
   suit la meme regle : un intitule court a gauche, le message a droite,
   un filet dessous, et la meme grille que le reste du site. Ce n'est ni
   un ruban ni une mention de marge : c'est une ligne de fiche technique.

   IL NE SE REFERME PAS : aucune croix, aucune hauteur animee, donc aucun
   decalage de mise en page au chargement.
   ========================================================================= */

.releve-haut {
  background: var(--calcaire-2);
  border-bottom: 1px solid var(--filet);
}
.releve-haut__ligne {
  max-width: var(--large);
  margin-inline: auto;
  padding: .8rem var(--gouttiere);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3rem clamp(16px, 2vw, 40px);
}
.releve-haut__cle { margin: 0; flex: none; color: var(--graphite-2); }
.releve-haut__mot {
  margin: 0;
  font-size: var(--t-petit);
  line-height: 1.45;
  color: var(--graphite);
}
.releve-haut__lien {
  color: var(--ardoise);
  text-decoration: underline;
  text-underline-offset: .3em;
  white-space: nowrap;
}
.releve-haut__lien:hover { color: var(--graphite); }

/* =========================================================================
   LES OFFRES DU MOMENT — des rangees alternees pleine largeur

   Les hebergements de ce theme sont des rangees dont la photo occupe
   55 %, alternees gauche-droite. Une offre suit la meme grille stricte.

   TOUT CE QUI SE COMPTE PASSE EN MONOSPACE : le rang, le prix, ce que
   l'offre comprend, sa validite. Ils sont ranges en TABLE DE RELEVE, au
   meme titre que les informations pratiques — dans un dossier
   d'architecte, une echeance est une donnee, pas une mention en bas de
   bloc.

   IL N'Y A PAS DE CAS « UNE SEULE » : la rangee est deja pleine largeur,
   elle n'a rien a compenser. C'est la vertu de ce gabarit.
   ========================================================================= */

.rangee-offre {
  display: grid;
  gap: clamp(20px, 3vw, 44px);
  align-items: center;
  padding-block: clamp(28px, 4vh, 56px);
  border-top: 1px solid var(--filet);
}
.rangee-offre__photo { margin: 0; }
.rangee-offre__photo img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.rangee-offre__legende {
  margin-top: .5rem;
  font-size: var(--t-petit);
  color: var(--graphite-2);
}
.rangee-offre__rang { margin: 0 0 .5rem; color: var(--graphite-2); }
.rangee-offre__nom {
  margin: 0;
  font-family: var(--geo);
  font-weight: 300;
  font-size: var(--t-h3);
  line-height: 1.15;
}
.rangee-offre__accroche {
  margin: .5em 0 0;
  font-size: var(--t-lead);
  color: var(--graphite-2);
}
.rangee-offre__mots > .corps { margin-top: 1em; max-width: 54ch; }

.rangee-offre__releve {
  margin: 1.4em 0 0;
  display: grid;
  gap: 0;
  border-top: 1px solid var(--filet);
}
.rangee-offre__releve > div {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr);
  gap: 0 clamp(12px, 2vw, 28px);
  padding-block: .6rem;
  border-bottom: 1px solid var(--filet);
}
.rangee-offre__releve dt { margin: 0; color: var(--graphite-2); padding-top: .15em; }
.rangee-offre__releve dd { margin: 0; }
.rangee-offre__action { margin: 1.6em 0 0; }

@media (min-width: 56rem) {
  .rangee-offre { grid-template-columns: minmax(0, 55fr) minmax(0, 45fr); column-gap: clamp(32px, 4vw, 72px); }
  /* Une rangee sur deux inverse ses colonnes : l'oeil ne descend pas une
     colonne d'images, il traverse la page. */
  .rangee-offre--miroir .rangee-offre__photo { order: 2; }
  .rangee-offre--miroir .rangee-offre__mots  { order: 1; }
}

/* =========================================================================
   LA POLICE DU BANDEAU — « optional », et c'est tout le sujet

   MESURÉ, PAS SUPPOSÉ. Le bandeau d'information est le PREMIER bloc de la
   page : s'il change de hauteur au chargement, toute la page descend, et
   c'est le décalage le plus cher qui soit. Or il en changeait — 71 px
   puis 90 px a 768 px sur ce theme, une ligne de plus — parce que le
   texte se replie autrement selon que la police de repli ou la police du
   site est en place. Les surcharges metriques (size-adjust,
   ascent-override) egalisent la HAUTEUR d'une ligne ; elles n'egalisent
   pas la largeur de chaque glyphe, donc pas le point de coupure.

   `font-display: optional` supprime la cause au lieu d'absorber l'effet :
   si la police n'est pas deja la au premier rendu, le navigateur ne
   l'echange PLUS de la page — il garde le repli jusqu'au bout. Aucun
   remplacement, donc aucun repli de texte, donc aucun decalage. A la
   visite suivante elle est en cache et sert des le premier pixel.

   Ce que ca coute : un tout premier visiteur peut lire ces quelques mots
   dans la police de repli. Pour une ligne de service de 140 signes, c'est
   exactement l'echange que `optional` existe pour faire.

   Le fichier est le MEME que celui de la police du site : meme adresse,
   meme entree de cache, aucun telechargement de plus.
   ========================================================================= */
@font-face {
  font-family: 'Jost bandeau';
  font-style: normal; font-weight: 400;
  font-display: optional;
  src: url('../../../assets/fonts/jost-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Plex bandeau';
  font-style: normal; font-weight: 400;
  font-display: optional;
  src: url('../../../assets/fonts/plexmono-400.woff2') format('woff2');
}
.releve-haut__mot,
.releve-haut__lien { font-family: 'Jost bandeau', 'Jost repli', 'Century Gothic', Avenir, sans-serif; }
.releve-haut__cle  { font-family: 'Plex bandeau', ui-monospace, 'SFMono-Regular', Menlo, monospace; }


/* =========================================================================
   LES PRESTATIONS — ce qui se paie en plus de la nuit.

   Quatre niveaux, et l'ordre est le meme sur les cinq themes : a qui elle
   s'adresse, ce que c'est, ce qu'elle coute, ce qu'elle contient. Les deux
   releves — usages, equipements — sont la raison d'etre de ce bloc : un
   espace de seminaire arrive avec quatorze equipements, et quatorze
   mentions a la file dans un paragraphe ne se lisent pas. En colonnes
   intitulees, elles se parcourent d'un regard.

   Le gabarit est celui du socle, unique. Ce sont les feuilles qui donnent
   a chaque theme sa voix — c'est moins cher que cinq gabarits, et cela
   garantit que les quatre niveaux restent dans le meme ordre partout.
   ========================================================================= */

.prestations { display: grid; }
.prestation {
  display: grid;
  gap: clamp(20px, 3vw, 44px);
  align-items: start;
  padding-block: clamp(28px, 4vh, 56px);
  border-top: 1px solid var(--filet);
}
.prestation__photo { margin: 0; }
.prestation__photo img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.prestation__photo figcaption {
  margin-top: .5rem;
  font-size: var(--t-petit);
  color: var(--graphite-2);
}
.prestation__mots { min-width: 0; }
.prestation__pour {
  margin: 0 0 .5rem;
  font-family: var(--mono);
  font-size: var(--t-mesure);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--graphite-2);
}
.prestation__nom {
  margin: 0;
  font-family: var(--geo);
  font-weight: 300;
  font-size: var(--t-h3);
  line-height: 1.15;
}
.prestation__prix {
  margin: .8em 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .2rem .8rem;
  font-family: var(--mono);
  font-size: var(--t-mesure);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.prestation__montant { color: var(--ardoise); }
.prestation__mention { color: var(--graphite-2); }
.prestation__texte { margin-top: 1em; max-width: 54ch; color: var(--graphite-2); }

/* Le releve suit la table de releve des offres de ce theme : intitule a
   gauche en petite chasse, valeurs a droite, un filet par ligne. */
.prestation__releve { margin-top: 1.4em; display: grid; border-top: 1px solid var(--filet); }
.prestation__groupe {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr);
  gap: 0 clamp(12px, 2vw, 28px);
  padding-block: .8rem;
  border-bottom: 1px solid var(--filet);
}
.prestation__intitule {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--t-mesure);
  font-weight: 400;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--graphite-2);
}
.prestation__suite {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .3rem 1rem;
  font-size: var(--t-petit);
}
.prestation__suite li { position: relative; }
.prestation__suite li + li { padding-left: 1rem; }
.prestation__suite li + li::before {
  content: "";
  position: absolute;
  left: 0; top: .3em; bottom: .3em;
  border-left: 1px solid var(--filet);
}

@media (min-width: 820px) {
  .prestation { grid-template-columns: minmax(0, 45fr) minmax(0, 55fr); }
  .prestation:nth-child(even) > .prestation__photo { order: 2; }
}

.prestation__vues { margin-top: 1.4em; }
.prestation__compte {
  display: inline-block;
  margin-left: .4em;
  font-variant-numeric: tabular-nums;
}
.prestation__serie {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
  gap: .5rem;
}
.prestation__serie figure { margin: 0; }
.prestation__serie img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.prestation__serie figcaption {
  margin-top: .25rem;
  font-size: var(--t-petit);
}
.prestation__compte { color: var(--graphite-2); font-family: var(--mono); }
.prestation__serie figcaption { color: var(--graphite-2); }
.prestation__categorie { margin: .9rem 0 .4rem; font-family: var(--mono); font-size: var(--t-mesure); letter-spacing: .1em; text-transform: uppercase; color: var(--graphite-2); }
