/* Fichier ASSEMBLÉ — ne pas modifier à la main.
 * Source : assets/css/parts/*.css, recollés par tools/build-css.php.
 * 15 morceaux, 2026-10-06 16:04 UTC.
 */

/* ═══ appel.css ═══ */
/* modulo-appel — la bande d'appel, charnière entre deux sections.
 *
 * Elle n'est pas une section pleine : un padding vertical réduit et un titre plus
 * petit la posent entre deux sections sans jamais leur voler la vedette.
 *
 * Ce morceau ne style que `.mdl-appel` et ses descendants — voir tools/build-css.php.
 * 1 rem = 10 px : Bricks pose html{font-size:62.5%}.
 */

/* Le padding réduit. `section:where(.mdl){padding-block:var(--mdl-sp)}` de modulo.css
 * pèse (0,0,1) — `:where()` ne compte pour rien. On lui répond à la même spécificité,
 * et c'est l'ordre de chargement qui tranche : functions.php met modulo-pages.css en
 * file derrière modulo.css. Ni classe de plus, ni !important. */
section:where(.mdl-appel) { padding-block: clamp(5rem, 6vw, 8rem); }

/* Texte à gauche, boutons à droite, sur une seule ligne optique. La colonne des
 * boutons est en `auto` : elle prend sa largeur et laisse tout le reste au texte. */
.mdl-appel .mdl-wrap {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: clamp(2.4rem, 3vw, 6.4rem);
	align-items: center;
}

/* Plus petit que le <h2> d'une vraie section (clamp(3.4rem,3.8vw,5.6rem) dans
 * modulo.css) : la charnière annonce, elle n'ouvre pas un chapitre. */
.mdl-appel h2 {
	font-size: clamp(2.4rem, 2.6vw, 3.4rem);
	max-width: 24ch;
}

/* La marge est portée par la paire, pas par la phrase : une bande passée sans titre
 * — une page assemblée par script peut le vider — reste centrée sur ses boutons. */
.mdl-appel .mdl-lead { max-width: 52ch; }
.mdl-appel h2 + .mdl-lead { margin-top: 1.2rem; }

.mdl-appel .mdl-appel-ctas {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: 1.2rem;
}

/* Les points de rupture restent en pixels, comme ceux de modulo.css : dans une media
 * query, `rem` se mesure sur la taille initiale du navigateur (16 px) et non sur le
 * html{font-size:62.5%} de Bricks. En dessous de 760 px, la bande s'empile et les
 * boutons prennent toute la largeur — l'un sous l'autre, jamais deux moitiés. */
@media (max-width: 760px) {
	.mdl-appel .mdl-wrap { grid-template-columns: minmax(0, 1fr); }

	.mdl-appel .mdl-appel-ctas { justify-content: flex-start; }

	/* `.mdl-btn` est en inline-flex sans justification : étiré, son libellé resterait
	 * collé à gauche du bouton. */
	.mdl-appel .mdl-appel-ctas .mdl-btn {
		flex: 1 1 100%;
		justify-content: center;
	}
}

/* ═══ avis.css ═══ */
/* .mdl-avis — la note Google, sous les boutons du hero.
 *
 * Une rangée d'étoiles et une ligne de texte, pas une pastille : ce qui rassure ici
 * n'a pas à se faire remarquer plus que le bouton juste au-dessus. Elle prend sa
 * place dans la grille de `.mdl-side` (gap 2,4 rem), sans marge propre.
 *
 * Ce morceau ne style que `.mdl-avis` et ses descendants — voir tools/build-css.php.
 * 1 rem = 10 px : Bricks pose html{font-size:62.5%}.
 */

.mdl-avis {
	display: flex;
	align-items: center;
	gap: 1.2rem;
	flex-wrap: wrap;
	font-size: 1.5rem;
	line-height: 1.3;
}

/* Le socle des deux rangées d'étoiles. `line-height:0` supprime l'espace que la
 * ligne de base réserve sous un SVG en ligne — sans lui, la rangée flotte trois
 * pixels au-dessus du texte. */
.mdl-avis-etoiles {
	position: relative;
	display: inline-block;
	line-height: 0;
	flex: none;
}

/* La rangée pleine est posée par-dessus la rangée grise et découpée à la largeur
 * que dit la note (calculée dans modulo-hero.php). `overflow:hidden` coupe la
 * cinquième étoile en cours de route : c'est ce qui rend 4,9 lisible comme 4,9 et
 * non comme 5. */
.mdl-avis-plein {
	position: absolute;
	inset: 0;
	overflow: hidden;
	display: block;
	line-height: 0;
}

.mdl-avis-etoiles svg { display: block; }

/* Le gris est celui des filets, pas un gris neutre : la rangée vide doit se lire
 * comme le fond du cadran, jamais comme une étoile éteinte. */
.mdl-avis-vide { fill: var(--mdl-tint-2); }
.mdl-avis-plein svg { fill: var(--mdl-amber); }

/* Le texte est un lien : une note affichée sans moyen de la vérifier ne vaut rien.
 * Souligné seulement au survol — souligné en permanence, il tirerait l'œil au
 * détriment du bouton ambre à trois centimètres de là. */
.mdl-avis-txt {
	color: var(--mdl-ink);
	text-decoration: none;
	display: inline-flex;
	align-items: baseline;
	gap: .6rem;
}

.mdl-avis-txt strong {
	font-weight: 600;
	font-size: 1.7rem;
	letter-spacing: -.01em;
}

.mdl-avis-detail { color: var(--mdl-ink-2); }

.mdl-avis-txt:hover .mdl-avis-detail {
	color: var(--mdl-blue-deep);
	text-decoration: underline;
	text-underline-offset: .25em;
	text-decoration-thickness: 1.5px;
}

/* Sur un fond foncé — le hero ne l'est pas aujourd'hui, mais la section peut être
 * teintée un jour —, le texte suit la couleur héritée plutôt que l'encre fixe. */
.mdl-dark .mdl-avis-txt { color: inherit; }

@media (max-width: 640px) {
	.mdl-avis { font-size: 1.4rem; }
	.mdl-avis-txt strong { font-size: 1.6rem; }
}

/* ── barre du bas : « Gérer le consentement » ─────────────────────────────────
 * Ce n'est pas une ancre mais un <button> — Complianz n'écoute que les boutons
 * (voir modulo-footer.php, CONSENTEMENT_SENTINELLE). Il doit néanmoins se lire
 * comme ses voisins : `.mdl-foot-bottom a` (modulo.css) leur donne la couleur et
 * retire le soulignement ; on répète la règle pour le bouton, dont la remise à
 * zéro de `:where(.mdl) button` ne couvre ni la couleur ni la taille.
 */
.mdl-foot-bottom button.cmplz-manage-consent {
	color: #9DB0BD;
	font: inherit;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	text-decoration: none;
}

