/************************************************************
 *  Inspection Strux — site styles
 *
 *  Aurox's design, hand-written over Awning's Bootstrap 5 base.
 *  Values are ported from prototype/aurox-hero-fidelity-test.html, which was
 *  measured against the live Aurox demo (nav pill geometry, 58px/69.6px
 *  headline, the 5px-radius CTA with its dark square arrow box, the bordered
 *  feature row). Do not "tidy" these numbers — they are the design.
 *
 *  Loads after tokens.css. Colours come from there; nothing is hardcoded here
 *  except opacities and neutral shadows, which have no token.
 ************************************************************/

*, *::before, *::after { box-sizing: border-box; }

/* ============================================================
   Fonds foncés — l'aiguillage de l'accent
   ------------------------------------------------------------
   Le bleu du logo n'est lisible que sur encre ; sa version foncée
   que sur blanc. La démonstration chiffrée est en tête de
   tokens.css. Ces quatre sélecteurs sont les QUATRE fonds foncés
   du site, et ils redéclarent les trois propriétés dont dépend
   var(--accent-color).

   Les propriétés personnalisées héritent : tout descendant de ces
   quatre sections résout donc --accent-color vers le bon bleu sans
   qu'aucune règle n'ait à savoir sur quel fond elle s'applique.
   Toute section foncée AJOUTÉE plus tard doit être ajoutée ici —
   c'est la seule ligne à tenir à jour, et l'oublier se voit
   immédiatement (l'accent y devient un bleu sourd sur du noir).

   Pourquoi pas une liste de surcharges par règle : une liste ne
   protège que ce qu'on a pensé à auditer. Écrite ainsi, la
   prochaine règle posée sur .bandeau est correcte d'office.

   .entete N'EST PAS dans cette liste, et c'est volontaire : la
   pilule de navigation est blanche et vit HORS de .hero dans le
   DOM (voir _header.php), donc elle garde les valeurs claires.
   ============================================================ */
.hero,
.bandeau,
.page-entete,
.pied {
    --accent-ground-rgb: var(--accent-rgb);
    --accent-hover-rgb:  255 255 255;
    --accent-contraste:  var(--primary-color);

    /* ---------------------------------------------------------------
       CES DEUX LIGNES NE SONT PAS REDONDANTES, et les omettre est un
       bogue SILENCIEUX. Mesuré dans un navigateur le 2026-09-17, pas
       déduit : sans elles, .hero rendait --accent-ground-rgb à
       « 128 176 208 » (l'aiguillage marche) et --accent-color à
       « rgb(61 110 146) » quand même.

       Pourquoi : un var() écrit DANS une propriété personnalisée est
       substitué à l'endroit où cette propriété est DÉCLARÉE, pas là où
       elle est lue. :root déclare
           --accent-color: rgb(var(--accent-ground-rgb))
       donc la substitution a lieu à :root, où l'aiguillage vaut encore
       le bleu foncé, et c'est le littéral « rgb(61 110 146) » qui
       descend par héritage. Redéclarer --accent-ground-rgb plus bas
       n'a rien à réévaluer : le calcul est déjà fait.

       Le résultat sans ces lignes était pire que les deux options
       envisagées : aplat bleu FONCÉ avec étiquette encre, soit 2.98.
       La dérivation est réécrite à l'identique, donc la valeur reste
       à source unique — c'est le POINT DE CALCUL qui change, pas la
       formule. M07 exige les cinq lignes pour cette raison.
       --------------------------------------------------------------- */
    --accent-color: rgb(var(--accent-ground-rgb));
    --accent-hover: rgb(var(--accent-hover-rgb));
}

/* ============================================================
   États partagés — mise au point clavier, sélection, ascenseur
   ------------------------------------------------------------
   BRANDING.md §2 règle 7 et §4.2 : ce sont les endroits qu'un
   rebranding rate systématiquement, parce qu'ils n'apparaissent
   sur aucune maquette. Écrits UNE fois, en tokens, donc corrects
   sur les deux fonds par le même héritage que ci-dessus.
   ============================================================ */

/* :where() garde la spécificité à zéro : une règle de composant
   qui veut son propre anneau n'a pas à lutter contre celle-ci.
   Ne jamais remplacer par outline:none sans mettre autre chose. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--accent-color);
    outline-offset: 2px;
}

::selection {
    background: var(--accent-color);
    color: var(--accent-contraste);
}

html {
    scrollbar-color: var(--metal-mid) var(--background-color);
}

body {
    font-family: var(--default-font);
    font-size: 16px;
    line-height: 1.6;
    color: var(--text-color);
    background-color: var(--white-color);
    -webkit-font-smoothing: antialiased;
}

/* Texte justifie des 3 lignes (demande client 2026-10-13). La classe est posee par le script de _footer.php, qui compte les lignes : le CSS seul ne le sait pas. La derniere ligne garde l'alignement d'origine (centre dans les entetes). */
.justifie { text-align: justify; -webkit-hyphens: auto; hyphens: auto; }

h1, h2, h3, h4 {
    color: var(--primary-color);
    font-weight: 600;
    letter-spacing: -0.015em;
}

a { color: var(--accent-color); }
a:hover { color: var(--accent-hover); }

.skip-link {
    position: absolute; top: 8px; left: 8px; z-index: 100;
    background: var(--white-color); color: var(--primary-color);
    padding: 10px 18px; border-radius: 6px;
}

/* ============================================================
   Buttons — Aurox's bar with a dark square arrow tucked in
   ============================================================ */
.bouton {
    display: inline-flex; align-items: center; justify-content: center; gap: 14px;
    text-decoration: none; font-weight: 600; font-size: 16px;
    border: none; cursor: pointer; border-radius: 5px;
    padding: 5px 5px 5px 22px;
    transition: background-color .2s ease, color .2s ease, border-color .2s ease;
}

/* L'étiquette est --accent-contraste et non du blanc en dur, donc elle suit le
   fond : blanc sur #3D6E92 en section claire (5.46), encre sur #80B0D0 dans le
   héros et le bandeau (7.01). Un color:var(--white-color) ici mesurerait 2.32
   aux deux endroits les plus regardés du site.

   Le survol est une VALEUR et non filter:brightness() : éclaircir #3D6E92 lui
   retire du contraste, ce qui fait d'un état de survol une régression
   d'accessibilité. BRANDING.md §2 règle 3. */
.bouton--accent {
    background: var(--accent-color);
    color: var(--accent-contraste);
}
.bouton--accent:hover { background: var(--accent-hover); }

