/* ===========================================================================
   BâtiConseil Résidentiel — système de design « MÉTIER »
   ---------------------------------------------------------------------------
   Le raisonnement, en une phrase : l'argument de vente de cette entreprise
   n'est pas un document, c'est un homme. Trente ans de chantier, compagnon
   charpentier-menuisier, surintendant sur plusieurs centaines de maisons — et
   aujourd'hui aucun intérêt dans ce que le client choisit. Le site doit donner
   les deux à la fois : le métier et l'indépendance.

   Ce qui vient avant tout le reste : la PHOTOGRAPHIE. Un conseiller en
   construction dont le site ne montre aucun chantier n'a pas l'air prudent,
   il a l'air de ne pas en avoir. Le design est donc bâti autour de l'image —
   entête photographique, planches pleine largeur, portraits — et la typographie
   travaille par-dessus, pas à sa place.

   La matière : béton chaud, graphite mouillé, et le cèdre du bois de charpente
   fraîchement livré. Rien de crémeux, rien de bureaucratique. Des blocs
   massifs, des angles adoucis, des ombres portées courtes — du bâti, pas du
   papier.

   Quatre décisions structurent le fichier :

   1. TOUT EST JETON. .band--rust, .band--ink, le pied de page et le mode
      sombre ne surchargent aucun composant : ils rebasculent --paper, --ink,
      --line, --accent. 74 pages ne restent tenables qu'à ce prix.
   2. UN ACCENT CHAUD QUI PORTE L'ÉNERGIE, un bleu d'acier qui porte le calme.
      Le cèdre appelle à l'action et souligne; l'acier structure.
   3. LE STATUTAIRE SE SIGNALE PAR LA FORME, pas par une couleur réservée :
      .boundary porte une bande hachurée de chantier. On sait ce que c'est
      avant de l'avoir lue.
   4. AUCUN JAVASCRIPT. Le menu mobile est un <details>, la navigation un
      <nav>, et chaque mot est dans le HTML servi.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   POLICES SERVIES D'ICI, PAS DE GOOGLE FONTS. Un <link> vers l'API Google Fonts
   transmettait l'adresse IP de chaque visiteur à Google LLC (États-Unis) à
   chaque page vue, alors que la politique de confidentialité ne nomme que
   Netlify et Namecheap comme destinataires (Loi 25, P-39.1, art. 17). Plutôt
   que d'ajouter Google à la politique, on a cessé la transmission.

   src/fonts/ contient les fichiers woff2 que Google servait à ce site pour la
   plage « latin » (Archivo v2.001, Source Sans 3 v3.052, relevés le
   2026-09-19), donc le rendu ne change pas. La plage « latin » couvre tout le
   français : accents, œ, guillemets, espaces insécables, tirets, €. Les deux
   seuls caractères du site hors de cette plage (≈, →) venaient déjà de la
   police de secours. Licence SIL OFL 1.1 : les textes sont à côté des fichiers.

   Les descripteurs reprennent ceux du CSS de Google — mêmes noms de famille,
   donc --f-head et --f-text ne bougent pas. Un fichier par face, sans
   unicode-range. layout.html précharge les deux faces présentes sur chaque page.
   --------------------------------------------------------------------------- */
@font-face{
  font-family:"Archivo";
  font-style:normal;
  font-weight:400 800;
  font-stretch:75% 100%;
  font-display:swap;
  src:url(/fonts/archivo-latin.woff2) format("woff2");
}
@font-face{
  font-family:"Source Sans 3";
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
  src:url(/fonts/source-sans-3-latin.woff2) format("woff2");
}
@font-face{
  font-family:"Source Sans 3";
  font-style:italic;
  font-weight:400;
  font-display:swap;
  src:url(/fonts/source-sans-3-italic-latin.woff2) format("woff2");
}

:root{
  /* --- surfaces & encre ---------------------------------------------------- */
  --paper:#ffffff;          /* la page : blanc franc */
  --surface:#f4f1ec;        /* béton chaud : les bandes alternées, les panneaux */
  --raised:#ffffff;         /* les cartes posées sur le béton */
  --deep:#14181c;           /* graphite mouillé : bandes inversées, pied */
  --ink:#171a1e;            /* le texte */
  --line:#e3ded4;           /* le filet */
  --line-firm:#cdc6b8;

  /* --- accents ------------------------------------------------------------- */
  --accent:#bd5423;         /* cèdre : appels à l'action, marques, soulignés */
  --accent-deep:#9c421a;    /* sa version qui tient le 4,5:1 sur blanc */
  --steel:#2b4759;          /* acier : structure, liens, chiffres */

  /* Ce qui s'écrit PAR-DESSUS un aplat d'accent. En clair l'accent est foncé,
     donc le texte est blanc; en sombre l'accent s'éclaircit pour tenir sur la
     page, et un bouton blanc sur pêche tombe à 2,6:1. Le premier plan doit
     donc basculer avec l'accent, pas être écrit en dur dans le composant. */
  --on-accent:#ffffff;
  --on-steel:#ffffff;

  /* Trois valeurs d'encre, pas une de plus, et les pourcentages sont mesurés
     plutôt que choisis à l'œil : sur le papier, --ink-soft donne 9,7:1 et
     --ink-mute 5,1:1. Tout ce qui est réglé en --ink-mute est du 12–14 px, donc
     doit tenir le 4,5:1 de la norme AA — à 58 % il tombait à 4,1:1.

     PIÈGE, et il a mordu : une propriété personnalisée résout ses var() là où
     elle est DÉCLARÉE, pas là où elle est utilisée. Ces trois-là sont déclarées
     sur :root, donc elles restent accrochées à l'encre de :root. Toute portée
     qui rebascule --ink (.band--ink, .site-foot, l'entête photographique) doit
     les redéclarer, sinon elle hérite d'un texte foncé sur un fond foncé. */
  --ink-soft:color-mix(in srgb,var(--ink) 72%,transparent);
  --ink-mute:color-mix(in srgb,var(--ink) 64%,transparent);
  --ink-wash:color-mix(in srgb,var(--ink) 8%,transparent);

  /* --- caractères ---------------------------------------------------------- */
  /* Archivo porte le titrage : un grotesque un peu resserré, de la famille des
     lettrages de signalisation de chantier. Source Sans 3 porte la lecture :
     ces pages font 2 000 mots et se lisent le soir. Aucun monospace — la voix
     « formulaire administratif » est exactement ce qu'on quitte. */
  --f-head:"Archivo",ui-sans-serif,system-ui,"Segoe UI",Roboto,sans-serif;
  --f-text:"Source Sans 3",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;

  --t-micro:12px; --t-cap:14px; --t-sm:16px; --t-body:18.5px; --t-lede:22px;

  --s-4:4px;  --s-8:8px;  --s-12:12px; --s-16:16px; --s-24:24px; --s-32:32px;
  --s-40:40px; --s-48:48px; --s-56:56px; --s-64:64px; --s-80:80px; --s-96:96px;

  --page:1300px;            /* la coquille : entête, barre de fiche, pied.
                               1300 et non 1180 : à 1180 la coquille n'offrait
                               que 1116 px de contenu, alors que marque (150) +
                               nav (668 au maximum de son contenu) + téléphone
                               et bouton (333) en demandent 1216. La nav, qui
                               porte min-width:0, se laissait comprimer sans
                               protester et ses liens — en white-space:nowrap —
                               débordaient de leur boîte pour se peindre par
                               dessus le numéro de téléphone. « Contact » et
                               « (514) 246-9596 » s'imprimaient l'un sur l'autre
                               sur les 74 pages, à toutes les largeurs. */
  --content:1000px;         /* la colonne de contenu, à l'intérieur des bandes.
                               1000 et non 1180 : la mesure de lecture fait 607 px,
                               et une rangée de cartes 1,6 fois plus large qu'un
                               paragraphe se lit encore comme le même système. Au-delà,
                               ça se lit comme deux mises en page superposées. */
  --gap:88px;               /* respiration entre sections */
  --pad:32px;
  --head-h:74px;

  --r-sm:6px; --r:10px; --r-lg:16px;
  --lift:0 1px 2px rgba(23,26,30,.06), 0 10px 28px -18px rgba(23,26,30,.35);
  --lift-hi:0 2px 4px rgba(23,26,30,.07), 0 20px 44px -22px rgba(23,26,30,.42);
}

/* Le mode sombre n'est pas une coquetterie : ce site se lit le soir, après le
   chantier. Il ne redéfinit que des jetons. */
@media (prefers-color-scheme:dark){
  :root{
    --paper:#101316; --surface:#181d21; --raised:#1b2126; --deep:#0b0e10;
    --ink:#eceae5; --line:#2a3137; --line-firm:#3c454c;
    --accent:#e88a55; --accent-deep:#f0a074; --steel:#8fb6cf;
    --on-accent:#14181c; --on-steel:#101316;
    --lift:0 1px 2px rgba(0,0,0,.5), 0 10px 28px -18px rgba(0,0,0,.8);
    --lift-hi:0 2px 4px rgba(0,0,0,.55), 0 20px 44px -22px rgba(0,0,0,.9);
  }
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:calc(var(--head-h) + 24px)}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--f-text);
  font-size:var(--t-body);
  line-height:1.68;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

img{max-width:100%;height:auto}

/* ------------------------------------------------------------- structure --- */

.band{padding:var(--gap) 0;position:relative}
.band--tight{padding:calc(var(--gap) * .62) 0}

/* Le panneau. Un demi-ton de béton chaud, pleine largeur, sans filet : la
   couleur suffit à séparer, et un filet en plus ferait « tableau ». */
.band--rust{background:var(--surface)}

/* L'inversion. Elle ne surcharge aucun composant : elle rebascule les jetons,
   et .note, .boundary, table, .btn suivent tout seuls. Un filet de cèdre en
   haut donne le bord — sinon, en mode sombre, la bande disparaît dans la page. */