.mdl-foot-bottom button.cmplz-manage-consent:hover { color: #F3F7FA; }

/* ── simulateur : l'écran de consentement ─────────────────────────────────────
 * Le pendant de `.mdl-sim-attente` (modulo.css) pour l'état « consentement » :
 * le service tiers n'a pas encore été accepté. Même place, même centrage — c'est
 * `data-etat` sur le cadre qui décide lequel des deux paraît.
 */
.mdl-sim-consent { display: none; }

.mdl-sim-stage[data-etat="consentement"] { padding: 3.2rem; background: var(--mdl-tint); }
.mdl-sim-stage[data-etat="consentement"] > .spacestacker,
.mdl-sim-stage[data-etat="consentement"] .mdl-sim-attente { display: none; }

.mdl-sim-stage[data-etat="consentement"] .mdl-sim-consent {
	display: grid;
	justify-items: center;
	gap: 2rem;
	max-width: 48ch;
	text-align: center;
}

.mdl-sim-consent p { margin: 0; color: var(--mdl-ink-2); }

/* ═══ banniere.css ═══ */
/* ─── modulo-banniere — le bandeau qui ouvre les onze pages intérieures ───────────
 *
 * Tout est accroché à `.mdl-banniere` : ce morceau ne touche à rien d'autre.
 *
 * Les primitives partagées (.mdl-wrap, .mdl-lead, .mdl-btn, .mdl-anchor) et surtout la
 * règle `:where(.mdl) h1` de modulo.css — graisse 600, letter-spacing -.035em,
 * line-height 1.02, text-wrap:balance — ne sont PAS redites ici. C'est justement ce
 * silence qui garantit que le <h1> du bandeau et celui du hero de l'accueil sont
 * rigoureusement accordés : ils héritent de la même règle, une seule taille les sépare.
 *
 * 1 rem = 10 px (Bricks pose html{font-size:62.5%}). Les filets s'écrivent donc .15rem
 * et non 1.5px, et aucune couleur ne sort des variables --mdl-*.
 */

.mdl-banniere{
  /* Le haut est réduit : l'en-tête collant (8rem de haut) est immédiatement au-dessus,
     et `section:where(.mdl){padding-block:var(--mdl-sp)}` y creuserait un trou. Le bas
     garde --mdl-sp, la respiration commune à toutes les sections. Les deux valeurs
     tiennent dans une seule déclaration plutôt que d'écraser la moitié d'un raccourci
     logique par une propriété physique. */
  padding-block:clamp(4rem,6vw,8rem) var(--mdl-sp);
}

/* Texte à gauche, photo à droite. `minmax(0,…)` sur les deux pistes : sans lui, un mot
   long du <h1> à 7.2rem impose sa largeur minimale et fait déborder la grille. */
.mdl-banniere .mdl-wrap{
  display:grid;
  grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:clamp(3.2rem,4vw,6.4rem);
  align-items:center;
}

/* Le surtitre : petites capitales bleues, un point ambre en tête, et un filet qui court
   sous lui. `width:fit-content` cale ce filet exactement sur la largeur du texte — il
   forme un crochet posé au-dessus des premiers caractères du titre plutôt qu'une ligne
   qui traverse la colonne. C'est là tout le rattachement au <h1> : rien d'ajouté, la
   marge basse fait le reste. */
.mdl-banniere .mdl-kick{
  display:flex;
  align-items:center;
  gap:1.04rem;
  width:fit-content;
  max-width:100%;
  margin-bottom:clamp(2rem,1.8vw,2.8rem);
  padding-bottom:1.44rem;
  border-bottom:.15rem solid var(--mdl-blue-pale);
  color:var(--mdl-blue-deep);
  font-size:1.36rem;
  font-weight:600;
  line-height:1.2;
  letter-spacing:.14em;
  text-transform:uppercase;
}

.mdl-banniere .mdl-kick::before{
  content:"";
  flex:none;
  width:.72rem;
  height:.72rem;
  border-radius:50%;
  background:var(--mdl-amber);
}

/* La seule chose que le bandeau ajoute au <h1> de la maison : sa taille. */
.mdl-banniere h1{
  font-size:clamp(3.6rem,5.4vw,7.2rem);
}

/* L'accroche reste plus étroite que le titre : le titre remplit sa colonne, l'accroche
   se lit d'un trait. Écrase le `max-width:62ch` que modulo.css pose sur tous les <p>. */
.mdl-banniere .mdl-lead{
  margin-top:clamp(2rem,2vw,2.8rem);
  max-width:44ch;
}

.mdl-banniere .mdl-ctas{
  display:flex;
  flex-wrap:wrap;
  gap:1.2rem;
  margin-top:clamp(2.8rem,3vw,4rem);
}

.mdl-banniere .mdl-shot{
  width:100%;
  aspect-ratio:4/3;
  border-radius:var(--mdl-r);
  /* Le fond retient la place le temps du chargement : sans lui, la grille sursaute. */
  background:var(--mdl-tint);
  /* Le débordement est coupé ici : la parallaxe agrandit l'image et la fait glisser
     à l'intérieur de ce cadre, qui, lui, garde sa place dans la grille. */
  overflow:hidden;
}

.mdl-banniere .mdl-shot-img{
  width:100%;
  /* `height:100%` n'est pas décoratif. wp_get_attachment_image() écrit les attributs
     width et height du fichier, que le navigateur traduit en indications de présentation
     — donc en vraies déclarations CSS. Sans hauteur explicite, l'image reprend les
     proportions du fichier au lieu de remplir le cadre 4/3. */
  height:100%;
  object-fit:cover;
  display:block;
}

/* ─── sans photo — la F.A.Q., la politique de confidentialité ──────────────────────
 * Une mise en page à part entière, pas un repli dégradé : une seule colonne, et deux
 * mesures de lecture tenues, sinon le titre courrait sur les 144rem du contenu.
 * Le modificateur est toujours qualifié par `.mdl-banniere` : il ne peut pas fuir sur
 * la racine d'un autre élément. */
.mdl-banniere.mdl-banniere-solo .mdl-wrap{
  grid-template-columns:minmax(0,1fr);
}

/* RONDE 7 — le bas du bandeau sans photo est raccourci.
 *
 * `--mdl-sp` en bas réserve la respiration d'un bandeau à deux colonnes, où la photo
 * descend bien plus bas que le texte et où cet espace est celui qui suit l'IMAGE. Sans
 * photo il n'y a que trois lignes de texte au-dessus, et les 13,6 rem s'ajoutent aux
 * 13,6 rem que la section suivante pose en haut : 258 px de blanc sous « Foire aux
 * questions », que le client a lus comme un trou. Le bandeau garde une respiration,
 * c'est la section d'après qui porte désormais l'essentiel de l'intervalle.
 *
 * Vaut aussi pour « Contactez-nous », « Guide des tailles » et la politique de
 * confidentialité — tous les bandeaux sans photo, qui creusaient le même trou. */
.mdl-banniere.mdl-banniere-solo{
  padding-bottom:clamp(2.4rem,3vw,4.8rem);
}

.mdl-banniere.mdl-banniere-solo h1{
  max-width:18ch;
}

.mdl-banniere.mdl-banniere-solo .mdl-lead{
  max-width:48ch;
}

/* ─── avec formulaire — « Tarifs et réservation » (ronde 10, épingle 36) ───────────
 * La grille reste celle du bandeau à photo, 7/5 — une colonne de titre plus étroite
 * coupait le <h1> en « de mini- / entrepôt ». Le formulaire prend la place du cadre 4/3,
 * dans une carte teintée qui garde le poids visuel de la photo. Les champs, eux, sont
 * ceux de modulo.css (`.mdl-form`) — fond papier, donc lisibles sur la teinte.
 *
 * Le resserrement vertical a un but précis : que le bouton d'envoi tienne au-dessus de
 * la ligne de flottaison sur un portable (1440 × 876), ce que la cliente a demandé. */
.mdl-banniere .mdl-banniere-carte{
  padding:clamp(2.4rem,2.6vw,4rem);
  border-radius:var(--mdl-r);
  background:var(--mdl-tint);
}

.mdl-banniere .mdl-banniere-carte h2{
  margin-bottom:clamp(1.6rem,1.6vw,2.4rem);
  font-size:clamp(2.4rem,2vw,3rem);
  line-height:1.15;
}

.mdl-banniere .mdl-banniere-carte .mdl-form p{
  margin-bottom:1.4rem;
}

.mdl-banniere .mdl-banniere-carte .mdl-form textarea{
  height:8.8rem;
  min-height:8.8rem;
}

/* Sous 900 px, la photo passe sous le texte. Elle est déjà seconde dans le flux : il
   suffit de replier la grille sur une colonne, l'ordre du document fait le reste. */
@media (max-width:900px){
  .mdl-banniere .mdl-wrap{
    grid-template-columns:minmax(0,1fr);
  }
}

/* ═══ barre.css ═══ */
/* Barre promo de l'en-tête — `.mdl-bar`
 *
 * Balisage : elements/modulo-barre.php. Comportement : assets/js/modulo.js, initBarre().
 *
 * Un ruban ambre au-dessus de l'en-tête, où les annonces défilent sans fin de droite à
 * gauche. Il est posé dans le gabarit « En-tête », AVANT l'élément En-tête lui-même.
 *
 * Le défilé, en deux mots : `.mdl-bar-piste` contient un nombre PAIR de suites
 * identiques et se déplace de -50 %, c'est-à-dire exactement d'une demi-piste. À la fin
 * du tour, la seconde moitié occupe la place qu'occupait la première : l'image est la
 * même, la boucle ne se voit pas. C'est cette parité que tient initBarre() en clonant la
 * suite d'origine, et elle vaut aussi sans JavaScript — le PHP en écrit deux.
 *
 * Le collant, ensuite. modulo.css pose `#brx-header:has(.mdl-top){position:sticky;top:0}` :
 * l'enveloppe entière de Bricks colle, barre comprise. On la remonte donc d'une hauteur de
 * barre quand la barre est là — l'annonce s'en va avec le haut de la page, la barre de
 * navigation, elle, s'arrête net contre le bord. La promotion n'est pas perdue pour
 * autant : c'est à ce moment que la pastille du coin paraît (elements/modulo-promo.php).
 *
 * Chargé après modulo.css (functions.php met `modulo-pages` en file derrière `modulo`),
 * d'où la règle `#brx-header` qui l'emporte à spécificité égale.
 */

:root{
  /* La hauteur est une variable parce que trois règles en dépendent : la barre, le
     décalage du collant, et la réserve de hauteur du héros. */
  --mdl-bar-h:4.4rem;
  /* Repli si le script ne tourne pas : un tour en 40 s. initBarre() remplace cette
     valeur sur la piste, calculée d'après la largeur réelle et la vitesse demandée. */
  --mdl-bar-duree:40s;
}

.mdl-bar{
  height:var(--mdl-bar-h);
  background:var(--mdl-amber);
  color:var(--mdl-amber-ink);
  display:flex;
  align-items:center;
  overflow:hidden;
}

.mdl-bar-piste{
  display:flex;
  width:max-content;
  animation:mdl-bar-defile var(--mdl-bar-duree) linear infinite;
  will-change:transform;
}

/* On s'arrête sous le curseur : une ligne qui bouge ne se lit pas deux fois. Le
   `focus-within` fait la même chose au clavier, si un jour un message porte un lien. */
.mdl-bar:hover .mdl-bar-piste,
.mdl-bar:focus-within .mdl-bar-piste{animation-play-state:paused}

.mdl-bar-suite{display:flex;flex:none;align-items:center}

.mdl-bar-msg{
  display:flex;
  align-items:center;
  padding-left:1.2rem;
  font-size:1.3rem;
  font-weight:600;
  letter-spacing:.08em;
  text-transform:uppercase;
  white-space:nowrap;
}

/* Le point de séparation. En `::after` plutôt qu'entre deux messages : il suit chaque
   message, y compris le dernier, et la jonction entre deux suites est ponctuée comme le
   reste — sans quoi la boucle se trahirait à cet endroit précis. */
.mdl-bar-msg::after{
  content:"";
  flex:none;
  width:.4rem;
  height:.4rem;
  margin-left:1.2rem;
  border-radius:50%;
  background:rgba(27,19,0,.4);
}

@keyframes mdl-bar-defile{
  from{transform:translateX(0)}
  to{transform:translateX(-50%)}
}

/* L'en-tête collant remonte de la hauteur de la barre : l'annonce défile hors de l'écran,
   la barre de navigation s'arrête à 0. Sans `:has()`, un en-tête sans barre garderait ce
   décalage et perdrait ses premiers pixels. */
#brx-header:has(.mdl-bar){top:calc(-1 * var(--mdl-bar-h))}

/* Le héros vise « un écran plein » : `min-height:calc(100svh - 8rem)` dans modulo.css,
   8 rem étant la hauteur de l'en-tête. La barre s'ajoute au-dessus, il faut la déduire
   aussi, sinon le bas du héros passe sous la ligne de flottaison. */
body:has(.mdl-bar) .mdl-hero{min-height:calc(100svh - 8rem - var(--mdl-bar-h))}

@media (max-width:768px){
  :root{--mdl-bar-h:4rem}
  .mdl-bar-msg{font-size:1.2rem;padding-left:1rem}
  .mdl-bar-msg::after{margin-left:1rem}
}

/* Sans cette règle, la barre s'emballe au lieu de s'arrêter : modulo.css ramène
   `animation-duration` à .01 ms sur tout descendant de `.mdl` — ce qui suffit à figer une
   animation qui ne joue qu'une fois, mais fait tourner une boucle infinie cent fois par
   seconde. Il faut donc couper l'animation elle-même, et en `!important` pour passer
   devant la règle globale, qui l'est aussi. */
@media (prefers-reduced-motion:reduce){
  .mdl-bar-piste{animation:none!important;transform:none!important}
}

/* ═══ capsule.css ═══ */
/* capsule — le bouton de lecture et la fenêtre vidéo.
 *
 * Une primitive, pas une section : le HTML vient de `capsule_html()` dans
 * elements/base.php et n'importe quel bloc peut l'appeler. C'est pourquoi ce morceau
 * ne mentionne jamais `.mdl-duo` — la seule chose qu'il suppose de son hôte est un
 * ancêtre `.mdl`, dont il hérite la typographie et la remise à zéro.
 *
 * ── Implantation ──────────────────────────────────────────────────────────────
 * La `<dialog>` est écrite hors du `.mdl-wrap`, en dernier enfant de la <section>.
 * Deux raisons, dans cet ordre :
 *
 *   · elle n'est pas une case de la grille à deux colonnes du bloc image-et-texte,
 *     et une case fantôme y déplacerait la photo ;
 *   · `showModal()` la promeut dans la COUCHE DU DESSUS, qui échappe aux contextes
 *     d'empilement de ses ancêtres. C'est ce qui règle, sans une ligne de style, le
 *     piège relevé à la ronde 5 : GSAP laisse un `transform` sur chaque bloc révélé,
 *     donc un panneau ordinaire ne peut pas en sortir, quel que soit son `z-index`
 *     (voir .mdl-fsel-p.mdl-ouvert dans modulo.css, qui doit s'en défendre). Il n'y a donc
 *     AUCUN `z-index` ici, et il ne faut pas en ajouter : ce serait le signe qu'on a
 *     cessé d'ouvrir la fenêtre avec `showModal()`.
 *
 * 1 rem = 10 px — Bricks pose html{font-size:62.5%}. Aucune valeur en px.
 */

/* --------------------------------------------------------------- le bouton */

/* Un bouton au trait, du même dessin que `.mdl-btn-line` (modulo.css), mais qui ne
   le réutilise pas : il porte une icône, donc son rembourrage de gauche est plus
   court, et son ombre intérieure change au survol de la seule couleur du triangle.
   Le recopier ici tient en cinq déclarations ; l'habiller de deux classes obligerait
   `capsule_html()` à connaître le vocabulaire de la feuille. */
.mdl-caps-btn{
  display:inline-flex;
  align-items:center;
  gap:1.2rem;
  padding:1.6rem 2.56rem 1.6rem 1.92rem;
  border-radius:0.96rem;
  box-shadow:inset 0 0 0 1.5px var(--mdl-tint-2);
  color:var(--mdl-ink);
  font-weight:600;
  line-height:1;
  text-decoration:none;
  transition:box-shadow .2s,transform .2s var(--mdl-ease);
}
.mdl-caps-btn:hover{box-shadow:inset 0 0 0 1.5px var(--mdl-blue)}
.mdl-caps-btn:active{transform:translateY(1px)}

/* 2,4 rem, soit 24 px : une unité de la grille du dessin vaut exactement un pixel,
   comme la coche des points. `flex:none` — sans lui, une boîte flexible étroite
   écraserait l'icône avant de couper le libellé. */
.mdl-caps-btn svg{flex:none;width:2.4rem;height:2.4rem;color:var(--mdl-blue)}

/* Le paragraphe d'action peut désormais tenir DEUX appels — un lien et le bouton de
   capsule. Il ne l'a jamais fait avant cette ronde, d'où cette règle plutôt qu'une
   correction dans duo.css : c'est la capsule qui crée le cas.

   `:has()` limite la mise en ligne au seul cas à deux : un paragraphe qui ne porte
   qu'un lien souligné reste un paragraphe, avec sa ligne de base et son interligne,
   et non un conteneur flexible qui les redéfinirait. */
:where(.mdl) p:has(> .mdl-caps-btn){display:flex;flex-wrap:wrap;align-items:center;gap:1.6rem}

/* --------------------------------------------------------------- la fenêtre */

/* Une <dialog> est `display:none` tant qu'elle n'est pas ouverte : il n'y a rien à
   cacher à la main, et rien ne charge tant qu'on ne l'ouvre pas.

   `margin:auto` n'est pas décoratif. La feuille du navigateur centre la fenêtre
   modale ainsi, mais la remise à zéro de la maison — `:where(.mdl),:where(.mdl) *
   {margin:0}` dans modulo.css — l'écrase, et la fenêtre partirait se coller en haut
   à gauche. On la repose donc explicitement. */
.mdl-caps{
  margin:auto;
  width:min(108rem,100% - 4rem);
  max-width:none;
  padding:0;
  border:0;
  background:none;
  color:#F3F7FA;
  overflow:visible;
}

/* Le voile. Assez sombre pour que la page cesse d'exister derrière : la vidéo est
   filmée en intérieur et une lumière de fond en tirerait le contraste vers le bas. */
.mdl-caps::backdrop{background:rgba(6,15,21,.86)}

.mdl-caps-boite{
  position:relative;
  border-radius:var(--mdl-r);
  /* Le seul endroit du morceau où le découpage compte : c'est lui qui arrondit les
     coins de la vidéo, qu'aucun `border-radius` posé sur <video> ne suivrait sur
     tous les navigateurs. */
  overflow:hidden;
  background:#0A1720;
  box-shadow:0 2.4rem 6.4rem rgba(0,0,0,.5);
}

/* 16/9 déclaré ici et pas laissé à la vidéo : tant que le fichier n'est pas chargé
   — c'est-à-dire jusqu'au clic — le lecteur n'a aucune dimension intrinsèque, et la
   fenêtre s'ouvrirait sur une bande de quelques pixels avant de sauter à sa taille.
   L'affiche, elle, est déjà là et remplit le cadre. */
.mdl-caps-video{width:100%;height:auto;aspect-ratio:16/9;background:#0A1720}

/* Le titre et le bouton de fermeture flottent SUR la vidéo, dans un dégradé qui les
   décolle de l'image sans lui prendre de hauteur. Une barre pleine au-dessus du
   lecteur aurait coûté 6 rem sur un écran de portable tenu à l'horizontale, là où
   la place manque déjà. */
.mdl-caps-boite::before{
  content:"";
  position:absolute;
  inset:0 0 auto;
  height:9.6rem;
  background:linear-gradient(rgba(6,15,21,.72),rgba(6,15,21,0));
  pointer-events:none;
}

.mdl-caps-titre{
  position:absolute;
  top:1.6rem;
  left:2.4rem;
  /* La place du bouton de fermeture, plus sa marge : un titre long s'arrête avant
     de passer dessous au lieu de le traverser. */
  right:7.2rem;
  margin:0;
  max-width:none;
  font-size:1.6rem;
  font-weight:600;
  line-height:1.3;
  text-shadow:0 .1rem .3rem rgba(0,0,0,.4);
}

.mdl-caps-fermer{
  position:absolute;
  top:1.2rem;
  right:1.2rem;
  display:grid;
  place-items:center;
  width:4rem;
  height:4rem;
  border-radius:50%;
  color:#F3F7FA;
  background:rgba(6,15,21,.5);
  transition:background .2s;
}
.mdl-caps-fermer:hover{background:rgba(6,15,21,.85)}
.mdl-caps-fermer svg{width:2rem;height:2rem}

/* La croix et le titre s'effacent pendant la lecture, avec les contrôles du lecteur :
   c'est la classe que pose initCapsule() sur inactivité. Ils reviennent au moindre
   mouvement, et RESTENT tant que le clavier est dans la fenêtre — `:focus-within`
   l'emporte, sans quoi on masquerait la cible de la touche de tabulation. */
.mdl-caps-boite[data-mdl-repos="1"]:not(:focus-within) .mdl-caps-titre,
.mdl-caps-boite[data-mdl-repos="1"]:not(:focus-within)::before{opacity:0}
.mdl-caps-boite[data-mdl-repos="1"]:not(:focus-within) .mdl-caps-fermer{opacity:0;pointer-events:none}
.mdl-caps-titre,.mdl-caps-fermer,.mdl-caps-boite::before{transition:opacity .3s var(--mdl-ease)}

/* ------------------------------------------------------------------ l'ouverture */

/* Un fondu court, et rien d'autre : la fenêtre ne glisse pas, ne rebondit pas. Le
   `allow-discrete` et le `@starting-style` sont ce qui permet d'animer une propriété
   discrète (`display`, et l'entrée dans la couche du dessus) ; là où ils manquent, la
   fenêtre paraît d'un coup, ce qui a toujours été le comportement attendu d'une
   fenêtre modale. Rien à réparer dans ce cas. */
@media (prefers-reduced-motion:no-preference){
  .mdl-caps,.mdl-caps::backdrop{
    transition:opacity .25s var(--mdl-ease),display .25s allow-discrete,overlay .25s allow-discrete;
  }
  .mdl-caps,.mdl-caps::backdrop{opacity:0}
  .mdl-caps[open],.mdl-caps[open]::backdrop{opacity:1}
  @starting-style{
    .mdl-caps[open],.mdl-caps[open]::backdrop{opacity:0}
  }
}

/* ---------------------------------------------------------------- sous 700 px */

/* Le point de rupture est en px comme tous ceux de la maison : dans une media query,
   `rem` se mesure sur la taille initiale du navigateur et ignore le
   html{font-size:62.5%} de Bricks.

   Sur téléphone la fenêtre prend la largeur entière et perd ses coins : à cette
   taille, un arrondi ne fait que rogner l'image. Le titre passe en dessous du seuil
   de lisibilité s'il reste à 1,6 rem sur deux lignes, on le raccourcit d'un cran. */
@media (max-width:700px){
  .mdl-caps{width:100%}
  .mdl-caps-boite{border-radius:0}
  .mdl-caps-titre{font-size:1.44rem;top:1.2rem;left:1.6rem;right:6rem}
  .mdl-caps-fermer{width:3.6rem;height:3.6rem}
}

/* Une fenêtre modale n'a rien à faire sur une feuille imprimée : elle est fermée au
   moment où l'on imprime, mais un navigateur qui l'aurait laissée ouverte sortirait
   une page noire. */
@media print{.mdl-caps{display:none}}

/* ═══ carte.css ═══ */
/* ─────────────────────────────────────────────────────────────────────────────
   modulo-carte — où se trouve l'entrepôt
   Élément : elements/modulo-carte.php

   Rappel de la maison : `html{font-size:62.5%}` (Bricks), donc 1 rem = 10 px.
   Aucune valeur en px, aucune couleur hors des variables --mdl-*.

   La section est posée sous le formulaire, en fin de page : c'est la dernière
   chose qu'on lit avant le pied de page, et elle répond à une seule question —
   « c'est où ? ». Tout le reste est déjà dit plus haut.
   ───────────────────────────────────────────────────────────────────────────── */

/* Le titre reprend le rythme des autres sections ; il est facultatif et la carte
   remonte d'elle-même s'il est vide. */
/* RONDE 8 — les deux valeurs de la carte de nuit, nommées ici plutôt que répétées.
   `--mdl-carte-nuit` est la couleur MOYENNE des tuiles une fois filtrées, relevée sur
   le rendu (#202B3C) et assombrie d'un cran : le fond du cadre doit passer inaperçu
   pendant le chargement, pas éclairer plus que la carte qui va le couvrir.
   Elles vivent sur `.mdl-carte` et non sur `:root` : ce morceau ne style que la carte,
   et deux morceaux qui se disputeraient un jeton seraient un défaut (tools/LISEZ-MOI). */
.mdl-carte {
  --mdl-carte-nuit: #16212F;
  --mdl-carte-nuit-2: #1E2C3D;
}

.mdl-carte h2 {
  max-width: 18ch;
  margin-bottom: clamp(2.4rem, 3vw, 4rem);
}

/* SANS TITRE, la section se resserre par le haut.
 *
 * `section:where(.mdl){padding-block:var(--mdl-sp)}` réserve 13,6 rem, la respiration
 * qu'il faut entre deux sections qui commencent chacune par un titre. Sur la page
 * « Contactez-nous » la carte n'en a pas — elle est posée directement sous le <h1> de
 * la page — et ces 13,6 rem s'ajoutaient au bas du bandeau : 173 px de vide entre
 * l'accroche et la carte, alors que le client demandait la carte SOUS le titre.
 * Resserré à 99 px, l'ensemble se lit comme un seul en-tête.
 *
 * Le bas ne bouge pas : la section qui suit, elle, recommence par un titre. */
.mdl-carte:not(:has(h2)) {
  padding-top: clamp(3.2rem, 4vw, 5.6rem);
}

/* L'ancre recule d'autant — `scroll-margin-top` vaut `--mdl-sp` partout ailleurs
   (modulo.css), ce qui ferait reparaître ici le bas du bandeau au-dessus de la carte. */
.mdl-carte:not(:has(h2)) > .mdl-anchor {
  scroll-margin-top: clamp(3.2rem, 4vw, 5.6rem);
}

/* ── le cadre ───────────────────────────────────────────────────────────────── */

/* Le format plutôt qu'une hauteur : la carte garde ses proportions d'un écran à
   l'autre et ne devient ni une bande ni un carré. 21/9 sur grand écran fait une
   vue large, celle d'un plan d'accès ; la requête plus bas la resserre quand la
   largeur ne suffit plus.

   `overflow:hidden` avec le rayon : un iframe est un remplacé, il déborde des
   coins arrondis de son parent si on ne le coupe pas. Le fond teinté tient la
   place pendant que la carte arrive — sans lui, un rectangle blanc clignote. */
.mdl-carte-cadre {
  aspect-ratio: 21 / 9;
  border-radius: var(--mdl-r);
  overflow: hidden;
  /* RONDE 8 — le fond tient la place pendant que les tuiles arrivent. Depuis que la
     carte est en nuit, il doit être sombre lui aussi : le `--mdl-tint` d'avant
     faisait clignoter un rectangle bleu PÂLE avant chaque carte. La valeur est la
     couleur moyenne des tuiles filtrées, relevée sur le rendu. */
  background: var(--mdl-carte-nuit);
}

/* RONDE 8 — épingle 27 : « réduire hauteur de la map ».
   Le format est un réglage de l'élément (contrôle « Format »), pas une exception de
   page : la carte de « Contactez-nous » ouvre presque la page et 21:9 y prenait trop
   de hauteur, celle de l'accueil ferme la page et garde la sienne. */
.mdl-carte-cadre.mdl-carte-basse {
  aspect-ratio: 3 / 1;
}

/* Sur fond teinté, le cadre teinté disparaîtrait dans la section : il lui faut
   son propre filet, comme les cartes de tarifs. Filet INTERNE, qui n'agrandit
   pas la boîte. */
/* RONDE 8 — le filet servait à détacher un cadre CLAIR d'une section teintée. La
   carte de nuit se détache toute seule, et un filet pâle par-dessus ferait un halo. */
.mdl-carte.mdl-tinted .mdl-carte-cadre {
  box-shadow: none;
}

/* Le repli sans JavaScript sert l'embarqué d'OSM dans un <iframe>. `display:block`
   n'y est pas facultatif : un iframe est en ligne par défaut, et une boîte en ligne
   réserve la place d'un jambage sous elle — quelques pixels de fond qui dépassent
   sous la carte, au bas du cadre. */
.mdl-carte-cadre iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Sans JavaScript, le cadre de Leaflet resterait une boîte vide AU-DESSUS du repli :
   deux cadres, dont un mort. On masque le premier quand le second est là.

   Le sélecteur ne mord que dans ce cas précis : le contenu d'un <noscript> n'entre dans
   le DOM que si les scripts sont coupés. Scripts actifs, `.mdl-carte-repli` n'existe
   pas, `:has()` est faux, et la carte s'affiche normalement. */
.mdl-carte:has(.mdl-carte-repli) [data-mdl="carte"] {
  display: none;
}

/* ── la carte Leaflet ────────────────────────────────────────────────────────────
 *
 * Tout ce qui suit sert un seul but : que la carte soit de la maison. Elle arrive
 * avec l'habillage de Leaflet — police système, boutons carrés, attribution grise —
 * et rien de cela n'est de la charte. On ne surcharge que ce qui se voit.
 */

/* LA RÈGLE SANS LAQUELLE LA CARTE RESTE BLANCHE.
 *
 * modulo.css pose `:where(.mdl) img{max-width:100%}` sur toutes les images du site, et
 * les tuiles de Leaflet SONT des <img>, dans une section `.mdl`. Leur bloc contenant est
 * un conteneur de tuiles positionné, sans largeur propre : `max-width:100%` s'y résout
 * à zéro et les tuiles disparaissent. C'est le défaut classique de Leaflet dans un
 * thème WordPress, et il ne se voit qu'une fois monté dans la page — Leaflet 1.9.4 ne
 * se protège que pour `img.leaflet-image-layer`, pas pour `img.leaflet-tile`.
 *
 * `:where()` ne compte pour rien : ce sélecteur-ci (0,2,1) l'emporte sans `!important`. */
.mdl-carte .leaflet-container img {
  max-width: none;
}

.mdl-carte .leaflet-container {
  width: 100%;
  height: 100%;
  /* La police par défaut de Leaflet est une pile Helvetica/Arial. */
  font-family: inherit;
  font-size: 1.3rem;
  /* Le fond sous les tuiles, le temps qu'elles arrivent et sur les bords en cours
     de glissé : la teinte de la maison plutôt que le gris de Leaflet. */
  background: var(--mdl-tint);
}

/* LE POINT CENTRAL DE LA REVUE DE CHARTE : la tuile est adoucie.
 *
 * La tuile standard d'OpenStreetMap est faite pour être lue seule, en plein écran :
 * autoroutes roses, forêts vert vif, zones industrielles mauves. Posée dans une page
 * qui tient en bleu pâle, encre et un seul ambre, elle devenait l'élément le plus
 * bruyant du site — et elle est en bas de page, là où l'œil doit se reposer.
 *
 * Trois fonctions, et pas une de plus. Mesuré sur la tuile rendue : les verts et le
 * rose des autoroutes passent de 25 % à 3 % de saturation, c'est-à-dire SOUS le
 * `--mdl-tint` de la maison (6 %), pendant que l'ambre du repère reste à 87 %. La
 * carte se range donc derrière la page, et le point est la seule couleur franche —
 * exactement la hiérarchie qu'on veut d'un « où nous trouver ».
 *
 * RONDE 8 — épingles 11 et 27. « J'aimerais un autre look pour la map, peut-être
 * dans le bleu foncé et noir ? » ; « revoir couleurs ». La carte passe donc en nuit.
 *
 * Ce fichier portait jusqu'ici la consigne inverse — « pas de hue-rotate, pas de
 * sepia », parce qu'un essai bichromique bleu rappelait le traitement écarté à la
 * ronde 2. Cette consigne était le fruit d'un choix de ma part ; c'est le client qui
 * demande maintenant le bleu foncé, et c'est sa page. On la lève, pour la CARTE
 * seulement : le bichromique reste écarté sur les PHOTOGRAPHIES, qui sont un autre
 * sujet et où la décision de la ronde 2 tient toujours.
 *
 * La chaîne, dans cet ordre, et chaque fonction pour une raison :
 *   · `invert(1)`      — le fond clair devient sombre, les routes claires ;
 *   · `grayscale(1)`   — efface les catégories d'OSM (autoroute rose, forêt verte,
 *                        zone industrielle mauve). Sans lui, l'inversion les laisse
 *                        en magenta et vert sale : sombre, mais pas bleu ;
 *   · `sepia(1)` puis `hue-rotate(178deg)` — le seul moyen, en CSS, de TEINDRE une
 *                        image monochrome : sepia lui donne une couleur, hue-rotate
 *                        l'amène sur le bleu de la maison ;
 *   · `saturate(1.7) brightness(0.82) contrast(1.06)` — l'accord final.
 *
 * Le filtre reste sur le PLAN DES TUILES, jamais sur le conteneur : le repère, les
 * commandes et l'attribution vivent dans d'autres plans. C'est ce qui permet à
 * l'ambre du repère de rester franc sur le bleu de nuit — et c'est justement ce
 * qu'un filtre sur l'embarqué d'OSM ne permettait pas. */
.mdl-carte .leaflet-tile-pane {
  filter: invert(1) grayscale(1) sepia(1) hue-rotate(178deg) saturate(1.7) brightness(0.82) contrast(1.06);
}

/* LES JOINTURES DE TUILES, sur écran à haute densité.
 *
 * Leaflet 1.9.4 pose `mix-blend-mode:plus-lighter` sur ses tuiles pour masquer la
 * jointure pendant le fondu d'arrivée. Sur un écran rétine, où les tuiles de 256 px
 * sont agrandies deux fois, le recouvrement d'un demi-pixel entre voisines est alors
 * ADDITIONNÉ : il en reste une trame claire, permanente, sur toute la carte.
 *
 * Mesuré sur le staging, en écart de luminance au bord d'une tuile (sur 255) :
 *
 *     avec le blend                    36,0
 *     avec le blend, sans notre filtre 39,8   ← ce n'est donc pas le filtre
 *     sans le blend                     3,9   ← imperceptible
 *
 * Le fondu perd son maquillage — une jointure peut se deviner une fraction de seconde
 * à l'arrivée d'une tuile. C'est très peu cher payé pour supprimer une grille claire
 * affichée en permanence. Cadré sur `.mdl-carte` : on ne touche à rien d'autre.
 *
 * Le sélecteur reprend celui de leaflet.css — `.leaflet-container img.leaflet-tile`,
 * spécificité (0,2,1) — préfixé de `.mdl-carte`. Un simple `.mdl-carte .leaflet-tile`
 * (0,2,0) PERD contre lui, quel que soit l'ordre de chargement, et la trame revient. */
.mdl-carte .leaflet-container img.leaflet-tile {
  mix-blend-mode: normal;
}

/* Le repère. `L.divIcon` hérite d'un fond blanc et d'un filet dans leaflet.css :
   on les retire, le tracé se suffit. */
.mdl-carte .mdl-carte-pin {
  background: none;
  border: 0;
}

.mdl-carte .mdl-carte-pin svg {
  display: block;
  /* Il se détache du fond clair de la carte sans cerne dur. */
  filter: drop-shadow(0 2px 4px rgba(16, 33, 44, 0.28));
}

/* ── les commandes ───────────────────────────────────────────────────────────────
 * Même langue que `.mdl-pick-btn` et `.mdl-btn-line` : blanc, filet intérieur,
 * coins de la maison, bleu au survol. Les carrés gris de Leaflet ne restent pas. */

.mdl-carte .leaflet-control-zoom {
  border: 0;
  border-radius: 0.96rem;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(16, 33, 44, 0.14), inset 0 0 0 1.5px var(--mdl-tint-2);
}

/* RONDE 8 — sur la carte de nuit, un bouton blanc devient la tache la plus claire de
   la section et vole le regard au repère. Les commandes passent donc en sombre : même
   dessin, mêmes dimensions, valeurs retournées. */
.mdl-carte .leaflet-bar a,
.mdl-carte .leaflet-bar a:hover {
  width: 3.4rem;
  height: 3.4rem;
  line-height: 3.4rem;
  border: 0;
  background: var(--mdl-carte-nuit-2);
  color: rgba(255, 255, 255, 0.86);
  font-size: 1.9rem;
  font-weight: 600;
  transition: background .2s, color .2s;
}

.mdl-carte .leaflet-bar a:first-child {
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

.mdl-carte .leaflet-bar a:hover,
.mdl-carte .leaflet-bar a:focus-visible {
  background: var(--mdl-blue-deep);
  color: #fff;
}

/* L'état « on ne peut plus zoomer » : Leaflet grise le lien. */
.mdl-carte .leaflet-bar a.leaflet-disabled {
  background: var(--mdl-carte-nuit-2);
  color: rgba(255, 255, 255, 0.28);
}

.mdl-carte .leaflet-control-zoom,
.mdl-carte .leaflet-control-attribution {
  margin: 1.2rem;
}

/* ── l'attribution ───────────────────────────────────────────────────────────────
 * Elle est OBLIGATOIRE — la licence ODbL d'OpenStreetMap l'exige — et elle reste,
 * toujours. Ce qu'on retire est ce que l'embarqué d'OSM ajoutait par-dessus : le
 * « ❤ Make a Donation » et le « Report a problem », un appel au don et un outil de
 * contributeur qui n'ont rien à faire en bas de la page d'accueil d'un commerce.
 * Il ne reste que le crédit, à la taille des mentions du site. */
.mdl-carte .leaflet-control-attribution {
  padding: 0.3rem 0.8rem;
  border-radius: 0.6rem;
  /* RONDE 8 — retourné avec la carte. Le crédit reste OBLIGATOIRE (licence ODbL) et
     donc lisible : blanc à 72 % sur le bleu de nuit passe le rapport de contraste
     d'un texte secondaire, là où l'encre sur blanc translucide devenait illisible
     dès que la tuile sous elle était sombre. */
  background: rgba(8, 20, 30, 0.7);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  color: rgba(255, 255, 255, 0.72);
  font-size: 1.1rem;
  line-height: 1.5;
}

.mdl-carte .leaflet-control-attribution a {
  color: rgba(255, 255, 255, 0.72);
  text-decoration: underline;
  text-underline-offset: .2em;
}

.mdl-carte .leaflet-control-attribution a:hover {
  color: #fff;
}

/* ── l'adresse et l'itinéraire ──────────────────────────────────────────────── */

/* L'adresse porte l'information, la carte n'en est que l'image : elle reste donc
   en toutes lettres, lisible et sélectionnable, sous le cadre. */
.mdl-carte-pied {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.2rem 3.2rem;
  margin-top: clamp(1.6rem, 2vw, 2.4rem);
}

/* `<address>` est en italique dans la feuille par défaut du navigateur, et la
   maison n'a pas d'italique. */
.mdl-carte-pied address {
  font-style: normal;
  line-height: 1.5;
  color: var(--mdl-ink-2);
}

@media (max-width: 900px) {
  .mdl-carte-cadre {
    aspect-ratio: 16 / 10;
  }
}

@media (max-width: 600px) {
  /* Plus haut que large serait absurde, mais 16/10 sur 350 px de large ne montre
     plus qu'un pâté de maisons : on rend un peu de hauteur pour retrouver les
     rues qui mènent au bâtiment. */
  .mdl-carte-cadre {
    aspect-ratio: 4 / 3;
  }

  /* Empilés, l'adresse puis le lien : côte à côte, l'adresse sur deux lignes et
     le lien poussé au bout de la rangée se lisent mal. */
  .mdl-carte-pied {
    justify-content: flex-start;
  }
}

/* ═══ consentement.css ═══ */
/* Bannière de consentement — `.cmplz-cookiebanner`
 *
 * Réglages (position, couleurs, textes) : tools/consentement.php. Ici, sa taille seule.
 *
 * Pourquoi une feuille pour ça. La bannière de Complianz est une grille, et sur écran
 * large ses boutons sont un élément de grille comme un autre : ils s'étirent donc sur
 * toute la hauteur de la rangée, que le message décide. Avec le texte d'origine — cinq
 * lignes — cela donnait trois boutons de 110 px de haut et une barre de 231 px, un
 * cinquième de l'écran. Le texte est raccourci dans tools/consentement.php ; il reste à
 * empêcher l'étirement, sans quoi le défaut reviendrait au premier message un peu long.
 *
 * Une note sur l'ordre. `cmplz-banner-1-optin` est mise en file APRÈS `modulo-pages`
 * (c'est le greffon qui la pose, à sa propre priorité) : on ne peut pas compter sur la
 * cascade. Chaque règle part donc de `#cmplz-cookiebanner-container`, l'enveloppe que
 * Complianz écrit lui-même, et l'emporte par la spécificité — un identifiant contre des
 * classes. C'est aussi pourquoi rien ici n'est en `!important` : ce n'est pas nécessaire.
 *
 * 1 rem = 10 px : Bricks pose html{font-size:62.5%}.
 */

:root{
  /* La hauteur d'un bouton. Une variable parce que trois règles s'y accordent — le
     bouton lui-même, le centrage de la colonne sur écran large, et la rangée du bas
     sur téléphone. */
  --mdl-cmplz-btn-h:4.4rem;
}

#cmplz-cookiebanner-container .cmplz-cookiebanner{
  padding:1.6rem 2.4rem;
  grid-gap:.8rem;
}

/* Les boutons gardent leur hauteur propre au lieu de remplir la rangée. `height` et non
   `min-height` : c'est une hauteur posée qui annule l'étirement, une hauteur minimale
   le laisse faire. */
#cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons .cmplz-btn{
  height:var(--mdl-cmplz-btn-h);
  min-height:var(--mdl-cmplz-btn-h);
}

/* Le bloc de boutons est lui-même un élément de grille : sans ça il resterait collé en
   haut d'une rangée plus haute que lui quand le message dépasse une ligne. */
#cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons{
  align-self:center;
}

