@charset "UTF-8";
/* =========================================================
   SOLTECH Construction Inc.
   Design system unique du site (public/css/style.css).
   Reference : DA-SOLTECH.md + CONTRACT.md.
   Aucun preprocesseur, aucun import, aucune dependance.
   Regle d'ecriture : aucun tiret cadratin ni demi-cadratin,
   nulle part, y compris dans les commentaires.
   ========================================================= */

/* =========================================================
   1. TOKENS
   Bloc :root recopie tel quel de DA-SOLTECH.md, section 7.
   Les tokens ajoutes en fin de bloc sont des complements,
   aucune valeur d'origine n'a ete modifiee ni retiree.
   ========================================================= */
:root {
  /* Couleurs */
  --c-sable: #FAF6EF;
  --c-sable-fonce: #F2EADC;
  --c-blanc: #FFFFFF;
  --c-bordeaux: #A6301F;
  --c-bordeaux-fonce: #82230F;
  --c-bordeaux-voile: rgba(166, 48, 31, 0.08);
  --c-bordeaux-55: rgba(166, 48, 31, 0.55);
  --c-bordeaux-78: rgba(166, 48, 31, 0.78);
  --c-ocre: #DC9418;
  --c-ocre-voile: rgba(220, 148, 24, 0.12);
  --c-ocre-bord: rgba(220, 148, 24, 0.35);
  --c-beton: #6E6357;
  --c-beton-clair: #8D8478;
  --c-vert: #1F7A40;
  --c-vert-voile: rgba(31, 122, 64, 0.10);
  --c-encre: #1C1813;
  --c-texte: #2A2520;
  --c-texte-doux: #5C544A;
  --c-ligne: #E8DECD;
  --c-alerte: #B8321C;

  /* Typo */
  --ff-titre: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ff-body: 'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Espacement */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --sp-9: 96px;
  --sp-10: 128px;

  /* Layout */
  /* 1120 plutot que 1200 : la mesure de lecture (62 rem, soit 992 px) et la
     pleine largeur de grille ne different alors plus que de 64 px, ce qui se
     lit comme un seul bord et non comme deux. La page est aussi plus dense. */
  --max-w: 1120px;
  /* Mesure de lecture.
     EN REM, PAS EN CH : l'unite ch est relative a la taille de police de
     l'element qui la porte. Avec 68ch, un paragraphe a 17 px faisait 554 px,
     un .lead a 20 px en faisait 647 et un titre encore autre chose. La colonne
     avait donc quatre bords droits differents et paraissait cassee.
     En rem, tous les blocs de texte partagent exactement le meme bord. */
  --max-w-text: 44rem;
  /* Largeur des blocs qui gagnent a respirer sans aller au bord : tableaux,
     FAQ, encadres. Deuxieme et DERNIERE largeur du systeme, avec la pleine
     largeur de grille. */
  --max-w-lecture: 62rem;
  --gutter: clamp(16px, 4vw, 32px);
  --header-h: 76px;

  /* Rayons */
  --r-sm: 4px;
  --r-md: 8px;
  --r-lg: 14px;
  --r-xl: 22px;
  --r-pill: 999px;

  /* Transitions */
  --t-fast: 140ms ease-out;
  --t-base: 240ms ease-out;
  --t-slow: 420ms ease-out;

  /* Ombres, discretes et chaudes */
  --sh-sm: 0 1px 2px rgba(28, 24, 19, 0.06);
  --sh-card: 0 6px 22px rgba(28, 24, 19, 0.07);
  --sh-lift: 0 14px 34px rgba(28, 24, 19, 0.12);

  /* Signature */
  --filet-h: 3px;
  --filet-w: 56px;

  /* ---- Complements Umbeli (ajouts, aucune valeur DA touchee) ---- */

  /* Voiles utilitaires derives de la palette */
  --c-sable-voile: rgba(250, 246, 239, 0.92);
  --c-ocre-halo: rgba(220, 148, 24, 0.30);
  --c-ocre-fonce: #A66E0D;
  --c-alerte-voile: rgba(176, 58, 46, 0.08);
  --c-alerte-bord: rgba(176, 58, 46, 0.38);
  --c-encre-voile: rgba(28, 24, 19, 0.06);

  /* Textes et filets sur fond fonce (beton, encre, heros) */
  --c-sur-fonce: #FFFFFF;
  --c-sur-fonce-doux: rgba(255, 255, 255, 0.80);
  --c-sur-fonce-faible: rgba(255, 255, 255, 0.62);
  --c-sur-fonce-ligne: rgba(255, 255, 255, 0.16);
  --c-sur-fonce-voile: rgba(255, 255, 255, 0.10);

  /* Rythme vertical des sections */
  /* Resserre : 112 px en haut ET en bas donnaient 224 px entre deux blocs de
     contenu, ce qui delaye la page et oblige a beaucoup defiler. */
  --sp-section: clamp(48px, 5.5vw, 84px);
  --sp-section-court: clamp(36px, 4vw, 60px);
  --gap-grille: clamp(16px, 2.4vw, 28px);

  /* Hauteurs de frappe */
  --tap-min: 44px;
  --tap-btn: 48px;

  /* Plans de superposition */
  --z-header: 200;
  --z-tiroir: 300;
  --z-barre: 400;

  /* Image de heros par defaut, surchargee par style="--hero-img:url(...)" */
  --hero-img: none;
}

/* =========================================================
   2. RESET ET BASE
   ========================================================= */
*,
*::before,
*::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Les ancres ne passent pas sous l'en-tete colle */
  scroll-padding-top: calc(var(--header-h) + var(--filet-h) + 16px);
}
body {
  margin: 0;
  padding-top: var(--filet-h); /* place reservee a la barre ocre de signature */
  font-family: var(--ff-body);
  font-size: clamp(1rem, 0.97rem + 0.14vw, 1.0625rem);
  font-weight: 400;
  line-height: 1.68;
  color: var(--c-texte);
  background: var(--c-sable);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Filet de securite seulement : chaque composant tient deja seul. */
  overflow-x: hidden;
}

/* Blocage du defilement quand le tiroir mobile est ouvert */
body.is-open { overflow: hidden; }
img,
svg,
video,
canvas,
picture {
  display: block;
  max-width: 100%;
  height: auto;
}
img {
  border-style: none;
  /* Le fond sable n'est qu'un espace reserve pendant le chargement des
     photos. Une illustration SVG transparente, elle, doit rester
     transparente : la coupe du heros flotte sur la photo de fond, un panneau
     opaque derriere elle alourdirait toute la moitie droite. */
  background-color: var(--c-sable-fonce);
}
img[src$=".svg"] { background-color: transparent; }
svg { background-color: transparent; }
a {
  color: var(--c-bordeaux);
  text-decoration: none;
}
a:hover { color: var(--c-bordeaux-fonce); }
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  margin: 0;
}
button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: inherit;
}
ul,
ol {
  margin: 0 0 var(--sp-5);
  padding-left: 22px;
}
li { margin-bottom: var(--sp-2); }
li:last-child { margin-bottom: 0; }
figure { margin: 0; }
hr {
  border: 0;
  border-top: 1px solid var(--c-ligne);
  margin: var(--sp-6) 0;
}
table {
  border-collapse: collapse;
  width: 100%;
  max-width: 100%;
}
th,
td {
  text-align: left;
  vertical-align: top;
}
strong,
b {
  font-weight: 600;
  color: var(--c-texte);
}
small { font-size: 0.85em; }
abbr[title] {
  text-decoration: none;
  border-bottom: 1px dotted var(--c-texte-doux);
  cursor: help;
}
address { font-style: normal; }

/* Focus visible global, ocre, conforme a la DA section 5.1 */
:focus-visible {
  outline: 3px solid var(--c-ocre);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* Les navigateurs qui ne connaissent pas :focus-visible gardent un focus net */
:focus:not(:focus-visible) { outline: none; }
::selection {
  background: var(--c-bordeaux);
  color: var(--c-blanc);
}

/* Lien d'evitement, visible seulement au clavier */
.skip-link {
  position: absolute;
  top: -120px;
  left: var(--sp-4);
  z-index: calc(var(--z-barre) + 10);
  display: inline-block;
  padding: 12px 20px;
  background: var(--c-bordeaux);
  color: var(--c-blanc);
  font-family: var(--ff-titre);
  font-weight: 700;
  font-size: 0.9rem;
  border-radius: var(--r-md);
  box-shadow: var(--sh-lift);
  transition: top var(--t-fast);
}
.skip-link:focus {
  top: calc(var(--filet-h) + 12px);
  color: var(--c-blanc);
}

/* Utilitaire d'accessibilite : lisible par les lecteurs d'ecran seulement */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* =========================================================
   3. TYPOGRAPHIE
   Echelle fluide integrale, aucune media query necessaire.
   ========================================================= */
h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--ff-titre);
  font-weight: 700;
  color: var(--c-texte);
  margin: 0 0 var(--sp-4);
  /* balance repartit les lignes d'un titre court de facon plus reguliere.
     On autorise la coupure seulement en dernier recours : sans cette limite,
     un toponyme a trait d'union comme Saint-Maurice se coupe en deux. */
  text-wrap: balance;
  overflow-wrap: break-word;
  hyphens: manual;
}
h1 {
  font-size: clamp(2.1rem, 1.35rem + 3.2vw, 3.8rem);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.02em;
}
h2 {
  font-size: clamp(1.7rem, 1.25rem + 1.9vw, 2.6rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
}
h3 {
  font-size: clamp(1.25rem, 1.08rem + 0.75vw, 1.6rem);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.01em;
}
h4 {
  font-size: clamp(1.05rem, 0.99rem + 0.28vw, 1.2rem);
  font-weight: 600;
  line-height: 1.35;
}
h5,
h6 {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.4;
}
p { margin: 0 0 var(--sp-4); }
p:last-child { margin-bottom: 0; }
.lead {
  font-size: clamp(1.08rem, 1.01rem + 0.34vw, 1.25rem);
  line-height: 1.6;
  color: var(--c-texte-doux);
  max-width: var(--max-w-text);
  margin-bottom: var(--sp-5);
}
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--ff-titre);
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-bordeaux);
  margin: 0 0 var(--sp-3);
}
.eyebrow::before {
  content: '';
  display: inline-block;
  width: 26px;
  height: var(--filet-h);
  border-radius: 2px;
  background: var(--c-ocre);
  flex-shrink: 0;
}

/* Titre de section : filet ocre de signature (DA section 4) */
.section-title { margin-bottom: var(--sp-5); }
.section-title::after {
  content: '';
  display: block;
  width: var(--filet-w);
  height: var(--filet-h);
  border-radius: 2px;
  background: var(--c-ocre);
  margin-top: 18px;
}

/* ---- Texte suivi ---- */
.prose {
  max-width: var(--max-w-text);
  /* Les URL, courriels et mots techniques ne debordent jamais */
  overflow-wrap: anywhere;
  word-break: normal;
}
.prose > * + * { margin-top: var(--sp-4); }
.prose h2 {
  margin-top: var(--sp-7);
  margin-bottom: var(--sp-3);
}
.prose h3 {
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-3);
}
.prose h4 {
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-2);
}
.prose > h2:first-child,
.prose > h3:first-child { margin-top: 0; }
.prose ul,
.prose ol {
  padding-left: 22px;
  margin-bottom: var(--sp-4);
}
.prose ul {
  list-style: none;
  padding-left: 0;
}
.prose ul li {
  position: relative;
  padding-left: 24px;
}
.prose ul li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 0.72em;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--c-ocre);
}
.prose ol li::marker {
  color: var(--c-bordeaux);
  font-weight: 600;
}
.prose a {
  color: var(--c-bordeaux);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  text-decoration-color: var(--c-ocre-bord);
  overflow-wrap: anywhere;
  transition: color var(--t-fast), text-decoration-color var(--t-fast);
}
.prose a:hover {
  color: var(--c-bordeaux-fonce);
  text-decoration-color: var(--c-ocre);
}
.prose blockquote {
  margin: var(--sp-5) 0;
  padding: var(--sp-4) var(--sp-5);
  border-left: var(--filet-h) solid var(--c-ocre);
  background: var(--c-sable-fonce);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  color: var(--c-texte-doux);
  font-size: 1.02em;
}
.prose blockquote p:last-child { margin-bottom: 0; }
.prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  background: var(--c-encre-voile);
  color: var(--c-bordeaux-fonce);
  overflow-wrap: anywhere;
}
.prose pre {
  overflow-x: auto;
  padding: var(--sp-4);
  border-radius: var(--r-md);
  background: var(--c-encre);
  color: var(--c-sable);
  max-width: 100%;
}
.prose pre code {
  background: none;
  color: inherit;
  padding: 0;
}
.prose img {
  border-radius: var(--r-md);
  margin: var(--sp-5) 0;
}
.prose hr { margin: var(--sp-6) 0; }

/* Les courriels et telephones ne cassent jamais la mise en page */
a[href^="mailto:"],
a[href^="tel:"] { overflow-wrap: anywhere; }

/*
  Filet de securite contre les debordements horizontaux.

  Le piege reel rencontre en test : un conteneur en display flex donne a son
  texte brut un element anonyme dont le min-width vaut auto. Cet element refuse
  alors de descendre sous sa largeur min-content, et un seul mot long, une
  adresse courriel par exemple, pousse la page entiere a deborder sur un
  telephone de 320 px. Ni min-width: 0 sur le parent ni overflow-wrap sur le
  lien ne suffisent : on ne peut pas viser un element anonyme en CSS.

  overflow-wrap: anywhere, lui, reduit bien le min-content : le mot casse au
  lieu de deborder. C'est la seule declaration qui corrige le cas. Elle ne
  coupe un mot que lorsqu'il ne rentre pas, donc aucun effet sur du texte
  normal.

  Les elements en white-space: nowrap (boutons, liens de navigation) ne sont
  pas affectes, nowrap l'emporte.
*/
p,
li,
dd,
dt,
td,
th,
label,
legend,
figcaption,
blockquote,
.lead,
.note,
.card-meta,
.compare-caption,
.form-help,
.stat__label { overflow-wrap: anywhere; }

/* =========================================================
   4. SIGNATURE : barre ocre de 3 px en haut de la fenetre
   Rendue par body::before, aucun balisage a ecrire.
   ========================================================= */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--filet-h);
  background: var(--c-ocre);
  z-index: var(--z-barre);
  pointer-events: none;
}

/* =========================================================
   5. LAYOUT
   ========================================================= */
.container {
  width: 100%;
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section {
  position: relative;
  padding-block: var(--sp-section);
}
.section--sable {
  background: var(--c-sable);
  color: var(--c-texte);
}
.section--blanc {
  background: var(--c-blanc);
  color: var(--c-texte);
}
.section--beton {
  background: var(--c-beton);
  color: var(--c-sur-fonce);
}
.section--encre {
  background: var(--c-encre);
  color: var(--c-sur-fonce-doux);
}

/* Textes et filets des sections foncees */
.section--beton h1,
.section--beton h2,
.section--beton h3,
.section--beton h4,
.section--encre h1,
.section--encre h2,
.section--encre h3,
.section--encre h4 { color: var(--c-sur-fonce); }
.section--beton .lead,
.section--encre .lead { color: var(--c-sur-fonce-doux); }
.section--beton .eyebrow,
.section--encre .eyebrow { color: var(--c-ocre); }
.section--beton strong,
.section--encre strong { color: var(--c-sur-fonce); }
.section--beton a,
.section--encre a { color: var(--c-ocre); }
.section--beton a:hover,
.section--encre a:hover { color: var(--c-blanc); }
.section-head .lead,
.section-head > p:not(.eyebrow) { max-width: var(--max-w-text); }
.section-head {
  /* Le titre a droit a plus de largeur que le corps de texte. Bride a la
     mesure de lecture, un titre de 3,8 rem cassait au milieu d'un toponyme
     (« La vallee du Saint- / Maurice »), ce qui se voit tout de suite.
     Le .lead a l'interieur reste, lui, a la mesure de lecture. */
  max-width: var(--max-w-lecture);
  margin-bottom: clamp(24px, 3vw, 36px);
}
.section-head > :last-child { margin-bottom: 0; }

/* ---- Grilles. Toujours minmax(0, 1fr) pour ne jamais deborder ---- */
.grid {
  display: grid;
  gap: var(--gap-grille);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
/* align-items: start convient a des colonnes de texte, pas a des cartes : les
   cartes d'une meme rangee finissaient a trois hauteurs differentes selon la
   longueur du resume, et leur bouton avec. Des qu'une grille contient une
   carte, ses elements reprennent la hauteur de la rangee.
   Un navigateur sans :has ignore la regle et retrouve l'ancien comportement,
   ce qui reste lisible. */
.grid:has(> .card),
.blog-list,
.gallery { align-items: stretch; }

.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Empilement vertical regulier */
.stack {
  display: grid;
  gap: var(--sp-5);
  align-content: start;
}

/* Tableaux larges : defilement horizontal contenu dans le bloc */
.table-wrap {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-md);
  background: var(--c-blanc);
}
.table-wrap table { min-width: 520px; }

/* =========================================================
   6. EN-TETE
   ========================================================= */
.site-header {
  position: sticky;
  top: var(--filet-h); /* la barre ocre reste visible au-dessus */
  z-index: var(--z-header);
  background: var(--c-sable-voile);
  -webkit-backdrop-filter: blur(10px) saturate(1.08);
  backdrop-filter: blur(10px) saturate(1.08);
  border-bottom: 1px solid var(--c-ligne);
}

/* Repli opaque si le flou d'arriere-plan n'est pas pris en charge */
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .site-header { background: var(--c-sable); }
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: var(--header-h);
}