.band--ink{
  --paper:#14181c; --surface:#1c2228; --raised:#1c2228; --ink:#f2f0ea;
  --ink-soft:rgba(242,240,234,.78); --ink-mute:rgba(242,240,234,.66);
  --ink-wash:rgba(242,240,234,.10);
  --line:rgba(242,240,234,.16); --line-firm:rgba(242,240,234,.30);
  --accent:#e88a55; --accent-deep:#f0a074; --steel:#9fc3da;
  --on-accent:#14181c; --on-steel:#14181c;
  background:var(--paper);
  color:var(--ink);
  border-top:3px solid var(--accent);
}
@media (prefers-color-scheme:dark){ .band--ink{--paper:#1a2026;--surface:#232a31;--raised:#232a31} }

/* La bande et la colonne sont deux choses différentes, et les confondre est
   exactement ce qui cassait la mise en page : .band--rust et .band--ink portent
   leur fond sur le MÊME élément que la largeur maximale, donc les bandes
   flottaient en dalles de 1180 px au milieu d'un écran de 1920. Ici .bleed est
   une grille pleine largeur : le fond touche les deux bords de la fenêtre, et
   les enfants se rangent dans la colonne du milieu. */
.bleed{
  width:100%;
  display:grid;
  grid-template-columns:
    [full-start] minmax(var(--pad),1fr)
    [content-start] minmax(0,var(--content)) [content-end]
    minmax(var(--pad),1fr) [full-end];
}
/* min-width:0 est obligatoire, pas décoratif : un enfant de grille a
   min-width:auto, donc il refuse de descendre sous sa largeur min-content. Un
   tableau comparatif large impose alors 590 px à la colonne dans une bande qui
   n'en fait que 305, et la page entière déborde. */
.bleed > *{grid-column:content;min-width:0}

/* La mesure de lecture est centrée dans la colonne, pas collée à sa gauche :
   sinon chaque paragraphe traîne 540 px de vide à sa droite pendant que la
   rangée de cartes juste au-dessus fait toute la largeur. */
/* width:100% n'est pas redondant : sur un enfant de grille, `margin-inline:auto`
   désactive l'étirement, la boîte se dimensionne alors sur son contenu et monte
   jusqu'à sa max-width — 590 px dans une piste de 324, donc toute la page
   déborde dès qu'un tableau comparatif est présent. Avec width:100%, la boîte
   suit la piste, et les marges auto ne centrent que le reste. */
.measure{width:100%;max-width:72ch;margin-inline:auto}
/* La règle qui suivait ici — `.bleed > .measure{margin-inline:0 auto}` — disait
   exactement le contraire du commentaire ci-dessus : marge gauche nulle, marge
   droite automatique, donc TOUT le texte collé au bord gauche de la colonne de
   contenu. Mesuré à 1512 px : le paragraphe occupait 256→918, la rangée de
   cartes juste au-dessus 256→1256, et l'entête 256→771. Trois blocs, un seul
   bord commun à gauche, trois bords droits différents, et 594 px de vide à
   droite de chaque paragraphe. C'est ce ressaut que le commentaire prétendait
   avoir corrigé et que la règle rétablissait.
   Un seul axe, donc : tout est concentrique à la fenêtre, et les trois largeurs
   — lecture 72ch, entête 820, contenu 1000 — s'emboîtent au lieu de se
   décaler. */
.measure--narrow{width:100%;max-width:50ch;margin-inline:auto}
/* Un sommaire n'est pas un texte suivi : il prend toute la colonne. Mais c'est LE
   SOMMAIRE qui la prend, pas le bloc entier — en relâchant la largeur de .measure,
   le paragraphe d'introduction et le titre au-dessus partaient eux aussi à 1000 px,
   deux fois la mesure de lecture du reste du site. La liste débord donc comme les
   tableaux, sur le même axe, et le texte qui l'annonce garde ses 662 px. */
@media (min-width:1000px){
  .measure > .link-list{margin-inline:calc((100% - var(--content)) / 2)}
}

/* Le filet est une coupure douce à l'intérieur d'un texte suivi. Deux emplois le
   rendaient muet ou redondant : juste avant un h2, qui trace déjà sa propre poutre
   — la coupure était dessinée deux fois, à 48 px d'intervalle — et en tête d'une
   bande, où il flottait à 103 px du bord sans rien séparer. */
.rule{border:0;border-top:1px solid var(--line);margin:var(--s-48) 0}
.rule:has(+ h2),
.measure > .rule:first-child,
.measure--narrow > .rule:first-child{display:none}

/* --------------------------------------------------------------- titrage --- */

h1,h2,h3{
  margin:0;
  font-family:var(--f-head);
  font-weight:700;
  line-height:1.14;
  letter-spacing:-.022em;
  text-wrap:balance;
}

.display{
  font-size:clamp(34px,5.2vw,58px);
  font-weight:800;
  font-stretch:96%;
  letter-spacing:-.032em;
  line-height:1.05;
  margin-bottom:var(--s-24);
  max-width:17ch;
  overflow-wrap:break-word;
}
.display--lg{font-size:clamp(37px,6vw,68px);max-width:16ch}

/* Le mot opératoire. Un trait de crayon de menuisier posé sous la ligne de
   base — plein, chaud, assumé. Pas un lavis, pas un surligneur de bureau. */
.hl{
  background-image:linear-gradient(var(--accent),var(--accent));
  background-size:100% .16em;
  background-position:0 92%;
  background-repeat:no-repeat;
  padding-bottom:.02em;
  box-decoration-break:clone;-webkit-box-decoration-break:clone;
}

/* LE geste de section : une poutre. Un filet épais d'encre qui traverse toute
   la mesure, avec un about de cèdre à son extrémité gauche — la façon dont une
   solive est reprise sur son appui. C'est ce qui découpe 74 pages de lecture
   en morceaux qu'on ose commencer. */
h2{
  font-size:clamp(26px,3.2vw,38px);
  letter-spacing:-.026em;
  margin-bottom:var(--s-24);
  padding-top:var(--s-24);
  border-top:3px solid var(--ink);
  position:relative;
  overflow-wrap:break-word;
}
h2:not(.marker)::before{
  content:"";position:absolute;top:-3px;left:0;
  width:64px;height:3px;background:var(--accent);
}
/* La poutre n'a pas de marge haute : quand le h2 ouvre une bande, les 88 px de la
   bande lui tiennent lieu d'élan. Quand il suit un paragraphe DANS la même bande —
   ce qui arrive sur une trentaine de pages — il ne lui restait que les 24 px de
   marge basse du paragraphe, et la poutre venait heurter la ligne précédente.
   La même barre séparait donc deux sections avec deux respirations différentes. */
:where(p,ul,ol,figure,table,hr,.cols,.stack,.note,.boundary,.table-bleed,.verified) + h2:not(.marker){
  margin-top:var(--s-64);
}
/* .marker est l'étiquette du bloc de navigation de bas de page : elle n'est pas
   un titre de section, elle est exclue par le sélecteur plutôt que par un ordre
   de cascade. */
/* L'étiquette de bloc. La typographie était accrochée à `.siblings .marker`,
   donc elle ne servait que le bloc de navigation de bas de page : les 80 autres
   `.marker` répartis sur 43 pages tombaient en corps de texte, indistincts du
   paragraphe suivant. Trois pages — hypotheque-autoconstruction-quebec,
   budget-preliminaire-construction-maison et certificat-de-localisation-prix —
   n'avaient plus alors AUCUN niveau de titre visible dans leur corps. */
.marker{
  border-top:0;padding-top:0;
  font-family:var(--f-head);font-size:var(--t-micro);font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-mute);
  margin-bottom:var(--s-24);
}
/* .marker fait deux métiers, et un seul des deux était habillé.
   Trente-neuf fois, elle est posée AU-DESSUS d'un titre : c'est un sur-titre, et
   les 12 px gris en capitales sont exactement ce qu'il faut.
   Trente-cinq fois, rien ne la suit qu'un paragraphe ou un tableau : elle EST le
   titre de la section. En capitales interlettrées de 12 px, « Les allocations : une
   quantité, pas un souhait » se lit deux fois moins vite qu'en bas de casse — et sur
   trois pages (budget préliminaire, hypothèque, prix du certificat de localisation)
   elle est le SEUL niveau de titre du corps : 1 400 mots sans un seul repère.
   Le sélecteur fait la différence toute seule, sans toucher au balisage. */
p.marker:not(:has(+ :is(h1,h2,h3))){
  /* Entre h2 — clamp(26,3.2vw,38) — et h3 — clamp(20,2.2vw,25). À 19–23 px elle
     passait SOUS les h3 qu'elle est censée coiffer, et la hiérarchie s'inversait. */
  font-size:clamp(23px,2.6vw,29px);
  font-weight:700;
  letter-spacing:-.016em;
  line-height:1.28;
  text-transform:none;
  color:var(--ink);
  margin-top:var(--s-48);
  margin-bottom:var(--s-12);
}
p.marker:not(:has(+ :is(h1,h2,h3))):first-child{margin-top:0}
/* Sauf seule dans sa bande : là, elle annonce la SECTION SUIVANTE par-dessus une
   frontière de bande — c'est un sur-titre, et en corps de titre elle devenait un
   mot isolé au milieu d'un aplat de béton, juste au-dessus d'un h2 qui redit la
   même chose. */
p.marker:only-child{
  font-size:var(--t-micro);font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-mute);line-height:1.5;
  margin-top:0;margin-bottom:0;
}

h3{
  font-size:clamp(20px,2.2vw,25px);
  font-weight:700;
  letter-spacing:-.018em;
  margin-bottom:var(--s-12);
}

/* L'étiquette. Archivo capitales, interlettré : le lettrage au pochoir d'une
   caisse de matériaux. */
h4{
  font-family:var(--f-head);
  font-size:var(--t-micro);
  font-weight:700;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--ink-mute);
  margin:0 0 var(--s-16);
}

p{margin:0 0 var(--s-24);text-wrap:pretty}
p:last-child{margin-bottom:0}