/* Le padding de .bouton est asymetrique parce que la fleche est collee au bord
   DROIT ; sans fleche (pied de page), l'etiquette reprend un padding egal pour
   rester centree dans le bouton (demande client 2026-10-13). */
.bouton:not(:has(.bouton-fleche)) { padding: 12px 22px; }

/* Secondary action. .bouton's asymmetric padding exists to tuck the dark arrow
   box against the right edge; without an arrow that padding looks broken, so
   this variant restores an even one. */
.bouton--contour {
    background: transparent; color: var(--primary-color);
    border: 1px solid var(--metal-light);
    padding: 12px 24px;
}
.bouton--contour:hover {
    border-color: var(--accent-color); color: var(--accent-color);
}

.bouton-fleche {
    width: 38px; height: 38px; border-radius: 4px;
    background: var(--primary-color); color: var(--white-color);
    display: grid; place-items: center; flex: 0 0 auto;
    font-size: 14px;
}

.lien-fleche {
    display: inline-flex; align-items: center; gap: 8px;
    color: var(--accent-color); font-weight: 600; text-decoration: none;
}
.lien-fleche:hover { gap: 12px; transition: gap .2s ease; color: var(--accent-hover); }

/* ============================================================
   Floating nav pill — the signature Aurox element
   ============================================================ */
.entete { position: absolute; top: 0; left: 0; right: 0; z-index: 10; }

.nav-pilule {
    margin: 28px 32px;
    background: var(--white-color);
    border-radius: 16px;
    padding: 16px 16px 16px 26px;
    display: flex; align-items: center; gap: 40px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .10);
}

.marque {
    display: flex; align-items: center; gap: 12px;
    font-weight: 700; font-size: 26px; letter-spacing: -.02em;
    color: var(--primary-color); text-decoration: none;
    --marque-taille: 46px;
}
/* One box, two possible occupants — the accent pastille until the client's
   logo lands, the logo itself afterwards (see marque_mark()). Both are pinned
   to --marque-taille so an artwork of unknown proportions cannot resize the
   nav pill, which is the same fixed-slot rule .img-slot applies to every
   content photograph on the site. Only the three breakpoint values below
   change the size; neither rule carries its own. */
.marque-pastille {
    width: var(--marque-taille); height: var(--marque-taille); border-radius: 50%;
    background: var(--accent-color); flex: 0 0 auto;
}
.marque-logo {
    width: auto; height: var(--marque-taille);
    max-width: calc(var(--marque-taille) * 3);   /* a wide wordmark stays a mark */
    object-fit: contain; flex: 0 0 auto;
}
.marque-nom { white-space: nowrap; }

.nav-liens { display: flex; gap: 26px; margin-left: auto; }
.nav-lien {
    color: var(--primary-color); text-decoration: none;
    font-weight: 500; font-size: 16px; transition: color .2s ease;
    /* Strux has six nav items where Aurox's demo has four, and the French
       labels are longer than the English ones. Without this they wrap to two
       lines and the pill loses its shape. */
    white-space: nowrap;
}
.nav-lien:hover, .nav-lien.active { color: var(--accent-color); }

/* La page courante ne se signale plus par la seule couleur. Un filet sous le
   libellé actif est la version de ce repère qui survit à un daltonisme et à un
   écran mal calibré ; BRANDING.md §4.2 le nomme parmi les oublis habituels.
   text-decoration plutôt qu'une bordure ou une ombre interne : le filet colle
   au LIBELLÉ. Dans le menu déroulant mobile, .nav-lien est une dalle rembourrée
   de 26px — une bordure basse y tracerait un trait d'un bord à l'autre de
   l'écran au lieu de désigner un mot. */
.nav-lien.active {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 6px;
}

.nav-cta { white-space: nowrap; flex: 0 0 auto; }

/* Le selecteur de langue (2026-09-02). Volontairement plus discret que les six
   liens de navigation : c'est une commande, pas une septieme destination, et
   sur une page francaise il porte le seul mot anglais de la barre. La bordure
   suffit a le distinguer sans lui donner le poids d'un onglet. */
.nav-lien--langue {
    padding: 2px 10px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 999px;
    font-size: 14px;
    letter-spacing: .02em;
}
.nav-lien--langue:hover { border-color: var(--accent-color); }

/* Mobile-only duplicate of the CTA, living inside the dropdown. Hidden here;
   revealed in the <=1100px block where .nav-cta itself is hidden. */
.nav-lien--cta { display: none; }

/* Below this the six French labels no longer fit beside the brand and CTA.
   Higher than the 1100px the prototype used, for exactly that reason. */
@media (max-width: 1400px) {
    .nav-liens { gap: 20px; }
    .nav-lien { font-size: 15px; }
    .nav-pilule { gap: 24px; padding-left: 20px; }
    .marque { font-size: 22px; --marque-taille: 40px; }
}

.nav-bascule {
    display: none; margin-left: auto;
    background: none; border: none; padding: 10px; cursor: pointer;
}
.nav-bascule span {
    display: block; width: 24px; height: 2px; margin: 5px 0;
    background: var(--primary-color);
}

/* ============================================================
   Hero
   ============================================================ */
.hero {
    position: relative; min-height: 100vh;
    display: flex; align-items: center; overflow: hidden;
    background-size: cover; background-position: center;
}
/* IL N'Y A PLUS DE VOILE SUR LE HÉROS — 2026-09-24, décision de Joel.
   Ce qui protège le texte, désormais, c'est l'ombre portée ci-dessous, et
   elle seule. Les deux règles sont écrites ensemble parce que la seconde
   remplace la première : qui retire l'ombre rend le héros illisible.

   Ce qu'il y avait avant, et qui a disparu : un .hero::after en
   dégradé horizontal, encre à 88 % à gauche puis 10 % à droite, hérité du
   portage d'Aurox (a8856f7). Il datait du temps où le héros portait une
   photo fixe ; la vidéo (8eb610f) est passée DESSOUS sans y toucher.

   CE QUE ÇA COÛTE, mesuré et non estimé — douze images de la vidéo rendues
   par un vrai navigateur, le texte mis en color:transparent pour lire le
   fond composite EXACT sous la lettre, ombre comprise, pire tuile de 24 px.
   Rapports de contraste, avec voile → sans :
       sur-titre  4,72 → 1,03      sous-titre  6,30 → 2,32
       titre      7,11 → 3,76      atouts      4,93 → 1,88
   AA demande 4,50, sauf le titre (grand texte) à 3,00. Trois bandes sur
   quatre passent donc sous le seuil, et le sur-titre s'effondre : #80B0D0
   est un bleu CLAIR, choisi pour du texte sur fond sombre, et aucune ombre
   ne rattrape une encre claire posée sur un fond clair. Le choix est
   assumé, il est esthétique, et il est documenté dans la note de projet
   (Projects/Inspection-Strux.md, encadré du 2026-09-24) avec les deux
   pistes conformes qui ont été écartées. Ne pas le « corriger » par
   inadvertance en recollant un voile : le remettre est un choix à prendre,
   pas un oubli à réparer.

   L'IMAGE DE REPLI EST CONCERNÉE ELLE AUSSI. Le voile ne couvrait pas que
   la vidéo : il tenait aussi le .hero { background-image } que voient le
   mode économie de données et tout visiteur dont le mp4 n'arrive pas.
   Depuis le 2026-09-24 ce fond EST la frame 0 de la vidéo (index.php), donc
   la question ne se pose plus deux fois : ce qui est jugé sur la vidéo vaut
   pour le repli, c'est la même image. Elle se posera entière, en revanche,
   le jour où une photographie remplacera la vidéo — ce n'est plus la
   feuille de style qui garantit un tiers gauche sombre ou calme.

   Dérivée de --primary-rgb, comme l'était le voile depuis le 2026-09-06 :
   les quatre arrêts étaient des rgba(28,29,24,…) en dur, et un changement
   de palette en phase 7 aurait repeint le site en laissant le héros sur
   l'ancien noir olive. L'ombre ne refait pas cette erreur. */