/* Le seuil est celui de Complianz : au-dessus de 768 px la bannière est la carte du
   coin, au-dessous elle reprend toute la largeur du bas. Les deux blocs qui suivent se
   partagent exactement cette frontière. */
@media (min-width:769px){
  /* Complianz demande `width:100%` par bouton : trois boutons qui veulent chacun toute
     la largeur de la carte, dans 484 px. Ils se compriment jusqu'à couper leur propre
     libellé — « Voir les préférences » est en `white-space:nowrap`, il déborde au lieu de
     se replier. On les laisse donc prendre la largeur de leur texte, rangés à gauche
     comme la carte elle-même. */
  #cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons{
    justify-content:flex-start;
    flex-wrap:wrap;
  }
  #cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons .cmplz-btn{
    flex:0 0 auto;
    width:auto;
    min-width:0;
    padding-inline:2.4rem;
  }
}

@media (max-width:768px){
  /* Trois boutons empilés font 152 px à eux seuls sur un téléphone. « Accepter » et
     « Refuser » tiennent côte à côte — ils doivent de toute façon avoir le même poids,
     la Loi 25 l'exige — et « Voir les préférences » passe dessous, sur toute la largeur.
     Deux rangées au lieu de trois. */
  #cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons{
    flex-direction:row;
    flex-wrap:wrap;
  }
  #cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons .cmplz-btn{
    flex:1 1 12rem;
    width:auto;
    min-width:0;
  }
  #cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-view-preferences,
  #cmplz-cookiebanner-container .cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-save-preferences{
    flex-basis:100%;
  }
}