/* ---- Marque ---- */
.brand {
  display: inline-flex;
  align-items: center;
  /* Cible tactile : 44 px de haut au minimum, meme quand le sous-titre
     passe sur une seule ligne courte. */
  min-height: var(--tap-min);
  gap: var(--sp-3);
  color: var(--c-texte);
  flex-shrink: 0;
  min-width: 0;
}
.brand:hover { color: var(--c-texte); }
/* La pastille porte le logo reel, un badge circulaire qui a son propre fond
   blanc : elle n'a donc plus de fond a elle. Sur l'encre du pied de page, un
   fin liseret sable detache le cercle du fond sans le denaturer. */
.brand-mark {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
}
.brand-mark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 50%;
}
.brand-name {
  display: block;
  font-family: var(--ff-titre);
  font-weight: 800;
  font-size: 1.05rem;
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: var(--c-texte);
  min-width: 0;
}
.brand-name small {
  display: block;
  font-family: var(--ff-body);
  /* Plancher a 12 px : en dessous, le sous-titre devient illisible sur un
     telephone et tombe sous le seuil de confort de lecture. */
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-texte-doux);
  margin-top: 3px;
}

/* ---- Navigation principale ---- */
.nav-main {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  min-width: 0;
}
.nav-main > ul {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-main > ul > li {
  margin: 0;
  position: relative;
}
/*
  Cible UNIQUEMENT les liens de premier niveau de la barre de navigation.

  Deux pieges evites par ce selecteur en enfants directs :
   - le bouton de soumission est un enfant direct de .nav-main, hors du <ul> :
     il n'est donc pas atteint, et garde son texte blanc et ses marges. Une
     version anterieure reglait ca par un :not(.btn), ce qui montait la
     specificite a 0,2,1 ;
   - a 0,2,1, la regle ecrasait aussi .submenu a (0,1,1) et imposait son
     « padding: 8px 0 » aux liens des sous-menus, qui se retrouvaient sans
     aucune marge horizontale, colles au bord du panneau.
  En visant « > ul > li > a », les liens de sous-menu, plus profonds, ne sont
  jamais concernes.
*/
.nav-main > ul > li > a {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--ff-body);
  font-size: 0.94rem;
  font-weight: 500;
  color: var(--c-texte);
  padding: 8px 0;
  position: relative;
  white-space: nowrap;
  transition: color var(--t-fast);
}
.nav-main > ul > li > a:hover { color: var(--c-bordeaux); }
.nav-main > ul > li > a[aria-current="page"] {
  color: var(--c-bordeaux);
  font-weight: 600;
}
.nav-main > ul > li > a[aria-current="page"]::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--filet-h);
  border-radius: 2px;
  background: var(--c-ocre);
}
.nav-main svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ---- Sous-menus : ouverts au survol ET au focus clavier ---- */
.has-submenu { position: relative; }
.has-submenu > a > svg { transition: transform var(--t-fast); }
.has-submenu:hover > a > svg,
.has-submenu:focus-within > a > svg { transform: rotate(180deg); }
.submenu {
  position: absolute;
  top: calc(100% + 10px);
  left: -14px;
  min-width: 274px;
  max-width: min(340px, calc(100vw - 2 * var(--gutter)));
  list-style: none;
  margin: 0;
  padding: 8px;
  display: grid;
  gap: 2px;
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-top: var(--filet-h) solid var(--c-ocre);
  border-radius: var(--r-md);
  box-shadow: var(--sh-lift);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--t-base), transform var(--t-base), visibility var(--t-base);
  z-index: 5;
}

/* Pont invisible pour que le menu ne se ferme pas dans l'ecart de 10 px */
.submenu::before {
  content: '';
  position: absolute;
  top: calc(-1 * var(--filet-h) - 10px);
  left: 0;
  right: 0;
  height: 13px;
}
.has-submenu:hover > .submenu,
.has-submenu:focus-within > .submenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.submenu li { margin: 0; }
.submenu a {
  display: block;
  width: 100%;
  padding: 11px 14px;
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--c-texte);
  border-radius: var(--r-sm);
  white-space: normal;
  transition: background var(--t-fast), color var(--t-fast);
}
.submenu a:hover {
  background: var(--c-bordeaux-voile);
  color: var(--c-bordeaux);
}
.submenu a[aria-current="page"] {
  background: var(--c-ocre-voile);
  color: var(--c-bordeaux);
  font-weight: 600;
}
.submenu a small {
  display: block;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--c-texte-doux);
  margin-top: 2px;
}
.submenu-divider {
  height: 1px;
  background: var(--c-ligne);
  margin: 6px 4px;
  list-style: none;
}

/* ---- Mega menu des services ----
   Le sous-menu simple listait huit services a plat. Avec les familles de
   services, la liste depassait la hauteur utile de l'ecran et ne disait plus
   rien de la structure de l'offre. Le mega menu la remplace par deux colonnes
   lues de gauche a droite :

     - a gauche, .megamenu__familles, la liste des familles. Une seule est
       active a la fois, celle que la souris survole ou que le clavier vient
       d'atteindre ;
     - a droite, .megamenu__panneaux, le detail de la famille active : titre,
       phrase de situation, sous services avec leur precision, puis un lien
       vers la page de la famille.

   Deux partis pris de mise en oeuvre :

     1. le panneau est ancre sur l'en-tete et non sur le <li>. La regle
        « .nav-main > ul > li » pose position: relative sur chaque entree de
        nav ; a 720 px de large, un panneau ancre sur l'entree « Services »
        sortait de la fenetre des 1080 px. On repasse donc CE li en static,
        le bloc englobant devient .site-header (elle est en sticky, donc
        positionnee), et le bord gauche du panneau se cale exactement sur
        celui du .container ;
     2. les panneaux sont EMPILES dans une seule cellule de grille, pas caches
        en display: none. La hauteur du mega menu est celle du panneau le plus
        haut, une fois pour toutes : elle ne saute plus d'un survol a l'autre.
        visibility: hidden sort quand meme les panneaux inactifs de l'ordre de
        tabulation, ce que opacity seul n'aurait pas fait.
*/

/* Specificite 0,2,2 : il faut battre « .nav-main > ul > li » (0,1,2) qui pose
   le position: relative commun a toutes les entrees de la barre. */
.nav-main > ul > li.has-megamenu { position: static; }
.has-megamenu > a > svg { transition: transform var(--t-fast); }
.has-megamenu:hover > a > svg,
.has-megamenu:focus-within > a > svg,
.has-megamenu > a[aria-expanded="true"] > svg { transform: rotate(180deg); }

.megamenu {
  position: absolute;
  /* 100 % vaut ici la hauteur de la boite de remplissage de l'en-tete : le
     panneau se pose juste sous le filet bas, pas dessus. */
  top: calc(100% + 1px);
  /* Bord gauche du .container : la moitie de la fenetre, moins la demi
     largeur de grille, plus la gouttiere. Le max() garde la gouttiere comme
     plancher quand la fenetre est plus etroite que la grille. */
  left: max(var(--gutter), calc(50% - var(--max-w) / 2 + var(--gutter)));
  width: min(720px, calc(100% - 2 * var(--gutter)));
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-top: var(--filet-h) solid var(--c-ocre);
  border-radius: var(--r-md);
  box-shadow: var(--sh-lift);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--t-base), transform var(--t-base), visibility var(--t-base);
  z-index: 5;
  /* Inerte au pointeur tant qu'il n'est pas ouvert. Sans cette ligne, le
     panneau garde visibility: visible pendant toute la duree du fondu de
     fermeture, puisque visibility fait partie de la transition et ne bascule
     qu'a la fin. Une souris qui quitte la nav et retraverse cette zone, large
     de 720 px par dessus le heros, entrait alors dans un descendant du <li> et
     relancait son mouseenter : le menu se rouvrait sans qu'on ait touche la
     navigation. Le pont ::before herite de cette regle, il faut donc la lever
     sur lui aussi a l'ouverture. */
  pointer-events: none;
}

/* Pont invisible : entre le bas du lien « Services » et le bas de l'en-tete il
   reste une vingtaine de pixels qui n'appartiennent pas au <li>. Sans ce pont,
   la souris qui descend vers le panneau quitte la zone de survol et le menu se
   referme. Meme dispositif que sur .submenu. */
.megamenu::before {
  content: '';
  position: absolute;
  top: -24px;
  left: 0;
  right: 0;
  height: 24px;
}
.has-megamenu:hover > .megamenu,
.has-megamenu:focus-within > .megamenu,
.has-megamenu.is-open > .megamenu,
.has-megamenu > a[aria-expanded="true"] + .megamenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}

/* ---- Colonne de gauche : les familles ---- */
.megamenu__familles {
  list-style: none;
  margin: 0;
  padding: var(--sp-2);
  display: grid;
  gap: 2px;
  align-content: start;
  /* Le filet de separation des deux colonnes, volontairement discret. */
  border-right: 1px solid var(--c-ligne);
}
.megamenu__familles > li { margin: 0; }
.megamenu__famille {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px var(--sp-3);
  font-size: 0.92rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--c-texte);
  border-radius: var(--r-sm);
  transition: background var(--t-fast), color var(--t-fast);
}
/* .lien-icone se cale sur la premiere ligne d'un lien de sous-menu et porte
   pour cela un decalage de 2 px. Ici la rangee tient sur une seule ligne et
   l'alignement est deja centre : le decalage ferait pencher le pictogramme. */
.megamenu__famille .lien-icone { margin-top: 0; }
.megamenu__famille-label {
  flex: 1 1 auto;
  min-width: 0;
}
.megamenu__chevron {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--c-beton-clair);
  transition: transform var(--t-fast), color var(--t-fast);
}
.megamenu__famille:hover,
.megamenu__famille:focus-visible,
.megamenu__famille.is-active {
  background: var(--c-sable-fonce);
  color: var(--c-bordeaux);
}
.megamenu__famille:hover .megamenu__chevron,
.megamenu__famille:focus-visible .megamenu__chevron,
.megamenu__famille.is-active .megamenu__chevron {
  transform: translateX(3px);
  color: var(--c-bordeaux);
}
.megamenu__famille[aria-current="page"] {
  font-weight: 600;
  color: var(--c-bordeaux);
}

/* ---- Colonne de droite : les panneaux empiles ---- */
.megamenu__panneaux {
  display: grid;
  min-width: 0;
  padding: var(--sp-4) var(--sp-5) var(--sp-3);
}
.megamenu__panneau {
  /* Tous a la meme place : la cellule prend la hauteur du plus haut. */
  grid-area: 1 / 1;
  align-self: start;
  min-width: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast);
}
.megamenu__panneau.is-active {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.megamenu__panneau-titre {
  font-family: var(--ff-titre);
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-bordeaux);
  margin: 0 0 var(--sp-1);
}
.megamenu__panneau-intro {
  font-size: 0.84rem;
  line-height: 1.5;
  color: var(--c-texte-doux);
  margin: 0 0 var(--sp-3);
}
.megamenu__sous {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}
.megamenu__sous > li { margin: 0; }
.megamenu__sous a {
  display: block;
  padding: 8px 10px;
  color: var(--c-texte);
  border-radius: var(--r-sm);
  transition: background var(--t-fast), color var(--t-fast);
}
.megamenu__sous a strong {
  display: block;
  font-family: var(--ff-titre);
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.3;
  color: inherit;
  transition: color var(--t-fast);
}
.megamenu__sous a small {
  display: block;
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.45;
  color: var(--c-texte-doux);
  margin-top: 2px;
}
.megamenu__sous a:hover,
.megamenu__sous a:focus-visible { background: var(--c-bordeaux-voile); }
.megamenu__sous a:hover strong,
.megamenu__sous a:focus-visible strong { color: var(--c-bordeaux); }
.megamenu__sous a[aria-current="page"] { background: var(--c-ocre-voile); }
.megamenu__sous a[aria-current="page"] strong { color: var(--c-bordeaux); }

/* ---- Lien d'appel en bas de panneau ---- */
.megamenu__tout {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  padding: 8px 10px;
  font-family: var(--ff-titre);
  font-size: 0.86rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--c-ocre-fonce);
  border-radius: var(--r-sm);
  transition: background var(--t-fast), color var(--t-fast);
}
/* Chevron dessine au trait plutot qu'ecrit : la charte interdit les symboles
   decoratifs, et deux bordures suffisent a poser la pointe. */
.megamenu__tout::after {
  content: '';
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform var(--t-fast);
}
.megamenu__tout:hover,
.megamenu__tout:focus-visible {
  background: var(--c-ocre-voile);
  color: var(--c-bordeaux);
}
.megamenu__tout:hover::after,
.megamenu__tout:focus-visible::after { transform: translateX(3px) rotate(45deg); }

/* ---- Telephone d'en-tete ---- */
.nav-tel {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap-min);
  padding-right: var(--sp-4);
  border-right: 1px solid var(--c-ligne);
  font-family: var(--ff-titre);
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--c-texte);
  white-space: nowrap;
  transition: color var(--t-fast);
}
.nav-tel svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--c-bordeaux);
}
.nav-tel:hover { color: var(--c-bordeaux); }

/* ---- Bouton d'appel a l'action de l'en-tete ---- */
.btn--nav-cta {
  min-height: var(--tap-min);
  padding: 10px 20px;
  font-size: 0.9rem;
  white-space: nowrap;
}
/*
  Deux libelles cohabitent dans le bouton : le long au dessus de 1080 px, le
  court en dessous, quand la barre de navigation se resserre. Un seul est
  affiche a la fois, sinon le bouton affiche les deux et deborde.
  Le libelle court porte aria-hidden dans le balisage : les lecteurs d'ecran
  n'entendent donc jamais l'intitule en double.
*/
.btn--nav-cta__short { display: none; }

/* ---- Bouton du tiroir mobile ---- */
.mobile-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  flex-shrink: 0;
  border-radius: var(--r-md);
  border: 1px solid var(--c-ligne);
  background: var(--c-blanc);
  color: var(--c-texte);
  transition: background var(--t-fast), border-color var(--t-fast);
}
.mobile-toggle svg {
  width: 24px;
  height: 24px;
}
.mobile-toggle:hover {
  background: var(--c-sable-fonce);
  border-color: var(--c-ocre-bord);
}

