@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;
  background-color: var(--c-sable-fonce);
}
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); }
.brand-mark {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: var(--r-md);
  background: var(--c-bordeaux);
  color: var(--c-blanc);
}
.brand-mark svg {
  width: 24px;
  height: 24px;
}
.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;
}

/* ---- 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.
   ========================================================= */
.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-bordeaux);
  background-image: linear-gradient(to right, var(--c-bordeaux-78), var(--c-bordeaux-55)),
    var(--hero-img, none);
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  isolation: isolate;
  overflow: hidden;
}
.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 : compacte, pictogramme en tete ---- */
.card--zone {
  flex-direction: row;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
}
.card--zone .card-body {
  padding: 0;
  gap: var(--sp-1);
}
.card--zone svg {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  color: var(--c-bordeaux);
}
.card--zone .card-title { font-size: 1.08rem; }

/* ---- 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) */
.ph { filter: saturate(.82) contrast(1.04) sepia(.06); }
.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(48px, 7vw, 80px) 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;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-6) var(--sp-5);
  padding-bottom: var(--sp-7);
}
.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 {
  background: var(--c-ocre);
  color: var(--c-encre);
}
.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; }
.footer-col h3,
.footer-col h4 {
  font-family: var(--ff-titre);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-sur-fonce);
  margin: 0 0 var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-sur-fonce-ligne);
}
.footer-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}
.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-3);
}
.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;
}
.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 + *,
.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; }
}

/* =========================================================
   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; }
  .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; }
  .mobile-toggle { display: inline-flex; }
  .mobile-nav { display: flex; }
  .grid--3 { 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); }
  .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);
    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 ---- */
.hero {
  background-image:
    linear-gradient(104deg, rgba(130, 35, 15, 0.90) 0%, rgba(166, 48, 31, 0.72) 46%, rgba(196, 81, 43, 0.58) 100%),
    var(--hero-img, none);
}
.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; }
}

/* ---- Deux regimes de visuel, et il faut les distinguer ----

   1. Les VRAIES ILLUSTRATIONS. Les huit vignettes de service sont dessinees a
      la main, une par metier : un garage a flocons, un entrepot a bandes de
      circulation, une coupe de fondation avec son drain francais, un terrain
      de pickleball ligne. Elles portent deja leurs couleurs et leur sujet.
      On n'y touche pas.

   2. Les PLACEHOLDERS PHOTO. La galerie de realisations, le comparateur et les
      visuels d'article attendent de vraies photos de chantier. En attendant,
      ce sont des compositions abstraites presque identiques. La bichromie de
      marque existe pour eux, et pour eux seulement : le fond porte un degrade
      chaud, l'image est fusionnee en luminosite, un mur de beige devient une
      serie coloree. Le procede fonctionnera tel quel quand les photos
      arriveront.

   Appliquer le regime 2 au regime 1 detruirait les illustrations : elles
   perdraient leurs couleurs propres pour prendre celle du degrade, et on
   reviendrait exactement au probleme qu'elles resolvent. */

.card--service .card-media {
  background: var(--c-sable);
}