/* ═══ duo.css ═══ */
/* duo — le bloc image + texte des pages de service.
 *
 * Deux colonnes de largeur égale, la photo et le texte, alignées sur leur milieu.
 * Le fond (blanc ou teinté) vient de `mdl-tinted` et le rythme vertical de
 * `section:where(.mdl){padding-block:var(--mdl-sp)}`, tous deux dans modulo.css :
 * rien à reprendre ici. Ce morceau ne style que `.mdl-duo` et ses descendants.
 *
 * 1 rem = 10 px — Bricks pose html{font-size:62.5%}. Aucune valeur en px.
 */

.mdl-duo .mdl-wrap{
  display:grid;
  /* minmax(0,1fr) plutôt que 1fr : une piste de grille a `min-width:auto`, et un
     mot long — « mini-entrepôts » — l'empêcherait de descendre sous sa largeur
     intrinsèque, poussant la seconde colonne hors de la page. */
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(3rem,5vw,8rem);
  align-items:center;
}

/* Sans photo — pièce jointe supprimée de la médiathèque, adresse externe rompue —
   l'élément pose `mdl-duo-sans-image` : le texte prend toute la largeur au lieu de
   se serrer sur la moitié, à côté d'une colonne vide. */
.mdl-duo-sans-image .mdl-wrap{grid-template-columns:minmax(0,1fr)}

/* ------------------------------------------------------------------- la photo */

/* `height:auto` n'est pas décoratif : wp_get_attachment_image() écrit les attributs
   `width` et `height` de la pièce jointe, que le navigateur applique comme indices de
   présentation. Tant que `height` n'est pas `auto`, il fixe la hauteur et le rapport
   4/3 n'est jamais calculé — la photo sortirait à ses proportions d'origine. La
   feuille de Bricks pose bien un `img{height:auto}`, mais la géométrie du bloc ne
   doit pas dépendre d'une autre feuille. */
.mdl-duo-pic img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;border-radius:var(--mdl-r)}

/* RONDE 8 — épingle 15 : « je pense que je mettrais les coins arrondis des images
   dans ces sections aussi ». Ils y ÉTAIENT — sur l'image, ligne du dessus — mais on
   ne les voyait pas : dès que la parallaxe est active, modulo-motion.js pose `mdl-par`
   sur le cadre, donc `overflow:hidden` (parts/motion.css), et l'image agrandie de
   quelques pour cent voit ses quatre coins arrondis glisser HORS de la boîte de
   découpe. Ce qui restait visible, c'étaient les coins carrés du cadre.
   Tous les autres cadres parallaxés du thème portent déjà le rayon — `.mdl-frame`,
   `.mdl-services-pic`, `.mdl-par-boite`, `.mdl-shot` : celui-ci était le seul oublié.
   Il est posé ici, et pas sous `html.mdl-anim`, pour que le cadre ait la même forme
   que l'animation ait lieu ou non. */
.mdl-duo-pic{border-radius:var(--mdl-r)}

/* Photo à droite. On déplace des cases, jamais `direction:rtl`, qui renverserait
   aussi la ponctuation et le sens de lecture. Les DEUX cases sont posées : ne
   placer que la photo en colonne 2 suffirait à renvoyer le texte à la rangée
   suivante, le placement automatique de la grille ne revenant jamais en arrière. */
.mdl-duo-inverse .mdl-duo-pic{grid-column:2;grid-row:1}
.mdl-duo-inverse .mdl-duo-txt{grid-column:1;grid-row:1}

/* --------------------------------------------------------- la colonne de texte */

/* La mesure de lecture, et la voix courante du bloc. La couleur se pose sur la
   colonne plutôt que sur les <p> : chaque partie qui parle d'une autre voix — le
   titre, les points, le lien — la redéclare pour elle-même, et une déclaration
   l'emporte toujours sur un héritage, sans qu'aucun sélecteur ait à monter en
   spécificité. */
.mdl-duo-txt{max-width:56ch;color:var(--mdl-ink-2)}
.mdl-duo-txt h2{color:var(--mdl-ink);margin-bottom:2rem}
.mdl-duo-txt p+p{margin-top:1.44rem}