.hero-contenu h1,
.hero-contenu p,
.hero-contenu .eyebrow {
    text-shadow: 0 1px 2px  rgb(var(--primary-rgb) / .58),
                 0 2px 18px rgb(var(--primary-rgb) / .78);
}
.hero-contenu {
    position: relative; z-index: 5; width: 100%;
    max-width: 1320px; margin: 0 auto; padding: 0 32px;
}

/* ---- La vidéo du bandeau — 2026-09-23 ---------------------------------
   Toujours pas de z-index ici, et la raison a changé le 2026-09-24 : il n'y
   a plus de voile à passer par-dessus. Restent deux couches, et l'ordre de
   peinture les sépare déjà — la vidéo est positionnée sans z-index, le
   texte est dans .hero-contenu qui porte z-index: 5. Lui en donner un ici
   n'ajouterait rien qu'une valeur de plus à tenir à jour.

   object-fit: cover reproduit exactement le background-size: cover de
   l'image de repli — le cadrage ne bouge pas quand la vidéo prend le relais.

   L'élément arrive avec `hidden` et c'est le JS d'index.php qui l'enlève,
   une fois saveData vérifié — c'est désormais la seule garde, et la vidéo
   joue à toutes les largeurs, téléphones compris.

   IL N'Y A PLUS DE RÈGLE prefers-reduced-motion ICI, et sa disparition est
   volontaire — 2026-09-23. Elle doublait la garde JS ; la laisser seule
   aurait annulé le retrait de cette garde, puisque display:none aurait caché
   la vidéo de toute façon. Le raisonnement complet est dans le commentaire de
   la vidéo, dans index.php. Les deux autres règles prefers-reduced-motion de
   ce fichier (scroll-behavior, jauge du parcours) ne sont pas concernées et
   restent en place. */
.hero-video {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
    pointer-events: none;
}

/* Le sur-titre, et la reprise la plus reconnaissable de la marque.
   BRANDING.md §3 : c'est le traitement de « INSPECTION » dans le logo —
   majuscules, 0.22em d'approche, graisse normale, accent. Le logo pose ce mot
   en bleu sous un mot-clé noir ; la page le pose au-dessus de chaque titre de
   section, ce qui fait de la même signature un élément de mise en page.

   La couleur passe par --accent-color, donc l'aiguillage de fond s'en charge :
   #80B0D0 sur fond sombre, #3D6E92 en section claire (5.46). C'est pourquoi
   .eyebrow--fonce n'a plus de déclaration propre.

   ATTENTION AU HÉROS depuis le 2026-09-24 : il n'y a plus de voile encre
   sous ce bleu, et #80B0D0 y tombe à 1,03 sur les images claires de la
   vidéo (il valait 7.01 sur le voile). C'est le prix assumé du retrait —
   voir le commentaire de .hero-contenu plus haut. Le jour où .bandeau,
   .page-entete ou .pied perdrait son fond sombre, le même effondrement s'y
   produirait : ce bleu est choisi POUR le fond sombre, pas malgré lui.

   Était : blanc, 15px, 600, 0.04em. */
.eyebrow {
    display: flex; align-items: center; gap: 10px;
    color: var(--accent-color);
    font-size: 13.5px; font-weight: 400;
    letter-spacing: .22em; text-transform: uppercase;
    margin-bottom: 22px;
}
.eyebrow i { color: var(--accent-color); letter-spacing: normal; }

.hero h1 {
    font-size: 58px; line-height: 69.6px; font-weight: 600;
    color: var(--white-color); letter-spacing: -.015em; max-width: 830px;
}
.hero-lede {
    margin-top: 20px; font-size: 16.5px; line-height: 1.7;
    color: rgba(255,255,255,.82); max-width: 660px;
}

.hero-atouts {
    display: flex; gap: 56px; margin-top: 44px; padding-top: 38px;
    border-top: 1px solid rgba(255,255,255,.18); max-width: 900px;
}
.atout { display: flex; align-items: center; gap: 15px; }
/* Le fond à 12 % de blanc et le filet à 20 % supposent un fond sombre
   dessous : sans le voile (2026-09-24) ils disparaissent purement et
   simplement sur une pelouse ou une porte de garage blanche. Le box-shadow
   est la contrepartie — il pose la pastille sur sa propre ombre plutôt que
   sur la vidéo. Même dosage que l'ombre du texte. */
.atout-icone {
    width: 52px; height: 52px; border-radius: 50%;
    background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.2);
    display: grid; place-items: center; flex: 0 0 auto;
    color: var(--white-color); font-size: 20px;
    box-shadow: 0 2px 20px rgb(var(--primary-rgb) / .55);
}
.atout p {
    color: var(--white-color); font-weight: 600;
    font-size: 17px; line-height: 1.4; max-width: 230px; margin: 0;
}
.hero-cta { margin-top: 52px; }

/* ============================================================
   Sections
   ============================================================ */
.section { padding: 110px 0; }
.section-entete { max-width: 720px; margin: 0 auto 60px; text-align: center; }
.section-entete h2 { font-size: 42px; line-height: 1.2; margin-bottom: 16px; }
.section-entete p { margin: 0; }