/* Les placeholders photo, eux, prennent la bichromie. */
.blog-card .card-media {
  background: linear-gradient(152deg, var(--c-bordeaux) 0%, #C4512B 58%, var(--c-ocre) 100%);
}
.blog-card:nth-child(3n + 2) .card-media {
  background: linear-gradient(152deg, #1C1813 0%, #82230F 55%, var(--c-bordeaux) 100%);
}
.blog-card:nth-child(3n + 3) .card-media {
  background: linear-gradient(152deg, #4A2F0C 0%, var(--c-ocre-fonce) 52%, var(--c-ocre) 100%);
}
/* Les placeholders sont clairs : en fusion luminosite, un pixel presque blanc
   reste presque blanc et la teinte du degrade ne se voit plus. On assombrit
   donc la source avant de fusionner. Au survol le filtre tombe avec la fusion. */
.blog-card .card-media img {
  mix-blend-mode: luminosity;
  opacity: 0.95;
  filter: contrast(1.24) brightness(0.78);
  transition: opacity var(--t-base), transform var(--t-slow),
              filter var(--t-base), mix-blend-mode var(--t-base);
}
.blog-card:hover .card-media img,
.blog-card:focus-within .card-media img {
  mix-blend-mode: normal;
  opacity: 1;
  filter: none;
}

/* ---- Bichromie de galerie, teintee par famille de travaux ----
   La teinte suit l'attribut data-cat et non le rang : quand on filtre sur une
   famille, les vignettes restantes forment une serie coherente au lieu de
   perdre leur rythme. En vue « Tout », les sept teintes se croisent et la
   grille cesse d'etre un mur de beige.
   isolation: isolate confine la fusion a la vignette, sinon l'image se
   melangerait au fond de la section. */
.gallery-item {
  isolation: isolate;
  background: linear-gradient(152deg, var(--c-bordeaux) 0%, #C4512B 58%, var(--c-ocre) 100%);
}
.gallery-item[data-cat="epoxy-commercial"] {
  background: linear-gradient(152deg, var(--c-encre) 0%, var(--c-bordeaux-fonce) 55%, var(--c-bordeaux) 100%);
}
.gallery-item[data-cat="acrylique-exterieur"] {
  background: linear-gradient(152deg, #8A4A1E 0%, #C4512B 50%, var(--c-ocre) 100%);
}
.gallery-item[data-cat="acrylique-interieur"] {
  background: linear-gradient(152deg, #4A2F0C 0%, var(--c-ocre-fonce) 52%, var(--c-ocre) 100%);
}
.gallery-item[data-cat="terrains-sportifs"] {
  background: linear-gradient(152deg, #14532B 0%, var(--c-vert) 55%, var(--c-ocre) 100%);
}
.gallery-item[data-cat="resurfacage"] {
  background: linear-gradient(152deg, var(--c-encre) 0%, var(--c-beton) 58%, #A89076 100%);
}
.gallery-item[data-cat="solages"] {
  background: linear-gradient(152deg, #331608 0%, #6E4130 55%, var(--c-beton) 100%);
}
.gallery-item[data-cat="scellant"] {
  background: linear-gradient(152deg, #5A3A2A 0%, var(--c-bordeaux) 55%, var(--c-ocre) 100%);
}
.gallery-item img {
  mix-blend-mode: luminosity;
  opacity: 0.95;
  filter: contrast(1.24) brightness(0.78);
  transition: opacity var(--t-base), transform var(--t-slow),
              filter var(--t-base), mix-blend-mode var(--t-base);
}
.gallery-item:hover img,
.gallery-item:focus-within img {
  mix-blend-mode: normal;
  opacity: 1;
  filter: none;
}
/* Le filet de la legende reprend la teinte de la vignette : le lien entre
   l'image et son texte se voit meme quand la carte est isolee. */
.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));
}

/* ---- Rangees alternees ----
   Ces deux rangees parlent de l'epoxy de garage et de l'epoxy commercial :
   elles montrent donc les illustrations de ces deux services la, et non un
   placeholder abstrait. Pas de bichromie ici non plus, pour la meme raison
   que sur les cartes : les illustrations portent deja leurs couleurs.
   La bichromie ne reste que sur .ph, les visuels encore en attente de photo. */
.service-alt__media {
  background: var(--c-sable);
  border: 1px solid var(--c-ligne);
}
.service-alt__media img { object-fit: contain; }
/* Un placeholder photo dans une rangee alternee garde, lui, la bichromie. */
.service-alt__media:has(> .ph) {
  isolation: isolate;
  background: linear-gradient(152deg, var(--c-bordeaux) 0%, #C4512B 58%, var(--c-ocre) 100%);
  border: 0;
}
.service-alt:nth-child(even) .service-alt__media:has(> .ph) {
  background: linear-gradient(208deg, var(--c-encre) 0%, var(--c-bordeaux-fonce) 55%, var(--c-ocre-fonce) 100%);
}
.service-alt__media > .ph {
  object-fit: cover;
  mix-blend-mode: luminosity;
  opacity: 0.95;
  filter: contrast(1.24) brightness(0.78);
  transition: opacity var(--t-base), filter var(--t-base), mix-blend-mode var(--t-base);
}
.service-alt:hover .service-alt__media > .ph {
  mix-blend-mode: normal;
  opacity: 1;
  filter: none;
}

/* ---- 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); }

/* ---- Visuel d'ouverture d'article : meme bichromie que les cartes ---- */
.article-media {
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: linear-gradient(152deg, var(--c-bordeaux) 0%, #C4512B 58%, var(--c-ocre) 100%);
}
.article-media img {
  display: block;
  width: 100%;
  /* Cadre impose plutot que subi : le back-office accepte n'importe quelle
     photo, et sans ratio fixe une image carree ou verticale ferait exploser
     le haut de l'article. */
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 0;
  mix-blend-mode: luminosity;
  opacity: 0.95;
  filter: contrast(1.24) brightness(0.78);
  transition: opacity var(--t-base), filter var(--t-base), mix-blend-mode var(--t-base);
}
.article-media:hover img {
  mix-blend-mode: normal;
  opacity: 1;
  filter: none;
}

/* ---- 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.
   ========================================================= */

.hero--systeme .hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  gap: clamp(32px, 4vw, 72px);
  align-items: center;
}
.hero--systeme .hero-inner { max-width: none; }

.hero-systeme {
  position: relative;
  margin: 0;
  /* Le SVG occupe la gauche du bloc, les etiquettes occupent la droite.
     Ses cinq lignes de rappel se terminent a 87,8 % de sa propre largeur :
     a 60 % de largeur d'image, elles arrivent donc a 52,7 % du bloc, et les
     etiquettes se posent juste apres. Ces nombres viennent du <desc> du
     fichier, ils ne sont pas devines. */
  --largeur-image: 60%;
  --x-etiquette: 55%;
}
.hero-systeme img {
  display: block;
  width: var(--largeur-image);
  height: auto;
}
.systeme-legende {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}
.systeme-legende li {
  position: absolute;
  left: var(--x-etiquette);
  top: var(--y);
  transform: translateY(-50%);
  display: flex;
  align-items: baseline;
  gap: 9px;
  font-size: clamp(0.78rem, 0.72rem + 0.24vw, 0.92rem);
  font-weight: 500;
  line-height: 1.25;
  color: var(--c-sur-fonce);
  white-space: nowrap;
}
.systeme-legende b {
  font-family: var(--ff-titre);
  font-size: 0.72em;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--c-ocre);
}
.hero-systeme figcaption {
  margin-top: var(--sp-3);
  padding-left: 2px;
  font-size: 0.86rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.74);
  max-width: 34ch;
}

/* Sous 1080 px le heros repasse sur une colonne. La coupe reste, mais elle
   passe sous le texte et se recentre : c'est le meilleur argument du metier,
   on ne le supprime pas sur telephone. */
@media (max-width: 1080px) {
  .hero--systeme .hero-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(28px, 5vw, 44px);
  }
  .hero-systeme {
    --largeur-image: 46%;
    --x-etiquette: 50%;
    max-width: 520px;
  }
}
@media (max-width: 560px) {
  .hero-systeme {
    --largeur-image: 42%;
    --x-etiquette: 47%;
  }
  /* 0.74rem tombait a 11,84 px, sous le plancher de 12 px que le site
     s'impose : en dessous, la lecture devient penible sur un telephone. */
  .systeme-legende li { font-size: 0.8rem; gap: 6px; }
  .hero-systeme figcaption { font-size: 0.8rem; }
}

/* =========================================================
   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. */
.carte-zone--large {
  max-width: 860px;
  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, poser un appel a l'action quand elle ne le peut pas.
   ========================================================= */

/* ---- 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)); }
}

/* ---- 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; }

/* ---- Carte d'appel a l'action en fin de grille ----
   Huit services sur trois colonnes donnent 3 + 3 + 2. Impossible de les
   redecouper sans deformer une carte qui porte une illustration, donc la
   neuvieme place recoit un appel a l'action. Il ferme la liste au lieu de la
   laisser en suspens, et il tombe la ou le lecteur vient justement de finir
   de comparer. */
.card--cta {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--sp-3);
  padding: var(--sp-5);
  background:
    linear-gradient(152deg, var(--c-bordeaux) 0%, #8E2717 55%, var(--c-bordeaux-fonce) 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.06' stroke-width='2'/%3E%3C/svg%3E");
  border: 0;
  color: var(--c-sur-fonce);
}
.card--cta h3 {
  font-size: clamp(1.15rem, 1.05rem + 0.45vw, 1.4rem);
  line-height: 1.25;
  color: var(--c-blanc);
  margin: 0;
}
.card--cta p {
  margin: 0;
  font-size: 0.94rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.86);
}
.card--cta .btn { align-self: flex-start; margin-top: var(--sp-2); }
/* Cette carte n'a pas de lien qui recouvre toute sa surface : c'est son
   bouton qui porte l'action, et le survol ne doit donc pas la soulever comme
   une carte cliquable. */
.card--cta:hover { transform: none; box-shadow: var(--sh-card); }
.card--cta::before { display: none; }