/* Le surtitre : un filet bleu, puis deux ou trois mots en petites capitales. */
.mdl-duo-sur{
  display:flex;
  align-items:center;
  gap:1.2rem;
  margin-bottom:1.6rem;
  color:var(--mdl-blue-deep);
  font-size:1.4rem;
  font-weight:600;
  line-height:1.2;
  letter-spacing:.12em;
  text-transform:uppercase;
}
.mdl-duo-sur::before{content:"";flex:none;width:2.8rem;height:.15rem;background:var(--mdl-blue)}

/* ------------------------------------------------------------------ les points */

/* Une coche dessinée, jamais une puce de texte : `list-style:none` retire celle du
   navigateur, la grille tient la coche et le texte dans deux pistes distinctes pour
   qu'un point de deux lignes reste aligné sous lui-même. */
.mdl-duo-points{list-style:none;display:grid;gap:1.2rem;margin-top:2.4rem;color:var(--mdl-ink)}
.mdl-duo-points li{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:1.44rem;align-items:start}
/* 2,4 rem, soit 24 px : une unité de la grille du dessin vaut exactement un pixel,
   et le trait de 1,25 sort au même poids que les filets de la maison. */
.mdl-duo-points svg{
  width:2.4rem;
  height:2.4rem;
  color:var(--mdl-blue);
  /* Centrée sur la PREMIÈRE ligne du point et non sur le bloc entier : une rangée
     de deux lignes garde sa coche en haut. La boîte de ligne fait 1.6em (le
     line-height du corps, modulo.css), l'écart avec la coche se partage en deux. */
  margin-top:calc((1.6em - 2.4rem) / 2);
}

/* -------------------------------------------------------------------- le lien */

/* Le <p> porte l'écart, pas l'ancre : les trois allures (lien souligné, bouton
   ambre, bouton au trait) gardent ainsi la même assise, alors qu'elles n'ont ni le
   même display ni la même hauteur. */
.mdl-duo-act{margin-top:2.8rem}

/* ---------------------------------------------------------------- sous 900 px */

/* Le point de rupture est en px comme tous ceux de la maison : dans une media
   query, `rem` se mesure sur la taille initiale du navigateur et ignore le
   html{font-size:62.5%} de Bricks — 900 px ne s'y écrit donc pas en rem sans
   ambiguïté.

   Une seule colonne, et la photo TOUJOURS au-dessus du texte : c'est déjà l'ordre
   du code, il suffit de relâcher le placement de « Photo à droite ». Sans cette
   remise à zéro, une page de service sur deux ouvrirait sur un mur de texte. */
@media (max-width:900px){
  .mdl-duo .mdl-wrap{grid-template-columns:minmax(0,1fr);gap:clamp(2.8rem,5vw,4.4rem)}
  .mdl-duo-inverse .mdl-duo-pic,
  .mdl-duo-inverse .mdl-duo-txt{grid-column:auto;grid-row:auto}
  /* La colonne prend toute la largeur : une mesure de 56ch sous une photo pleine
     largeur laisserait un grand vide à droite. Les paragraphes restent tenus par le
     plafond de 62ch que modulo.css pose sur les <p> ; les <li> n'en héritent pas,
     on le leur donne. */
  .mdl-duo-txt{max-width:none}
  .mdl-duo-points{max-width:62ch}
}

/* ═══ equipe.css ═══ */
/* ─────────────────────────────────────────────────────────────────────────────
   modulo-equipe — les portraits
   Élément : elements/modulo-equipe.php

   Rappel de la maison : `html{font-size:62.5%}` (Bricks), donc 1 rem = 10 px.
   Aucune valeur en px, aucune couleur hors des variables --mdl-*.

   Pas de carte, pas d'ombre, pas de fond : la photo, le nom, le rôle. La retenue est
   le sujet — toute la mise en forme tient dans la grille et deux lignes de légende.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── l'introduction ─────────────────────────────────────────────────────────── */

.mdl-equipe .mdl-equipe-intro h2 {
  max-width: 18ch;
}

.mdl-equipe .mdl-equipe-intro .mdl-lead {
  max-width: 56ch;
  margin-top: 1.6rem;
}

.mdl-equipe .mdl-equipe-intro .mdl-lead + .mdl-lead {
  margin-top: 1.2rem;
}

/* ── la grille ──────────────────────────────────────────────────────────────── */

/* La marge est portée par le voisinage, pas par la grille : sans introduction —
   « Masquer le titre » coché et texte vide —, les portraits ouvrent la section sans
   traîner une marge haute par-dessus le `--mdl-sp` de `section:where(.mdl)`. */
.mdl-equipe .mdl-equipe-intro + .mdl-equipe-grille {
  margin-top: clamp(4rem, 5vw, 6.4rem);
}

/* RONDE 7 — la rangée est passée de cinq portraits à quatre (Louis Lessard retiré).
   Les colonnes suivent : 2 puis 4, et plus 2-3-5. Le compte des colonnes doit DIVISER
   celui des portraits, sinon la dernière rangée laisse un orphelin — cinq colonnes
   pour quatre personnes creusaient un vide au bout de la rangée, et trois en
   laissaient une seule, seule, à la ligne. 2 × 2, puis 4 × 1 : aucune rangée
   incomplète, à aucune largeur.

   Écrite en min-width, du plus étroit au plus large. Dans une requête média, `em` vaut
   la taille de police initiale (16 px) et non le 10 px de `html{font-size:62.5%}` :
   50em = 800 px. À ce seuil, quatre colonnes laissent ~185 px par portrait, soit plus
   que les 5 colonnes de 1200 px qu'on avait avant. */
.mdl-equipe .mdl-equipe-grille {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(3.2rem, 3.6vw, 4.8rem) clamp(2rem, 2.4vw, 3.2rem);
}