/* =========================================================
   7. TIROIR MOBILE
   Affiche seulement sous 920 px (voir bloc media queries).
   ========================================================= */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: var(--z-tiroir);
  display: none; /* passe en flex sous 920 px */
  flex-direction: column;
  background: var(--c-sable);
  transform: translateX(100%);
  visibility: hidden;
  /* Le tiroir defile en interne : reste utilisable en paysage sur telephone */
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  transition: transform var(--t-base), visibility var(--t-base);
}
.mobile-nav.is-open {
  transform: translateX(0);
  visibility: visible;
}
.mobile-nav[hidden] { display: none; }
.mobile-nav-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  min-height: var(--header-h);
  padding: var(--sp-3) var(--gutter);
  background: var(--c-sable);
  border-bottom: 1px solid var(--c-ligne);
  box-shadow: var(--sh-sm);
}
.mobile-nav-head .mobile-toggle { display: inline-flex; }
.mobile-nav > ul,
.mobile-nav nav > ul {
  list-style: none;
  margin: 0;
  padding: var(--sp-4) var(--gutter) 0;
  display: grid;
  gap: 2px;
}
.mobile-nav ul ul {
  list-style: none;
  margin: 2px 0 var(--sp-2);
  padding: 0 0 0 var(--sp-4);
  display: grid;
  gap: 2px;
  border-left: 2px solid var(--c-ligne);
}
.mobile-nav li { margin: 0; }
.mobile-nav a {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--tap-min);
  padding: 11px var(--sp-3);
  font-family: var(--ff-titre);
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--c-texte);
  border-radius: var(--r-md);
  transition: background var(--t-fast), color var(--t-fast);
}
.mobile-nav ul ul a {
  font-family: var(--ff-body);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--c-texte-doux);
}
.mobile-nav a:hover,
.mobile-nav a[aria-current="page"] {
  background: var(--c-bordeaux-voile);
  color: var(--c-bordeaux);
}
.mobile-nav-ctas {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--gutter) calc(var(--sp-7) + env(safe-area-inset-bottom, 0px));
  margin-top: auto;
}
.mobile-nav-ctas .btn { width: 100%; }
.mobile-nav-ctas .nav-tel {
  justify-content: center;
  padding: 0;
  border-right: 0;
}

/* =========================================================
   8. BOUTONS
   Pilules, hauteur de frappe 48 px minimum (DA section 5.1).
   ========================================================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--tap-btn);
  padding: 12px 26px;
  font-family: var(--ff-titre);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.01em;
  text-align: center;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  cursor: pointer;
  max-width: 100%;
  transition: background-color var(--t-fast), border-color var(--t-fast),
    color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast);
}
.btn svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:focus-visible {
  outline: 3px solid var(--c-ocre);
  outline-offset: 3px;
}
.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

/* Plein bordeaux, texte blanc */
.btn--primary {
  background: var(--c-bordeaux);
  color: var(--c-blanc);
  box-shadow: var(--sh-sm);
}
.btn--primary:hover {
  background: var(--c-bordeaux-fonce);
  color: var(--c-blanc);
  box-shadow: var(--sh-card);
}

/* Contour bordeaux 2 px, fond transparent */
.btn--ghost {
  background: transparent;
  color: var(--c-bordeaux);
  border-color: var(--c-bordeaux);
}
.btn--ghost:hover {
  background: var(--c-bordeaux);
  color: var(--c-blanc);
}

/* Plein blanc sur fond fonce */
.btn--light {
  background: var(--c-blanc);
  color: var(--c-bordeaux);
  box-shadow: var(--sh-sm);
}
.btn--light:hover {
  background: var(--c-sable-fonce);
  color: var(--c-bordeaux-fonce);
}

/* Contour blanc sur fond fonce */
.btn--ghost-light {
  background: transparent;
  color: var(--c-blanc);
  border-color: rgba(255, 255, 255, 0.55);
}
.btn--ghost-light:hover {
  background: var(--c-blanc);
  color: var(--c-bordeaux);
  border-color: var(--c-blanc);
}

/* Variante haute, pour les appels a l'action de heros */
.btn--lg {
  min-height: 56px;
  padding: 15px 34px;
  font-size: 1.02rem;
}
.btn--lg svg {
  width: 20px;
  height: 20px;
}

/* Pleine largeur */
.btn--block {
  display: flex;
  width: 100%;
}

/* Rangee de boutons generique */
.btn + .btn { margin-left: 0; }

/* =========================================================
   9. HEROS
   Overlay bordeaux superpose a l'image d'instance --hero-img.
   ========================================================= */
/* La photo etait noyee sous un aplat bordeaux a 72-90 % : on ne la devinait
   plus. Elle vit maintenant sur ::before, VISIBLE, et anime d'un zoom tres
   lent ; le contraste du texte vient d'un voile d'encre qui part du bord
   gauche, la ou le texte est pose, et s'efface vers la droite.

   Le voile est pose dans le meme calque que la photo : il se met donc a
   l'echelle avec elle pendant le zoom. Sur un degrade aussi large, ce
   deplacement est invisible, et ca evite de sacrifier ::after, qui porte
   deja le halo decoratif.

   transform est le seul propriete animee : le zoom se joue entierement sur
   le compositeur, sans relayout ni repaint, d'ou sa fluidite. L'amplitude
   reste faible (1 a 1.09) et la duree longue : un fond doit respirer, pas
   bouger. */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(460px, 62vh, 620px);
  padding-block: clamp(48px, 8vw, 96px);
  color: var(--c-sur-fonce);
  background-color: var(--c-encre);
  isolation: isolate;
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image:
    linear-gradient(100deg,
      rgba(28, 24, 19, 0.86) 0%,
      rgba(28, 24, 19, 0.62) 38%,
      rgba(28, 24, 19, 0.30) 68%,
      rgba(28, 24, 19, 0.14) 100%),
    var(--hero-img, none);
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  transform-origin: center;
  animation: hero-zoom 32s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes hero-zoom {
  from { transform: scale(1) translateX(0); }
  to   { transform: scale(1.09) translateX(-1.2%); }
}
@media (prefers-reduced-motion: reduce) {
  .hero::before { animation: none; }
}
.hero--compact { min-height: clamp(300px, 38vh, 380px); }
.hero--service { min-height: clamp(400px, 52vh, 520px); }
.hero h1,
.hero h2,
.hero h3 { color: var(--c-sur-fonce); }
.hero p { color: var(--c-sur-fonce-doux); }
.hero strong { color: var(--c-sur-fonce); }
.hero .eyebrow { color: var(--c-blanc); }
.hero .eyebrow::before { background: var(--c-ocre); }
.hero-inner {
  position: relative;
  z-index: 1;
  max-width: 760px;
  min-width: 0;
}
.hero-inner > :last-child { margin-bottom: 0; }
.hero h1 { margin-bottom: var(--sp-4); }
.hero-lead {
  font-size: clamp(1.08rem, 1.01rem + 0.34vw, 1.25rem);
  line-height: 1.6;
  color: var(--c-sur-fonce-doux);
  max-width: 60ch;
  margin: 0 0 var(--sp-6);
}
.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}
.hero-trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--c-sur-fonce-ligne);
  font-size: 0.92rem;
  color: var(--c-sur-fonce-doux);
}
.hero-trust > * { min-width: 0; }
.hero-trust .badge {
  background: var(--c-sur-fonce-voile);
  border-color: rgba(255, 255, 255, 0.34);
  color: var(--c-sur-fonce);
}
.hero-trust svg { color: var(--c-ocre); }

/* ---- Fil d'Ariane ---- */
.breadcrumb {
  font-size: 0.86rem;
  line-height: 1.4;
  margin-bottom: var(--sp-4);
  color: var(--c-texte-doux);
}
.breadcrumb ol,
.breadcrumb ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  min-width: 0;
}
.breadcrumb li + li::before {
  content: '/';
  opacity: 0.6;
  flex-shrink: 0;
}
.breadcrumb a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-fast);
  /* Zone de frappe portee a 24 px de haut, minimum exige par le critere
     WCAG 2.5.8. Le padding est vertical seulement, la ligne du fil d'Ariane
     garde donc exactement la meme allure. */
  display: inline-block;
  padding-block: 3px;
  min-height: 24px;
}
.breadcrumb a:hover {
  color: inherit;
  border-bottom-color: currentColor;
}
.breadcrumb [aria-current="page"] { font-weight: 600; }
.hero .breadcrumb { color: var(--c-sur-fonce-doux); }
.hero .breadcrumb [aria-current="page"] { color: var(--c-sur-fonce); }

/* =========================================================
   10. CARTES
   ========================================================= */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
  overflow: hidden;
  transition: transform var(--t-base), box-shadow var(--t-base), border-color var(--t-base);
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-card);
  border-color: var(--c-ocre-bord);
}

/* Carte entierement cliquable : le lien du titre couvre la carte */
.card a.card-title::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.card-media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--c-sable-fonce);
  flex-shrink: 0;
}
.card-media img,
.card-media svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow);
}
/* Les illustrations de service sont dessinees dans un cadre 4:3 exact, comme
   la vignette. contain plutot que cover : rien n'est recadre, donc rien du
   dessin ne se perd. */
.card--service .card-media img { object-fit: contain; }
.blog-card:hover .card-media img { transform: scale(1.04); }
.card-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--sp-5);
}
.card-body > :last-child { margin-bottom: 0; }
.card-body p {
  margin: 0;
  color: var(--c-texte-doux);
}
.card-title {
  font-family: var(--ff-titre);
  font-size: clamp(1.12rem, 1.05rem + 0.35vw, 1.3rem);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -0.01em;
  color: var(--c-texte);
  margin: 0;
  overflow-wrap: break-word;
}
.card-title a { color: inherit; }

/*
  Lien etendu a toute la carte.

  Sans ca, la zone cliquable se limite a la ligne de titre, environ 20 px de
  haut : trop petit au doigt (le minimum vise est 44 px) et frustrant, parce
  que le visiteur tape naturellement sur la carte, pas sur le titre.
  La carte porte deja position: relative, la pastille invisible ci dessous
  couvre donc exactement la carte.

  Tout autre lien ou bouton place dans la carte repasse au dessus grace au
  z-index 2 : il reste cliquable et ne se fait pas avaler par la pastille.
*/
.card-title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}
.card:has(.card-title a) { cursor: pointer; }
.card .card-body a:not(.card-title a),
.card .btn,
.card .compare-slider { position: relative; z-index: 2; }
.card:hover .card-title,
.card:hover .card-title a { color: var(--c-bordeaux); }
.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--c-texte-doux);
  margin: 0;
}
.card-meta > span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.card-meta svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--c-ocre-fonce);
}

/* ---- Carte service : filet ocre qui se revele au survol ---- */
.card--service .card-body { padding-top: var(--sp-5); }
.card--service::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--filet-h);
  background: var(--c-ocre);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-base);
  z-index: 2;
}
.card--service:hover::before,
.card--service:focus-within::before { transform: scaleX(1); }
.card--service .card-body .btn {
  margin-top: auto;
  align-self: flex-start;
}

/* ---- Carte zone : pictogramme en tete, texte en pleine largeur ----
   La carte etait en rangee, pictogramme a gauche et texte a droite. Ca tenait
   tant que le resume faisait une ligne. Sur la page des zones, ou chaque ville
   porte un vrai paragraphe, la colonne de texte tombait sous les 160 px en
   grille de quatre : deux ou trois mots par ligne, un mot coupe sur deux, et
   le pictogramme centre en vis a vis d'un bloc de dix lignes.
   Le pictogramme passe donc au dessus et le texte reprend toute la largeur
   utile de la carte. */
.card--zone {
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5);
}
.card--zone .card-body {
  padding: 0;
  gap: var(--sp-2);
}
.card--zone svg {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  color: var(--c-bordeaux);
}
.card--zone .card-title { font-size: 1.08rem; }

/* ---- Blocs region : la page des zones couvre toute la province ----
   Un bloc par region administrative : le nom, le temps de route, puis les
   villes. Une ville avec lien a sa page detaillee. Une ville en texte simple
   est desservie pareil, sa page n'est juste pas encore ecrite : le lien
   viendra sans changer le balisage autour. */
.regions-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-6) clamp(24px, 3.5vw, 56px);
  margin-bottom: var(--sp-7);
}
.region-bloc { min-width: 0; }
.region-bloc h3 {
  font-size: 1.02rem;
  margin: 0;
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--c-ligne);
}
.region-meta {
  margin: var(--sp-2) 0 var(--sp-2);
  font-size: 0.85rem;
  color: var(--c-texte-doux);
}
.region-villes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-1) var(--sp-2);
  line-height: 1.7;
}
.region-villes li {
  margin: 0;
  min-width: 0;
}
/* Point mediant entre les villes, jamais apres la derniere */
.region-villes li:not(:last-child)::after {
  content: '\00B7';
  margin-left: var(--sp-2);
  color: var(--c-ligne);
}
.region-villes span { color: var(--c-texte-doux); }
.region-villes a {
  font-weight: 600;
  color: var(--c-bordeaux);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--t-fast);
}
.region-villes a:hover { color: var(--c-bordeaux-fonce); }

/* ---- Carte etape ---- */
.card--step {
  padding: var(--sp-5);
  gap: var(--sp-3);
}
.card--step .card-body { padding: 0; }
.card--step:hover {
  transform: none;
  border-color: var(--c-ocre-bord);
}

/* =========================================================
   11. RANGEES SERVICE ALTERNEES
   ========================================================= */
.service-alt {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
.service-alt + .service-alt { margin-top: clamp(48px, 7vw, 88px); }
.service-alt__media {
  position: relative;
  min-width: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-sable-fonce);
  box-shadow: var(--sh-card);
}
.service-alt__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.service-alt__body { min-width: 0; }
.service-alt__body > :last-child { margin-bottom: 0; }
.service-alt__body h3 { margin-bottom: var(--sp-3); }
.service-alt__body p { color: var(--c-texte-doux); }

/* Inversion une rangee sur deux */
.service-alt:nth-child(even) .service-alt__media { order: 2; }
.service-alt:nth-child(even) .service-alt__body { order: 1; }

/*
  Sous 880 px : une seule colonne et remise a zero de TOUS les order,
  sinon une rangee sur deux affiche le texte avant l'image sur mobile,
  ce qui casse la lecture (DA section 5.3).
*/
@media (max-width: 880px) {
  .service-alt {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-5);
  }
  .service-alt .service-alt__media,
  .service-alt .service-alt__body,
  .service-alt:nth-child(even) .service-alt__media,
  .service-alt:nth-child(even) .service-alt__body { order: 0; }
}

/* =========================================================
   12. COMPOSANTS DE CONTENU
   ========================================================= */

/* ---- Checklist verte ---- */
.checklist {
  list-style: none;
  margin: 0 0 var(--sp-5);
  padding: 0;
  display: grid;
  gap: var(--sp-3);
}
.checklist li {
  position: relative;
  margin: 0;
  padding-left: 30px;
  line-height: 1.6;
  min-width: 0;
}

/* Coche verte alignee sur la premiere ligne du texte */
.checklist li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.2em;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231F7A40' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 20px 20px;
}
.checklist--dense { gap: var(--sp-2); }

/* Sur fond fonce la coche passe en ocre pour rester lisible */
.section--beton .checklist li::before,
.section--encre .checklist li::before,
.cta-band .checklist li::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DC9418' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E"); }

/* ---- Chiffres cles ---- */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  gap: var(--sp-5);
  margin: 0;
  padding: 0;
  list-style: none;
}
.stat {
  min-width: 0;
  padding: var(--sp-4) 0 var(--sp-4) var(--sp-4);
  border-left: var(--filet-h) solid var(--c-ocre);
  margin: 0;
}
.stat__num {
  display: block;
  font-family: var(--ff-titre);
  font-size: clamp(1.7rem, 1.2rem + 1.9vw, 2.4rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--c-bordeaux);
  overflow-wrap: anywhere;
}
.stat__label {
  display: block;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--c-texte-doux);
  margin-top: 6px;
}
.section--beton .stat__num,
.section--encre .stat__num,
.hero .stat__num { color: var(--c-ocre); }
.section--beton .stat__label,
.section--encre .stat__label,
.hero .stat__label { color: var(--c-sur-fonce-doux); }