.lede{
  font-size:clamp(19px,2vw,var(--t-lede));
  line-height:1.55;
  color:var(--ink-soft);
  max-width:46ch;
  margin-bottom:var(--s-32);
  /* Seize chapôs sur 74 finissaient sur un mot seul — « obligation. », « gonflée. »
     — parce qu'un chapô fait trois ou quatre lignes et que la dernière tombe où
     elle tombe. text-wrap:pretty demande au moteur de rendu de reprendre les
     deux dernières lignes pour éviter ça. Là où il n'existe pas, rien ne change. */
  text-wrap:pretty;
}
.caption{
  font-family:var(--f-head);
  font-size:var(--t-cap);line-height:1.5;font-weight:500;
  color:var(--ink-mute);
  /* Collée à sa figure au-dessus, détachée de ce qui suit : sans marge basse, une
     légende qui n'était pas le dernier enfant de son bloc se lisait comme le
     premier paragraphe du texte suivant. */
  margin:var(--s-12) 0 var(--s-32);
  padding-left:var(--s-16);
  border-left:2px solid var(--accent);
}
/* Un <caption> est centré par défaut dans le navigateur, et .caption pose son filet
   de cèdre sur le bord GAUCHE de la boîte : le texte partait au milieu, le trait
   restait à gauche, et les deux n'avaient plus l'air d'aller ensemble. */
caption.caption{text-align:left}
.small{font-size:var(--t-sm);line-height:1.6;color:var(--ink-soft)}
/* Les « Pourquoi » de l'appel découverte : même taille que la question, ton plus
   clair. L'œil distingue ainsi la question de son explication sans que celle-ci
   devienne de la petite note de bas de page. */
.pourquoi{color:var(--ink-soft)}
.micro{
  font-family:var(--f-head);font-size:var(--t-micro);font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--ink-mute);
}
/* .micro est une ÉTIQUETTE — un mot, deux au plus, au pochoir. Les huit endroits
   où elle est posée sur un <p> ne sont pas des étiquettes : ce sont les notes de
   source, de 151 à 382 signes, et ce sont les phrases du site qu'on lit le plus
   attentivement, puisqu'elles portent les numéros d'articles de loi, les dates de
   relevé de prix et une adresse de courriel. En capitales espacées de 12 px, elles
   étaient le texte le plus dur à lire de la page — et le courriel s'affichait
   « INFO@BATICONSEILRESIDENTIEL.COM », qu'il faut alors retranscrire à la main.
   Une note de source reste discrète par la taille et la couleur, pas par la casse. */
p.micro{
  font-family:var(--f-text);
  font-size:var(--t-cap);
  font-weight:400;
  line-height:1.65;
  letter-spacing:normal;
  text-transform:none;
}

strong{font-weight:600}
em{font-style:italic}

a{
  color:inherit;
  text-decoration:underline;
  text-underline-offset:.16em;
  text-decoration-thickness:1.5px;
  text-decoration-color:color-mix(in srgb,var(--accent) 45%,transparent);
  transition:color .14s ease,text-decoration-color .14s ease;
}
a:hover{color:var(--accent-deep);text-decoration-color:var(--accent)}
a:focus-visible{outline:2.5px solid var(--accent);outline-offset:3px;border-radius:3px}

/* ---------------------------------------------------------------- entête --- */

/* Massive et opaque, pas un voile flou : sur un site de 74 pages, l'entête est
   un élément de structure. Elle porte le numéro de téléphone, parce que la
   moitié des gens qui se décident le font en appelant. */
.masthead{
  position:sticky;top:0;z-index:40;
  background:var(--paper);
  border-bottom:1px solid var(--line);
}
.masthead-in{
  max-width:var(--page);margin:0 auto;
  padding:0 var(--pad);
  min-height:var(--head-h);
  display:flex;align-items:center;gap:var(--s-32);
}

/* La marque fait 34 px de haut au doigt sur un téléphone, dans une entête qui en
   mesure 74 : la zone tactile passe à 46 px sans déplacer un pixel. */
.brand{display:inline-flex;align-items:center;gap:var(--s-12);text-decoration:none;flex:none;
  padding-block:6px}
.brand-mark{
  width:34px;height:34px;flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--ink);border-radius:var(--r-sm);
}
.brand-mark svg{width:26px;height:26px;fill:var(--paper)}
/* Le verrou de marque : le dessin du logo à gauche, son lettrage à droite. Ce sont
   deux découpes du fichier fourni, pas une police reconstituée — la graisse et les
   deux couleurs viennent du logo lui-même. Les attributs width/height sont ceux des
   fichiers : ils réservent la place avant le chargement, donc le bandeau ne sursaute
   pas. La hauteur commande, la largeur suit. */
/* <picture> est en ligne par défaut : sans ceci il ajoute trois pixels de fond
   de ligne sous chaque image, et le verrou cesse d'être centré sur le bandeau. */
/* Le logo ne se pose jamais sur une bande noire : son marine y disparaît. En mode
   clair c'est lui qu'on voit dans le bandeau ; en mode sombre, l'ancien pictogramme
   reprend sa place — carré plein, maison en creux, lisible sur n'importe quel fond.
   Les deux sont dans la page et c'est l'affichage qui tranche : aucun JavaScript,
   et pas de requête pour l'image que le mode n'utilise pas, le navigateur ne
   chargeant pas une image dont l'ancêtre est en display:none. */
.brand .brand-mark{display:none}
@media (prefers-color-scheme:dark){
  .brand .brand-maison{display:none}
  .brand .brand-mark{display:inline-flex}
}
.brand-maison{height:46px;width:auto;flex:none}
/* Le nom reprend la coupe du logo : « Bâti » en marine, « Conseil » en olive, et
   « Résidentiel inc. » dessous. Deux jetons plutôt que deux valeurs écrites en dur,
   parce que le marine tombe à 2,1:1 sur la page sombre et doit s'éclaircir. Le <b>
   et le <em> ne portent aucune emphase de sens — la marque est un mot unique —
   d'où le font-weight et le font-style hérités. */