@media (min-width: 50em) {
  .mdl-equipe .mdl-equipe-grille {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ── un portrait ────────────────────────────────────────────────────────────── */

/* 2/3 portrait, jamais carré : les fichiers de la médiathèque sont cadrés en
   hauteur et un recadrage carré leur couperait le haut et le bas du visage.
   Le fond tient la case le temps du chargement — et si la photo manque. */
.mdl-equipe .mdl-equipe-grille img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: var(--mdl-r);
  background: var(--mdl-tint);
}

.mdl-equipe .mdl-equipe-grille figcaption {
  margin-top: 1.6rem;
}

.mdl-equipe .mdl-equipe-grille figcaption b {
  display: block;
  font-weight: 600;
  font-size: 1.8rem;
  /* Le crénage des termes du registre (`.mdl-inclus dt`) : les noms propres se
     tiennent au même serrage que le reste de la maison. */
  letter-spacing: -0.012em;
  line-height: 1.3;
}

.mdl-equipe .mdl-equipe-grille figcaption span {
  display: block;
  margin-top: 0.4rem;
  color: var(--mdl-ink-2);
  font-size: 1.6rem;
  line-height: 1.4;
  text-wrap: pretty;
}

/* ═══ etapes.css ═══ */
/* modulo-etapes — les trois temps de la réservation.
 *
 * Le registre gradué de la maquette : un filet bleu au-dessus de chaque temps, qui
 * relie les trois colonnes d'une même ligne, et un gros numéro pâle qui fait le décor
 * sans jamais porter le texte.
 *
 * Ce morceau ne style que `.mdl-etapes` et ses descendants — voir tools/build-css.php.
 * 1 rem = 10 px : Bricks pose html{font-size:62.5%}.
 */

.mdl-etapes h2 { max-width: 24ch; }

/* La marge est portée par la paire, pas par l'accroche : titre masqué, l'accroche
 * ouvre la section sans s'en décoller. */
.mdl-etapes .mdl-lead { max-width: 56ch; }
.mdl-etapes h2 + .mdl-lead { margin-top: 1.6rem; }

/* La série. Le compteur est remis à zéro ici, sur la liste, et non sur la section :
 * deux séries dans une même page repartent chacune à 1. */
.mdl-etapes ol {
	counter-reset: mdl-etape;
	list-style: none; /* le numéro n'est plus celui de la liste : voir ::before */
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(3.2rem, 4vw, 6.4rem);
	margin-top: clamp(4rem, 5vw, 7.2rem);
}

/* Même raison : sans titre ni accroche, la série est le premier bloc de la section
 * et n'a rien à quoi se décoller. */
.mdl-etapes .mdl-wrap > ol:first-child { margin-top: 0; }

/* Le filet de 1,5 px (0,15 rem) : la règle graduée du registre. Il est posé sur chaque
 * temps plutôt que sur la liste, pour qu'il s'interrompe dans les gouttières et se
 * reconstitue à l'identique quand la série passe sur une seule colonne. */
.mdl-etapes li {
	counter-increment: mdl-etape;
	border-top: 0.15rem solid var(--mdl-blue);
	padding-top: 2.4rem;
}

/* Le numéro. Il est dessiné ici, pas écrit dans le HTML : l'ordre est déjà porté par
 * le <ol>, et retirer un temps renumérote la série sans retouche. Le bleu pâle le
 * laisse au rang de décor — le texte, lui, garde l'encre pleine. */
.mdl-etapes li::before {
	content: counter(mdl-etape);
	display: block;
	font-size: clamp(4.8rem, 6vw, 7.2rem);
	font-weight: 600;
	letter-spacing: -0.03em;
	line-height: 1;
	color: var(--mdl-blue-pale);
	margin-bottom: 1.6rem;
}

.mdl-etapes li h3 { margin-bottom: 0.8rem; }

/* La colonne est étroite : on resserre la mesure pour qu'elle ne se lise pas comme
 * un paragraphe de page pleine (`:where(.mdl) p` la laisse à 62ch). */
.mdl-etapes li p { max-width: 38ch; }

/* inline-block : la marge haute d'un lien resté en ligne n'aurait aucun effet. */
.mdl-etapes .mdl-link {
	display: inline-block;
	margin-top: clamp(3.2rem, 4vw, 5.6rem);
}

/* Les points de rupture restent en pixels, comme ceux de modulo.css : dans une
 * media query, `rem` se mesure sur la taille initiale du navigateur (16 px) et non
 * sur le html{font-size:62.5%} de Bricks — il ne voudrait donc pas dire ce qu'il
 * dit. En dessous de 800 px, trois colonnes ne tiennent plus une ligne de texte
 * lisible : la série s'empile, sans étape intermédiaire à deux colonnes qui
 * laisserait le troisième temps orphelin. */
@media (max-width: 800px) {
	.mdl-etapes ol {
		grid-template-columns: minmax(0, 1fr);
		gap: 3.2rem;
	}

	.mdl-etapes li p { max-width: 56ch; }
}

/* ═══ faq.css ═══ */
/* modulo-faq — la foire aux questions.
   Ne style que `.mdl-faq` et ses descendants : ce morceau ne croise aucun autre.

   Un registre, pas une pile de cartes : un filet entre les questions, rien autour,
   rien dessous. Le numéro est compté ici même — il n'existe pas dans le HTML.
   L'accordéon est un <details> natif : la feuille dessine ce qui est à dessiner,
   le navigateur fait le reste. Aucune ligne de script. */

.mdl-faq{
  /* Les quatre mesures partagées par la question et sa réponse. Elles sont ici, en
     un seul endroit, parce que trois règles doivent s'accorder : la colonne du
     numéro et l'alinéa de la réponse, la hauteur de ligne et la hauteur du chevron. */
  --mdl-faq-question:clamp(1.8rem,1.15vw,2.1rem);   /* le corps de la question       */
  --mdl-faq-ligne:calc(var(--mdl-faq-question)*1.4);/* sa hauteur de ligne, EN LONGUEUR */
  --mdl-faq-num:3.2rem;                             /* la colonne du numéro          */
  --mdl-faq-ecart:clamp(1.6rem,1.5vw,2.4rem);       /* ce qui la sépare du texte     */
}

/* Le registre du thème : le titre à gauche, la matière à droite — celui de
   `.mdl-inclus`. `align-items:start` est ce qui rend le collage possible ci-dessous :
   une case étirée sur toute la hauteur n'a aucune marge où coller. */
.mdl-faq .mdl-wrap{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:4.8rem 8rem;align-items:start}

/* Dix-huit questions font une longue colonne : le titre suit la lecture. 11,2rem,
   c'est la hauteur de l'en-tête collant (8rem) et un peu d'air — la même valeur que
   `.mdl-panel` du sélecteur. */
.mdl-faq-intro{position:sticky;top:11.2rem}
.mdl-faq-intro h2{max-width:12ch}
.mdl-faq-intro .mdl-lead{max-width:34ch;margin-top:1.6rem}

/* L'introduction est facultative et l'élément ne rend pas de bloc vide : quand elle
   manque, le registre prend les deux colonnes plutôt que de laisser un trou. Et
   l'inverse, un registre vidé de ses rangées, laisse le titre s'étaler. */
.mdl-faq-list:only-child{grid-column:1/-1}
.mdl-faq-intro:only-child{grid-column:1/-1;position:static}

/* -------------------------------------------------------------- la numérotation */

/* Le compteur naît sur la liste, avance d'une question à l'autre et s'écrit dans le
   ::before du <summary>. Rien n'est saisi à la main : ajouter, déplacer ou retirer
   une question renumérote la série toute seule. */
.mdl-faq-list{counter-reset:mdl-faq}
.mdl-faq-item{counter-increment:mdl-faq}

/* Un filet ENTRE les questions, aucun autour. Le sélecteur de frère adjacent laisse
   la première sans trait de tête et la dernière sans trait de pied : rien à annuler
   avec un :first-child ou un :last-child. */
.mdl-faq-item+.mdl-faq-item{border-top:1px solid var(--mdl-rule)}

/* ------------------------------------------------------------------ la question */

.mdl-faq-q{
  display:grid;
  grid-template-columns:var(--mdl-faq-num) minmax(0,1fr) auto;
  column-gap:var(--mdl-faq-ecart);
  align-items:start;
  /* La zone cliquable : toute la largeur de la colonne, et de l'air au-dessus comme
     en dessous. On vise la question, pas le chevron. */
  padding-block:clamp(2.2rem,2.2vw,2.8rem);
  font-size:var(--mdl-faq-question);
  /* Hauteur de ligne donnée EN LONGUEUR, pas en facteur : elle s'hérite alors telle
     quelle par le numéro, dont le corps est plus petit. Les trois cases de la grille
     ont ainsi exactement la même première ligne, et le numéro comme le chevron s'y
     centrent d'eux-mêmes — aucun décalage à rattraper à la main. */
  line-height:var(--mdl-faq-ligne);
  cursor:pointer;
  /* Le marqueur natif du <summary> : `list-style` le retire dans Firefox et Chrome,
     le pseudo-élément -webkit dans Safari. Les deux sont nécessaires. */
  list-style:none;
}
.mdl-faq-q::-webkit-details-marker{display:none}

.mdl-faq-q::before{
  content:counter(mdl-faq,decimal-leading-zero); /* 01, 02, … 18 : toujours deux chiffres */
  font-size:1.44rem;
  font-weight:600;
  letter-spacing:.02em;
  /* Chiffres de même chasse : la colonne reste d'aplomb du 01 au 18. */
  font-variant-numeric:tabular-nums;
  /* Le numéro est lu par les lecteurs d'écran comme n'importe quel texte, il doit
     donc tenir le contraste AA. `--mdl-blue` n'y arrive pas à ce corps (3,7:1 sur le
     blanc) ; `--mdl-blue-deep`, le bleu des liens du thème, donne 5,5:1 sur le blanc
     et 4,9:1 sur le fond teinté. Même famille, même variable maison. */
  color:var(--mdl-blue-deep);
}

/* `pretty` et non `balance` : une question est une phrase, pas un titre d'affiche.
   Équilibrer ses lignes la rétrécirait en colonne étroite sur un téléphone ; on se
   contente d'éviter le mot esseulé en dernière ligne. */
.mdl-faq-t{font-weight:600;letter-spacing:-.012em;text-wrap:pretty;transition:color .2s var(--mdl-ease)}

.mdl-faq-chev{
  width:2.4rem;
  /* Haute comme la ligne : le dessin, centré dans sa boîte par `preserveAspectRatio`,
     tombe pile sur la première ligne de la question, qu'elle en fasse une ou trois. */
  height:var(--mdl-faq-ligne);
  color:var(--mdl-ink-2);
  /* Ce qui s'anime proprement : la rotation et la couleur. La hauteur d'un <details>,
     elle, ne s'anime pas — on ne fait pas semblant. */
  transition:transform .3s var(--mdl-ease),color .2s var(--mdl-ease);
}

/* Survol et ouverture parlent la même langue : la question et son chevron passent au
   bleu, le chevron pivote. Le focus, lui, garde le contour global du thème. */
.mdl-faq-q:hover .mdl-faq-t,
.mdl-faq-item[open] .mdl-faq-t{color:var(--mdl-blue-deep)}
.mdl-faq-q:hover .mdl-faq-chev,
.mdl-faq-item[open] .mdl-faq-chev{color:var(--mdl-blue-deep)}
.mdl-faq-item[open] .mdl-faq-chev{transform:rotate(180deg)}

/* ------------------------------------------------------------------- la réponse */

.mdl-faq-a{
  display:grid;                 /* l'écart entre paragraphes et listes, une seule fois */
  gap:1.2rem;
  /* Alignée sous la question, jamais sous le numéro : la colonne du numéro et son
     écart, repris des mêmes variables — les deux ne peuvent pas diverger. */
  padding-left:calc(var(--mdl-faq-num) + var(--mdl-faq-ecart));
  padding-bottom:clamp(2.4rem,2.4vw,3.2rem);
  color:var(--mdl-ink-2);
}

/* L'ouverture est franche — la réponse est là tout de suite, à sa pleine hauteur —
   mais elle arrive en fondu d'un demi-pas. On n'anime pas la hauteur d'un <details> :
   la boîte ne bouge pas, seul son contenu se pose. */
@keyframes mdl-faq-ouvre{from{opacity:0;transform:translateY(-.6rem)}}
.mdl-faq-item[open] .mdl-faq-a{animation:mdl-faq-ouvre .28s var(--mdl-ease)}

.mdl-faq-a ul{list-style:none;display:grid;gap:.8rem;max-width:62ch}
.mdl-faq-a li{position:relative;padding-left:2.2rem}
/* La pastille se pose au milieu de la première ligne : .8em, c'est la moitié de la
   hauteur de ligne du corps (1,6), et la translation la recentre sur elle-même. */
.mdl-faq-a li::before{content:"";position:absolute;left:.5rem;top:.8em;transform:translateY(-50%);width:.6rem;height:.6rem;border-radius:50%;background:var(--mdl-blue)}

/* ------------------------------------------------------------------ adaptations */

@media (max-width:1024px){
  /* Une colonne : le titre repasse au-dessus du registre et cesse de coller. */
  .mdl-faq .mdl-wrap{grid-template-columns:1fr}
  .mdl-faq-intro{position:static}
  .mdl-faq-intro h2{max-width:20ch}
  .mdl-faq-intro .mdl-lead{max-width:52ch}
}

@media (max-width:600px){
  /* L'alinéa de la réponse mangerait la mesure sur un écran étroit : le numéro garde
     sa colonne dans la question, la réponse repart de la marge. */
  .mdl-faq{--mdl-faq-num:2.8rem}
  .mdl-faq-a{padding-left:0}
}

@media (prefers-reduced-motion:reduce){
  /* La feuille maîtresse coupe déjà les durées ; on retire ici le déplacement, qui
     resterait visible même réduit à un instant. */
  .mdl-faq-item[open] .mdl-faq-a{animation:none}
  .mdl-faq-chev{transition:none}
}

/* ═══ motion.css ═══ */
/* ═══════════════════════════════════════════════════════════════════════════════════
   La couche d'animation — ce que la CSS doit poser AVANT que GSAP se réveille.

   Le comportement vit dans assets/js/modulo-motion.js. Ce morceau-ci ne fait que trois
   choses, et rien d'autre :

     1. cacher ce qui est déjà à l'écran au chargement (le héros, le bandeau de page),
        pour qu'il n'apparaisse pas une fraction de seconde avant d'être animé ;
     2. donner aux cadres d'image de quoi contenir la parallaxe ;
     3. préparer les filets qui se tracent.

   Tout est sous `html.mdl-anim`, une classe posée par un script en ligne dans <head>
   (functions.php, modulo_motion_amorce) UNIQUEMENT si le visiteur ne demande pas de
   réduire les animations. Elle se retire d'elle-même au bout de 2,5 s si le script
   d'animation n'a jamais démarré : sans JavaScript, ou si GSAP ne se charge pas, la
   page reste entièrement lisible. C'est la règle : rien de ce qui est caché ici ne
   peut le rester si l'animation n'a pas lieu.

   Ce qui est SOUS la ligne de flottaison n'a pas besoin d'être caché en CSS : GSAP en
   pose l'état de départ une demi-hauteur d'écran avant qu'il entre (ronde 9 — avant,
   c'était au départ de l'animation, déjà à l'écran, et les titres clignotaient). Cacher aussi
   ces sections-là allongerait la liste ci-dessous à chaque section ajoutée, et
   dupliquerait en CSS la chorégraphie qui vit en JavaScript.
   ═══════════════════════════════════════════════════════════════════════════════════ */

/* ─── 1. l'entrée de page : héros et bandeau ─────────────────────────────────────── */

/* Le héros s'animait en @keyframes depuis la maquette. Quand GSAP prend la main, les
   deux se disputeraient la même opacité — on éteint donc les keyframes ici, et
   modulo-motion.js redonne exactement le même mouvement, au même tempo. */
html.mdl-anim .mdl-hero h1,
html.mdl-anim .mdl-hero .mdl-side,
html.mdl-anim .mdl-frame {
  animation: none;
  /* `transform:none` va avec `animation:none`, et il n'est pas facultatif. L'état de
     départ des keyframes est posé en dur sur ces trois éléments (`translateY(.4em)` sur
     le titre, `translateY(1.6rem)` sur la colonne de droite) et c'est l'image-clé finale
     qui le remettait à zéro. En coupant l'animation sans couper le décalage, le titre du
     héros resterait à 0,4 em trop bas pour toujours — GSAP anime son opacité, pas sa
     position. */
  transform: none;
}

html.mdl-anim .mdl-hero h1,
html.mdl-anim .mdl-hero .mdl-side,
html.mdl-anim .mdl-frame,
html.mdl-anim .mdl-banniere .mdl-kick,
html.mdl-anim .mdl-banniere h1,
html.mdl-anim .mdl-banniere .mdl-lead,
html.mdl-anim .mdl-banniere .mdl-ctas,
html.mdl-anim .mdl-banniere .mdl-shot {
  opacity: 0;
}

/* ─── 2. la parallaxe ────────────────────────────────────────────────────────────────
 * `mdl-par` est posée par le JavaScript sur le CADRE, jamais sur l'image. Le cadre
 * garde sa place dans la grille ; l'image, agrandie de quelques pour cent, glisse à
 * l'intérieur. C'est pour cela que chaque photo parallaxée a un cadre — deux éléments
 * ont dû en recevoir un (modulo-banniere, modulo-services).
 *
 * `overflow:hidden` est ici et pas dans les feuilles de section : c'est la parallaxe
 * qui l'exige, et une section qui n'est pas animée n'a pas à le porter. */
html.mdl-anim .mdl-par {
  overflow: hidden;
}

/* La boîte que modulo-motion.js fabrique quand le cadre d'origine contient aussi une
   légende (`.mdl-place`, `.mdl-fam`, les portraits) : elle épouse la photo et rien
   d'autre. `display:block` parce qu'un <span> est en ligne par défaut, et une boîte en
   ligne prend la hauteur de la ligne, pas celle de l'image. */
html.mdl-anim .mdl-par-boite {
  display: block;
}

/* `will-change` seulement sur ce qui bouge vraiment, et seulement pendant la
   parallaxe : posé partout, il coûte une couche de composition par image. */
html.mdl-anim .mdl-par > img,
html.mdl-anim .mdl-par > video {
  will-change: transform;
}

/* ─── 3. les filets qui se tracent ───────────────────────────────────────────────────
 * Le registre réglé est la signature de la proposition L : le trait sous les mots dans
 * « Inclus avec chaque unité », le filet bleu au-dessus de chaque temps de « comment ça
 * fonctionne ». Les deux sont des `border-top`, qu'on ne peut pas mettre à l'échelle.
 * On rend donc la bordure transparente et on superpose un trait identique, en `::after`
 * — libre dans les deux cas, `::before` portant déjà le numéro des étapes.
 *
 * `top:-Xrem` remonte le trait sur la bordure : le bloc contenant d'un absolu est la
 * boîte de rembourrage, c'est-à-dire le bord INTÉRIEUR de la bordure. */
/* Le trait se trace en mettant à l'échelle un `::after`, mais un pseudo-élément est
   hors de portée du JavaScript. On anime donc une variable personnalisée sur l'élément,
   que le pseudo lit dans son `transform`. `@property` la déclare comme un nombre pour
   qu'elle s'interpole proprement et, surtout, `inherits:true` la fait descendre jusqu'au
   pseudo-élément — sans quoi il ne la verrait jamais. Le `var(…, 0)` reste le repli pour
   les navigateurs sans @property : le trait part quand même de zéro. */
@property --mdl-filet {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

html.mdl-anim .mdl-etapes li,
html.mdl-anim .mdl-inclus .mdl-cell {
  position: relative;
}

html.mdl-anim .mdl-etapes li::after,
html.mdl-anim .mdl-inclus .mdl-cell::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  transform: scaleX(var(--mdl-filet, 0));
  transform-origin: left center;
}

html.mdl-anim .mdl-etapes li {
  border-top-color: transparent;
}

html.mdl-anim .mdl-etapes li::after {
  top: -0.15rem;
  height: 0.15rem;
  background: var(--mdl-blue);
}

html.mdl-anim .mdl-inclus .mdl-cell {
  border-top-color: transparent;
}

html.mdl-anim .mdl-inclus .mdl-cell::after {
  top: -1px;
  height: 1px;
  background: var(--mdl-rule);
}

/* ─── 4. les lignes de titre découpées ───────────────────────────────────────────────
 * SplitText enveloppe chaque ligne dans un masque quand on lui demande `mask:'lines'`
 * (`.mdl-ligne-masque-mask`, en `overflow:clip`) et pose `linesClass` sur la ligne
 * elle-même. Le débordement est déjà coupé par le plugin ; il reste à empêcher que les
 * jambages (p, g, j) soient rognés, ce que `line-height` seul ne garantit pas sur un
 * titre très serré (-.035em, line-height 1.02).
 *
 * CE QU'IL NE FAUT PAS FAIRE, et pourquoi — c'est le défaut qu'on a corrigé :
 * `padding-bottom:.12em` + `margin-bottom:-.12em` sur la LIGNE semble s'annuler, et ne
 * s'annule pas. La marge négative traverse le masque (`overflow:clip` n'ouvre pas de
 * contexte de formatage, contrairement à `hidden`) et va se fondre avec la suivante ;
 * selon que le titre porte ou non une marge basse, il restait 0,12 em non compensé.
 * Mesuré : 46 titres sur 57 sautaient de 6 à 27 px à la fin de leur animation, au
 * moment où le découpage est défait. C'est ce saut que le client voyait — le texte se
 * remettait en place d'un coup.
 *
 * `overflow-clip-margin` agrandit la zone de découpe SANS toucher à la mise en page :
 * c'est exactement la propriété faite pour ça. La hauteur du titre est donc rigoureusement
 * la même avant, pendant et après l'animation. Les deux longhands visent le seul côté
 * qui nous intéresse — un `overflow-clip-margin` sur les quatre côtés laisserait la
 * ligne paraître sous le masque avant d'y entrer. */
html.mdl-anim .mdl-ligne-masque-mask {
  overflow-clip-margin-bottom: 0.14em;
}

/* Repli pour les navigateurs sans les longhands (Safari < 17.4) : la version courte
   n'est comprise qu'à quatre côtés, mais elle vaut mieux qu'un jambage rogné, et
   l'artefact du haut est invisible — le masque précédent le recouvre. */
@supports not (overflow-clip-margin-bottom: 1px) {
  html.mdl-anim .mdl-ligne-masque-mask {
    overflow-clip-margin: 0.14em;
  }
}

/* ─── 5. le respect du réglage système ───────────────────────────────────────────────
 * Deux filets, et ils sont volontairement redondants. Le script en ligne ne pose déjà
 * pas `mdl-anim` quand le visiteur demande moins d'animation ; si le réglage change en
 * cours de visite, gsap.matchMedia() défait les animations. Cette règle-ci est le
 * dernier mot : quoi qu'il arrive, rien ne reste caché ni décalé. */
@media (prefers-reduced-motion: reduce) {
  html.mdl-anim .mdl-hero h1,
  html.mdl-anim .mdl-hero .mdl-side,
  html.mdl-anim .mdl-frame,
  html.mdl-anim .mdl-banniere .mdl-kick,
  html.mdl-anim .mdl-banniere h1,
  html.mdl-anim .mdl-banniere .mdl-lead,
  html.mdl-anim .mdl-banniere .mdl-ctas,
  html.mdl-anim .mdl-banniere .mdl-shot {
    opacity: 1;
  }

  html.mdl-anim .mdl-etapes li,
  html.mdl-anim .mdl-inclus .mdl-cell {
    border-top-color: var(--mdl-rule);
  }

  html.mdl-anim .mdl-etapes li {
    border-top-color: var(--mdl-blue);
  }

  html.mdl-anim .mdl-etapes li::after,
  html.mdl-anim .mdl-inclus .mdl-cell::after {
    display: none;
  }

  html.mdl-anim .mdl-par > img,
  html.mdl-anim .mdl-par > video {
    will-change: auto;
    transform: none !important;
  }
}

/* ═══ nav.css ═══ */
/* Navigation à deux niveaux de l'en-tête — `.mdl-nav`
 *
 * Balisage : elements/modulo-header.php. Comportement : assets/js/modulo-nav.js.
 *
 * Ce morceau ne style que `.mdl-nav` et ses descendants. La barre elle-même — le fond,
 * le collant, le logo, le téléphone, le bouton, le hamburger — reste à modulo.css, qui
 * pose déjà, pour la navigation :
 *
 *     .mdl-top nav{margin-left:auto}
 *     .mdl-top nav ul{display:flex;gap:3.6rem;list-style:none}
 *     .mdl-top nav a{text-decoration:none;font-weight:500;font-size:1.52rem}
 *     @media (max-width:768px){ .mdl-top nav{display:none}
 *                               .mdl-top.mdl-open nav{position:absolute;top:8rem;…}
 *                               .mdl-top.mdl-open nav ul{flex-direction:column;gap:2rem;font-size:2rem} }
 *
 * Ces règles-là visent `nav ul` et `nav a` : elles attrapent donc aussi le tiroir du
 * deuxième niveau, qui n'existait pas quand elles ont été écrites. Là où il faut les
 * défaire, on compte les classes plutôt que de monter en !important — c'est ce que fait
 * déjà modulo.css avec `:where()`. `.mdl-nav .mdl-nav-item .mdl-nav-sub` (trois classes)
 * passe devant `.mdl-top.mdl-open nav ul` (deux classes, deux balises), parce que les
 * classes se comptent avant les balises. Les sélecteurs à rallonge ci-dessous ne sont
 * donc pas décoratifs : chacun est taillé pour l'emporter sur une règle précise.
 *
 * Rien à ajouter pour `prefers-reduced-motion` : la règle globale de modulo.css ramène
 * `animation-duration` et `transition-duration` à .01 ms sur tout descendant de `.mdl`,
 * et l'ouverture n'a pas d'autre ressort que ces deux propriétés.
 */

/* ------------------------------------------------------- le premier niveau, la barre */

/* La navigation prend toute la hauteur de l'en-tête : chaque entrée devient une cible
   de survol pleine hauteur, et le tiroir peut s'ouvrir à `top:100%`, c'est-à-dire pile
   sous la barre, sans vide à traverser ni hauteur à coder en dur. */
.mdl-nav{align-self:stretch}

.mdl-nav .mdl-nav-list{height:100%;align-items:stretch}

.mdl-nav .mdl-nav-item{position:relative}

/* Le bouton d'une entrée à tiroir et le lien d'une entrée simple se ressemblent trait
   pour trait : au premier niveau, seul le chevron distingue les deux. */
.mdl-nav .mdl-nav-btn,
.mdl-nav .mdl-nav-list > .mdl-nav-item > .mdl-nav-link{
  display:inline-flex;align-items:center;gap:.6rem;height:100%;
  font-weight:500;font-size:1.52rem;line-height:1;
  text-decoration:none;
  transition:color .2s;
}
.mdl-nav .mdl-nav-btn:hover,
.mdl-nav .mdl-nav-list > .mdl-nav-item > .mdl-nav-link:hover{color:var(--mdl-blue-deep)}

/* Le chevron, dessiné sur la grille de 24 de la maison. Il pivote à l'ouverture, comme
   celui de `.mdl-pick-btn`. */
.mdl-nav .mdl-nav-chev{
  width:1.44rem;height:1.44rem;flex:none;
  color:var(--mdl-blue);
  transition:transform .25s var(--mdl-ease);
}
.mdl-nav .mdl-nav-btn[aria-expanded="true"] .mdl-nav-chev{transform:rotate(180deg)}

/* ------------------------------------------------------ le deuxième niveau, le tiroir */

.mdl-nav .mdl-nav-item .mdl-nav-sub{
  display:none;
  /* Le `gap:3.6rem` de `.mdl-top nav ul` espace les entrées de la barre ; hérité tel
     quel, il écarterait les lignes du tiroir de dix-huit fois ce qu'il leur faut. */
  gap:.2rem;
  position:absolute;top:100%;z-index:6;
  /* Le rembourrage du panneau plus celui du lien : le premier libellé du tiroir tombe
     à l'aplomb du libellé du bouton. */
  left:-2.08rem;
  min-width:24rem;
  padding:.72rem;
  background:var(--mdl-paper);
  border-radius:.85rem;
  /* L'ombre douce de `.mdl-pick-list`, reprise au caractère près pour que les deux
     panneaux de la maison soient le même objet — sa seconde couche EST le filet de
     1 px en `--mdl-tint-2`. */
  box-shadow:0 24px 48px -12px rgba(16,33,44,.25),0 0 0 1px var(--mdl-tint-2);
}

.mdl-nav .mdl-nav-item.mdl-nav-ouvert .mdl-nav-sub{
  display:grid;
  animation:mdl-nav-drop .18s var(--mdl-ease);
}

/* La même apparition courte que la liste du sélecteur de grandeur. */
@keyframes mdl-nav-drop{from{opacity:0;transform:translateY(-.56rem) scale(.985)}}

.mdl-nav .mdl-nav-sub .mdl-nav-link{
  display:block;
  padding:1.2rem 1.36rem;
  border-radius:.88rem;
  font-size:1.52rem;font-weight:500;line-height:1.3;
  white-space:nowrap;
  text-decoration:none;
  transition:background .2s,color .2s;
}
.mdl-nav .mdl-nav-sub .mdl-nav-link:hover{background:var(--mdl-tint);color:var(--mdl-blue-deep)}

/* ---------------------------------------------------------------- la page affichée */

/* Un repère discret, le même aux deux niveaux : le texte passe au bleu profond et
   l'ambre de la maison souligne l'entrée. `aria-current="page"`, posé par le PHP quand
   l'adresse de l'entrée est celle de la page, dit le reste aux lecteurs d'écran.
   Placé après les règles de tiroir, qui ont la même spécificité. */
.mdl-nav .mdl-nav-link[aria-current="page"]{
  color:var(--mdl-blue-deep);
  text-decoration:underline;
  text-decoration-color:var(--mdl-amber);
  text-decoration-thickness:.2rem;
  text-underline-offset:.5em;
}

/* La section courante, quand c'est un enfant du tiroir qui est affiché. Le bouton ne
   prend pas `aria-current` : il n'est pas la page, il la contient. */
.mdl-nav .mdl-nav-item.mdl-nav-actif > .mdl-nav-btn{color:var(--mdl-blue-deep)}

/* ------------------------------------------------------------ le repli sans script */

/* Tant que modulo-nav.js n'a pas pris la main — script bloqué, canevas du constructeur,
   ou simplement pas encore exécuté — le survol et le focus ouvrent quand même : les
   entrées parentes sont des boutons sans destination, sans quoi le deuxième niveau
   serait injoignable. Le script pose `mdl-nav-js` et reprend seul la responsabilité de
   l'ouverture, pour qu'un clic qui ferme ne soit pas contredit par un survol qui dure. */
.mdl-nav:not(.mdl-nav-js) .mdl-nav-item:focus-within .mdl-nav-sub{
  display:grid;
  animation:mdl-nav-drop .18s var(--mdl-ease);
}
.mdl-nav:not(.mdl-nav-js) .mdl-nav-item:focus-within .mdl-nav-chev{transform:rotate(180deg)}

@media (hover:hover){
  .mdl-nav:not(.mdl-nav-js) .mdl-nav-item:hover .mdl-nav-sub{
    display:grid;
    animation:mdl-nav-drop .18s var(--mdl-ease);
  }
  .mdl-nav:not(.mdl-nav-js) .mdl-nav-item:hover .mdl-nav-chev{transform:rotate(180deg)}
}

/* -------------------------------------------------------------- la barre resserrée */

/* Entre 769 et 1024 px, la barre est chargée : logo, trois entrées, téléphone et bouton
   sur une seule ligne. On rend au menu la place qu'on peut sans toucher au reste de
   l'en-tête, qui ne nous appartient pas. */
@media (max-width:1024px){
  .mdl-nav .mdl-nav-list{gap:2.4rem}
  .mdl-nav .mdl-nav-btn,
  .mdl-nav .mdl-nav-list > .mdl-nav-item > .mdl-nav-link{font-size:1.44rem}
}

/* ------------------------------------------------------- le panneau du hamburger */

/* Sous 768 px, la navigation est le panneau que déplie `.mdl-top.mdl-open nav`. Il
   montre TOUT : les tiroirs sont dépliés et décalés, il n'y a plus rien à basculer.
   modulo-nav.js laisse alors `aria-expanded="true"` sur les boutons, qui ne sont plus
   que les intitulés de leurs listes — d'où le curseur ordinaire et le chevron retiré. */
@media (max-width:768px){
  .mdl-nav .mdl-nav-list{height:auto}

  .mdl-nav .mdl-nav-btn,
  .mdl-nav .mdl-nav-list > .mdl-nav-item > .mdl-nav-link{height:auto;font-size:2rem}

  .mdl-nav .mdl-nav-btn{cursor:default}

  .mdl-nav .mdl-nav-chev{display:none}

  .mdl-nav .mdl-nav-item .mdl-nav-sub{
    display:grid;gap:.4rem;
    position:static;z-index:auto;
    min-width:0;
    margin-top:1.2rem;
    padding:0 0 0 1.6rem;
    /* Le décalage se lit : un filet part de l'intitulé et court le long de sa liste. */
    border-left:.1rem solid var(--mdl-tint-2);
    background:none;
    border-radius:0;
    box-shadow:none;
    animation:none;
  }

  .mdl-nav .mdl-nav-sub .mdl-nav-link{
    padding:.8rem 0;
    border-radius:0;
    font-size:1.7rem;
    white-space:normal;
  }

  /* Le téléphone au pied du panneau (elements/modulo-header.php). Séparé des pages
     par un filet : ce n'est pas une destination, c'est un appel. Le combiné reprend
     le pictogramme de « Nous trouver », en bleu comme là-bas. */
  .mdl-nav .mdl-nav-tel{
    display:flex;align-items:center;gap:1.2rem;
    margin-top:2.4rem;padding-top:2.4rem;
    border-top:1px solid var(--mdl-tint-2);
    font-size:2rem;font-weight:600;white-space:nowrap;
  }
  .mdl-nav .mdl-nav-tel svg{width:2.4rem;height:2.4rem;flex:none;color:var(--mdl-blue)}
}

/* Au-dessus du point de bascule, la barre affiche déjà `.mdl-tel` : le double reste caché. */
@media (min-width:769px){
  .mdl-nav .mdl-nav-tel{display:none}
}

/* ═══ prose.css ═══ */
/* ─────────────────────────────────────────────────────────────────────────────
   modulo-prose — le texte long
   Élément : elements/modulo-prose.php

   Rappel de la maison : `html{font-size:62.5%}` (Bricks), donc 1 rem = 10 px.
   Aucune valeur en px, aucune couleur hors des variables --mdl-*.

   Une seule mesure de lecture, 68ch, portée par le conteneur du corps : titres,
   paragraphes et listes s'y alignent tous. Le rythme vertical est réglé par quatre
   règles dont l'ordre compte (voir plus bas), pas par des marges sur chaque balise.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── mise en page large : le registre de `modulo-inclus` ─────────────────────── */

.mdl-prose .mdl-wrap {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: 4.8rem 8rem;
  /* Sans `start`, les deux colonnes s'étirent sur la hauteur de la rangée et le
     titre n'a plus de place pour coller. */
  align-items: start;
}

/* Le titre suit la lecture, comme le panneau du sélecteur de la page d'accueil.
   8rem : la hauteur de l'en-tête collant (`.mdl-top .mdl-wrap{min-height:8rem}`) ;
   3.2rem : la respiration en dessous, la même que `.mdl-panel{top:11.2rem}`. */
.mdl-prose .mdl-prose-titre {
  position: sticky;
  top: calc(8rem + 3.2rem);
  max-width: 16ch;
}

/* Le corps est épinglé sur la deuxième piste. Sans titre, la première reste vide et
   la mesure du texte tombe au même endroit d'une section à l'autre — le PHP n'a donc
   pas de colonne fantôme à écrire. */
.mdl-prose .mdl-prose-corps {
  grid-column: 2;
  max-width: 68ch;
  /* Un cran au-dessus du 1,7 rem de la maison : un document de 4 000 signes se lit
     mieux un peu plus grand, et un peu plus aéré. */
  font-size: 1.8rem;
  line-height: 1.7;
  color: var(--mdl-ink);
}

/* ── mise en page étroite : un document qui se lit d'un bout à l'autre ───────── */

/* Les deux classes sont sur la même racine : `.mdl-prose.mdl-prose-etroit` passe
   devant `.mdl-prose` quel que soit l'ordre des règles. */
.mdl-prose.mdl-prose-etroit .mdl-wrap {
  display: block;
}

/* La mesure de lecture se prend sur le CONTENU, pas sur `.mdl-wrap`.
   Resserrer le conteneur lui-même donnerait une section plus étroite que ses voisines
   et un bord gauche qui rentre au milieu de la page — c'est précisément ce que le
   client a reproché à la ronde 3 (« les conteneurs ne font pas tous la même largeur »).
   Le conteneur garde donc ses 1440 px et son bord ; seule la colonne de texte est
   bornée, et elle reste calée à gauche pour que le bord tienne du haut en bas. */
.mdl-prose.mdl-prose-etroit .mdl-prose-titre,
.mdl-prose.mdl-prose-etroit .mdl-prose-corps {
  max-width: 68ch;
  margin-inline: 0;
}

.mdl-prose.mdl-prose-etroit .mdl-prose-titre {
  position: static;
  /* Le titre couronne le document : il reprend toute la mesure. */
  max-width: none;
  margin-bottom: clamp(2.4rem, 3vw, 4rem);
}

.mdl-prose.mdl-prose-etroit .mdl-prose-corps {
  grid-column: auto;
}

/* ── le rythme vertical ─────────────────────────────────────────────────────── */

/* L'ordre de ces quatre règles est délibéré : à spécificité égale, la dernière
   l'emporte. `> h3 + *` vient AVANT `> h3` pour que deux sous-titres qui se suivent
   gardent le grand écart, tandis qu'un paragraphe qui suit un sous-titre prend le
   petit. `:first-child` passe devant tout le monde et remet la marge à zéro. */

.mdl-prose .mdl-prose-corps > * + * {
  margin-top: 2rem;
}

.mdl-prose .mdl-prose-corps > h3 + * {
  margin-top: 1.6rem;
}

.mdl-prose .mdl-prose-corps > h3 {
  margin-top: clamp(4rem, 4.4vw, 6.4rem);
}

.mdl-prose .mdl-prose-corps > :first-child {
  margin-top: 0;
}

/* ── les blocs ──────────────────────────────────────────────────────────────── */

.mdl-prose .mdl-prose-corps h3 {
  /* La graisse et le crénage de la maison (`:where(.mdl) h3`), redits ici parce que
     le corps de la prose est un cran plus grand et que le titre le suit. */
  font-size: 2.4rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  color: var(--mdl-ink);
  text-wrap: balance;
}

/* `:where(.mdl) p{max-width:62ch}` couperait les paragraphes six caractères avant
   les sous-titres et les listes, qui suivent la mesure du conteneur. Une seule
   mesure pour tout le document : celle du bloc. */
.mdl-prose .mdl-prose-corps p {
  max-width: none;
  text-wrap: pretty;
}

/* La remise à zéro de la maison (`:where(.mdl) *{padding:0}`) laisserait les puces
   natives déborder du bloc : on les redessine, alignées sur la première ligne. */
.mdl-prose .mdl-prose-corps ul {
  list-style: none;
}

.mdl-prose .mdl-prose-corps li {
  position: relative;
  padding-inline-start: 2.4rem;
  text-wrap: pretty;
}

.mdl-prose .mdl-prose-corps li + li {
  margin-top: 0.8rem;
}

.mdl-prose .mdl-prose-corps li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  /* 1.7em = la hauteur de ligne du corps : la moitié tombe sur le milieu de la
     première ligne, quel que soit le nombre de lignes de la puce. */
  top: calc(1.7em / 2);
  transform: translateY(-50%);
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--mdl-blue);
}