/* ---- Badges ---- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  min-height: 32px;
  font-family: var(--ff-body);
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--c-texte);
  background: var(--c-ocre-voile);
  border: 1px solid var(--c-ocre-bord);
  border-radius: var(--r-pill);
  white-space: nowrap;
  max-width: 100%;
}
.badge svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--c-ocre-fonce);
}

/* Badge licence RBQ, pictogramme bouclier */
.badge--rbq::before {
  content: '';
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A0731F' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3 4 6v6c0 5 3.4 8.4 8 9 4.6-.6 8-4 8-9V6l-8-3z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

/* Badge soumission, pictogramme document */
.badge--soumission::before {
  content: '';
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A0731F' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5z'/%3E%3Cpath d='M14 3v5h5'/%3E%3Cpath d='M9 13h6M9 17h4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

/* Badge ocre plein, reserve aux mises en avant courtes */
.badge--ocre {
  background: var(--c-ocre);
  border-color: var(--c-ocre);
  color: var(--c-encre);
  font-weight: 700;
}
.badge--ocre svg { color: var(--c-encre); }

/* Sur fond fonce, les badges a pictogramme passent en ocre clair */
.section--beton .badge--rbq::before,
.section--encre .badge--rbq::before,
.hero .badge--rbq::before,
.cta-band .badge--rbq::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DC9418' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3 4 6v6c0 5 3.4 8.4 8 9 4.6-.6 8-4 8-9V6l-8-3z'/%3E%3C/svg%3E"); }
.section--beton .badge--soumission::before,
.section--encre .badge--soumission::before,
.hero .badge--soumission::before,
.cta-band .badge--soumission::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23DC9418' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5z'/%3E%3Cpath d='M14 3v5h5'/%3E%3Cpath d='M9 13h6M9 17h4'/%3E%3C/svg%3E"); }
.section--beton .badge,
.section--encre .badge {
  background: var(--c-sur-fonce-voile);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--c-sur-fonce);
}

/* ---- Rangee de pastilles ---- */
.pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  margin: 0 0 var(--sp-4);
  padding: 0;
}
.pill-row li {
  margin: 0;
  min-width: 0;
}

/* ---- Citation ---- */
.quote {
  position: relative;
  margin: 0;
  padding: var(--sp-5) var(--sp-5) var(--sp-5) var(--sp-6);
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-left: var(--filet-h) solid var(--c-ocre);
  border-radius: 0 var(--r-lg) var(--r-lg) 0;
  font-size: 1.04rem;
  line-height: 1.6;
  color: var(--c-texte);
  min-width: 0;
}
.quote p { margin: 0 0 var(--sp-3); }
.quote p:last-of-type { margin-bottom: 0; }
.quote__author {
  display: block;
  margin-top: var(--sp-3);
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--c-texte-doux);
  font-style: normal;
}
.section--beton .quote,
.section--encre .quote {
  background: var(--c-sur-fonce-voile);
  border-color: var(--c-sur-fonce-ligne);
  border-left-color: var(--c-ocre);
  color: var(--c-sur-fonce);
}
.section--beton .quote__author,
.section--encre .quote__author { color: var(--c-sur-fonce-faible); }

/* ---- Etapes numerotees ---- */
.steps {
  display: grid;
  gap: var(--gap-grille);
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  counter-reset: soltech-etape;
  list-style: none;
  margin: 0;
  padding: 0;
}
.steps > li {
  margin: 0;
  min-width: 0;
}
.step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  margin-bottom: var(--sp-3);
  font-family: var(--ff-titre);
  font-size: 1.12rem;
  font-weight: 800;
  line-height: 1;
  color: var(--c-blanc);
  background: var(--c-bordeaux);
  border-radius: var(--r-pill);
}
.section--beton .step-num,
.section--encre .step-num {
  background: var(--c-ocre);
  color: var(--c-encre);
}

/* ---- Tableau de specifications ---- */
.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
  background: var(--c-blanc);
}
.spec-table caption {
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
  font-size: 0.86rem;
  color: var(--c-texte-doux);
}
.spec-table th,
.spec-table td {
  padding: 13px var(--sp-4);
  border-bottom: 1px solid var(--c-ligne);
  vertical-align: top;
  line-height: 1.55;
}
.spec-table thead th {
  font-family: var(--ff-titre);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-texte);
  background: var(--c-sable-fonce);
  border-bottom: 2px solid var(--c-ocre-bord);
  white-space: nowrap;
}
.spec-table tbody th {
  font-weight: 600;
  color: var(--c-texte);
  white-space: normal;
}
.spec-table tbody tr:last-child th,
.spec-table tbody tr:last-child td { border-bottom: 0; }
.spec-table tbody tr:nth-child(even) { background: rgba(250, 246, 239, 0.6); }

/* ---- Note de prix ---- */
.price-note {
  display: block;
  margin: var(--sp-3) 0 0;
  padding-left: var(--sp-3);
  border-left: var(--filet-h) solid var(--c-ocre);
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--c-texte-doux);
}

/* ---- Encadres d'information ---- */
/*
  Bloc en FLUX NORMAL, pas en flex.

  En display:flex, chaque suite de texte brut devient un element anonyme et
  chaque <a> devient un element a part entiere. Le lien se fait alors ecraser a
  sa largeur minimale, et comme le filet de securite overflow-wrap:anywhere
  autorise la coupure n'importe ou, une adresse courriel se retrouvait affichee
  en colonne d'un caractere de large sur 267 px de haut. Constate sur la page de
  soumission, mention Loi 25.

  L'icone flotte a gauche : le texte l'habille, les liens restent en ligne, et
  aucune coupure parasite n'est possible.
*/
.note {
  display: block;
  padding: var(--sp-4) var(--sp-5);
  margin: var(--sp-5) 0;
  background: var(--c-sable-fonce);
  border: 1px solid var(--c-ligne);
  border-left: var(--filet-h) solid var(--c-ocre);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--c-texte);
  min-width: 0;
}
.note > svg {
  float: left;
  margin-right: var(--sp-3);
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--c-ocre-fonce);
}
.note p { margin: 0 0 var(--sp-2); }
.note p:last-child { margin-bottom: 0; }
.note strong { font-weight: 700; }
.note--warn {
  background: var(--c-alerte-voile);
  border-color: var(--c-alerte-bord);
  border-left-color: var(--c-alerte);
}
.note--warn > svg { color: var(--c-alerte); }

/* =========================================================
   13. GALERIE
   ========================================================= */

/* Traitement photo constant : chaud et desature (DA section 6).
   Il unifie des photos prises sur des annees avec des telephones differents.
   Les illustrations dessinees, elles, sont DEJA dans la palette exacte :
   les desaturer les ferait deriver, donc les SVG en sont exempts. */
.ph { filter: saturate(.82) contrast(1.04) sepia(.06); }
.ph[src$=".svg"] { filter: none; }
.gallery-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-5);
  padding: 0;
  list-style: none;
}
.gallery-filters li { margin: 0; }
.gallery-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tap-min);
  padding: 10px 18px;
  font-family: var(--ff-body);
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--c-texte);
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.gallery-chip:hover {
  border-color: var(--c-ocre);
  background: var(--c-ocre-voile);
}
.gallery-chip.is-active,
.gallery-chip[aria-pressed="true"] {
  background: var(--c-bordeaux);
  border-color: var(--c-bordeaux);
  color: var(--c-blanc);
}
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: var(--sp-4);
  list-style: none;
  margin: 0;
  padding: 0;
}
.gallery-item {
  position: relative;
  margin: 0;
  min-width: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-sable-fonce);
  border: 1px solid var(--c-ligne);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.gallery-item img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform var(--t-slow);
}
.gallery-item:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-card);
}
.gallery-item:hover img { transform: scale(1.05); }
.gallery-item figcaption {
  display: block;
  padding: var(--sp-3) var(--sp-4);
  background: var(--c-blanc);
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--c-texte-doux);
  min-width: 0;
  overflow-wrap: anywhere;
}
.gallery-item figcaption strong {
  display: block;
  font-family: var(--ff-titre);
  font-size: 0.98rem;
  font-weight: 700;
  color: var(--c-texte);
  margin-bottom: 2px;
}
.gallery-item[hidden] { display: none; }

/* =========================================================
   14. COMPARATEUR AVANT ET APRES
   ========================================================= */
.compare {
  display: grid;
  gap: var(--sp-4);
  min-width: 0;
}
.compare-slider {
  --pos: 50%;
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: var(--r-lg);
  border: 1px solid var(--c-ligne);
  background: var(--c-sable-fonce);
  cursor: ew-resize;
  user-select: none;
  -webkit-user-select: none;
  /* Le geste vertical reste au defilement de la page */
  touch-action: pan-y;
  isolation: isolate;
}
.compare-slider__before,
.compare-slider__after {
  position: absolute;
  inset: 0;
  margin: 0;
  overflow: hidden;
}
.compare-slider__before img,
.compare-slider__after img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  -webkit-user-drag: none;
}
.compare-slider__before { z-index: 1; }

/* La couche "apres" est rognee a droite de la poignee */
.compare-slider__after {
  z-index: 2;
  clip-path: inset(0 0 0 var(--pos));
}

/* Etiquettes de coin, generees sans balisage supplementaire */
.compare-slider::before,
.compare-slider::after {
  position: absolute;
  top: 12px;
  z-index: 4;
  padding: 5px 12px;
  font-family: var(--ff-titre);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  line-height: 1.3;
  border-radius: var(--r-pill);
  pointer-events: none;
}
.compare-slider::before {
  content: 'AVANT';
  left: 12px;
  background: rgba(28, 24, 19, 0.72);
  color: var(--c-blanc);
}
.compare-slider::after {
  content: 'APRÈS';
  right: 12px;
  background: var(--c-bordeaux);
  color: var(--c-blanc);
}

/* Poignee : barre blanche de 3 px et pastille ronde de 44 px */
.compare-slider__handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  z-index: 3;
  width: var(--filet-h);
  margin-left: calc(var(--filet-h) / -2);
  background: var(--c-blanc);
  box-shadow: 0 0 0 1px rgba(28, 24, 19, 0.18);
  cursor: ew-resize;
  touch-action: pan-y;
}
.compare-slider__handle::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background-color: var(--c-blanc);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A6301F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 7 5 12l5 5'/%3E%3Cpath d='M14 7l5 5-5 5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 24px 24px;
  box-shadow: var(--sh-lift);
}

/* Zone de saisie tactile elargie autour de la poignee */
.compare-slider__handle::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 48px;
  transform: translateX(-50%);
}
.compare-slider:focus-visible {
  outline: 3px solid var(--c-ocre);
  outline-offset: 3px;
}
.compare-slider:focus-visible .compare-slider__handle::before { box-shadow: var(--sh-lift), 0 0 0 3px var(--c-ocre); }

/* Deplacement fluide au clavier, immediat a la souris et au doigt */
.compare-slider .compare-slider__after,
.compare-slider .compare-slider__handle { transition: clip-path var(--t-fast), left var(--t-fast); }
.compare-slider.is-dragging { cursor: ew-resize; }
.compare-slider.is-dragging .compare-slider__after,
.compare-slider.is-dragging .compare-slider__handle { transition: none; }

/* Bascule par onglets (variante sans glissement) */
.compare-slider.is-switching .compare-slider__after { transition: opacity var(--t-base); }
.compare-caption {
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--c-texte-doux);
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
.section--beton .compare-caption,
.section--encre .compare-caption { color: var(--c-sur-fonce-doux); }

/* ---- Onglets avant et apres ---- */
.ba-tabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  margin: 0;
  list-style: none;
  background: var(--c-sable-fonce);
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-pill);
  max-width: 100%;
}
.ba-tabs li { margin: 0; }
.ba-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 8px 18px;
  font-family: var(--ff-titre);
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--c-texte-doux);
  background: transparent;
  border: 0;
  border-radius: var(--r-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-fast), color var(--t-fast);
}
.ba-tab:hover { color: var(--c-bordeaux); }
.ba-tab.is-active,
.ba-tab[aria-selected="true"] {
  background: var(--c-bordeaux);
  color: var(--c-blanc);
}

/* =========================================================
   15. FAQ
   Le contenu reste dans le flux : lisible par les moteurs.
   ========================================================= */
.faq-list {
  display: grid;
  gap: var(--sp-3);
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 920px;
}
.faq-item {
  margin: 0;
  min-width: 0;
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.faq-item:hover { border-color: var(--c-ocre-bord); }
.faq-item.is-open {
  border-color: var(--c-ocre-bord);
  box-shadow: var(--sh-sm);
}
.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  width: 100%;
  min-height: var(--tap-btn);
  padding: var(--sp-4) var(--sp-5);
  text-align: left;
  font-family: var(--ff-titre);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.1rem);
  font-weight: 700;
  line-height: 1.4;
  color: var(--c-texte);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast);
}
.faq-q:hover {
  color: var(--c-bordeaux);
  background: var(--c-bordeaux-voile);
}
.faq-q svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  color: var(--c-ocre-fonce);
  transition: transform var(--t-base);
}
.faq-item.is-open .faq-q,
.faq-q[aria-expanded="true"] { color: var(--c-bordeaux); }
.faq-item.is-open .faq-q svg,
.faq-q[aria-expanded="true"] svg { transform: rotate(180deg); }
.faq-a {
  max-height: 0;
  overflow: hidden;
  padding: 0 var(--sp-5);
  color: var(--c-texte-doux);
  line-height: 1.68;
  transition: max-height var(--t-base), padding var(--t-base);
}
.faq-item.is-open .faq-a {
  max-height: 1600px;
  padding-bottom: var(--sp-5);
}
.faq-a > :last-child { margin-bottom: 0; }
.faq-a ul,
.faq-a ol { margin-bottom: var(--sp-3); }

/* =========================================================
   16. BANDEAU D'APPEL A L'ACTION
   ========================================================= */
.cta-band {
  position: relative;
  background: var(--c-beton);
  color: var(--c-sur-fonce);
  border-top: var(--filet-h) solid var(--c-ocre);
  padding-block: clamp(44px, 6.5vw, 76px);
}
.cta-band h2,
.cta-band h3 {
  color: var(--c-sur-fonce);
  margin-bottom: var(--sp-3);
}
.cta-band p {
  color: var(--c-sur-fonce-doux);
  margin-bottom: 0;
  max-width: 56ch;
}
.cta-band strong { color: var(--c-sur-fonce); }
.cta-band .eyebrow { color: var(--c-blanc); }
.cta-band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5) var(--sp-6);
}
.cta-band__inner > * { min-width: 0; }
.cta-band__inner > :first-child { flex: 1 1 420px; }
.cta-band__inner .hero-ctas,
.cta-band__inner > .btn + .btn { margin-bottom: 0; }
.cta-band .hero-ctas {
  margin-bottom: 0;
  flex-shrink: 0;
}

/* =========================================================
   17. PIED DE PAGE
   ========================================================= */
.site-footer {
  background: var(--c-encre);
  color: var(--c-sur-fonce-doux);
  padding-block: clamp(64px, 9vw, 112px) 0;
  font-size: 0.95rem;
}
.site-footer h2,
.site-footer h3,
.site-footer h4 { color: var(--c-sur-fonce); }
.site-footer a {
  color: var(--c-sur-fonce-doux);
  transition: color var(--t-fast);
}
.site-footer a:hover { color: var(--c-ocre); }
.site-footer strong { color: var(--c-sur-fonce); }
.footer-grid {
  display: grid;
  /* La colonne de marque porte le plus de contenu : elle respire plus large,
     et l'ecart entre colonnes est franc pour que chacune se lise seule. */
  grid-template-columns: 1.35fr 1fr 0.85fr 0.85fr;
  gap: var(--sp-7) clamp(32px, 4vw, 72px);
  padding-bottom: var(--sp-8, 72px);
}
.footer-brand { min-width: 0; }
.footer-brand .brand,
.footer-brand .brand-name { color: var(--c-sur-fonce); }
.footer-brand .brand-name small { color: var(--c-sur-fonce-faible); }
.footer-brand .brand-mark img {
  box-shadow: 0 0 0 2px rgba(250, 246, 239, 0.35);
}
.footer-brand p {
  margin-top: var(--sp-4);
  color: var(--c-sur-fonce-faible);
  line-height: 1.6;
  max-width: 40ch;
}
.footer-col { min-width: 0; }
/* Le balisage des colonnes emet des <h2> (bonne hierarchie de document :
   un pied de page n'a pas a inventer des niveaux). La regle doit donc les
   couvrir aussi, sinon ils sortent en taille de titre de section et
   ecrasent tout le pied de page. C'est arrive. */