:root{--marque-1:#1e3a5c; --marque-2:#6d7b1c}
@media (prefers-color-scheme:dark){ :root{--marque-1:#9db8d6; --marque-2:#b6c85a} }
.brand-name{
  font-family:var(--f-head);font-weight:800;font-size:19px;
  letter-spacing:-.03em;line-height:1;white-space:nowrap;
  display:flex;flex-direction:column;gap:3px;
}
.brand-line{display:block}
.brand-name b{font-weight:inherit;color:var(--marque-1)}
.brand-name em{font-style:normal;font-weight:inherit;color:var(--marque-2)}
.brand-name i{
  font-style:normal;font-weight:600;font-size:10.5px;
  letter-spacing:.15em;text-transform:uppercase;color:var(--ink-mute);
}
/* Sous 560 px, le lettrage se réduit avant le dessin : une marque illisible vaut
   moins qu'une marque petite, et c'est le dessin qu'on reconnaît de loin. */
@media (max-width:560px){
  .brand-maison{height:34px}
}

.nav{display:flex;gap:var(--s-4);margin-left:auto;min-width:0}
.nav a{
  font-family:var(--f-head);font-size:14px;font-weight:600;letter-spacing:-.005em;
  color:var(--ink-soft);text-decoration:none;
  padding:9px 11px;border-radius:var(--r-sm);
  white-space:nowrap;
}
.nav a:hover{color:var(--ink);background:var(--ink-wash)}
.nav a[aria-current="page"]{color:var(--ink);box-shadow:inset 0 -3px 0 var(--accent)}

/* Le seul onglet qui ne vend rien : la documentation est en accès libre, et elle
   se distingue par le vert plutôt que par la place. Le ton reprend celui des
   encadrés .note--mint, déjà au dossier — deux valeurs, une par mode, parce que
   le vert foncé tombe à 2,4:1 sur la page sombre. Le mot « gratuite » est un
   second registre, pas un second onglet : plus petit, en capitales espacées,
   pour qu'il se lise comme une étiquette collée et non comme un nom de page. */
:root{--libre:#3f6a48; --libre-fond:#eef4ef}
@media (prefers-color-scheme:dark){ :root{--libre:#8fc198; --libre-fond:#1d2a21} }
.nav a.nav-libre{color:var(--libre);background:var(--libre-fond)}
.nav a.nav-libre:hover{color:var(--libre);background:color-mix(in srgb, var(--libre) 14%, var(--libre-fond))}
.nav a.nav-libre[aria-current="page"]{color:var(--libre);box-shadow:inset 0 -3px 0 var(--libre)}
.nav a.nav-libre span{
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  margin-left:5px;vertical-align:1px;
}
.menu-panel a.nav-libre{color:var(--libre)}
.menu-panel a.nav-libre span{
  font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-left:6px;
}

.masthead-act{display:flex;align-items:center;gap:var(--s-16);flex:none}

/* Le menu mobile : un <details>, donc aucun JavaScript. */
.menu{display:none;margin-left:auto;position:relative}
.menu summary{
  list-style:none;cursor:pointer;
  width:44px;height:44px;border-radius:var(--r-sm);
  display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line-firm);
}
.menu summary::-webkit-details-marker{display:none}
.menu summary span,.menu summary span::before,.menu summary span::after{
  display:block;width:18px;height:2px;background:var(--ink);border-radius:2px;
}
.menu summary span{position:relative}
.menu summary span::before{content:"";position:absolute;top:-6px}
.menu summary span::after{content:"";position:absolute;top:6px}
.menu[open] summary span{background:transparent}
.menu[open] summary span::before{transform:translateY(6px) rotate(45deg)}
.menu[open] summary span::after{transform:translateY(-6px) rotate(-45deg)}
.menu-panel{
  position:absolute;right:0;top:calc(100% + 12px);
  width:min(78vw,290px);
  background:var(--raised);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--lift-hi);
  padding:var(--s-8);
  display:flex;flex-direction:column;
}
.menu-panel a{
  font-family:var(--f-head);font-weight:600;font-size:16px;
  text-decoration:none;padding:11px var(--s-16);border-radius:var(--r-sm);
}
.menu-panel a:hover{background:var(--ink-wash)}
.menu-panel .btn{margin:var(--s-8) 0 0;justify-content:center}
.menu-tel{text-align:center;color:var(--ink-mute) !important;font-size:14px !important}

/* La barre de classement. Sur un site dont l'argument est l'exactitude, la date
   de vérification est un élément de design — pas une mention en bas de page. */
.filebar{background:var(--surface);border-bottom:1px solid var(--line)}
.filebar-in{
  max-width:var(--page);margin:0 auto;padding:11px var(--pad);
  display:flex;gap:var(--s-16);justify-content:space-between;align-items:center;
  font-family:var(--f-head);font-size:var(--t-micro);font-weight:600;
}
.filebar-where{
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-mute);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.stamp{
  display:inline-flex;align-items:center;gap:7px;white-space:nowrap;
  color:var(--ink-mute);
}
.stamp::before{
  content:"";width:7px;height:7px;border-radius:50%;
  background:var(--accent);flex:none;
}
.stamp b{font-weight:700;color:var(--ink-soft)}

/* --------------------------------------------------------- entête de page --- */

/* La première bande de chaque page. Sur les pages porteuses elle reçoit une
   photographie de chantier en fond; ailleurs, un aplat de béton et la
   typographie seule. Dans les deux cas la mise en page est la même, ce qui
   évite d'avoir deux entêtes à entretenir. */
.band--hero{
  background:var(--surface);
  padding-top:calc(var(--gap) * .8);
  padding-bottom:calc(var(--gap) * .8);
  border-bottom:1px solid var(--line);
}
.band--hero.has-shot{
  --ink:#ffffff;
  --ink-soft:rgba(255,255,255,.86);
  --ink-mute:rgba(255,255,255,.72);
  --ink-wash:rgba(255,255,255,.14);
  --line:rgba(255,255,255,.24);
  --line-firm:rgba(255,255,255,.4);
  --accent:#f0a074; --accent-deep:#f7bb98;
  --on-accent:#14181c; --on-steel:#14181c;
  --surface:rgba(255,255,255,.10);
  --raised:rgba(255,255,255,.08);
  color:var(--ink);
  background-color:#14181c;
  /* Le voile était horizontal — noir à gauche, photographie à droite — parce que
     le titre vivait dans une colonne de 515 px collée au bord gauche. Le titre
     est maintenant concentrique, donc le voile l'est aussi : vertical, plus
     dense sous l'entête collante et au pied de la bande, plus clair au milieu.
     Le tirage se lit sur toute la largeur au lieu d'être à moitié caché sous un
     aplat, ce qui est la raison pour laquelle il est là.
     .70 au plus clair n'est pas choisi à l'œil : la photographie la plus claire
     du lot (des plans blancs en plein jour) tombe alors à L≈0,10, ce qui donne
     7,5:1 au texte blanc — le titre tient le AA même sur le tirage le plus pâle. */
  background-image:
    linear-gradient(to bottom,
      rgba(10,13,16,.88) 0%,
      rgba(10,13,16,.72) 32%,
      rgba(10,13,16,.70) 60%,
      rgba(10,13,16,.87) 100%),
    var(--hero);
  background-size:cover,cover;
  background-position:center,center;
  padding-top:calc(var(--gap) * 1.15);
  padding-bottom:calc(var(--gap) * 1.15);
  border-bottom:0;
}
/* La planche de section. Un dessin technique adossé à l'entête, tracé en
   currentColor : la même planche sert le mode clair et le mode sombre, et rien
   ne prétend être une photographie. Elle disparaît sous 900 px, où la largeur
   appartient au texte. */
.band--hero.has-plate{overflow:hidden}
.plate{
  position:absolute;
  /* Adossée au bord droit de la fenêtre, pas calée sur la colonne : la mesure de
     l'entête fait 820 px centrés, donc sa moitié vaut 410, et `50vw - 430`
     laisse exactement 20 px entre le dernier caractère du titre et le premier
     trait de la planche — à 1280 px comme à 1920. Une largeur fixe, elle,
     rentrait dans le titre dès que la fenêtre se resserrait. */
  left:auto;
  right:0;
  top:50%;transform:translateY(-50%);
  width:min(540px,calc(50vw - 430px));height:auto;
  color:var(--steel);
  opacity:.17;
  pointer-events:none;
  z-index:0;
  -webkit-mask-image:linear-gradient(to right,transparent,#000 20%);
  mask-image:linear-gradient(to right,transparent,#000 20%);
}
@media (prefers-color-scheme:dark){ .plate{opacity:.22} }
.band--hero > .measure,.band--hero > .cols,.band--hero > div{position:relative;z-index:1}

/* Le dégradé de l'entête va du sombre au clair, de gauche à droite : le texte
   appartient au côté sombre, aligné sur la gouttière de la coquille, et la
   photographie respire à droite. Centré dans la fenêtre, il flottait au milieu
   de l'image et cachait justement ce qu'on avait payé pour montrer. */
.band--hero > .measure{
  width:100%;
  max-width:min(820px,100%);
  margin-inline:auto;
}
/* Sous 1280 px il ne reste plus de gouttière à droite de la mesure : la planche
   n'aurait plus que 130 px de large et ne dessinerait plus rien. */
@media (max-width:1279px){ .plate{display:none} }
@media print{ .plate{display:none} }
/* L'entête était la seule bande dont le texte n'était pas centré. La note qui
   justifiait ça disait qu'il partageait son axe avec les rangées de cartes et
   les tableaux : mesuré, c'est faux — 87 des 92 tableaux du site sont à 657 px,
   pas à 460. Sur 731 blocs mesurés à 1920 px, 74 seulement n'étaient pas
   concentriques à la fenêtre : les 74 entêtes, toujours décalés de 197 px. Le
   titre commençait donc 197 px à gauche du paragraphe qui le suit — un ressaut
   visible sous chaque H1, sur chaque page.
   Le reste du site alterne bien entre 607 et 1000 px, mais autour du MÊME axe :
   ça, c'est un système de débords concentriques, et on n'y touche pas. */

/* Dans l'entête, c'est la mesure qui donne la largeur du titre, pas un plafond
   en ch. Les trois plafonds qui se disputaient la place — 17ch sur .display,
   16ch sur .display--lg, 19ch quand l'entête porte une photographie — étaient de
   toute façon écrasés par les 515 px de l'ancienne mesure, et l'unité ch d'un
   titre à 68 px ne vaut pas celle du même titre à 58. */
.band--hero .display{max-width:none}
/* Sous le titre, la prose de l'entête reprend EXACTEMENT la mesure de lecture du
   reste du site — 662 px, la valeur que donne .measure à 72ch. En ch, elle ne
   l'aurait pas : le chapô est à 22 px et les paragraphes à 18,5, donc 58ch et
   72ch produisaient 634 et 820 px l'un au-dessus de l'autre, deux bords droits
   différents dans le même bloc. Le titre garde les 820 px de la mesure d'entête;
   tout ce qui le suit se cale sur la colonne du reste de la page. */
.band--hero > .measure > p{max-width:662px}
.band--hero .lede{color:var(--ink-soft)}
/* Le h2 « poutre » n'a pas de sens dans un entête : il n'y découpe rien. */
.band--hero h2{border-top:0;padding-top:0}
.band--hero h2::before{display:none}

/* ------------------------------------------------------------------ CTA ---- */

.cta,.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  background:var(--accent);color:var(--on-accent);
  font-family:var(--f-head);font-weight:700;font-size:var(--t-sm);line-height:1.2;
  letter-spacing:-.008em;
  padding:15px 24px;
  border:2px solid var(--accent);border-radius:var(--r-sm);
  text-decoration:none;
  box-shadow:var(--lift);
  transition:background .14s ease,border-color .14s ease,transform .14s ease,box-shadow .14s ease;
}
.cta::after,.btn::after{content:"→";font-size:1.05em;line-height:1;transition:transform .16s ease}
.cta:hover,.btn:hover{
  background:var(--accent-deep);border-color:var(--accent-deep);color:var(--on-accent);
  transform:translateY(-1px);box-shadow:var(--lift-hi);
}
.cta:hover::after,.btn:hover::after{transform:translateX(4px)}
.btn--sm{padding:10px 15px;font-size:13.5px;box-shadow:none}
.btn--sm::after{content:none}

.cta--ghost{
  background:transparent;color:var(--ink);border-color:var(--line-firm);
  box-shadow:none;
}
.cta--ghost:hover{
  background:transparent;color:var(--ink);
  border-color:var(--ink);transform:translateY(-1px);box-shadow:none;
}
/* Marge basse comprise : la ligne d'adresse qui suivait les boutons était collée
   au bord inférieur du bouton fantôme, alors que le paragraphe au-dessus, lui,
   avait sa respiration. `:not(:last-child)` pour que la rangée reste à ras quand
   elle ferme vraiment son bloc. */
.cta-row{display:flex;flex-wrap:wrap;gap:var(--s-16);align-items:center;margin-top:var(--s-32)}
.cta-row:not(:last-child){margin-bottom:var(--s-32)}

/* --------------------------------------------- schémas des montages --- */
/* Quatre petits croquis en tête du tableau « Les quatre montages » : un rond
   plein pour vous, un rond creux pour le tiers, des carrés pour les corps de
   métier. Trait plein = donne les instructions, tirets = conseille seulement.
   Le cadre marque ce que le tiers prend dans son propre contrat. Tout est en
   currentColor : le croquis suit la couleur du texte, bande claire ou ink. */
.montage{display:block;width:104px;height:71px;margin:0 auto var(--s-12);
  color:inherit;opacity:.8;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;overflow:visible}
.montage circle,.montage rect{fill:currentColor;stroke:none}
.montage .mg-open{fill:none;stroke:currentColor}
.montage .mg-box{fill:none;stroke:currentColor;stroke-width:1}
.montage .mg-dash{stroke-dasharray:3 3}
.montage .mg-thin{stroke-width:.7;opacity:.75}
.mg-t{display:block}
@media (max-width:640px){ .montage{display:none} }


/* ---------------------------------------------------------- formulaire --- */

/* Le formulaire était en style par défaut du navigateur : Times, champs gris de
   1 px, bouton système. Sur les 74 autres pages tout est réglé au jeton près, et
   le seul endroit où on demande quelque chose au visiteur ressemblait à un
   brouillon. Un formulaire mal habillé sur un site soigné se lit comme « ce
   n'est pas vraiment branché » — ce qui, jusqu'à aujourd'hui, était vrai. */
form label{
  display:inline-block;
  font-family:var(--f-head);font-size:var(--t-cap);font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;color:var(--ink-mute);
  margin-bottom:var(--s-8);
}
/* Par exclusion plutôt que par énumération : `input[type=text],[type=email]`
   avait déjà oublié `type=tel`, qui rendait le champ Téléphone deux fois plus
   court que les deux au-dessus. La liste des types de saisie s'allonge; celle
   des cases et des boutons radio, non. */
form input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=submit]),
form select,form textarea{
  width:100%;
  font-family:var(--f-text);font-size:var(--t-sm);line-height:1.5;color:var(--ink);
  background:var(--paper);
  border:1px solid var(--line-firm);border-radius:var(--r-sm);
  padding:12px 14px;
  transition:border-color .14s ease,box-shadow .14s ease;
}
form textarea{resize:vertical;min-height:150px}
form select{
  /* La flèche système ne suit pas la palette : on la redessine. */
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink-mute) 50%),
                   linear-gradient(135deg,var(--ink-mute) 50%,transparent 50%);
  background-position:calc(100% - 19px) calc(50% + 2px),calc(100% - 14px) calc(50% + 2px);
  background-size:5px 5px,5px 5px;
  background-repeat:no-repeat;
  padding-right:42px;
}
form input:focus-visible,form select:focus-visible,form textarea:focus-visible{
  outline:none;
  border-color:var(--accent);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 26%,transparent);
}
form input::placeholder,form textarea::placeholder{color:var(--ink-mute)}