/* ── petits écrans ──────────────────────────────────────────────────────────── */

/* 64em = 1024 px : le point de rupture où `modulo.css` replie déjà le même registre
   (`.mdl-inclus .mdl-wrap`). Dans une requête média, `em` vaut la taille de police
   initiale (16 px) et non le 10 px de `html{font-size:62.5%}`. */
@media (max-width: 64em) {
  .mdl-prose .mdl-wrap {
    grid-template-columns: 1fr;
  }

  .mdl-prose .mdl-prose-titre {
    /* Plus rien à côté de quoi coller. */
    position: static;
    max-width: 24ch;
  }

  .mdl-prose .mdl-prose-corps {
    /* Sans cela, `grid-column:2` créerait une deuxième piste implicite et le texte
       sortirait de la seule colonne déclarée. */
    grid-column: auto;
  }
}

/* ═══ tarifs.css ═══ */
/* modulo-tarifs — la grille des grandeurs et des prix.
 *
 * Ne style que `.mdl-tarifs` et ses descendants : tools/build-css.php recolle les
 * morceaux dans l'ordre alphabétique, et deux morceaux qui se disputent un sélecteur
 * seraient un défaut, pas un réglage.
 *
 * 1 rem = 10 px — Bricks pose `html{font-size:62.5%}`. Aucune valeur en px hors des
 * filets d'un pixel et des paliers de media query, comme dans assets/css/modulo.css.
 */