.footer-col h2,
.footer-col h3,
.footer-col h4 {
  font-family: var(--ff-titre);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-ocre);
  margin: 0 0 var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-sur-fonce-ligne);
}
/* Les sous-groupes de la colonne des zones (Mauricie, Ailleurs au Quebec)
   ne repetent pas le trait du titre de colonne : un seul filet par colonne,
   sinon les lignes se multiplient et tout semble colle. Le sous-titre est
   plus discret, et il reprend son air au-dessus quand une liste le precede. */
.footer-col h3,
.footer-col h4 {
  font-size: 0.72rem;
  color: var(--c-sur-fonce-faible);
  border-bottom: 0;
  padding-bottom: 0;
  margin-bottom: var(--sp-3);
}
.footer-col ul + h3,
.footer-col ul + h4 { margin-top: var(--sp-6); }
.footer-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.footer-col li {
  margin: 0;
  min-width: 0;
}
.footer-col li a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 3px 0;
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.footer-coord {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-4);
}
.footer-coord li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin: 0;
  line-height: 1.55;
  min-width: 0;
  overflow-wrap: anywhere;
}
.footer-coord svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--c-ocre);
}
.footer-coord a { overflow-wrap: anywhere; }
.footer-social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  margin: var(--sp-5) 0 0;
  padding: 0;
}
.footer-social li { margin: 0; }
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border: 1px solid var(--c-sur-fonce-ligne);
  border-radius: var(--r-md);
  color: var(--c-sur-fonce-doux);
  transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
.footer-social a:hover {
  border-color: var(--c-ocre);
  color: var(--c-ocre);
  background: var(--c-sur-fonce-voile);
}
.footer-social svg {
  width: 20px;
  height: 20px;
}
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3) var(--sp-5);
  padding-block: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--c-sur-fonce-ligne);
  font-size: 0.85rem;
  color: var(--c-sur-fonce-faible);
}
.footer-bottom p {
  margin: 0;
  min-width: 0;
}
.footer-bottom ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer-bottom li { margin: 0; }
.footer-bottom a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
}

/* =========================================================
   18. FORMULAIRES
   Champs de 48 px, police de 16 px minimum pour empecher
   le zoom automatique de Safari iOS.
   ========================================================= */
.form {
  display: grid;
  gap: var(--sp-5);
  min-width: 0;
}
.form-card {
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-top: var(--filet-h) solid var(--c-ocre);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-card);
  padding: clamp(20px, 3.2vw, 40px);
  min-width: 0;
}
.form-card h2,
.form-card h3 { margin-top: 0; }

/* ---- Progression du formulaire multi-etapes ---- */
.form-progress {
  display: grid;
  gap: var(--sp-3);
  margin-bottom: var(--sp-6);
}
.form-progress-bar {
  height: 6px;
  width: 100%;
  background: var(--c-sable-fonce);
  border-radius: var(--r-pill);
  overflow: hidden;
}
.form-progress-bar-fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--c-bordeaux);
  border-radius: inherit;
  transition: width var(--t-base);
}
.form-progress ol,
.form-progress ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  list-style: none;
  margin: 0;
  padding: 0;
}
.form-progress-step {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--c-texte-doux);
  min-width: 0;
}
.form-progress-step::before {
  content: '';
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--c-ligne);
  transition: background var(--t-fast), box-shadow var(--t-fast);
}
.form-progress-step.is-active { color: var(--c-bordeaux); }
.form-progress-step.is-active::before {
  background: var(--c-bordeaux);
  box-shadow: 0 0 0 3px var(--c-bordeaux-voile);
}
.form-progress-step.is-visible::before { background: var(--c-vert); }

/* ---- Etapes ---- */
.form-step { display: none; }
.form-step.is-active { display: block; }
.form-step > :first-child { margin-top: 0; }

/* ---- Rangees et champs ---- */
.form-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
  margin-bottom: var(--sp-4);
}
.form-row:last-of-type { margin-bottom: 0; }
/* align-content: start est indispensable, pas cosmetique.
   La valeur par defaut (normal, qui se comporte comme stretch) fait absorber
   par les pistes toute la hauteur que la rangee leur donne. Deux champs cote a
   cote n'ont pas le meme nombre de pistes : celui de gauche a une legende sous
   le champ, celui de droite non. La hauteur en trop se repartissait donc sur
   deux pistes d'un cote et sur trois de l'autre. Resultat mesure : un select
   etire a 72 px au lieu de 50, qui demarrait 22 px plus bas que l'input voisin.
   En start, les pistes gardent leur taille naturelle et le vide reste en bas. */
.form-field {
  display: grid;
  align-content: start;
  gap: 6px;
  min-width: 0;
}
.form-field--full { grid-column: 1 / -1; }
.form-field > label,
.form-field > .form-label {
  font-family: var(--ff-body);
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--c-texte);
}
.form-field > label .req,
.form-field > label abbr {
  color: var(--c-alerte);
  border: 0;
  margin-left: 2px;
}
.form-field input[type="text"],
.form-field input[type="tel"],
.form-field input[type="email"],
.form-field input[type="url"],
.form-field input[type="number"],
.form-field input[type="date"],
.form-field input[type="search"],
.form-field select,
.form-field textarea {
  width: 100%;
  max-width: 100%;
  min-height: var(--tap-btn);
  padding: 12px 14px;
  /* 16 px stricts : plus petit, Safari iOS zoome au focus */
  font-family: var(--ff-body);
  font-size: 16px;
  line-height: 1.5;
  color: var(--c-texte);
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-md);
  appearance: none;
  -webkit-appearance: none;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}
.form-field textarea {
  min-height: 148px;
  resize: vertical;
  line-height: 1.6;
}
.form-field select {
  padding-right: 42px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235C544A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 18px 18px;
  cursor: pointer;
}
.form-field input::placeholder,
.form-field textarea::placeholder {
  color: var(--c-texte-doux);
  opacity: 0.75;
}

/* Focus : bordure bordeaux et halo ocre */
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--c-bordeaux);
  box-shadow: 0 0 0 3px var(--c-ocre-halo);
}
.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible { outline: none; }
.form-field input[type="checkbox"],
.form-field input[type="radio"] {
  width: 20px;
  height: 20px;
  min-height: 0;
  flex-shrink: 0;
  accent-color: var(--c-bordeaux);
  cursor: pointer;
}

/* Case a cocher de consentement : etiquette a droite, cible de 44 px.

   Le :not(.choice) est essentiel. Sans lui, ce selecteur (specificite 0,2,1)
   l'emporte sur .choice (0,1,0) et impose son padding de 6px 0 et son
   min-height de 44 px a toutes les cartes de choix du questionnaire. Resultat :
   des cartes sans marge interne horizontale, ou la pastille, l'icone et le
   texte se touchent et ou un libelle sur deux lignes colle aux bordures. */
.form-field label:not(.choice):has(input[type="checkbox"]),
.form-field label:not(.choice):has(input[type="radio"]) {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  min-height: var(--tap-min);
  padding: 6px 0;
  font-weight: 400;
  line-height: 1.55;
  cursor: pointer;
}

/* Texte d'aide sous le champ */
.form-field small,
.form-field .form-help {
  font-size: 0.83rem;
  line-height: 1.45;
  color: var(--c-texte-doux);
  overflow-wrap: anywhere;
}

/* Message d'erreur */
.field-error {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--c-alerte);
}
.field-error:empty { display: none; }
.form-field.is-error input,
.form-field.is-error select,
.form-field.is-error textarea,
.is-error input,
.is-error select,
.is-error textarea {
  border-color: var(--c-alerte);
  background: var(--c-alerte-voile);
}
.form-field.is-error input:focus,
.form-field.is-error select:focus,
.form-field.is-error textarea:focus { box-shadow: 0 0 0 3px rgba(176, 58, 46, 0.22); }

/* ---- Actions ---- */
.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--c-ligne);
}
.form-actions .btn { flex: 0 1 auto; }
.form-actions > .form-help,
.form-actions > small {
  flex: 1 1 220px;
  font-size: 0.83rem;
  color: var(--c-texte-doux);
  min-width: 0;
}

/* ---- Ecran de succes ---- */
.form-success {
  display: none;
  text-align: center;
  padding: clamp(28px, 5vw, 56px) var(--sp-5);
  background: var(--c-vert-voile);
  border: 1px solid rgba(31, 122, 64, 0.32);
  border-radius: var(--r-lg);
}
.form-success.is-visible { display: block; }
.form-success svg {
  width: 56px;
  height: 56px;
  margin: 0 auto var(--sp-4);
  color: var(--c-vert);
}
.form-success h2,
.form-success h3 {
  color: var(--c-texte);
  margin-bottom: var(--sp-3);
}
.form-success p {
  color: var(--c-texte-doux);
  max-width: 52ch;
  margin-inline: auto;
}
.form-success .btn { margin-top: var(--sp-5); }

/* ---- Piege a pourriels (honeypot) ----
   Reellement invisible et hors du flux, sans display:none pour que
   les robots le remplissent. Le HTML porte aria-hidden et tabindex -1. */
.form-hp {
  position: absolute !important;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}

/* ---- Cartes de choix ---- */
.choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: var(--sp-3);
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.choice-grid > legend {
  padding: 0;
  margin-bottom: var(--sp-3);
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--c-texte);
}
.choice {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 60px;
  padding: 14px var(--sp-4);
  background: var(--c-blanc);
  border: 2px solid var(--c-ligne);
  border-radius: var(--r-md);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--c-texte);
  cursor: pointer;
  min-width: 0;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
/* Pastille de selection.
   Sans indicateur visible, une .choice ressemble a une simple boite bordee et
   rien ne dit qu'elle est cliquable ni laquelle est retenue. La vraie case est
   masquee pour l'affichage mais reste dans le DOM pour le clavier et les
   lecteurs d'ecran. */
.choice::before {
  content: "";
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border: 2px solid var(--c-ligne);
  border-radius: 50%;
  background: var(--c-blanc);
  transition: border-color var(--t-fast), background var(--t-fast), box-shadow var(--t-fast);
}
.choice:has(input[type="checkbox"])::before { border-radius: var(--r-sm); }
.choice:has(input:checked)::before {
  border-color: var(--c-bordeaux);
  background: var(--c-bordeaux);
  box-shadow: inset 0 0 0 3px var(--c-blanc);
}
.choice:hover::before { border-color: var(--c-bordeaux); }

.choice:hover {
  border-color: var(--c-ocre-bord);
  background: var(--c-ocre-voile);
}
.choice svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--c-bordeaux);
}
.choice span {
  min-width: 0;
  overflow-wrap: anywhere;
}
.choice small {
  display: block;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--c-texte-doux);
  margin-top: 2px;
}

/* Le bouton radio reste dans le flux pour le clavier, mais invisible */
.choice input[type="radio"],
.choice input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}

/* Etat coche, navigateurs recents */
.choice:has(input:checked) {
  border-color: var(--c-bordeaux);
  background: var(--c-bordeaux-voile);
  color: var(--c-bordeaux);
}
.choice:has(input:checked) small { color: var(--c-bordeaux-fonce); }

/*
  Repli si :has n'est pas pris en charge : le HTML place alors
  l'input juste avant le label .choice (input + label.choice).
*/
.choice-grid input[type="radio"]:checked + .choice,
.choice-grid input[type="checkbox"]:checked + .choice {
  border-color: var(--c-bordeaux);
  background: var(--c-bordeaux-voile);
  color: var(--c-bordeaux);
}
.choice-grid > input[type="radio"],
.choice-grid > input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

/* Le focus clavier est visible sur la carte entiere, partout */
.choice:focus-within {
  outline-offset: 3px;
  outline: 3px solid var(--c-ocre);
  outline-offset: 3px;
}
.choice-grid input:focus-visible + .choice {
  outline: 3px solid var(--c-ocre);
  outline-offset: 3px;
}

/* ---- Depot de fichier ---- */
.file-drop {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 140px;
  padding: var(--sp-5);
  text-align: center;
  background: var(--c-sable);
  border: 2px dashed var(--c-ocre-bord);
  border-radius: var(--r-lg);
  color: var(--c-texte-doux);
  font-size: 0.92rem;
  line-height: 1.5;
  cursor: pointer;
  min-width: 0;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.file-drop svg {
  width: 30px;
  height: 30px;
  color: var(--c-ocre-fonce);
}
.file-drop strong {
  font-family: var(--ff-titre);
  font-size: 1rem;
  color: var(--c-texte);
}
.file-drop small { font-size: 0.82rem; }
.file-drop input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  /* 16 px, comme tous les champs : sous ce seuil, Safari sur iOS zoome
     automatiquement a la prise de focus et la mise en page saute. */
  font-size: 16px;
}
.file-drop:hover,
.file-drop.is-active {
  border-color: var(--c-bordeaux);
  background: var(--c-bordeaux-voile);
  color: var(--c-bordeaux);
}
.file-drop.is-error {
  border-color: var(--c-alerte);
  background: var(--c-alerte-voile);
}
.file-drop:focus-within {
  outline: 3px solid var(--c-ocre);
  outline-offset: 3px;
}

/* =========================================================
   19. BLOG
   Rendu par le serveur en EJS, meme feuille de style.
   ========================================================= */
.blog-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: var(--gap-grille);
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Un <figure> arrive avec une marge par defaut du navigateur, de 1em de
   chaque cote. Une carte batie sur <figure> se decalait donc de sa grille. */
figure.card { margin: 0; }

.blog-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  margin: 0;
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-sm);
  transition: transform var(--t-base), box-shadow var(--t-base), border-color var(--t-base);
}
.blog-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--sh-card);
  border-color: var(--c-ocre-bord);
}
.blog-card img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--c-sable-fonce);
}
/* Le corps occupe la hauteur restante et pousse le bouton en bas : sans ça,
   trois cartes de resumes inegaux alignent leur bouton a trois hauteurs
   differentes, ce qui se voit immediatement sur une rangee. */
.blog-card .card-body {
  padding: var(--sp-5);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  flex: 1 1 auto;
}
.blog-card .card-body > p:last-child { margin-top: auto; padding-top: var(--sp-2); }
/* La categorie prend sa propre ligne, toujours. Selon sa longueur elle passait
   ou non a la ligne suivante, et le titre de chaque carte d'une meme rangee
   demarrait a une hauteur differente. En bloc, la mesure est la meme pour
   toutes les cartes quel que soit le libelle. */
.blog-card .card-meta { display: block; }
.blog-card .card-meta .badge {
  display: flex;
  width: fit-content;
  margin-bottom: 8px;
}
.blog-card .card-meta time { margin-right: var(--sp-4); }
.blog-card h2,
.blog-card h3 {
  font-size: clamp(1.1rem, 1.02rem + 0.4vw, 1.32rem);
  line-height: 1.3;
  margin: 0;
}
.blog-card h2 a::after,
.blog-card h3 a::after {
  content: '';
  position: absolute;
  inset: 0;
}
.blog-card p {
  color: var(--c-texte-doux);
  margin: 0;
}