/* Service cards */
.carte {
    height: 100%; padding: 34px;
    background: var(--white-color);
    border: 1px solid var(--divider-color); border-radius: 14px;
    transition: box-shadow .25s ease, transform .25s ease;
}
.carte:hover { box-shadow: 0 14px 44px rgba(0,0,0,.08); transform: translateY(-4px); }
.carte-icone {
    width: 58px; height: 58px; border-radius: 50%;
    background: var(--accent-color); color: var(--accent-contraste);
    display: grid; place-items: center; font-size: 22px; margin-bottom: 22px;
}
.carte h3 { font-size: 22px; margin-bottom: 12px; }
.carte p { margin-bottom: 20px; }

/* Numbered steps */
.etape { text-align: center; padding: 0 12px; }
.etape-numero {
    width: 64px; height: 64px; border-radius: 50%; margin: 0 auto 20px;
    background: var(--accent-color); color: var(--accent-contraste);
    display: grid; place-items: center;
    font-size: 22px; font-weight: 700;
}
.etape h3 { font-size: 20px; margin-bottom: 10px; }

/* Accueil, « Ce que nous incluons » : les deux visuels du client sous la
   liste. Colonnes en fr proportionnelles aux largeurs (437 / 477) pour que
   les deux images, de même hauteur source, gardent la même hauteur. */
.inclus-visuels {
    display: grid; grid-template-columns: 437fr 477fr; gap: 24px;
    margin-top: 40px;
}
.inclus-visuels img {
    display: block; width: 100%; height: auto;
    border-radius: 14px;
}
@media (max-width: 575px) {
    .inclus-visuels { grid-template-columns: 1fr; gap: 16px; margin-top: 30px; }
}

/* Full-width CTA band */
.bandeau {
    background: var(--primary-color);
    padding: 80px 0; text-align: center;
}
.bandeau h2 { color: var(--white-color); font-size: 38px; margin-bottom: 14px; }
.bandeau p { color: rgba(255,255,255,.75); max-width: 620px; margin: 0 auto 30px; }

/* ============================================================
   Footer
   ============================================================ */
.pied { background: var(--primary-color); color: rgba(255,255,255,.72); padding: 80px 0 30px; }
.marque--pied { color: var(--white-color); margin-bottom: 18px; }
.pied-texte { max-width: 320px; }
.pied-titre { color: var(--white-color); font-size: 18px; margin-bottom: 18px; }
.pied-liste { list-style: none; padding: 0; margin: 0 0 22px; }
.pied-liste li { margin-bottom: 6px; }
/* WCAG 2.5.8 : la cible de clic doit faire 24px. Un <a> en ligne ne mesurait
   que sa line-height (~20px). inline-block + min-height donne la boite; le
   padding vertical absorbe la difference et margin-bottom passe de 10 a 6
   pour que le rythme visuel du pied reste identique. */
.pied-liste a {
  color: rgba(255,255,255,.72);
  text-decoration: none;
  display: inline-block;
  min-height: 24px;
  padding-block: 2px;
}
.pied-liste a:hover { color: var(--accent-color); }
.pied-bas {
    margin-top: 50px; padding-top: 24px;
    border-top: 1px solid var(--dark-divider-color);
    font-size: 14px;
}
.pied-bas p { margin-bottom: 6px; }
.pied-bas a { color: rgba(255,255,255,.72); text-decoration: underline; }

/* ============================================================
   Interior page header
   ------------------------------------------------------------
   .entete is position:absolute, so it sits OVER the first block of
   every page. The homepage gets away with it because its hero is
   100vh; every other page needs a band tall enough to clear the
   floating pill (28px margin + ~78px pill). Dark, like .bandeau,
   so the white pill reads against it.
   ============================================================ */
.page-entete {
    background: var(--primary-color);
    padding: 210px 0 90px;
    text-align: center;
}
.page-entete .container { max-width: 860px; }
.page-entete h1 {
    color: var(--white-color);
    font-size: 48px; line-height: 1.15; margin-bottom: 18px;
}
.page-entete-lede {
    color: rgba(255,255,255,.78);
    font-size: 17px; margin: 0 auto; max-width: 680px;
}
.page-entete-date {
    color: rgba(255,255,255,.55);
    font-size: 14px; margin: 18px 0 0;
}

/* .eyebrow--fonce portait la seule différence entre le sur-titre du héros
   (blanc sur photo) et celui d'une section claire (accent). Depuis que
   .eyebrow est le kicker de la marque et tire sa couleur de --accent-color,
   l'aiguillage de fond fait ce travail et la classe n'a plus rien à déclarer.
   Elle reste dans le balisage — la retirer voudrait dire éditer huit gabarits
   pour un gain nul — et ce sélecteur existe pour que la prochaine lecture de
   cette feuille trouve la réponse ici plutôt que de la chercher.

   Les deux sont flex, donc les deux ont besoin d'être centrés dans un en-tête
   centré. */
.page-entete .eyebrow,
.section-entete .eyebrow { justify-content: center; }