.mdl-tarifs {
	/* L'ambre foncé du montant. modulo.css l'écrit en clair dans `.mdl-plate .mdl-price b`
	 * et `.mdl-badge-big` sans jamais le publier en variable, et cette feuille-là ne
	 * m'appartient pas : on le nomme donc ici, une fois, plutôt que de le répéter. */
	--mdl-tarifs-prix: #CC8200;
}

/* ------------------------------------------------------------ titre et accroche */

.mdl-tarifs h2 {
	max-width: 18ch;
}

.mdl-tarifs .mdl-lead {
	margin-top: 1.6rem;
	max-width: 56ch;
}

/* ------------------------------------------------------------------ les groupes */

.mdl-tarifs .mdl-groupe {
	margin-top: clamp(4.8rem, 5vw, 7.2rem);
}

/* Sans titre ni accroche, le premier groupe ouvre la section : le padding vertical de
   `section:where(.mdl)` suffit alors, l'écart d'entre-groupes ferait double emploi. */
.mdl-tarifs .mdl-wrap > :first-child {
	margin-top: 0;
}

.mdl-tarifs .mdl-groupe > h3 {
	margin-bottom: clamp(2.4rem, 2.4vw, 3.2rem);
	font-size: clamp(2.2rem, 1.8vw, 2.6rem);
	letter-spacing: -.02em;
}

/* -------------------------------------------------------------------- la grille */

.mdl-tarifs .mdl-grille {
	list-style: none;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(2rem, 2.4vw, 3.2rem);
}

/* Les paliers de la SPEC se disent « à partir de » : `min-width` les écrit tels quels,
   sans le pixel d'écart qu'introduirait un `max-width` à la borne. */
@media (min-width: 700px) {
	.mdl-tarifs .mdl-grille {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1100px) {
	.mdl-tarifs .mdl-grille {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* --------------------------------------------------------------------- la carte */

.mdl-tarifs .mdl-carte {
	display: flex;
	flex-direction: column;
	background: var(--mdl-paper);
	border-radius: var(--mdl-r);
	padding: clamp(2rem, 2.2vw, 2.8rem);
}

/* Sur fond teinté, la carte blanche ressort d'elle-même. Sur fond blanc, elle flotte :
   un filet interne la pose. La teinte est déjà l'interrupteur — pas besoin d'une classe
   de plus. Filet INTERNE (`inset`) et non bordure : une bordure agrandirait la boîte et
   décalerait les cartes entre elles. */
.mdl-tarifs:not(.mdl-tinted) .mdl-carte {
	box-shadow: inset 0 0 0 1.5px var(--mdl-tint-2);
}

/* ----------------------------------------------------------------------- le plan */

.mdl-tarifs .mdl-plan {
	aspect-ratio: 16 / 10;
	display: grid;
	place-items: center;
	/* RONDE 7 — 1,2 rem d'air ne suffisaient pas : les grands plans (16 × 12, 25 × 12)
	   venaient toucher le bord, et leur dalle grise passait sous le coin arrondi du
	   cadre. On lit alors une image qui déborde, et c'est ce que le client a signalé.
	   2,4 rem laissent à chaque plan la même marge, du 10 × 5 au 25 × 12. */
	padding: 2.4rem;
	margin-bottom: 2.4rem;
	background: var(--mdl-tint);
	/* Rayon plus serré que celui de la carte : à rayon égal, un coin intérieur paraît
	   plus rond que celui qui l'entoure. */
	border-radius: 1.2rem;
	/* Le format est une CONSIGNE, pas un souhait : sans cela un plan trop haut allonge
	   la boîte et les cadres de la rangée ne font plus la même hauteur. */
	overflow: hidden;
}

/* Le cadre tient son format tout seul : une unité sans plan garde sa place et la carte
   reste alignée sur ses voisines.

   `min-width:0; min-height:0` n'est pas une précaution de style, c'est ce qui fait
   tenir le `max-height:100%`. La taille minimale automatique d'un élément de grille
   vaut sa taille intrinsèque : le plan du 16 × 12 (247 px de haut) refusait donc de
   descendre sous 247 px, poussait le cadre de 228 à 271 px et annulait
   l'`aspect-ratio` au passage. Remis à zéro, l'image se plie enfin à sa boîte. */
/* RONDE 8 — les plans sont stockés à DENSITÉ DOUBLE (elements/base.php, plan_tag).
   `width` et `height` restent à `auto` — c'est ce qui laisse le navigateur recalculer
   une dimension quand l'autre est rognée, donc ce qui garde les proportions — et la
   taille voulue arrive par `--mdl-plan-w`, posée sur le <img> par plan_tag et lue ici
   comme un PLAFOND. Sans ce plafond, la taille naturelle serait le double et les huit
   plans rempliraient tous leur cadre : le guide des grandeurs ne montrerait plus
   aucune grandeur. Le repli `100%` couvre un plan dont la variable manque. */
.mdl-tarifs .mdl-plan img {
	width: auto;
	height: auto;
	min-width: 0;
	min-height: 0;
	max-width: min(100%, var(--mdl-plan-w, 100%));
	max-height: 100%;
	object-fit: contain;
}

/* -------------------------------------------------------- grandeur et superficie */

/* Bricks impose à `h4` une taille (1.6em), une hauteur de ligne (1.4) et une marge :
   on redit tout ce qui compte, à une spécificité qui le dépasse (0,2,0 contre 0,0,1). */
.mdl-tarifs .mdl-dim {
	margin: 0;
	font-size: clamp(2.4rem, 2.6vw, 3.2rem);
	font-weight: 600;
	letter-spacing: -.03em;
	line-height: 1.05;
}

.mdl-tarifs .mdl-area {
	margin-top: .56rem;
	font-size: 1.6rem;
	color: var(--mdl-ink-2);
}

.mdl-tarifs .mdl-fits {
	margin-top: 1.6rem;
	font-size: 1.6rem;
	line-height: 1.55;
}

/* ------------------------------------------------------- le pied : prix et bouton */

/* `margin-top:auto` colle le pied au bas de la carte. Les cartes d'une rangée ont la
   même hauteur (comportement par défaut de la grille), donc les prix et les boutons
   s'alignent d'une carte à l'autre même quand les textes n'ont pas la même longueur. */
.mdl-tarifs .mdl-pied {
	margin-top: auto;
	padding-top: 2.4rem;
	border-top: 1px solid var(--mdl-tint-2);
	display: flex;
	flex-wrap: wrap;
	align-items: end;
	justify-content: space-between;
	gap: 1.6rem;
}

.mdl-tarifs .mdl-prix {
	margin: 0;
}

/* Bricks pose `small{font-size:80%}` : on fixe la taille plutôt que d'hériter d'un
   pourcentage qui suivrait la taille du parent. */
.mdl-tarifs .mdl-prix small {
	display: block;
	margin-bottom: .4rem;
	font-size: 1.44rem;
	color: var(--mdl-ink-2);
}

.mdl-tarifs .mdl-prix b {
	display: block;
	font-size: clamp(2.4rem, 2.4vw, 3rem);
	font-weight: 600;
	letter-spacing: -.03em;
	line-height: 1;
	color: var(--mdl-tarifs-prix);
}

/* « /mois » garde la TAILLE du montant : l'ambre foncé donne 3,1:1 sur le blanc de la
   carte, un rapport qui n'atteint le AA qu'au régime « grand texte » des WCAG, soit
   24 px — le plancher du clamp ci-dessus. Le rapetisser le ferait passer sous le seuil.
   C'est donc la graisse, et non la taille, qui fait la hiérarchie. */
.mdl-tarifs .mdl-prix b span {
	font-weight: 500;
	letter-spacing: -.01em;
}

/* Le bouton d'une carte est plus court que celui d'une bande : mêmes proportions que
   celui de l'en-tête, qui vit dans la même étroitesse. */
.mdl-tarifs .mdl-pied .mdl-btn {
	padding: 1.28rem 2rem;
	font-size: 1.52rem;
}