/* Les groupes de choix du formulaire de réservation. Un <fieldset> plutôt qu'une
   suite de cases sans lien : sans lui, un lecteur d'écran annonce « lundi, case
   à cocher » sans jamais dire de quoi lundi est la réponse. */
.field-group{
  border:1px solid var(--line);border-radius:var(--r-sm);
  padding:var(--s-16) var(--s-24) var(--s-8);
  margin:0;
}
.field-group legend{
  font-family:var(--f-head);font-size:var(--t-cap);font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;color:var(--ink-mute);
  padding:0 var(--s-8);
}
.choice{display:flex;align-items:center;gap:10px;margin:0 0 var(--s-8)}
.choice input{
  width:19px;height:19px;flex:none;margin:0;
  accent-color:var(--accent);   /* la case cochée prend le cèdre, pas le bleu système */
}
/* L'étiquette d'un choix se lit comme du texte, pas comme un titre de champ. */
.choice label{
  font-family:var(--f-text);font-size:var(--t-sm);font-weight:400;
  letter-spacing:normal;text-transform:none;color:var(--ink);
  margin:0;cursor:pointer;
}
.opt{font-weight:400;text-transform:none;letter-spacing:normal;color:var(--ink-mute)}
/* Le bouton d'envoi porte le même habit que les appels à l'action du site : même
   cèdre, même rayon, même flèche. `button` ne suit pas .cta tout seul. */
form button[type=submit]{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  background:var(--accent);color:var(--on-accent);
  font-family:var(--f-head);font-weight:700;font-size:var(--t-sm);line-height:1.2;
  letter-spacing:-.008em;
  padding:15px 24px;
  border:2px solid var(--accent);border-radius:var(--r-sm);
  box-shadow:var(--lift);cursor:pointer;
  transition:background .14s ease,border-color .14s ease,transform .14s ease,box-shadow .14s ease;
}
form button[type=submit]::after{content:"→";font-size:1.05em;line-height:1;transition:transform .16s ease}
form button[type=submit]:hover{
  background:var(--accent-deep);border-color:var(--accent-deep);
  transform:translateY(-1px);box-shadow:var(--lift-hi);
}
form button[type=submit]:hover::after{transform:translateX(4px)}

/* ------------------------------------------------------- blocs encastrés --- */

/* LE composant le plus important du site : la limite légale. Ni carte, ni note
   de bas de page — une bande hachurée de chantier. On sait ce que c'est avant
   de l'avoir lue, et c'est exactement le but : ce bloc protège le client
   autant que l'entreprise. */
.boundary{
  position:relative;
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r);
  padding:var(--s-24) var(--s-32);
  padding-left:calc(var(--s-32) + 14px);
  margin:var(--s-40) 0;
  overflow:hidden;
}
.boundary::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:14px;
  background:repeating-linear-gradient(
    -45deg,
    var(--accent) 0 7px,
    color-mix(in srgb,var(--ink) 88%,transparent) 7px 14px
  );
}
.boundary h4{color:var(--accent-deep)}
.boundary p{font-size:var(--t-sm);line-height:1.65}
/* Le bloc le plus important du site sur le plan légal apparaissait sous deux
   aspects : sur 26 des 73 pages qui le portent il est niché dans une bande
   sombre, où --surface rebascule en #1c2228 et le panneau devenait gris foncé
   sur presque noir. Un jeton explicite pour que la limite se lise pareil
   partout. */
.band--ink .boundary{
  background:rgba(242,240,234,.06);
  border-color:var(--line-firm);
}

/* Les notes. Une seule forme — un panneau posé — et la variante ne change que
   la teinte de l'onglet. Un dossier n'a pas de papillons collants; un classeur
   de chantier a des onglets de couleur. */