/* Anything an in-page link targets clears the header band. */
[id] { scroll-margin-top: 40px; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Jump links to the anchored blocks on services.php */
.ancres {
    display: flex; flex-wrap: wrap; justify-content: center; gap: 12px;
    margin-top: 30px;
}
.ancres a {
    color: var(--white-color); text-decoration: none;
    font-size: 15px; font-weight: 600;
    padding: 9px 20px; border-radius: 999px;
    border: 1px solid var(--dark-divider-color);
    transition: background-color .2s ease, border-color .2s ease;
}
/* .ancres vit DANS .page-entete, donc --accent-color y vaut deja le bleu
   clair. L'etiquette doit basculer avec l'aplat : du blanc sur #80B0D0
   mesurerait 2.32. --accent-contraste vaut l'encre ici, par heritage. */
.ancres a:hover {
    background: var(--accent-color);
    border-color: var(--accent-color);
    color: var(--accent-contraste);
}

/* ============================================================
   Long-form blocks
   ============================================================ */
/* An anchored service block: copy on one side, image slot on the other.
   Alternating sides comes from .bloc--inverse, and alternating backgrounds
   from .bg-surface — neither needs a per-section rule, and neither needs a
   divider line to separate one block from the next. */
.bloc { padding: 100px 0; }
.bloc h2 { font-size: 38px; line-height: 1.2; margin-bottom: 18px; }
.bloc-lede { font-size: 17.5px; margin-bottom: 24px; }
.bloc-sous-titre { font-size: 20px; margin: 34px 0 14px; }
.bloc--inverse .row { flex-direction: row-reverse; }

/* Reading column for legal pages — measured, not full-bleed. */
.prose { max-width: 760px; margin: 0 auto; }
.prose h2 { font-size: 26px; margin: 46px 0 14px; }
.prose h2:first-child { margin-top: 0; }
.prose p { margin-bottom: 16px; }

/* Informational callout — a caveat or a precision set aside from the
   flow of the copy. Real content, and styled as such.

   --ink-soft et non --text-color : un encadre est une mise en avant, et a
   15px il doit tenir aussi sur --background-alt, ou --text-color mesure 4.21
   et echoue (voir la regle suivante). */
.encadre {
    border-left: 3px solid var(--accent-color);
    background: var(--background-color);
    color: var(--ink-soft);
    padding: 18px 22px; border-radius: 0 8px 8px 0;
    margin-bottom: 30px; font-size: 15px;
}
.encadre p:last-child, .encadre ul:last-child { margin-bottom: 0; }

/* Un encadre POSE sur le fond chaud reprenait exactement la couleur de ce
   fond : il ne restait de lui que son filet gauche. C'est la seule raison
   d'etre de --background-alt, et pourquoi ce n'est pas une troisieme couleur
   de page au sens de BRANDING.md §2 regle 5. */
.bg-surface .encadre,
.section--pale .encadre { background: var(--background-alt); }

/* Marks copy that is a jlmultimedia placeholder rather than client
   material, so it can never be mistaken for final text during review.
   Deliberately uglier than .encadre — dashed and grey, reading as
   scaffolding rather than design. Every one of these disappears when the
   client supplies content; `grep "À COMPLÉTER" includes/contenu.php`
   lists what is still outstanding. */
.avis-placeholder {
    border: 1px dashed var(--text-color);
    background: transparent;
    padding: 18px 22px; border-radius: 8px;
    margin-bottom: 30px; font-size: 15px; color: var(--text-color);
}
.avis-placeholder p:last-child, .avis-placeholder ul:last-child { margin-bottom: 0; }
.avis-placeholder strong { color: var(--primary-color); }

/* ============================================================
   Lists
   ============================================================ */
.liste-marquee { list-style: none; padding: 0; margin: 0 0 24px; }
.liste-marquee li {
    position: relative; padding-left: 32px; margin-bottom: 12px;
}
.liste-marquee li::before {
    font-family: "Font Awesome 6 Free"; font-weight: 900;
    position: absolute; left: 0; top: 1px; font-size: 14px;
}
.liste-marquee--oui li::before { content: "\f00c"; color: var(--accent-color); }
.liste-marquee--non li::before { content: "\f068"; color: var(--text-color); }

/* Plain municipality list — many short items, so columns beat rows. */
.liste-villes {
    list-style: none; padding: 0; margin: 0;
    columns: 4; column-gap: 30px;
}
.liste-villes li {
    break-inside: avoid; margin-bottom: 10px;
    padding-left: 22px; position: relative;
}
.liste-villes li::before {
    content: ""; position: absolute; left: 0; top: 10px;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--accent-color);
}
/* Dans l'avis de l'etape « territoire » la liste vit a l'interieur du
   formulaire, qui est bien plus etroit que la page des secteurs : 4 colonnes
   y couperaient « Sainte-Marthe-sur-le-Lac » au milieu. Le pas typographique
   suit, parce que 32 lignes ne sont plus le contenu principal de l'ecran. */
/* LA CLASSE EST DOUBLEE A DESSEIN — .liste-villes.liste-villes--formulaire.
   Les regles responsives de .liste-villes (columns:2 sous 1100px, columns:1
   sous 640px) vivent PLUS BAS dans ce fichier, et a specificite egale c'est la
   derniere qui gagne. Ecrite avec une seule classe, cette variante etait
   silencieusement ecrasee sous 1100px : la liste du formulaire repassait a une
   colonne de 32 lignes, mesure a 845px de haut au telephone. Doubler la classe
   la place au-dessus sans avoir a deplacer quoi que ce soit ni a ecrire
   !important. */
.liste-villes.liste-villes--formulaire {
    columns: 3; column-gap: 22px;
    margin-top: 14px; font-size: 15px;
}
.liste-villes--formulaire li { margin-bottom: 6px; padding-left: 18px; }
.liste-villes--formulaire li::before { top: 8px; width: 5px; height: 5px; }
@media (max-width: 860px) { .liste-villes.liste-villes--formulaire { columns: 2; } }
/* Deux colonnes tenues jusqu'en bas, et c'est un choix mesure : a 390 px une
   seule colonne fait 32 lignes, soit un ecran et demi de noms a faire defiler
   AVANT d'atteindre la case a cocher et le bouton « Continuer ». La liste est
   une information de contexte, pas le contenu de l'etape — elle ne doit pas
   enterrer l'action. Le nom le plus long, « Saint-Andre-d'Argenteuil »,
   revient a la ligne et c'est acceptable ; l'enterrement ne l'etait pas. */
@media (max-width: 520px) {
    .liste-villes.liste-villes--formulaire { columns: 2; column-gap: 14px; font-size: 14px; }
    .liste-villes--formulaire li { margin-bottom: 4px; padding-left: 15px; }
}

/* ============================================================
   Tiles — travel zones, contact details, approach principles
   ============================================================ */
.tuile {
    height: 100%; padding: 28px;
    background: var(--white-color);
    border: 1px solid var(--divider-color); border-radius: 14px;
}
.tuile h3 { font-size: 19px; margin-bottom: 10px; }
.tuile p:last-child { margin-bottom: 0; }
.tuile-etiquette {
    display: inline-block; margin-bottom: 14px;
    font-size: 13px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--accent-color);
}

/* Trusted-inspector card (inspecteurs-de-confiance.php) — a .tuile with
   an icon-led list of contact links. */
.partenaires { margin-top: 8px; }
.partenaire-tete {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
    margin-bottom: 14px;
}
.partenaire-tete h3, .partenaire-tete .partenaire-nom { margin-bottom: 4px; }
.partenaire-tete .partenaire-nom:last-child { margin-bottom: 0; }
/* Hauteur des deux lignes de texte d'en-tete ; le fichier est a 2x. */
.partenaire-logo {
    flex: 0 0 auto; width: auto; height: 60px;
    border-radius: 8px;
}
.partenaire-nom { font-weight: 600; color: var(--primary-color); }
.partenaire-liens { list-style: none; padding: 0; margin: 0; }
.partenaire-liens li {
    display: flex; align-items: baseline; gap: 10px;
    margin-bottom: 8px; overflow-wrap: anywhere;
}
.partenaire-liens li:last-child { margin-bottom: 0; }
.partenaire-liens i { flex: 0 0 16px; color: var(--accent-color); }