/* ---- Article ---- */
.article {
  max-width: 780px;
  margin-inline: auto;
  min-width: 0;
}
.article-head {
  margin-bottom: var(--sp-6);
  padding-bottom: var(--sp-5);
  border-bottom: 1px solid var(--c-ligne);
}
.article-head h1 { margin-bottom: var(--sp-4); }
.article-head > img {
  width: 100%;
  border-radius: var(--r-lg);
  margin-top: var(--sp-5);
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.article-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  font-size: 0.87rem;
  color: var(--c-texte-doux);
  margin: 0;
  list-style: none;
  padding: 0;
}
.article-meta li,
.article-meta > span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  min-width: 0;
}
.article-meta svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  color: var(--c-ocre-fonce);
}
.article-body {
  max-width: var(--max-w-text);
  overflow-wrap: anywhere;
  font-size: 1.04rem;
  line-height: 1.75;
}
.article-body > * + * { margin-top: var(--sp-4); }
.article-body h2 {
  margin-top: var(--sp-7);
  margin-bottom: var(--sp-3);
}
.article-body h3 {
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-3);
}
.article-body img {
  border-radius: var(--r-md);
  margin: var(--sp-5) 0;
}
.article-body a {
  color: var(--c-bordeaux);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  text-decoration-color: var(--c-ocre-bord);
  overflow-wrap: anywhere;
}
.article-body a:hover { text-decoration-color: var(--c-ocre); }
.article-body ul,
.article-body ol { padding-left: 22px; }
.article-body blockquote {
  margin: var(--sp-5) 0;
  padding: var(--sp-4) var(--sp-5);
  border-left: var(--filet-h) solid var(--c-ocre);
  background: var(--c-sable-fonce);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  color: var(--c-texte-doux);
}
.article-body table { min-width: 480px; }
.article-share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--c-ligne);
  font-size: 0.9rem;
  color: var(--c-texte-doux);
}
.article-share a,
.article-share button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap-min);
  padding: 8px 16px;
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-pill);
  background: var(--c-blanc);
  color: var(--c-texte);
  font-size: 0.88rem;
  font-weight: 600;
  transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
.article-share a:hover,
.article-share button:hover {
  border-color: var(--c-ocre);
  background: var(--c-ocre-voile);
  color: var(--c-bordeaux);
}
.article-share svg {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
}

/* ---- Pagination ---- */
.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  list-style: none;
  margin: var(--sp-7) 0 0;
  padding: 0;
}
.pagination li { margin: 0; }
.pagination a,
.pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 8px 14px;
  font-family: var(--ff-titre);
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--c-texte);
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  border-radius: var(--r-md);
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.pagination a:hover {
  border-color: var(--c-ocre);
  background: var(--c-ocre-voile);
  color: var(--c-bordeaux);
}
.pagination [aria-current="page"] {
  background: var(--c-bordeaux);
  border-color: var(--c-bordeaux);
  color: var(--c-blanc);
}
.pagination [aria-disabled="true"] {
  opacity: 0.45;
  pointer-events: none;
}

/* =========================================================
   19 bis. SYSTEME DE LARGEURS
   =========================================================
   Le site n'a que DEUX largeurs de contenu, plus la pleine largeur de la
   grille. Toute nouvelle largeur intermediaire casse l'alignement de la
   colonne et se voit immediatement.

     1. --max-w-text     44rem   texte suivi : .prose, .lead, .section-head
     2. --max-w-lecture  62rem   blocs qui respirent : tableaux, FAQ, encadres
     3. pleine largeur           grilles de cartes, galeries, comparateurs

   Les trois partagent le meme bord gauche, celui du .container.
   ========================================================= */

.table-wrap,
.spec-table,
.faq-list,
.note,
.price-note,
.steps,
.checklist,
.quote {
  max-width: var(--max-w-lecture);
}

/* Dans une grille ou une carte, ces blocs reprennent toute la place
   disponible : la contrainte de lecture ne vaut que dans le flux principal. */
.grid .table-wrap,
.grid .spec-table,
.grid .checklist,
.grid .note,
.card .checklist,
.card .note,
.service-alt__body .checklist,
.cta-band .note {
  max-width: none;
}

/* ---- Chrome compacte dans une carte de formulaire ----
   Le questionnaire empilait deux titres pleine taille et deux chapeaux avant
   le premier champ, soit pres de 380 px de hauteur perdue. Sur un portable,
   l'utilisateur devait defiler avant meme de voir un champ a remplir.
   Dans une .form-card, les titres et les chapeaux passent donc en version
   compacte. Ailleurs sur le site, ils gardent leur taille d'origine. */
.form-card .section-title {
  font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.55rem);
  margin-bottom: var(--sp-2);
}
.form-card .section-title::after {
  width: 34px;
  margin-top: 10px;
}
.form-card > .section-title {
  font-size: clamp(1.05rem, 1rem + 0.3vw, 1.2rem);
  color: var(--c-texte-doux);
  font-weight: 600;
}
.form-card > .section-title::after { display: none; }
.form-card .lead {
  font-size: 0.95rem;
  line-height: 1.55;
  margin-bottom: var(--sp-3);
}
.form-card > .lead { margin-bottom: var(--sp-4); }
.form-step > h2 + .lead { margin-bottom: var(--sp-4); }

/* ---- Rythme vertical du formulaire ----
   Les blocs de champ n'avaient aucune marge entre eux : une legende venait se
   coller sur le champ precedent et les groupes de choix touchaient le select
   du dessus. Tout le formulaire paraissait tasse.
   On espace ici les enfants successifs d'une etape, ce qui couvre aussi bien
   les champs simples que les rangees et les groupes de choix, sans avoir a
   toucher au balisage. */
.form-step > * + * {
  margin-top: var(--sp-5);
}
/* Le formulaire de contact n'a qu'une seule etape : ses champs sont des enfants
   directs de la carte, pas d'un .form-step. Sans cette regle ils se touchent.
   On vise les enfants DIRECTS pour ne pas frapper les deux champs d'une meme
   .form-row, qui doivent rester alignes cote a cote. */
.form-card > .form-field + .form-field,
.form-card > .form-row + .form-field,
.form-card > .form-field + .form-row,
.form-card > .form-row + .form-row,
.form-card > fieldset + .form-field,
.form-card > .form-field + fieldset {
  margin-top: var(--sp-5);
}
.form-step > .field-error + *,
.form-step > p.card-meta + * {
  margin-top: var(--sp-4);
}
/* Volontairement retire : « .form-field + .form-field » visait les champs
   empiles, mais il frappait aussi les deux champs d'une meme .form-row, qui
   sont des freres adjacents. La colonne de droite se retrouvait poussee de
   24 px vers le bas et les etiquettes ne s'alignaient plus.
   L'espacement des blocs empiles est deja assure par « .form-step > * + * »,
   et l'espacement interne d'une rangee par le gap de la grille. */
/* Une legende doit respirer au dessus de ses choix, et se detacher du bloc
   precedent. */
.form-field > legend,
fieldset > legend {
  margin-bottom: var(--sp-3);
}
.choice-grid { margin-top: var(--sp-2); }

/* ---- Focus pose par le script, pas par l'utilisateur ----
   Le passage a l'etape suivante deplace le focus sur le titre de l'etape pour
   que les lecteurs d'ecran annoncent le changement. Ces cibles portent
   tabindex="-1" : elles ne sont jamais atteintes au clavier, et dessiner autour
   d'elles le gros contour ocre du focus donne l'impression d'un encadre parasite
   au milieu du formulaire. On le retire pour ce cas precis uniquement.
   Le focus clavier reel, lui, reste parfaitement visible partout. */
[tabindex="-1"]:focus,
[tabindex="-1"]:focus-visible {
  outline: none;
}

/* ---- Pages a formulaire : le questionnaire prime sur la colonne d'appui ---- */
.grid--2:has(> .form-card) {
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
}
@media (max-width: 920px) {
  .grid--2:has(> .form-card) { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Groupes de champs ----
   Sans remise a zero, le navigateur dessine son propre cadre « groove » gris
   autour de chaque fieldset, ce qui jure completement avec la DA et donne
   l'impression d'un formulaire non style. */
fieldset {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
.form-field > legend,
fieldset > legend {
  display: block;
  padding: 0;
  margin-bottom: var(--sp-2);
  font-family: var(--ff-body);
  font-size: 0.94rem;
  font-weight: 600;
  color: var(--c-texte);
}

/* ---- Respiration entre blocs successifs d'une meme section ----
   Les colonnes d'une grille n'ont jamais la meme hauteur. Sans marge, le bloc
   qui suit vient se coller sous la colonne la plus haute et se lit comme s'il
   en faisait partie. Il faut une separation franche apres tout bloc large. */
/* Cote gauche de la paire : un bloc de texte suivi d'un tableau, d'une liste a
   coches ou d'un encadre. Sans marge, le tableau vient se coller sous le
   dernier paragraphe et les deux blocs se lisent comme un seul.
   .section-head est volontairement exclu : il porte deja sa propre marge basse,
   l'ajouter ici doublerait l'espace sous chaque titre de section. */
.container > .prose + *,
.container > .checklist + *,
.container > .note + *,
.container > .quote + *,
.container > .price-note + *,
.container > .spec-table + * {
  margin-top: clamp(28px, 3.5vw, 44px);
}

/* Restreint aux enfants directs du .container, c'est a dire au flux principal
   de la section. Sans le « .container > », ces regles frappent aussi deux
   colonnes voisines d'une meme grille, qui sont des freres adjacents : la
   colonne de droite descend alors de plusieurs dizaines de pixels et la rangee
   n'est plus alignee. Piege deja rencontre avec « .form-field + .form-field ». */
.container > .grid + *,
.container > .territoire + *,
/* La liste de villes sert aussi seule, hors du bloc .territoire : c'est le cas
   du groupe « ailleurs au Quebec » de l'accueil, pose directement dans le flux
   de la section. Sans cette ligne, le lien qui la suit se collait a la derniere
   ville et se lisait comme une neuvieme entree de la liste. */
.container > .territoire-liste + *,
.container > .carte-zone + *,
.container > .gallery + *,
.container > .steps + *,
.container > .service-alt + *,
.container > .stat-row + *,
.container > .table-wrap + *,
.container > .faq-list + *,
.container > .compare + *,
.container > .pill-row + * {
  margin-top: clamp(32px, 4vw, 56px);
}

/* =========================================================
   20. ANIMATIONS
   ========================================================= */
/*
  L'etat de depart invisible n'est applique QUE si JavaScript est disponible,
  grace a la classe js posee sur <html> par le petit script en tete de page.
  Sans cette precaution, une erreur JS, un bloqueur de scripts ou un navigateur
  ancien laisserait toutes les sections a opacity 0 : le visiteur verrait une
  page blanche. Ici, pas de JS veut simplement dire pas d'animation, et le
  contenu reste visible.
  Le bloc prefers-reduced-motion plus bas passe en !important, il gagne donc
  sur cette regle malgre sa specificite plus faible.
*/
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--t-slow), transform var(--t-slow);
  will-change: opacity, transform;
}
.reveal.is-revealed {
  opacity: 1;
  transform: translateY(0);
  will-change: auto;
}

/* Legers decalages en cascade dans une meme grille */
.grid > .reveal:nth-child(2),
.gallery > .reveal:nth-child(2),
.steps > .reveal:nth-child(2) { transition-delay: 70ms; }
.grid > .reveal:nth-child(3),
.gallery > .reveal:nth-child(3),
.steps > .reveal:nth-child(3) { transition-delay: 140ms; }
.grid > .reveal:nth-child(4),
.gallery > .reveal:nth-child(4),
.steps > .reveal:nth-child(4) { transition-delay: 210ms; }

/*
  Neutralisation complete des animations et transitions.
  Bloc volontairement place avant les media queries de largeur
  pour rester lisible, et redeclare en fin de fichier si besoin.
*/
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .reveal,
  .reveal.is-revealed {
    opacity: 1 !important;
    transform: none !important;
  }
  .btn:hover,
  .card:hover,
  .gallery-item:hover,
  .blog-card:hover { transform: none !important; }
  .card:hover .card-media img,
  .gallery-item:hover img { transform: none !important; }
  .mobile-nav { transition: none !important; }
  /* Le mega menu apparait sans glissement, et les deux pointes cessent de se
     decaler. La pointe de .megamenu__tout garde sa rotation : elle dessine la
     forme, elle n'anime rien. */
  .megamenu,
  .megamenu__panneau { transition: none !important; }
  .megamenu__famille:hover .megamenu__chevron,
  .megamenu__famille:focus-visible .megamenu__chevron,
  .megamenu__famille.is-active .megamenu__chevron { transform: none !important; }
  .megamenu__tout:hover::after,
  .megamenu__tout:focus-visible::after { transform: rotate(45deg) !important; }
}

/* =========================================================
   21. POINTS DE RUPTURE
   1080 px, 920 px, 700 px, 420 px (DA section 8).
   ========================================================= */

/* ---- 1080 px : grilles 4 colonnes vers 2, nav resserree ---- */
@media (max-width: 1080px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nav-main { gap: var(--sp-4); }
  .nav-main > ul { gap: var(--sp-4); }
  .nav-main > ul > li > a { font-size: 0.9rem; }
  .nav-tel { padding-right: var(--sp-3); }
  .btn--nav-cta {
    padding: 10px 16px;
    font-size: 0.86rem;
  }
  /* Bascule vers le libelle court : la barre n'a plus la place du long. */
  .btn--nav-cta__label { display: none; }
  .btn--nav-cta__short { display: inline; }
  .submenu { min-width: 240px; }
  /* La grille utile tombe a 1016 px : le panneau de 720 px tiendrait encore,
     mais colle a la gouttiere. On le resserre pour garder de l'air des deux
     cotes, et la colonne des familles suit. */
  .megamenu {
    width: min(640px, calc(100% - 2 * var(--gutter)));
    grid-template-columns: 232px minmax(0, 1fr);
  }
  .megamenu__panneaux { padding: var(--sp-4) var(--sp-4) var(--sp-3); }
  .cta-band__inner { gap: var(--sp-5); }
}

/* ---- 920 px : nav masquee, tiroir mobile actif, grilles 3 vers 2 ---- */
@media (max-width: 920px) {
  .nav-main,
  .site-header .nav-tel { display: none; }
  /* La barre de bureau disparait ici au profit du tiroir mobile : le mega menu
     n'a plus lieu d'etre. La regle est ecrite en clair et pas seulement
     heritee du .nav-main ci dessus, pour qu'aucun etat ouvert laisse par le
     JavaScript ne puisse le faire reapparaitre au redimensionnement. */
  .megamenu { display: none; }
  .mobile-toggle { display: inline-flex; }
  .mobile-nav { display: flex; }
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .regions-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sp-6) var(--sp-5);
  }
  .hero { min-height: clamp(420px, 56vh, 540px); }
  .card--zone { padding: var(--sp-4); }
  .article-body { font-size: 1.02rem; }
}

/* ---- 700 px : tout sur une colonne, boutons pleine largeur ---- */
@media (max-width: 700px) {
  :root { --sp-section: clamp(44px, 9vw, 72px); }
  .grid--2,
  .grid--3,
  .grid--4 { grid-template-columns: minmax(0, 1fr); }
  .regions-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-5);
  }
  .steps,
  .stat-row,
  .choice-grid,
  .blog-list,
  .gallery { grid-template-columns: minmax(0, 1fr); }
  .gallery { gap: var(--sp-3); }
  .form-row { grid-template-columns: minmax(0, 1fr); }
  /* Marges internes reduites : sur un ecran de telephone, la carte du
     questionnaire ne peut pas se permettre 32 px de chaque cote. */
  .form-card { padding: var(--sp-5) var(--sp-4); }
  .form-step > * + * { margin-top: var(--sp-3); }

  .form-card > .lead { margin-bottom: var(--sp-3); }
  .form-progress { margin-bottom: var(--sp-3); }
  .form-card .section-title { margin-bottom: var(--sp-2); }
  /* Les choix restent sur deux colonnes au telephone : sur une seule, une
     question a neuf options depasse la hauteur de l'ecran et oblige a defiler
     avant meme de pouvoir repondre. */
  .choice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .choice {
    min-height: 52px;
    padding: var(--sp-2) var(--sp-3);
    font-size: 0.9rem;
  }
  .hero {
    min-height: clamp(400px, 60vh, 500px);
    padding-block: clamp(40px, 11vw, 72px);
  }
  /* En etroit, deux ajustements au calque photo. Le sujet des photos de
     chantier est plus haut dans le cadre, donc on remonte le cadrage. Et le
     texte occupe toute la largeur : le voile lateral qui s'effacait vers la
     droite laisserait ses dernieres lignes sur la partie claire de la photo,
     alors il devient plus uniforme, presque vertical. */
  .hero::before {
    background-image:
      linear-gradient(175deg,
        rgba(28, 24, 19, 0.82) 0%,
        rgba(28, 24, 19, 0.68) 55%,
        rgba(28, 24, 19, 0.52) 100%),
      var(--hero-img, none);
    background-position: center, center 30%;
  }
  .hero-inner { max-width: 100%; }
  .hero-lead { margin-bottom: var(--sp-5); }

  /* Boutons de heros pleine largeur */
  .hero-ctas {
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-3);
  }
  .hero-ctas .btn { width: 100%; }
  .cta-band .hero-ctas,
  .form-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .cta-band .hero-ctas .btn,
  .form-actions .btn { width: 100%; }
  .form-actions > .form-help,
  .form-actions > small {
    order: 2;
    text-align: center;
  }
  .cta-band__inner {
    flex-direction: column;
    align-items: stretch;
  }
  .cta-band__inner > :first-child { flex: 1 1 auto; }
  .footer-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-6);
    padding-bottom: var(--sp-6);
  }
  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
  }
  .compare-slider { aspect-ratio: 4 / 3; }
  .compare-slider__handle::before {
    width: 48px;
    height: 48px;
  }
  .table-wrap table,
  .spec-table,
  .article-body table { min-width: 460px; }
  .quote { padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-5); }
  .article-share { gap: var(--sp-2); }
}