.note{
  --tab:var(--steel);
  position:relative;
  background:var(--raised);
  border:1px solid var(--line);
  border-radius:var(--r);
  box-shadow:var(--lift);
  padding:var(--s-24) var(--s-32);
  margin:var(--s-32) 0;
}
.note::before{
  content:"";position:absolute;left:var(--s-32);top:-1px;
  width:56px;height:4px;border-radius:0 0 3px 3px;background:var(--tab);
}
.note h4{color:var(--tab)}
.note p{font-size:var(--t-sm);line-height:1.65}
.note--mint{--tab:#4d7a54}
.note--teal{--tab:#2f6470}
.note--blush{--tab:#8a6a4e}
@media (prefers-color-scheme:dark){
  .note--mint{--tab:#8fc198} .note--teal{--tab:#7fb8c6} .note--blush{--tab:#c9a37c}
}
.band--ink .note--mint{--tab:#8fc198}
.band--ink .note--teal{--tab:#7fb8c6}
.band--ink .note--blush{--tab:#c9a37c}

/* Le tampon de vérification. Une pastille, pas une ligne de mentions légales. */
.verified{
  display:inline-flex;align-items:flex-start;gap:12px;
  font-family:var(--f-head);font-size:var(--t-cap);font-weight:600;line-height:1.5;
  color:var(--ink-soft);
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:999px;
  padding:10px var(--s-24);
  margin-top:var(--s-40);
}
/* Un crochet tracé à même la boîte : deux bords et une rotation. Il suit
   --accent dans les six portées de couleur, ce qu'une image encodée ne ferait
   pas. */
.verified::before{
  content:"";flex:none;
  width:8px;height:15px;margin:3px 3px 0 0;
  border:solid var(--accent);border-width:0 3px 3px 0;
  transform:rotate(40deg);
}

/* ------------------------------------------------------------- planches --- */

/* La photographie porte le site. Elle est traitée en bloc plein, coins
   adoucis, ombre courte — un tirage posé, pas un cadre. */
figure{margin:0}
.shot{
  display:block;width:100%;height:auto;
  border-radius:var(--r);
  background:var(--surface);
  box-shadow:var(--lift);
  aspect-ratio:3 / 2;object-fit:cover;
}
.shot--wide{aspect-ratio:16 / 9}
.shot--tall{aspect-ratio:4 / 5}

/* Le créneau : ce qui s'affiche tant que la photographie de la liste de prises
   de vue n'a pas été faite. Il ne simule pas une image — il réserve la place et
   dit ce qu'il y aura. */
.shot-slot{
  position:relative;
  border:1px dashed var(--line-firm);
  border-radius:var(--r);
  background:var(--surface);
  aspect-ratio:3 / 2;max-height:400px;
  display:flex;align-items:flex-end;
  padding:var(--s-24);
  font-family:var(--f-head);font-size:var(--t-cap);font-weight:500;line-height:1.5;
  color:var(--ink-mute);
}
.shot-slot--wide{aspect-ratio:16 / 9}
.contact-sheet{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-24)}
.contact-sheet--2{grid-template-columns:repeat(2,minmax(0,1fr))}
/* Une planche-contact dont toutes les photographies sont encore à prendre ne contient
   plus que des commentaires HTML — aucun élément — et réservait 245 px de page blanche
   au milieu d'une bande. APRÈS la règle ci-dessus, pas avant : `:has(> *)` et `:not()`
   prennent la spécificité de leur argument, et `*` n'en a aucune, donc les deux
   sélecteurs pèsent (0,1,0) et c'est l'ordre du fichier qui tranche. Placée au-dessus,
   la règle était écrasée par `display:grid` et ne faisait rien. */
.contact-sheet:not(:has(> *)),
.cols:not(:has(> *)),
.cols--3:not(:has(> *)){display:none}
.contact-sheet .shot,.contact-sheet .shot-slot{aspect-ratio:4 / 5;max-height:none}
.contact-sheet--2 .shot,.contact-sheet--2 .shot-slot{aspect-ratio:3 / 2}

/* ------------------------------------------------- listes de liens / index --- */

/* Presque toute la circulation arrive d'un moteur de recherche sur une page
   profonde. Le bloc qui navigue vraiment est celui du bas de page : il est
   traité comme une rangée de tiroirs étiquetés. */
.link-list{
  display:grid;
  /* min(300px,100%) et non 300px : sous 336 px de colonne, une piste de
     300 px déborde la page au lieu de se replier. */
  grid-template-columns:repeat(auto-fill,minmax(min(300px,100%),1fr));
  gap:0 var(--s-40);
  margin:0 0 var(--s-24);
}
/* Le filet est porté par le <li>, pas par le <a>. Le <li> est un enfant de
   grille, donc il s'étire à la hauteur de la plus haute cellule de sa rangée; le
   <a>, lui, fait la hauteur de son texte. Avec le filet sur le <a>, celui d'une
   étiquette d'une ligne se dessinait 23 px plus haut que celui de ses voisines
   de deux lignes, dans la même rangée : trois soulignés en escalier. */
.link-list li{padding-left:0;margin-bottom:0;display:flex;border-bottom:1px solid var(--line)}
.link-list li::before{content:none}
.link-list a{
  font-family:var(--f-head);font-size:var(--t-sm);font-weight:600;line-height:1.45;
  display:flex;align-items:baseline;gap:10px;
  width:100%;
  padding:13px 0;
  text-decoration:none;
}
.link-list a::before{
  content:"→";color:var(--accent);flex:none;
  transition:transform .16s ease;
}
.link-list a:hover{color:var(--accent-deep)}
.link-list a:hover::before{transform:translateX(3px)}

/* Même raison que pour le pied : les 80 px vivent dans la bande, pas devant. */
.siblings{background:var(--surface);border-top:1px solid var(--line);
  margin-top:0;padding-top:calc(var(--gap) + var(--s-80))}

/* ---------------------------------------------------------------- listes --- */

ul,ol{margin:0 0 var(--s-24);padding:0;list-style:none}
li{position:relative;padding-left:30px;margin-bottom:var(--s-12)}
ul > li::before{
  content:"";position:absolute;left:3px;top:.62em;
  width:9px;height:9px;border-radius:2px;
  background:var(--accent);
}
ol{counter-reset:n}
ol > li{counter-increment:n;padding-left:46px}
ol > li::before{
  content:counter(n);
  position:absolute;left:0;top:.16em;
  width:28px;height:28px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--f-head);font-size:14px;font-weight:700;
  color:var(--on-steel);background:var(--steel);
  border-radius:var(--r-sm);
}

/* --------------------------------------------------------------- tableaux --- */

/* Les tableaux comparatifs sont l'argument commercial du site : c'est là que
   « j'ai lu trois soumissions, voici ce qu'elles ne disent pas » devient
   visible. Bloc fermé, en-tête plein, rangées alternées : ça se lit en diagonale
   à minuit. */
/* La boîte de débord, posée par build.py autour de chaque .table-wrap. Elle ne
   se voit pas : elle ne fait qu'ouvrir la largeur disponible et donner sa
   respiration verticale. */
.table-bleed{margin:var(--s-32) 0}
.table-wrap{
  overflow-x:auto;
  border:1px solid var(--line);
  border-radius:var(--r);
  box-shadow:var(--lift);
  background:var(--raised);
  /* Se dimensionne sur le tableau, sans jamais dépasser ce que la boîte de
     débord lui offre, et se recentre dedans. Un tableau à deux colonnes fait
     donc 560 px encadrés au milieu de la page au lieu de 1000 px dont 500 vides;
     un comparatif à cinq colonnes prend tout et reste centré sur le même axe. */
  width:max-content;
  /* Jamais plus étroit que la mesure de lecture : un tableau à deux colonnes tombait
     à 560 px au milieu d'un texte de 662, et deux tableaux voisins se dessinaient à
     deux largeurs différentes sous le même paragraphe. Le plancher les recale sur la
     colonne du texte; ceux qui ont besoin de plus prennent ce qu'il leur faut. */
  min-width:min(100%,662px);
  max-width:100%;
  margin-inline:auto;
  /* Quand il reste malgré tout du tableau hors cadre, ça se voit. Le bord
     concerné porte une ombre courte qui s'efface d'elle-même quand on arrive au
     bout : les couches `local` suivent le contenu, les couches `scroll` restent
     collées au cadre, et l'une masque l'autre. Sans ce signal, un tableau coupé
     net sur un bord arrondi se lit comme un tableau complet — et la colonne
     manquante est justement celle qui porte les réponses. */
  background-image:
    linear-gradient(to right,var(--raised) 40%,rgba(0,0,0,0)),
    linear-gradient(to left,var(--raised) 40%,rgba(0,0,0,0)),
    /* En encre plutôt qu'en noir fixe : dans une bande inversée, --ink est clair, et
       l'ombre devient un halo — même signal, lisible sur les deux fonds. Un noir en
       dur y était invisible, et le tableau se coupait sans prévenir. */
    linear-gradient(to right,color-mix(in srgb,var(--ink) 34%,transparent),rgba(0,0,0,0)),
    linear-gradient(to left,color-mix(in srgb,var(--ink) 34%,transparent),rgba(0,0,0,0));
  background-position:0 0,100% 0,0 0,100% 0;
  background-repeat:no-repeat;
  background-size:40px 100%,40px 100%,18px 100%,18px 100%;
  background-attachment:local,local,scroll,scroll;
}
table{
  border-collapse:collapse;width:100%;min-width:560px;
  font-size:var(--t-sm);line-height:1.6;
}
th{
  font-family:var(--f-head);font-size:var(--t-micro);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;
  color:var(--paper);background:var(--ink);
  text-align:left;
  padding:var(--s-16) var(--s-24);
  /* Surtout pas nowrap : c'est la rangée d'en-tête, et elle seule, qui gonflait
     les tableaux comparatifs. « Conseiller ou entrepreneur général » passait de
     874 px à 1439 px à cause d'elle, et trois de ses cinq colonnes — dont celle
     qui vend le service — sortaient du cadre. Un en-tête sur deux lignes coûte
     38 px de hauteur; une colonne invisible coûte l'argument. */
  white-space:normal;
}
/* vertical-align:bottom appartenait à la rangée d'en-tête et à elle seule. Posé
   sur `th` tout court, il attrapait aussi les `th scope=row` : dans un tableau
   comparatif, l'étiquette de la rangée — « LICENCE RBQ REQUISE » — se posait au
   BAS d'une cellule de 100 px pendant que les quatre réponses qu'elle nomme
   commençaient en haut. 91 tableaux sur 74 pages. */
thead th{vertical-align:bottom}
tbody th{vertical-align:top}
td{padding:var(--s-16) var(--s-24);border-top:1px solid var(--line);vertical-align:top}
tbody tr:nth-child(even){background:var(--surface)}
td:first-child{font-weight:600}
/* Les colonnes de chiffres s'alignent à droite : c'est comme ça qu'on compare
   deux montants d'un coup d'œil.
   Deux corrections à la règle d'origine, `td.num,.num`.
   D'abord le sélecteur nu `.num` : posé sur un <tr> par mégarde (une page), il
   passait la rangée entière en nowrap; posé sur un <th>, il écrasait
   `th{white-space:normal}` par spécificité, et « Mises en chantier
   unifamiliales, 2025 » devenait un en-tête insécable de 332 px dans une fenêtre
   de 352. Il ne vise donc plus que les cellules.
   Ensuite `white-space:nowrap`, qui protégeait « 1 800 à 3 000 $ » d'une coupure.
   Il n'a plus lieu d'être : les groupes de chiffres et le symbole dollar sont
   maintenant liés par des espaces insécables dans la source, donc un montant ne
   se coupe déjà plus — alors que le nowrap, lui, empêchait AUSSI de couper entre
   deux montants et gonflait la colonne jusqu'à sortir du téléphone.
   L'en-tête d'une colonne entièrement numérique reçoit `num` à la construction :
   sans ça le titre restait à gauche pendant que ses chiffres allaient à droite,
   avec jusqu'à 280 px de vide entre les deux. */
td.num,th.num{font-variant-numeric:tabular-nums;text-align:right}

/* Un tableau comparatif est l'argument commercial du site : il sort de la
   colonne de lecture pour occuper la colonne de contenu, en restant centré sur
   le même axe. Sous 1064 px la piste de contenu est plus étroite que
   --content : la marge négative pousserait le tableau hors de l'écran, d'où la
   requête média, qui n'est pas décorative. */
/* La marge négative est symétrique, donc elle ne donne un tableau centré que si
   la boîte dont elle part l'est aussi. Tant que .measure était collée à gauche,
   ce calcul poussait le tableau 169 px À GAUCHE de la colonne de contenu, dans
   la gouttière : à 1920 px il commençait à 291 px quand le titre juste au-dessus
   commençait à 460. 92 tableaux sur 74 pages, tous décalés. */
/* Une rangée de cartes tombait dans le même piège que les tableaux, en pire :
   sept des neuf .cols--3 du site sont écrits DANS la mesure de lecture, pas dans
   la bande. Trois pistes dans 662 px donnent des cartes de 199 px, moins 64 px de
   marge intérieure : 135 px de texte par carte, soit deux mots par ligne. Elles
   sortent donc à la colonne de contenu comme les tableaux, sur le même axe. */
/* 1000 px et non 1064 : le débord vaut -169 px de chaque côté, le bord gauche de la
   mesure se trouve à vw/2 - 331, donc le tableau tient tant que vw/2 - 331 >= 169,
   c'est-à-dire à partir de 1000 px pile. À 1024 px, il occupe 1000 px avec 12 px de
   marge de chaque côté au lieu de rester serré dans les 662 px de la mesure. */
@media (min-width:1000px){
  .measure > .table-bleed,
  .measure > .cols--3,
  .measure > .contact-sheet{margin-inline:calc((100% - var(--content)) / 2)}
}
/* Et elles se donnent leur propre respiration : posées entre deux paragraphes,
   elles héritaient des 24 px du <p> au-dessus et de rien du tout en dessous.
   margin-block et non la propriété raccourcie `margin` : celle-ci remet
   margin-inline à zéro, donc elle annulait le débord ci-dessus — la règle la
   plus tardive gagnant à spécificité égale, les cartes restaient à 662 px. */
.measure > .cols,
.measure > .cols--3,
.measure > .contact-sheet{margin-block:var(--s-40)}

/* ------------------------------------------------------------- colonnes ---- */

.cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-48)}
.cols--3{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s-32)}
/* Quatre mandats sur une seule ligne. La rangée garde en tout point l'aspect des
   cartes à trois — fond, filet de cèdre, ombre, lien poussé en bas — et n'en change
   que le nombre de pistes : le modificateur s'ajoute à .cols--3, il ne le remplace
   pas. L'écart passe de 32 à 24 px, sans quoi quatre cartes dans 1000 px tombent à
   216 px de texte. Sous 1120 px elles se replient à deux, puis à une seule sous
   960 px, où la règle générale des colonnes reprend la main. */
.cols--quad{grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s-24)}
/* Quatre cartes dans la colonne de contenu de 1000 px tombent à 166 px de texte —
   trois mots par ligne, le défaut que la note sur .cols--3 décrit plus haut. La
   rangée sort donc jusqu'à la coquille de 1300 px, et non jusqu'aux 1000 px du
   contenu ; le max() garde une gouttière quand la fenêtre est plus étroite que la
   coquille, au lieu de laisser la rangée déborder. La marge intérieure des cartes
   passe de 32 à 24 px : 16 px de texte gagnés par carte, sans que l'aspect change. */
.bleed > .cols--quad{grid-column:full;margin-inline:max(var(--pad), calc((100% - var(--page)) / 2))}
.cols--quad > div{padding:var(--s-24)}
/* Les trois mandats portent le cèdre ; les mandats partiels restent sur le blanc
   des cartes ordinaires. C'est le sens qui commande la couleur : ce qui est mis en
   avant reçoit l'accent, ce qui est offert en complément reste neutre. Le filet
   passe de la ligne de béton au cèdre sur les quatre côtés, et le fond prend 4 % du
   même jeton : assez pour que l'œil sépare les deux familles, pas assez pour que la
   rangée crie. color-mix plutôt qu'une valeur écrite en dur, sinon les cartes se
   décrocheraient du cèdre le jour où il change — et elles suivent le mode sombre,
   où --accent s'éclaircit et --raised fonce. */
.cols--quad > div.carte--cedre{
  border-color:var(--accent);
  background:color-mix(in srgb, var(--accent) 4%, var(--raised));
}
@media (max-width:1120px){
  .cols--quad{grid-template-columns:repeat(2,minmax(0,1fr))}
  .bleed > .cols--quad{margin-inline:var(--pad)}
}
.cols--sidebar{grid-template-columns:minmax(0,1.75fr) minmax(0,1fr);gap:var(--s-56);align-items:start}
/* Tant que la photographie n'est pas prise, la construction remplace la figure
   par un commentaire HTML — qui n'est pas un élément. La grille garde donc sa
   seconde piste, vide, et le texte se retrouve dans 601 px collés au bord gauche
   de la colonne pendant que 399 px de page restent blancs à sa droite : le seul
   bloc de la page qui ne soit pas concentrique. Une grille à un seul enfant n'est
   plus une grille. Elle se remettra d'elle-même le jour où la photo arrivera. */
.cols--sidebar:has(> :first-child:last-child){display:block}
.cols--sidebar:has(> :first-child:last-child) > *{max-width:72ch;margin-inline:auto}

/* Les trois phases de service, et tout autre triptyque : des cartes posées. Le
   h3 y perd la poutre — trois poutres côte à côte feraient une clôture. */
.cols--3 > div{
  background:var(--raised);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:var(--lift);
  padding:var(--s-32);
  transition:transform .16s ease,box-shadow .16s ease;
  /* Les cartes s'étirent déjà à la hauteur de la plus haute; leur lien de fin, lui,
     restait accroché au dernier paragraphe. Sur trois cartes de longueurs
     différentes, les trois « La phase N en détail » flottaient à trois hauteurs
     différentes, avec jusqu'à 122 px de carte vide dessous. */
  display:flex;flex-direction:column;
}
/* Seulement le lien de fin — `<p class="small"><a>…</a></p>`. Sur `p:last-child` tout
   court, une carte qui ne contient qu'un titre et un paragraphe voyait son paragraphe
   poussé au BAS de la carte, avec un trou sous le titre. */
.cols--3 > div > p.small:last-child{margin-top:auto;margin-bottom:0}
/* Un <p> nu employé comme cellule de grille apporte sa propre marge basse en plus
   de l'écart de la grille : 24 + 32 = 56 px entre deux liens d'une ligne, une fois
   la rangée repliée sur une colonne. L'écart de grille suffit. */
.cols > p,.cols--3 > p{margin-bottom:0}
.cols--3 > div:hover{transform:translateY(-3px);box-shadow:var(--lift-hi)}
/* :is(h3,h4) et non h3 seul : certaines rangées de cartes ouvrent en h4, et
   elles perdaient silencieusement leur filet de cèdre. Le même composant
   rendait deux aspects différents à deux pages d'intervalle. */
.cols--3 > div > :is(h3,h4):first-child{
  padding-top:var(--s-16);
  border-top:3px solid var(--accent);
  display:inline-block;
}

/* ------------------------------------------------------------------ pied --- */

.site-foot{
  --paper:#14181c; --surface:#1c2228; --raised:#1c2228; --ink:#f2f0ea;
  --ink-soft:rgba(242,240,234,.78); --ink-mute:rgba(242,240,234,.66);
  --ink-wash:rgba(242,240,234,.10);
  --line:rgba(242,240,234,.16); --line-firm:rgba(242,240,234,.30);
  --accent:#e88a55; --accent-deep:#f0a074;
  --on-accent:#14181c;
  background:var(--paper);color:var(--ink);
  /* La respiration est DANS la boîte peinte, pas au-dessus. En marge, elle
     peignait une bande de page blanche de 96 px entre une bande sombre et le pied
     sombre : noir, blanc, filet orange, noir. Le filet de cèdre doit se poser sur
     ce qui précède, pas flotter au bout d'un couloir blanc. */
  margin-top:0;
  padding:calc(var(--s-96) + var(--s-80)) 0 var(--s-40);
  border-top:3px solid var(--accent);
}
.foot-grid,.foot-bottom{max-width:var(--page);margin:0 auto;padding:0 var(--pad)}
/* La colonne « Dossiers » porte maintenant les dix sections du site, donc elle
   vaut deux pistes et se divise en deux colonnes : sinon elle faisait le double
   de la hauteur des trois autres et la rangée partait en drapeau. */
.foot-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 2fr 1.4fr;gap:var(--s-40)}
.foot-dossiers .foot-map{columns:2;column-gap:var(--s-32)}
/* Les colonnes de liens étaient des <p> avec des <br>. À 1,85 d'interligne, une
   étiquette qui passait à la ligne prenait EXACTEMENT le même pas vertical que le
   saut vers le lien suivant : « Conseiller ou / entrepreneur général » se lisait
   comme deux entrées, et la colonne « Comprendre » comme six au lieu de trois.
   En liste, les deux espacements se séparent — l'interligne se resserre, le pas
   entre deux entrées s'ouvre — et la frontière redevient visible. */