/* ============================================================
   FAQ — native <details>, so it works without JavaScript and is
   keyboard-accessible by default. No accordion plugin.
   ============================================================ */
.faq-groupe { max-width: 860px; margin: 0 auto 50px; }
.faq-groupe h2 { font-size: 26px; margin-bottom: 22px; }

.faq-item {
    border: 1px solid var(--divider-color); border-radius: 12px;
    background: var(--white-color); margin-bottom: 12px;
}
.faq-item[open] { border-color: var(--accent-color); }
.faq-item > summary {
    display: flex; align-items: flex-start; gap: 16px;
    padding: 20px 24px; cursor: pointer; list-style: none;
    font-weight: 600; font-size: 17px; color: var(--primary-color);
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
    content: "\2b"; font-family: "Font Awesome 6 Free"; font-weight: 900;
    margin-left: auto; color: var(--accent-color); font-size: 14px;
    flex: 0 0 auto; padding-top: 3px;
}
.faq-item[open] > summary::after { content: "\f068"; }
.faq-reponse { padding: 0 24px 22px; }
.faq-reponse p:last-child { margin-bottom: 0; }

/* ============================================================
   Forms — contact now, the 17-step quote form later
   ============================================================ */
.formulaire { max-width: 640px; }
.champ { margin-bottom: 22px; }
.champ label {
    display: block; margin-bottom: 7px;
    font-weight: 600; color: var(--primary-color);
}
.champ-requis { color: var(--accent-color); }
.champ-note { font-weight: 400; color: var(--text-color); font-size: 14px; }

/* `select` a rejoint la liste le 2026-09-23, quand le champ « ville » est
   devenu une liste fermee de 32 municipalites. Sans lui, le seul menu
   deroulant du site rendait en chrome natif — etroit, gris, et pose sous deux
   champs texte styles, ce qui se lit comme un champ casse plutot que comme un
   autre type de champ. */
.champ input,
.champ select,
.champ textarea {
    width: 100%; padding: 13px 16px;
    font-family: var(--default-font); font-size: 16px; color: var(--primary-color);
    background: var(--white-color);
    border: 1px solid var(--divider-color); border-radius: 8px;
    transition: border-color .2s ease, box-shadow .2s ease;
}
.champ input:focus,
.champ select:focus,
.champ textarea:focus {
    outline: none; border-color: var(--accent-color);
    box-shadow: 0 0 0 3px rgb(var(--accent-ground-rgb) / .18);
}
/* L'indication n'est PAS une valeur, et elle ne doit pas se lire comme une
   reponse deja saisie : --text-color (5.33) contre --primary-color (16.29)
   pour le texte reellement tape. --metal-mid, plus proche du gris d'un
   placeholder de gabarit, tomberait a 3.26 et sortirait d'AA. */
.champ ::placeholder { color: var(--text-color); opacity: 1; }

.champ textarea { resize: vertical; min-height: 170px; }

/* appearance:none retire la fleche native EN MEME TEMPS que le chrome, donc
   elle est redessinee ici : un menu deroulant qui ne se signale pas comme tel
   se lit comme un champ texte qui refuse la frappe. Le chevron est une image
   SVG en data: URI plutot qu'un pseudo-element, parce qu'un <select> ne rend
   pas ::after. La couleur y est ecrite en clair et c'est inevitable — une
   data: URI ne lit pas les custom properties — mais c'est --text-color, une
   couleur d'INTERFACE et non une couleur de marque, donc M01 reste vert. */
.champ select {
    appearance: none; -webkit-appearance: none;
    padding-right: 44px; cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%235C5C5C' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
}
/* La premiere option, vide, doit se lire comme une invite et non comme une
   reponse deja donnee — meme regle que ::placeholder juste au-dessus. */
.champ select:invalid { color: var(--text-color); }

.champ--erreur input,
.champ--erreur select,
.champ--erreur textarea { border-color: var(--error-color); }
.champ-erreur {
    display: block; margin-top: 7px;
    color: var(--error-color); font-size: 14.5px;
}

/* Question anti-robot (2026-09-28). La reponse tient en deux caracteres : un
   champ pleine largeur au-dessus du bouton se lirait comme un deuxieme
   message. 220px laisse la place a « dix-huit » sans suggerer une phrase.
   .champ-note est un <span> inline partout ailleurs — sous le champ, il lui
   faut display:block, sinon l'aide se colle a la bordure de l'input. */
.champ--captcha input { max-width: 220px; }
.champ--captcha .champ-note { display: block; margin-top: 7px; }

/* Honeypot. Moved off-screen rather than display:none — a bot that
   parses styles skips hidden inputs, and the point is that it fills
   this one. aria-hidden + tabindex keep it away from real users. */
.pot-miel {
    position: absolute !important;
    left: -9999px; top: auto;
    width: 1px; height: 1px; overflow: hidden;
}

.alerte {
    padding: 20px 24px; border-radius: 12px; margin-bottom: 30px;
    border: 1px solid var(--divider-color);
}
.alerte h2 { font-size: 20px; margin-bottom: 8px; }
.alerte p:last-child, .alerte ul:last-child { margin-bottom: 0; }
.alerte ul { margin: 10px 0 0; padding-left: 20px; }
.alerte--succes { border-left: 4px solid var(--accent-color); background: var(--background-color); }
/* Le lavis descend de --error-rgb : ecrit #FDF3F3 en clair, il restait au
   rouge d'hier le jour ou la couleur d'erreur change. C'etait le DERNIER
   hexadecimal en clair de cette feuille (M01). */
.alerte--erreur { border-left: 4px solid var(--error-color); background: rgb(var(--error-rgb) / .07); }
.alerte--erreur h2 { color: var(--error-color); }

/* ---- L'avis de territoire — 2026-09-23 ---------------------------------
   Meme lavis a 7 % que .alerte--erreur, mais en ambre : il annonce une
   limite, pas une faute. L'icone est a GAUCHE et hors du flux du texte,
   donc le bloc devient un flex et le contenu part dans un <div>.

   L'icone est aria-hidden : elle redit ce que le texte dit deja, et un
   lecteur d'ecran qui annonce « triangle d'exclamation » avant chaque
   phrase gene plus qu'il n'informe. */
.alerte--avis {
    display: flex; gap: 16px; align-items: flex-start;
    border-left: 4px solid var(--warning-color);
    background: rgb(var(--warning-rgb) / .07);
}
.alerte--avis > i { color: var(--warning-color); font-size: 20px; margin-top: 2px; flex: 0 0 auto; }
.alerte--avis h2 { color: var(--warning-color); }
.alerte--avis > div { min-width: 0; }