/* ---- 420 px : marges internes reduites, badges empiles ---- */
@media (max-width: 420px) {
  .card-body,
  .card--step,
  .form-card { padding: var(--sp-4); }
  .card--zone { padding: var(--sp-3) var(--sp-4); }
  .faq-q {
    padding: var(--sp-3) var(--sp-4);
    gap: var(--sp-3);
  }
  .faq-a { padding-inline: var(--sp-4); }
  .faq-item.is-open .faq-a { padding-bottom: var(--sp-4); }
  .note { padding: var(--sp-3) var(--sp-4); }

  /* Badges empiles : chacun sur sa ligne, texte jamais tronque */
  .hero-trust,
  .pill-row {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-2);
  }
  .badge {
    white-space: normal;
    text-align: left;
  }
  .btn { padding-inline: 20px; }
  .btn--lg {
    padding-inline: 24px;
    font-size: 0.98rem;
  }
  .brand-mark {
    width: 38px;
    height: 38px;
  }
  .brand-name { font-size: 0.98rem; }
  .brand-name small {
    font-size: 0.75rem;
    letter-spacing: 0.06em;
  }
  .stat { padding-left: var(--sp-3); }
  .gallery-chip {
    padding: 10px 14px;
    font-size: 0.86rem;
  }
  .ba-tab {
    padding: 8px 14px;
    font-size: 0.8rem;
  }
  .compare-slider::before,
  .compare-slider::after {
    top: 8px;
    padding: 4px 9px;
    font-size: 0.64rem;
  }
  .compare-slider::before { left: 8px; }
  .compare-slider::after { right: 8px; }
  .article-share a,
  .article-share button { flex: 1 1 100%; }
}

/* =========================================================
   22. IMPRESSION
   ========================================================= */
@media print {
  :root {
    --c-texte: #000000;
    --c-texte-doux: #333333;
  }
  body {
    padding-top: 0;
    background: #FFFFFF;
    color: #000000;
    font-size: 11.5pt;
    line-height: 1.5;
  }
  body::before,
  .site-header,
  .site-footer,
  .mobile-nav,
  .mobile-toggle,
  .skip-link,
  .cta-band,
  .btn,
  .hero-ctas,
  .gallery-filters,
  .ba-tabs,
  .article-share,
  .pagination,
  .form-actions,
  .file-drop,
  .compare-slider__handle,
  .footer-social { display: none !important; }
  main,
  .container,
  .section,
  .card,
  .form-card,
  .article {
    max-width: none;
    width: auto;
    margin: 0;
    padding: 0;
    background: #FFFFFF !important;
    color: #000000 !important;
    box-shadow: none !important;
    border: 0;
  }
  .section { padding-block: 12pt; }
  .hero {
    min-height: 0;
    background: none !important;
    color: #000000 !important;
    padding-block: 0 12pt;
  }
  .hero h1,
  .hero h2,
  .hero p,
  .hero-lead,
  .section--beton,
  .section--encre,
  .section--beton h2,
  .section--encre h2 {
    color: #000000 !important;
    background: none !important;
  }
  h1,
  h2,
  h3,
  h4 {
    color: #000000 !important;
    page-break-after: avoid;
    break-after: avoid;
  }
  .section-title::after,
  .eyebrow::before { background: #000000 !important; }
  a {
    color: #000000 !important;
    text-decoration: underline;
  }

  /* On imprime l'adresse des liens internes utiles */
  .prose a[href^="/"]::after,
  .article-body a[href^="/"]::after {
    content: ' (www.soltechconstruction.com' attr(href) ')';
    font-size: 9pt;
  }
  .prose a[href^="http"]::after,
  .article-body a[href^="http"]::after {
    content: ' (' attr(href) ')';
    font-size: 9pt;
  }

  /* La FAQ s'imprime ouverte */
  .faq-a {
    max-height: none !important;
    overflow: visible !important;
    padding: 0 0 8pt !important;
  }
  .faq-item {
    border: 0;
    border-bottom: 1pt solid #999999;
    page-break-inside: avoid;
    break-inside: avoid;
  }
  .card,
  .gallery-item,
  .quote,
  .note,
  .steps > li,
  .service-alt {
    page-break-inside: avoid;
    break-inside: avoid;
  }
  img {
    max-width: 100% !important;
    page-break-inside: avoid;
    break-inside: avoid;
  }
  .ph { filter: none; }
  .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* =========================================================
   23. COUCHE CREATIVE
   =========================================================
   Tout ce qui donne du relief a la page sans toucher au balisage : textures,
   degrades, medaillons, filets a deux tons. Uniquement du CSS et des SVG en
   data-URI, donc aucune requete reseau supplementaire.
   Regle respectee : jamais de bleu ni de violet, la gamme reste chaude.
   ========================================================= */

/* ---- Trame de beton, tres discrete, sur les sections claires ---- */
.section--sable::before,
.section--blanc::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64'%3E%3Cpath d='M0 64L64 0M-8 8L8 -8M56 72L72 56' stroke='%23A6301F' stroke-opacity='0.045' stroke-width='1'/%3E%3C/svg%3E");
}
.section--sable,
.section--blanc { position: relative; }
.section--sable > .container,
.section--blanc > .container { position: relative; z-index: 1; }

/* ---- Sections foncees : grain et halo chaud ---- */
.section--beton,
.section--encre { position: relative; overflow: hidden; }
.section--beton::after,
.section--encre::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(70% 90% at 82% 12%, rgba(220, 148, 24, 0.16) 0%, rgba(220, 148, 24, 0) 60%),
    radial-gradient(60% 80% at 8% 95%, rgba(166, 48, 31, 0.22) 0%, rgba(166, 48, 31, 0) 62%);
}
.section--beton > .container,
.section--encre > .container { position: relative; z-index: 1; }

/* ---- Filet de titre a deux tons ---- */
.section-title::after {
  background: linear-gradient(90deg, var(--c-ocre) 0%, var(--c-bordeaux) 100%);
}

/* ---- Surtitre : petit trait plein plutot qu'un simple mot ---- */
.eyebrow::before {
  content: "";
  display: inline-block;
  width: 26px;
  height: var(--filet-h);
  margin-right: 10px;
  vertical-align: 0.22em;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--c-ocre), var(--c-bordeaux));
}

/* ---- Heros : degrade a trois arrets, plus profond ---- */
/* L'aplat bordeaux qui recouvrait la photo du heros a disparu : la photo est
   le fond, le voile d'encre de .hero::before assure le contraste. */
.hero::after {
  content: "";
  position: absolute;
  right: -6%;
  bottom: -34%;
  width: min(52vw, 620px);
  height: min(52vw, 620px);
  pointer-events: none;
  opacity: 0.5;
  background: radial-gradient(circle, rgba(220, 148, 24, 0.34) 0%, rgba(220, 148, 24, 0) 66%);
}

/* ---- Cartes de service : medaillon, liseré et relief au survol ---- */
.card--service,
.card--zone { position: relative; }
.card--service::before,
.card--zone::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--filet-h);
  z-index: 2;
  background: linear-gradient(90deg, var(--c-ocre), var(--c-bordeaux));
  opacity: 0;
  transition: opacity var(--t-base);
}
.card--service:hover::before,
.card--zone:hover::before,
.card--service:focus-within::before,
.card--zone:focus-within::before { opacity: 1; }

.card-media { position: relative; overflow: hidden; }
/* Le voile sombre du bas n'existe que pour rattraper un placeholder photo
   plat. Sur une illustration dessinee, il salit le tiers bas et mange le
   detail, donc il reste cantonne aux cartes de blogue. */
.blog-card .card-media::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(168deg, rgba(28, 24, 19, 0) 42%, rgba(28, 24, 19, 0.42) 100%);
}
.card-media img { transition: transform var(--t-slow); }
.blog-card:hover .card-media img { transform: scale(1.045); }
/* Pas de zoom sur les illustrations : la coupe de fondation porte ses lignes
   de cote au ras du cadre, un agrandissement les couperait. La carte se
   souleve deja au survol, ca suffit. */
.card--service:hover .card-media img { transform: none; }

/* ---- Pastille de numero d'etape : anneau ocre ---- */
.step-num {
  position: relative;
  background: linear-gradient(145deg, var(--c-bordeaux), #82230F);
  box-shadow: 0 0 0 4px rgba(220, 148, 24, 0.22);
}

/* ---- Coche de checklist dans un rond vert clair ----
   background-color et non background : le raccourci remet background-image a
   none, ce qui efface la coche elle meme et ne laisse qu'une pastille grise.
   Le glyphe est reduit a 13 px pour respirer a l'interieur du rond de 20. */
.checklist li::before {
  border-radius: 50%;
  background-color: var(--c-vert-voile);
  background-size: 13px 13px;
}
.section--beton .checklist li::before,
.section--encre .checklist li::before,
.cta-band .checklist li::before,
.hero .checklist li::before {
  background-color: rgba(220, 148, 24, 0.18);
}

/* ---- Bandeau d'appel a l'action : degrade et trame ---- */
.cta-band {
  background-image:
    linear-gradient(122deg, #5A5047 0%, var(--c-beton) 52%, #7C6E5F 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72'%3E%3Cpath d='M0 72L72 0' stroke='%23FFFFFF' stroke-opacity='0.05' stroke-width='2'/%3E%3C/svg%3E");
}

/* ---- Chiffres cles : le nombre en degrade ---- */
.stat__num {
  background: linear-gradient(120deg, var(--c-bordeaux) 0%, #C4512B 62%, var(--c-ocre) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.section--beton .stat__num,
.section--encre .stat__num,
.hero .stat__num {
  background: none;
  color: var(--c-sur-fonce);
  -webkit-text-fill-color: currentColor;
}

/* ---- Badges : leger degrade chaud ---- */
.badge {
  background-image: linear-gradient(135deg, rgba(220, 148, 24, 0.18), rgba(166, 48, 31, 0.10));
}

/* ---- Le mouvement reduit neutralise les effets de survol ---- */
@media (prefers-reduced-motion: reduce) {
  .card:hover .card-media img { transform: none !important; }
}

/* ---- Porte-visuel : un fond neutre, et rien de plus ----

   Ce bloc a longtemps porte une bichromie de marque : un degrade chaud sous
   l'image, fusionnee par dessus en mix-blend-mode: luminosity, plus un filtre
   qui assombrissait la source pour que la teinte ressorte.

   C'etait une bequille, assumee comme telle. Elle existait parce que la
   galerie, les comparateurs et les visuels d'article etaient des compositions
   abstraites presque identiques : la bichromie leur donnait la couleur et le
   rythme qu'ils n'avaient pas.

   Ces visuels sont maintenant de vraies photos de chantier, et les cartes de
   service de vraies illustrations. Les uns comme les autres portent leurs
   propres couleurs, et la fusion les detruisait : un terrain de pickleball
   ressortait terracotta, un plancher de microbeton ressortait rose. Elle est
   donc retiree entierement. Le fond ne sert plus qu'a occuper la place
   pendant le chargement de l'image.

   Si de nouveaux placeholders devaient reapparaitre un jour, la bequille est
   documentee dans DA-SOLTECH.md, section 9. Ne pas la remettre sur des
   photos. */
.card-media,
.blog-card .card-media,
.gallery-item,
.service-alt__media,
.article-media {
  background: var(--c-sable-fonce);
}

/* Les illustrations dessinees ne sont pas des photos : elles ont des marges
   composees et un fond sable qui leur appartient. Un object-fit: cover les
   rognerait. Les photos, elles, remplissent leur cadre. */
.card-media img[src$=".svg"],
.service-alt__media img[src$=".svg"] {
  object-fit: contain;
}

/* Le filet degrade sous la vignette de galerie reste : il rattache la legende
   a son image sans toucher a l'image elle meme. */
.gallery-item figcaption { position: relative; }
.gallery-item figcaption::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--c-ocre), var(--c-bordeaux));
}


/* ---- Tableaux : un en-tete de marque au lieu d'un ruban gris ----
   Les pages service portent jusqu'a trois tableaux. En gris, ils tirent la
   page vers le tableur. En encre avec un intitule ocre, ils reprennent le
   registre du pied de page et deviennent un element de composition.
   Contraste ocre sur encre : 7,0:1, largement au dessus du seuil AA. */
.spec-table thead th {
  background: linear-gradient(180deg, #2A241C 0%, var(--c-encre) 100%);
  color: var(--c-ocre);
  border-bottom: 2px solid var(--c-ocre);
}
/* La colonne d'intitules recoit un filet ocre : l'oeil retrouve le debut de
   chaque ligne sans avoir besoin d'un fond plein. */
.spec-table tbody th:first-child {
  box-shadow: inset 3px 0 0 var(--c-ocre-bord);
  padding-left: calc(var(--sp-4) + 3px);
}
.spec-table tbody tr:hover { background: var(--c-ocre-voile); }

/* ---- Tableaux ecrits dans un article ----
   Le contenu vient du back-office en HTML simple, sans classe. On applique
   donc le meme habillage que .spec-table a partir du contexte seul, sinon un
   tableau d'article ressort comme un bloc de texte aligne au hasard. */
/* Le cadre est porte par .table-wrap, que la route blogue pose autour de
   chaque tableau : deux bordures superposees se verraient. */
.article-body .table-wrap { margin: var(--sp-5) 0; }
.article-body table {
  font-size: 0.94rem;
  margin: 0;
}
.article-body th,
.article-body td {
  padding: 12px var(--sp-4);
  border-bottom: 1px solid var(--c-ligne);
  line-height: 1.55;
}
.article-body thead th {
  font-family: var(--ff-titre);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: linear-gradient(180deg, #2A241C 0%, var(--c-encre) 100%);
  color: var(--c-ocre);
  border-bottom: 2px solid var(--c-ocre);
  /* Le tableau defile deja dans son bloc : autant garder les intitules entiers
     plutot que de couper « PRIX INDICATIF » au milieu du mot. */
  white-space: nowrap;
}
.article-body tbody tr:nth-child(even) { background: var(--c-sable); }
.article-body tbody tr:last-child th,
.article-body tbody tr:last-child td { border-bottom: 0; }

/* =========================================================
   24. HEROS DE LA PAGE D ACCUEIL : LA COUPE DU SYSTEME
   Le heros etait un aplat degrade avec un titre pose dessus, comme sur
   n'importe quel site d'entrepreneur. Il porte maintenant la coupe
   axonometrique du systeme epoxy, avec ses cinq couches etiquetees.
   C'est l'argument de vente principal du metier, montre au lieu d'etre
   raconte, et c'est ce qu'aucun concurrent ne met en page d'accueil.
   ========================================================= */

/* ---- Le heros d'accueil, plein cadre ----
   La photo couvre presque toute la hauteur de l'ecran. A gauche, le titre et
   les deux boutons. A droite, quatre jalons de confiance minuscules : pas de
   badge, pas de panneau, juste un pictogramme et quelques mots poses sur la
   photo. Ils remplacent a la fois les badges d'antan et l'illustration. */
.hero--plein {
  min-height: clamp(600px, 88vh, 880px);
}
.hero--plein .hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(32px, 4vw, 72px);
  align-items: end;
}
.hero--plein .hero-inner {
  max-width: 640px;
  align-self: center;
}
.hero-jalons {
  list-style: none;
  margin: var(--sp-5) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
}
.hero-jalons li {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.78);
  text-shadow: 0 1px 10px rgba(28, 24, 19, 0.55);
}
.hero-jalons svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--c-ocre);
  opacity: 0.9;
}