.foot-list{margin:0}
.foot-list li{padding-left:0;margin:0 0 var(--s-12);line-height:1.4;break-inside:avoid}
.foot-list li::before{content:none}
.foot-list li:last-child{margin-bottom:0}
/* Une adresse de courriel ne se coupe pas toute seule : sans ça,
   info@baticonseilresidentiel.com imposait sa largeur à sa piste et comprimait
   les quatre autres. */
.site-foot a,.site-foot p{overflow-wrap:anywhere}
.foot-brand .brand-mark{background:var(--accent);margin-bottom:var(--s-16)}
.foot-brand .brand-mark svg{fill:#14181c}
.site-foot h4{color:var(--ink-mute)}
.foot-brand h4{
  font-size:17px;font-weight:800;letter-spacing:-.02em;
  text-transform:none;color:var(--ink);margin-bottom:var(--s-8);
}
/* 1,85 servait à espacer des liens séparés par des <br>. Ce sont des listes
   maintenant, et il ne reste que de la prose, qui n'a pas besoin de tant d'air. */
.site-foot p{font-size:var(--t-sm);line-height:1.6;margin-bottom:0;color:var(--ink-soft)}
.site-foot a{text-decoration:none;color:var(--ink-soft)}
.site-foot a:hover{color:var(--accent-deep)}

.foot-bottom{margin-top:var(--s-64)}
/* La déclaration de la Loi sur le bâtiment est un colophon, pas une note de bas
   de page : elle est encadrée et lisible. */
.foot-legal{
  border:1px solid var(--line);
  border-left:3px solid var(--accent);
  border-radius:var(--r);
  padding:18px var(--s-24);
  font-size:var(--t-cap);line-height:1.7;color:var(--ink-soft);
}
.foot-fine{
  margin-top:var(--s-24);padding-top:var(--s-24);
  border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:var(--s-12) var(--s-32);align-items:baseline;
  font-size:var(--t-cap);color:var(--ink-mute);
}

/* ------------------------------------------------------------- utilitaires --- */

.stack > * + *{margin-top:var(--s-24)}
/* Le lien de renvoi posé juste après une pile de livrables — « Le détail du
   mandat 1 » — n'appartient pas à la pile, donc il n'hérite d'aucun écart : il se
   collait au dernier paragraphe et se lisait comme sa dernière ligne. */
.stack + p{margin-top:var(--s-32)}
.stack-lg > * + *{margin-top:var(--s-48)}
.mt-sec{margin-top:var(--s-56)}
.nowrap{white-space:nowrap}
/* Le piège à robots du formulaire. Hors écran plutôt qu'en display:none : un
   robot qui vérifie la visibilité calculée le remplit quand même, et Netlify
   jette alors l'envoi. Un humain ne le voit ni ne l'atteint au clavier. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
.skip{
  position:absolute;left:var(--pad);top:-80px;z-index:60;
  background:var(--accent);color:var(--on-accent);padding:13px 22px;
  font-family:var(--f-head);font-weight:700;
  text-decoration:none;border-radius:var(--r-sm);
}
.skip:focus{top:var(--s-8)}

/* ------------------------------------------------------------- responsive --- */

/* Entre 1121 et 1299 px, élargir la coquille ne sert à rien : elle vaut déjà la
   fenêtre. C'est donc le bouton qui s'efface, comme il le faisait déjà sous
   1120 px. Il ne reste alors que la marque et les onglets : l'adresse de
   courriel a été retirée de l'entête — l'onglet Contact fait le même travail,
   et l'adresse au complet, trente caractères, poussait le dernier onglet
   par-dessus elle. Elle reste lisible dans le menu, dans le pied de page et
   sur la page contact. */
@media (max-width:1299px){
  .masthead-act .btn{display:none}
  .nav a{padding:9px 8px;font-size:13.5px}
}
@media (max-width:960px){
  :root{--gap:64px;--pad:24px;--t-body:18px}
  .nav,.masthead-act{display:none}
  .menu{display:block}
  .cols,.cols--3,.cols--sidebar{grid-template-columns:1fr;gap:var(--s-32)}
  .contact-sheet,.contact-sheet--2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .foot-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-32)}
  .foot-brand{grid-column:1 / -1}
}
/* ------------------------------------------------- tableaux en fiches --- */