/* La sortie de secours de l'etape « territoire » — 2026-09-23. Elle suit la
   liste des 32 villes, qui n'a pas de marge basse (.alerte ul), donc c'est ce
   paragraphe qui pose l'ecart. Le lien garde --accent-color : le lavis ambre
   est a 7 %, le fond reste clair, et #3D6E92 y tient son AA. */
.alerte-sortie { margin-top: 16px; }

/* L'encadré posé SOUS une liste de choix (types de bâtiment, logements,
   arrêts d'étape) — 2026-10-07. Même composant, mais il suit les cartes au
   lieu de les précéder, donc l'écart est en haut et non en bas. */
.alerte--sous-choix { margin: 24px 0 0; }
.alerte--sous-choix a { font-weight: 600; }

/* ============================================================
   Responsive — breakpoints ported from the prototype
   ============================================================ */
@media (max-width: 1100px) {
    .nav-liens {
        display: none; position: absolute; top: 100%; left: 0; right: 0;
        flex-direction: column; gap: 0; margin: 8px 0 0;
        background: var(--white-color); border-radius: 14px; padding: 10px 0;
        box-shadow: 0 10px 40px rgba(0,0,0,.12);
    }
    .nav-liens.est-ouvert { display: flex; }
    .nav-lien { padding: 12px 26px; }
    .nav-bascule { display: block; }
    .nav-pilule { position: relative; gap: 16px; }
    .nav-cta { display: none; }

    /* The CTA reappears as the last item in the dropdown, styled as the accent
       button so it still reads as the primary action. */
    .nav-lien--cta {
        display: block; margin: 10px 26px 4px;
        padding: 13px 20px; border-radius: 5px;
        background: var(--accent-color); color: var(--accent-contraste);
        font-weight: 600; text-align: center;
    }
    .nav-lien--cta:hover { background: var(--accent-hover); color: var(--accent-contraste); }

    .hero h1 { font-size: 44px; line-height: 1.2; }
    .hero-atouts { flex-direction: column; gap: 22px; }
    .section { padding: 80px 0; }
    .section-entete h2 { font-size: 34px; }

    .page-entete { padding: 170px 0 70px; }
    .page-entete h1 { font-size: 36px; }
    .bloc { padding: 70px 0; }
    .bloc h2 { font-size: 30px; }
    .liste-villes { columns: 2; }
}

/* Bootstrap stacks .col-lg-* below 992px. Once the columns are stacked,
   row-reverse would push the image slot above its own heading, so the
   alternating layout is dropped rather than inverted. */
@media (max-width: 991.98px) {
    .bloc--inverse .row { flex-direction: row; }
    .bloc .img-slot { margin-top: 34px; }
}

@media (max-width: 640px) {
    .nav-pilule { margin: 16px; padding: 12px 12px 12px 18px; }
    .marque { font-size: 21px; --marque-taille: 38px; }
    .hero { padding: 150px 0 70px; min-height: 0; }
    .hero-contenu { padding: 0 20px; }
    .hero h1 { font-size: 33px; }
    .section-entete h2 { font-size: 28px; }
    .bandeau h2 { font-size: 28px; }

    .page-entete { padding: 130px 0 56px; }
    .page-entete h1 { font-size: 29px; }
    .bloc h2 { font-size: 26px; }
    .liste-villes { columns: 1; }
    .ancres a { font-size: 14px; padding: 8px 16px; }
    .faq-item > summary { padding: 16px 18px; font-size: 16px; }
    .faq-reponse { padding: 0 18px 18px; }
    .tuile { padding: 22px; }
}


/* ============================================================
   Parcours de soumission (phase 4)

   Une question par écran (§5). Toute la mise en page vise une
   seule chose : que la question, ses réponses et le bouton
   tiennent ensemble sans défilement sur un téléphone — un
   parcours de 15 écrans où chacun demande de faire défiler pour
   trouver « Continuer » se fait abandonner en cours de route.
   ============================================================ */

/* L'en-tête de page complète mesure 210px de haut : juste pour la
   première étape, et beaucoup trop répété quinze fois de suite. */
.page-entete--compacte { padding: 170px 0 60px; }
.page-entete--compacte h1 { font-size: 38px; }

.section--parcours { padding: 60px 0 90px; }
.section--pale { background: var(--background-color); padding: 70px 0; }

/* Colonne de lecture, comme .prose : une ligne de 1200px rend une
   liste de cartes de réponse pénible à balayer. */
.parcours { max-width: 720px; margin: 0 auto; }

.parcours-progression { margin-bottom: 34px; }
.parcours-jauge {
    height: 6px; border-radius: 3px;
    background: var(--divider-color); overflow: hidden;
}
.parcours-jauge > span {
    display: block; height: 100%;
    background: var(--accent-color);
    transition: width .3s ease;
}
@media (prefers-reduced-motion: reduce) { .parcours-jauge > span { transition: none; } }

.parcours-compteur {
    margin: 10px 0 0; font-size: 14px;
    letter-spacing: .04em; text-transform: uppercase;
}

.parcours-question {
    font-size: 30px; line-height: 1.25;
    color: var(--primary-color); margin: 0 0 10px;
}
.parcours-aide { font-size: 15px; margin: 0 0 26px; }

/* ---- Les cartes de réponse --------------------------------
   <label> englobant son <input>, donc toute la carte est
   cliquable et la cible tactile fait la taille de la carte. */
.cartes-choix { display: grid; gap: 12px; margin-bottom: 8px; }

.carte-choix {
    display: flex; align-items: flex-start; gap: 14px;
    padding: 18px 20px; cursor: pointer;
    background: var(--white-color);
    border: 1px solid var(--divider-color); border-radius: 12px;
    transition: border-color .2s ease, box-shadow .2s ease;
}
.carte-choix:hover { border-color: var(--accent-color); }

.carte-choix input { margin-top: 4px; flex: 0 0 auto; accent-color: var(--accent-color); }

/* L'état choisi est dessiné en CSS, pas en JavaScript : le choix
   reste visible même si le script ne charge pas, et le focus
   clavier fonctionne sans rien écrire. */
.carte-choix:has(input:checked) {
    border-color: var(--accent-color);
    box-shadow: 0 0 0 1px var(--accent-color) inset;
}
.carte-choix:has(input:focus-visible) { outline: 2px solid var(--accent-color); outline-offset: 2px; }

.carte-choix-corps { display: block; }
.carte-choix-titre { display: block; color: var(--primary-color); font-weight: 600; }
.carte-choix-aide  { display: block; font-size: 14px; margin-top: 3px; }