/* ---- L'avant/apres de la banniere ----
   La meilleure preuve du metier, directement dans le heros : le meme
   comparateur que partout ailleurs, pose sur un panneau de verre. La photo
   d'avant est en portrait avec des bandes noires d'origine ; le cadrage 3/2
   en object-fit: cover les rogne. */
.hero-avap {
  width: min(100%, 520px);
  justify-self: end;
  padding: clamp(12px, 1.2vw, 18px);
  border-radius: var(--r-lg);
  background: rgba(28, 24, 19, 0.44);
  border: 1px solid rgba(250, 246, 239, 0.14);
}
@supports (backdrop-filter: blur(1px)) {
  .hero-avap {
    background: rgba(28, 24, 19, 0.30);
    backdrop-filter: blur(10px) saturate(1.05);
  }
}
.hero-avap .compare-slider { border-color: rgba(250, 246, 239, 0.2); }
.hero-avap__legende {
  margin: 10px 2px 0;
  font-size: 0.78rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.72);
}

@media (max-width: 920px) {
  .hero--plein { min-height: 0; }
  .hero--plein .hero-grid {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: var(--sp-6);
  }
  /* L'avant/apres reste : c'est la preuve du metier. Pleine largeur, sous le
     texte, et le heros reprend sa hauteur naturelle. */
  .hero-avap { justify-self: stretch; width: 100%; }
}

/* =========================================================
   25. TERRITOIRE : LA CARTE DE LA MAURICIE
   Cette section montrait huit cartes identiques, avec huit fois la meme
   epingle. Elle montre maintenant le territoire : le fleuve, la riviere
   Saint Maurice, les quatre axes routiers et les huit villes a leur place.
   Les coordonnees des points viennent du <desc> du fichier SVG, en
   pourcentage du cadre, elles ne sont pas devinees.
   ========================================================= */

.territoire {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(24px, 3.5vw, 56px);
  align-items: center;
}

.carte-zone {
  position: relative;
  margin: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--c-ligne);
  background: var(--c-sable);
}
.carte-zone img { display: block; width: 100%; height: auto; }

.carte-points { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; }
.point { position: absolute; left: var(--x); top: var(--y); }
.point a {
  position: absolute;
  top: 50%;
  display: block;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--c-blanc);
  border: 1px solid var(--c-ligne);
  box-shadow: 0 2px 6px rgba(28, 24, 19, 0.14);
  font-size: 0.76rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--c-texte);
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--t-base), color var(--t-base), border-color var(--t-base);
}
/* Le point du SVG est deja dessine a (x, y) : l'etiquette se pose a cote,
   d'un cote ou de l'autre selon la place disponible sur la carte. */
.point--droite a { left: 14px; transform: translateY(-50%); }
.point--gauche a { right: 14px; transform: translateY(-50%); }
.point--gauche a { left: auto; }
.point[data-siege="oui"] a {
  background: var(--c-bordeaux);
  border-color: var(--c-bordeaux);
  color: var(--c-blanc);
}
.point a:hover,
.point a:focus-visible {
  background: var(--c-encre);
  border-color: var(--c-encre);
  color: var(--c-sable);
}

.territoire-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
/* Le style de liste general pose une marge basse sur chaque li. Ici les
   entrees sont des rangees cliquables collees, la marge les disloquerait. */
.territoire-liste li { margin: 0; }
.territoire-liste a {
  display: block;
  padding: 11px var(--sp-3);
  border-radius: var(--r-md);
  text-decoration: none;
  color: var(--c-texte-doux);
  border-left: 3px solid transparent;
  transition: background var(--t-base), border-color var(--t-base);
}
.territoire-liste strong {
  display: block;
  font-family: var(--ff-titre);
  font-size: 1rem;
  color: var(--c-texte);
  margin-bottom: 1px;
}
.territoire-liste span { font-size: 0.86rem; line-height: 1.45; }
.territoire-liste a:hover,
.territoire-liste a:focus-visible {
  background: var(--c-blanc);
  border-left-color: var(--c-ocre);
}

/* Variante pleine largeur, pour la page qui liste les zones : la carte y sert
   de sommaire visuel avant la grille de secteurs. */
/* La carte de la Mauricie servie seule, au dessus de la liste des villes, sur
   /zones. Elle prend la largeur de lecture et non une largeur a elle : 860 px
   introduisait un quatrieme bord de colonne dans la section, ce que le systeme
   de largeurs interdit (voir « SYSTEME DE LARGEURS » plus haut). */
.carte-zone--large {
  max-width: var(--max-w-lecture);
  margin: 0 auto clamp(32px, 4vw, 56px);
}

/* Sous 900 px, la carte passe au dessus de la liste. Les etiquettes posees
   sur la carte deviennent trop petites pour etre des cibles tactiles fiables :
   on les masque, la liste dessous fait deja le travail et reste accessible. */
@media (max-width: 900px) {
  .territoire { grid-template-columns: minmax(0, 1fr); }
  .carte-points { display: none; }
}

/* ---- Pictogramme devant un lien de service ----
   Les sous-menus et la liste du pied de page alignaient huit entrees de texte
   de forme identique. Le pictogramme leur donne une silhouette, et permet de
   reperer un service avant d'avoir lu son nom. */
/* a.a-icone et non .a-icone : « .submenu a » vaut 0,1,1 et ecrasait un simple
   0,1,0, le lien restait en display: block et le pictogramme se retrouvait
   colle au texte. C'est le meme piege de specificite que sur .btn du menu,
   sur .choice du formulaire et sur .submenu a lui meme. */
a.a-icone {
  display: flex;
  /* Cale sur la premiere ligne, pas au milieu du bloc : sur un libelle qui
     passe sur deux lignes, un pictogramme centre flotte entre les deux. */
  align-items: flex-start;
  gap: 10px;
}
.lien-icone {
  display: inline-flex;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--c-ocre-fonce);
}
.lien-icone svg {
  width: 17px;
  height: 17px;
  display: block;
}
/* Dans le pied de page, sur fond encre, l'ocre franc ressort mieux. */
.site-footer .lien-icone { color: var(--c-ocre); }
.a-icone:hover .lien-icone,
.a-icone:focus-visible .lien-icone { color: currentColor; }

/* =========================================================
   26. DERNIERE RANGEE PLEINE
   Une grille de trois colonnes qui recoit cinq ou huit blocs laisse un trou
   a droite de sa derniere rangee. Le bloc se lit alors comme inacheve, et le
   defaut se voyait sur neuf pages du site.
   Deux reponses, dans cet ordre : redecouper quand la rangee peut se
   repartir autrement, completer la grille quand elle ne le peut pas. La
   grille des services a d'abord recu une carte d'appel a l'action pour
   combler sa neuvieme place ; le neuvieme service l'a rendue inutile.
   ========================================================= */

/* ---- Le principe ----
   Une grille laisse un trou quand son nombre de blocs n'est pas un multiple
   de son nombre de colonnes. La seule facon de traiter ca proprement est de
   rendre le nombre de colonnes PREVISIBLE a chaque palier : tant qu'une
   grille est en auto-fit, ce nombre change avec la largeur du conteneur et
   aucune regle ne peut savoir quel bloc se retrouve orphelin.
   On fixe donc les colonnes par palier, puis on rattrape l'orphelin restant.

   :nth-child(odd):nth-last-child(1) designe le dernier bloc quand son rang
   est impair, c'est a dire exactement le bloc qui reste seul sur une grille
   de deux colonnes. Il prend alors toute la largeur. */

/* ---- Au dessus de 920 px : trois colonnes, et cinq etapes sur base six ----
   En trois colonnes, cinq etapes donnent 3 + 2 et laissent 340 px de vide.
   Sur une base de six, les trois premieres prennent deux colonnes chacune et
   les deux dernieres en prennent trois : les deux rangees sont pleines, et
   aucune carte n'est mise en avant arbitrairement.
   :nth-child(4):nth-last-child(2) ne se verifie que si la liste compte
   exactement cinq elements : une liste de quatre ou de six garde donc le
   comportement normal sans qu'on ait rien a declarer. */
@media (min-width: 921px) {
  .steps { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .steps > * { grid-column: span 2; }
  .steps > :nth-child(4):nth-last-child(2),
  .steps > :nth-child(5):nth-last-child(1) { grid-column: span 3; }
}

/* ---- De 701 a 920 px : deux colonnes partout, orphelin en pleine largeur --- */
@media (min-width: 701px) and (max-width: 920px) {
  .steps,
  .stat-row,
  .blog-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .grid--2 > :nth-child(odd):nth-last-child(1),
  .grid--3 > :nth-child(odd):nth-last-child(1),
  .grid--4 > :nth-child(odd):nth-last-child(1),
  .steps > :nth-child(odd):nth-last-child(1),
  .stat-row > :nth-child(odd):nth-last-child(1),
  .blog-list > :nth-child(odd):nth-last-child(1),
  .gallery > :nth-child(odd):nth-last-child(1) { grid-column: 1 / -1; }
}

/* ---- De 921 a 1080 px : grilles de quatre et liste d'articles a deux ----
   La liste d'articles etait encore en auto-fill dans cette bande : trois
   articles y tombaient sur deux colonnes et le troisieme restait seul. */
@media (min-width: 921px) and (max-width: 1080px) {
  .blog-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--4 > :nth-child(odd):nth-last-child(1),
  .blog-list > :nth-child(odd):nth-last-child(1) { grid-column: 1 / -1; }
}

/* ---- Au dessus de 1080 px : la liste d'articles suit les grilles de trois -- */
@media (min-width: 1081px) {
  .blog-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---- Derniere rangee a deux blocs sur trois colonnes ----------------------
   Cinq familles de services, dix-sept realisations : des que le nombre de
   blocs vaut 3n+2, la derniere rangee laisse un trou d'un tiers a droite et
   la section se lit comme inachevee. Les regles d'orphelin plus haut ne
   traitent que le bloc SEUL ; il manquait le cas de la paire.

   On passe alors la grille a six pistes : un bloc ordinaire en occupe deux,
   ce qui donne exactement la meme largeur qu'un tiers (les gouttieres
   supplementaires se compensent), et les deux derniers en occupent trois,
   donc une demi largeur chacun. La rangee se ferme sans trou.

   Le :has() restreint la bascule aux seules grilles reellement en 3n+2 : une
   grille de six blocs garde ses trois colonnes. .gallery n'est reprise qu'au
   dessus de 1080 px, la ou son auto-fill donne surement trois colonnes ;
   .grid--3 des 921 px, ou elle passe a trois par regle explicite. */
@media (min-width: 921px) {
  .grid--3:has(> :last-child:nth-child(3n + 2)) {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
  .grid--3:has(> :last-child:nth-child(3n + 2)) > * { grid-column: span 2; }
  .grid--3:has(> :last-child:nth-child(3n + 2)) > :nth-last-child(-n + 2) { grid-column: span 3; }
}

@media (min-width: 1081px) {
  .gallery:has(> :last-child:nth-child(3n + 2)) {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
  .gallery:has(> :last-child:nth-child(3n + 2)) > * { grid-column: span 2; }
  .gallery:has(> :last-child:nth-child(3n + 2)) > :nth-last-child(-n + 2) { grid-column: span 3; }
}

/* ---- Les choix du questionnaire, deux colonnes a toutes les largeurs ----
   Ils etaient en auto-fit, donc a trois colonnes sur une tablette et a deux
   sur un grand ecran : le meme questionnaire laissait un trou a une largeur
   et pas a l'autre. Deux colonnes partout rendent le comportement lisible, et
   le dernier choix d'une liste impaire prend la pleine largeur, ce qui
   agrandit au passage sa cible tactile. */
.choice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.choice-grid > :nth-child(odd):nth-last-child(1) { grid-column: 1 / -1; }


/* =========================================================
   27. NUANCIER
   La charte de couleurs des enduits. Vingt-quatre teintes, qui viennent du
   fournisseur et non de la marque : elles sont donc posees en variable
   d'element, jamais en jeton de palette, pour qu'aucune ne se retrouve par
   accident dans l'interface.
   Vingt-quatre se divise par 6, 4, 3 et 2 : quel que soit le palier, la
   derniere rangee est pleine.
   ========================================================= */
.nuancier {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--sp-4) var(--sp-3);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nuancier > li {
  margin: 0;
  min-width: 0;
  text-align: center;
}
.nuance__pastille {
  display: block;
  aspect-ratio: 1 / 1;
  border-radius: var(--r-md);
  background: var(--teinte);
  /* Un filet interieur plutot qu'une bordure : sur une teinte tres claire la
     pastille garde un bord visible, sur une teinte foncee le filet ne creuse
     pas un halo clair autour du carre. */
  box-shadow: inset 0 0 0 1px rgba(28, 24, 19, 0.14), var(--sh-sm);
}
.nuance__code {
  display: block;
  margin-top: 8px;
  font-family: var(--ff-titre);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--c-texte-doux);
  overflow-wrap: anywhere;
}

@media (max-width: 920px) {
  .nuancier { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .nuancier { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
  .nuancier { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* =========================================================
   28. LA SCENE DU FORMULAIRE
   Le questionnaire de soumission occupait la colonne gauche d'une grille a
   deux, avec une colonne laterale aussi chargee que lui : trois etapes en
   cartes, une carte telephone, une carte d'avantages. Les deux se disputaient
   l'attention, et la colonne etroite ecrasait ses propres titres.
   Le formulaire est maintenant SEUL au centre. De part et d'autre, deux
   rives de reassurance : petites, en gris doux, sans carte ni bordure. Elles
   appartiennent au decor ; on les lit si on hesite, on ne les remarque pas
   sinon.
   ========================================================= */
.form-scene {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 700px) minmax(0, 1fr);
  grid-template-areas: "gauche formulaire droite";
  gap: clamp(28px, 3vw, 52px);
  align-items: start;
}
/* Le conteneur standard laisserait a peine 170 px a chaque rive : des lignes
   de deux mots. La scene du formulaire est la seule a avoir droit a un
   conteneur elargi, pour que les rives respirent sans grossir. */
.container:has(> .form-scene) { max-width: 1380px; }
.form-scene > .form-card { grid-area: formulaire; }
.form-rail--gauche { grid-area: gauche; }
.form-rail--droite { grid-area: droite; }

/* Les rives suivent le lecteur pendant qu'il descend le questionnaire :
   collantes, mais sous l'entete. */
.form-rail__inner {
  position: sticky;
  top: 104px;
  display: grid;
  gap: var(--sp-4);
}
.form-rail__titre {
  margin: 0;
  font-family: var(--ff-titre);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-texte-doux);
}
.rail-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.rail-item svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--c-ocre-fonce);
  opacity: 0.75;
}
.rail-item p {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--c-texte-doux);
}
.rail-item strong {
  font-weight: 600;
  color: var(--c-texte);
}
.rail-item a { color: var(--c-bordeaux); }

/* Sous 1080 px, plus de place pour des rives : elles se rangent sous le
   formulaire, sur deux colonnes, toujours aussi discretes. */
@media (max-width: 1080px) {
  .form-scene {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "formulaire" "gauche" "droite";
    gap: var(--sp-6);
  }
  .form-rail__inner {
    position: static;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .form-rail__titre { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .form-rail__inner { grid-template-columns: minmax(0, 1fr); }
}