/* Le problème, mesuré : à 390 px il reste 352 px de colonne, et `table{min-width:460px}`
   forçait CHAQUE tableau au-delà, y compris ceux qui rentraient. Le cadre du
   .table-wrap, arrondi et bordé, coupait alors net sur son bord droit — sans
   ombre, sans barre, sans rien : le tableau avait l'air complet. Sur 46 pages,
   la colonne perdue était celle des réponses. « Plafond » : 50 000 $ / 300 000 $ /
   6 000 $, invisible. « Part indicative » : 15 / 25 / 25 / 20 / 15 %, invisible.

   La réponse dépend du nombre de colonnes, parce que le défaut n'est pas le même.
   Deux colonnes — 37 tableaux — rentrent parfaitement dès qu'on cesse de leur
   imposer une largeur : ils restent des tableaux partout.
   Trois et quatre colonnes tiennent encore dans les 662 px de la mesure sur une
   tablette, mais plus sur un téléphone.
   Cinq et six colonnes — quatre tableaux — ne tiennent nulle part sous la colonne
   de contenu : à 662 px, « Ce que le sol doit permettre » se met à un mot par
   ligne et gonfle la rangée à huit lignes.

   D'où deux seuils pour un seul traitement : la rangée devient une fiche, l'en-tête
   de rangée en titre, chaque valeur précédée du nom de sa colonne (repris par la
   construction dans `data-th`). On perd la lecture en diagonale, qu'un écran
   étroit ne permettait de toute façon pas; on garde les chiffres, qui étaient
   simplement absents.

   Les deux blocs qui suivent portent les MÊMES déclarations à deux seuils
   différents. Ils sont générés ensemble : si l'un change, l'autre change. */
@media (max-width:999px){
  .table-wrap{width:auto;max-width:100%}
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]){min-width:0;display:block}
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) thead{
    position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap;
  }
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody,
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tr,
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) th,
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) td{display:block;width:auto}
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) caption{display:block}
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody tr{
    padding:var(--s-16) var(--s-16) var(--s-24);
    border-top:1px solid var(--line);
  }
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody tr:first-child{border-top:0}
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody tr:nth-child(even){background:var(--surface)}
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody th{
    background:none;color:var(--ink);
    font-family:var(--f-head);font-size:17px;font-weight:700;
    letter-spacing:-.01em;text-transform:none;line-height:1.3;
    padding:0 0 var(--s-8);
  }
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody td{
    border-top:0;
    padding:0;
    text-align:left;
    white-space:normal;
  }
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody td::before{
    content:attr(data-th);
    display:block;
    margin-top:var(--s-12);
    font-family:var(--f-head);font-size:var(--t-micro);font-weight:700;
    letter-spacing:.12em;text-transform:uppercase;color:var(--ink-mute);
  }
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody td:not([data-th])::before,
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) tbody td[data-th=""]::before{content:none}
  :is(table[data-cols="5"],table[data-cols="6"],table[data-cols="7"]) td.num{text-align:left}
}

@media (max-width:700px){
  table[data-cols="2"]{min-width:0}
  :is(table[data-cols="3"],table[data-cols="4"]){min-width:0;display:block}
  :is(table[data-cols="3"],table[data-cols="4"]) thead{
    position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap;
  }
  :is(table[data-cols="3"],table[data-cols="4"]) tbody,
  :is(table[data-cols="3"],table[data-cols="4"]) tr,
  :is(table[data-cols="3"],table[data-cols="4"]) th,
  :is(table[data-cols="3"],table[data-cols="4"]) td{display:block;width:auto}
  :is(table[data-cols="3"],table[data-cols="4"]) caption{display:block}
  :is(table[data-cols="3"],table[data-cols="4"]) tbody tr{
    padding:var(--s-16) var(--s-16) var(--s-24);
    border-top:1px solid var(--line);
  }
  :is(table[data-cols="3"],table[data-cols="4"]) tbody tr:first-child{border-top:0}
  :is(table[data-cols="3"],table[data-cols="4"]) tbody tr:nth-child(even){background:var(--surface)}
  :is(table[data-cols="3"],table[data-cols="4"]) tbody th{
    background:none;color:var(--ink);
    font-family:var(--f-head);font-size:17px;font-weight:700;
    letter-spacing:-.01em;text-transform:none;line-height:1.3;
    padding:0 0 var(--s-8);
  }
  :is(table[data-cols="3"],table[data-cols="4"]) tbody td{
    border-top:0;
    padding:0;
    text-align:left;
    white-space:normal;
  }
  :is(table[data-cols="3"],table[data-cols="4"]) tbody td::before{
    content:attr(data-th);
    display:block;
    margin-top:var(--s-12);
    font-family:var(--f-head);font-size:var(--t-micro);font-weight:700;
    letter-spacing:.12em;text-transform:uppercase;color:var(--ink-mute);
  }
  :is(table[data-cols="3"],table[data-cols="4"]) tbody td:not([data-th])::before,
  :is(table[data-cols="3"],table[data-cols="4"]) tbody td[data-th=""]::before{content:none}
  :is(table[data-cols="3"],table[data-cols="4"]) td.num{text-align:left}
}

@media (max-width:600px){
  :root{--pad:18px;--gap:52px}
  /* La politique de confidentialité et les conditions d'utilisation faisaient
     24 px de haut au doigt. Elles restent en petits caractères, mais la zone
     tactile passe à 44 px sans changer la ligne de base. */
  .foot-fine{gap:0 var(--s-24)}
  .foot-fine a{padding:10px 0;display:inline-block}
  .brand-name i{display:none}
  .filebar-in{gap:var(--s-8)}
  /* Le bouton d'envoi du formulaire est un <button>, pas un .cta : il restait une
     pastille de 140 px alignée à gauche pendant que les quatre autres actions de la
     page faisaient toute la largeur. */
  .cta,.cta-row > .cta,form button[type=submit]{width:100%}
  /* Moins de marge intérieure au téléphone : sur une étiquette longue, les 24 px de
     chaque côté suffisaient à renvoyer la flèche seule sur une deuxième ligne, et le
     bouton doublait de hauteur à côté de son voisin. */
  .cta,form button[type=submit]{padding-left:var(--s-16);padding-right:var(--s-16)}
  /* Pleine largeur, l'étiquette et la flèche sont deux éléments de flex : dès que
     l'étiquette passe à deux lignes elle s'étire pour remplir, part se ranger à
     gauche, et la flèche est jetée contre le bord droit, seule, à 80 px de la fin
     du texte. Le bouton à une ligne juste au-dessus, lui, reste centré — deux
     composants différents dans la même pile. En bloc centré, la flèche redevient
     un caractère à la suite du texte, quel que soit le nombre de lignes. */
  .cta{display:block;text-align:center}
  .cta::after{display:inline-block;margin-left:10px}
  .contact-sheet,.contact-sheet--2{grid-template-columns:1fr}
  .contact-sheet .shot,.contact-sheet .shot-slot{aspect-ratio:3 / 2}
  .foot-grid{grid-template-columns:1fr}
  .note,.boundary{padding:var(--s-24)}
  .boundary{padding-left:calc(var(--s-24) + 14px)}
  .note::before{left:var(--s-24)}
  th,td{padding:var(--s-12) var(--s-16)}
  /* Les fiches empilées portent déjà leur propre marge intérieure. */
  table:not([data-cols="2"]) tbody th,
  table:not([data-cols="2"]) tbody td{padding-inline:0}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* -------------------------------------------------------------- impression --- */

/* Ces guides sont imprimés et apportés à l'hôtel de ville, à la caisse et sur
   le terrain. L'URL des liens est imprimée derrière le texte, les tableaux ne
   se coupent pas, et la limite légale reste visible. */
@media print{
  :root{
    --paper:#fff;--surface:#fff;--raised:#fff;--deep:#fff;--ink:#000;
    --line:#bbb;--line-firm:#888;--accent:#000;--accent-deep:#000;--steel:#000;
    --gap:22px;--pad:0;--lift:none;--lift-hi:none;
  }
  .masthead,.menu,.skip,.cta,.btn,.cta-row,.siblings,.foot-grid{display:none}
  body{font-size:11pt;line-height:1.45;background:#fff;color:#000}
  .band,.band--rust,.band--ink,.band--hero{
    background:#fff!important;color:#000!important;border:0;padding:0 0 16pt;
  }
  .band--hero.has-shot{background-image:none!important}
  .measure,.measure--narrow{max-width:none}
  h1,h2,h3{break-after:avoid;color:#000}
  h2{border-top:2pt solid #000}
  .table-wrap,figure,.note,.boundary,.verified{break-inside:avoid;box-shadow:none}
  th{background:#fff!important;color:#000!important;border-bottom:1pt solid #000}
  .filebar{border-bottom:1pt solid #000;margin-bottom:10pt;background:#fff}
  a[href^="http"]::after,a[href^="/"]::after{
    content:" (" attr(href) ")";font-size:8pt;color:#555;
  }
  .site-foot{background:#fff!important;color:#000!important;margin-top:14pt;
    padding:10pt 0 0;border-top:1pt solid #000;
    /* Ces quatre jetons ne sont pas décoratifs : sans eux la déclaration de la
       Loi sur le bâtiment s'imprimait EN BLANC SUR BLANC sur les 74 pages.
       `.site-foot` rebascule --ink-soft en quasi-blanc pour le pied sombre, et
       le bloc print ne redéclarait les jetons que sur :root — or une propriété
       personnalisée résout ses var() là où elle est DÉCLARÉE. `color:#000` sur
       .site-foot ne sauve rien : .foot-legal porte sa propre déclaration
       `color:var(--ink-soft)`, qui gagne sur l'élément. Et /processus invite
       justement le lecteur à imprimer la page pour la montrer à son prêteur. */
    --ink-soft:#000;--ink-mute:#333;--line:#bbb;--accent:#000}
  .shot,.shot-slot{box-shadow:none}
}