/* ---- Les sous-questions conditionnelles -------------------
   Masquées tant que la réponse qui les appelle n'est pas
   cochée. Le serveur ne les exige que dans ce cas-là
   (valider_etape()), donc cet affichage ne décide de rien —
   d'où le repli @supports qui les affiche toujours là où
   :has() n'existe pas.

   CHAQUE sous-question a son id et son propre sélecteur de
   révélation. C'était `.sous-question` tout court jusqu'au
   2026-09-28, quand l'étape 13 en a reçu une deuxième : une
   règle de révélation nominative aurait laissé la nouvelle
   masquée pour toujours, parce que la règle `display: none`
   ci-dessous, elle, est générique. */
.sous-question {
    display: none;
    margin-top: 26px; padding-top: 22px;
    border-top: 1px solid var(--divider-color);
}
.sous-question h3 { font-size: 18px; color: var(--primary-color); margin-bottom: 6px; }

/* Étape 13 — la propriété est vendue par un courtier. */
.parcours-formulaire:has(input[name="avec_courtier"][value="oui"]:checked) #sous-question-courtier {
    display: block;
}

/* Étape 9 — « Puits privé » coché : la question de l'analyse d'eau. */
.parcours-formulaire:has(input[name="caracteristiques[]"][value="puits_prive"]:checked) #sous-question-eau {
    display: block;
}

/* Étape 13 — la propriété est vendue SANS courtier : la déclaration du vendeur. */
.parcours-formulaire:has(input[name="avec_courtier"][value="non"]:checked) #sous-question-declaration {
    display: block;
}

/* Étape 12 — « même adresse que le bâtiment » masque la saisie de l'adresse de
   résidence. Facultatif côté affichage : sans :has() la saisie reste visible. */
.parcours-formulaire:has(input[name="adresse_requerant_identique"]:checked) #champ-adresse-requerant {
    display: none;
}

@supports not selector(:has(*)) { .sous-question { display: block; } }

/* ---- Champs ------------------------------------------------ */
.champs-paire { display: grid; gap: 0 18px; grid-template-columns: 1fr 1fr; }

.case-simple {
    display: flex; align-items: flex-start; gap: 10px;
    cursor: pointer; margin-bottom: 14px;
}
.case-simple input { margin-top: 4px; accent-color: var(--accent-color); }

.parcours fieldset { border: 0; padding: 0; margin: 0 0 22px; }
/* Un <legend> ne s'aligne pas tout seul sur les <label> voisins : il hérite du
   corps de texte. Sur l'étape 12 il se retrouve juste sous « Téléphone », donc
   la différence de graisse se voit immédiatement. */
.parcours legend {
    padding: 0; margin-bottom: 7px;
    font-weight: 600; color: var(--primary-color);
}

.parcours-actions {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; margin-top: 34px;
}

/* ---- Récapitulatif de l'étape 14 --------------------------- */
.recapitulatif { margin: 0 0 30px; }
.recapitulatif-ligne {
    display: grid; grid-template-columns: 1fr 1.2fr; gap: 10px 20px;
    padding: 13px 0; border-bottom: 1px solid var(--divider-color);
}
.recapitulatif dt { font-size: 14px; margin: 0; }
.recapitulatif dd {
    margin: 0; display: flex; gap: 14px;
    align-items: baseline; justify-content: space-between;
    color: var(--primary-color);
}
.recapitulatif dd .lien-fleche { flex: 0 0 auto; font-size: 14px; }

/* ---- Écran de résultat ------------------------------------- */
.soumission-numero { margin-bottom: 34px; }
.soumission-pdf { margin: -14px 0 34px; }
.soumission-numero strong {
    display: block; color: var(--primary-color);
    font-size: 24px; letter-spacing: .04em;
}

.soumission-detail { width: 100%; margin-bottom: 34px; border-collapse: collapse; }
.soumission-detail th, .soumission-detail td {
    padding: 13px 0; text-align: left; font-weight: 400;
    border-bottom: 1px solid var(--divider-color);
}
.soumission-detail td { text-align: right; color: var(--primary-color); white-space: nowrap; }
.soumission-detail tfoot .soumission-detail-sous-total th,
.soumission-detail tfoot .soumission-detail-sous-total td { padding-top: 20px; }
.soumission-detail-total th, .soumission-detail-total td {
    border-bottom: 0; padding-top: 16px;
    font-size: 20px; font-weight: 600; color: var(--primary-color);
}

/* ---- Téléphone ---------------------------------------------
   640px est le point où l'accueil passe déjà en 33px : le
   parcours suit le même point plutôt que d'en inventer un. */
@media (max-width: 640px) {
    .page-entete--compacte { padding: 140px 0 46px; }
    .page-entete--compacte h1 { font-size: 28px; }
    .parcours-question { font-size: 24px; }
    .champs-paire { grid-template-columns: 1fr; }
    .recapitulatif-ligne { grid-template-columns: 1fr; }

    /* Le bouton principal passe en premier et prend toute la
       largeur ; « Précédent » se glisse dessous. Sur un écran de
       390px, deux boutons côte à côte se touchent. */
    .parcours-actions { flex-direction: column-reverse; align-items: stretch; }
    .parcours-actions .bouton { justify-content: center; }
}

/* ---- Collisions avec .champ -------------------------------
   .champ a été écrit en phase 2 pour le formulaire de contact,
   qui n'a que des champs texte : .champ input pose donc
   width:100% et 13px de rembourrage, et .champ label pose
   display:block. Appliqué à une case à cocher, ça en fait une
   dalle pleine largeur posée au-dessus de son texte.

   Deux endroits du parcours sont touchés, et le second est
   facile à manquer : l'étape 14 (les consentements) et
   l'étape 12, dont le « lien avec la propriété » est un
   <fieldset class="champ"> rempli de cartes radio. */
.champ input[type="checkbox"],
.champ input[type="radio"] {
    width: auto; padding: 0; box-shadow: none;
}
.champ .carte-choix,
.champ label.case-simple {
    display: flex; align-items: flex-start;
    margin-bottom: 0; font-weight: 400; color: var(--text-color);
}
.champ .carte-choix { gap: 14px; }
.champ label.case-simple { gap: 10px; margin-bottom: 14px; }
.champ .carte-choix-titre { font-weight: 600; color: var(--primary-color); }

/* Un enfant flex ne rétrécit pas sous sa largeur de contenu
   sans ceci : une réponse longue poussait « Modifier » hors du
   cadre, et le lien se retrouvait coupé par le bord de l'écran
   au lieu de passer à la ligne. */
.recapitulatif dd > span { min-width: 0; overflow-wrap: anywhere; }
