@charset "UTF-8";
/* ==========================================================================
   TOPCONSTRUCT — Feuille de styles
   --------------------------------------------------------------------------
   Conforme à la charte graphique & identité de marque v2 (juin 2026).
   Écrite en mobile first : les styles de base visent le mobile, les
   media queries `min-width` enrichissent progressivement vers le desktop.

   Rappels de charte appliqués partout dans ce fichier :
     · 4 couleurs uniquement — aucune cinquième couleur n'est introduite.
       Les nuances intermédiaires sont dérivées des 4 couleurs par color-mix().
     · Poppins uniquement, line-height 1.7 sur le corps de texte.
     · Interdits absolus : dégradé, ombre portée, flou, texture.
     · Rayons : 8px boutons · 12px cartes · 0px bordures d'accent.
     · Rythme d'espacement : 16px interne · 32px entre éléments ·
       64–80px entre sections.
     · Largeur max du contenu : 1200px centré.

   Sommaire
     01. Tokens
     02. Reset & base
     03. Typographie
     04. Layout & utilitaires
     05. Boutons & appels à l'action
     06. En-tête & navigation
     07. Hero
     08. Barre de confiance & témoignages
     09. Cartes modèles
     10. Étapes
     11. Bandeau CTA
     12. Formulaires
     13. Contenus éditoriaux
     14. Fiches modèles
     15. Galerie & lightbox
     16. Pied de page
     17. Cookies (RGPD)
     18. Accessibilité, mouvement réduit & impression
   ========================================================================== */


/* ==========================================================================
   01. TOKENS
   ========================================================================== */

:root {
  /* --- Les 4 couleurs de marque. Aucune autre couleur autorisée. --------- */
  --tc-marine:        #1A2E4A;
  --tc-jaune:         #FEC63D;
  --tc-blanc-chaud:   #F5F4F0;  /* fond de page — jamais #FFFFFF */
  --tc-vert-doux:     #E8F4F0;

  /* --- États d'interaction dérivés des couleurs de marque ---------------- */
  --tc-marine-survol: #243F64;  /* marine +10%, spécifié par la charte */
  --tc-jaune-survol:  #F5B71F;  /* repli pour les navigateurs sans color-mix */

  /* --- Nuances de texte : toutes dérivées du marine --------------------- */
  --tc-texte:         var(--tc-marine);
  --tc-texte-doux:    #5B6B80;  /* repli */
  --tc-texte-tenu:    #8492A4;  /* repli */
  --tc-filet:         rgba(26, 46, 74, .14);
  --tc-filet-clair:   rgba(255, 255, 255, .20);  /* séparateurs sur marine */

  /* --- Textes sur fond marine ------------------------------------------
     Trois nuances, et non une seule, parce qu'elles ne remplissent pas le
     même rôle. Elles étaient écrites en dur dans les règles concernées, ce
     qui contredisait la règle du projet (« jamais de couleur en dur ») et
     les rendait invisibles à toute relecture de la palette.

     Contrastes mesurés sur le marine #1A2E4A :
       #E9EBEF → 11,5:1    #C6CCD6 → 8,5:1    #AAAAAA → 5,9:1
     Les trois passent le seuil AA de 4,5:1 aux tailles employées.
     Ne pas les unifier sans validation : ce serait un changement visuel
     sur une maquette déjà approuvée par le client. */

  /* Chapô du hero — le texte le plus lu du site, donc le plus clair. */
  --tc-sur-marine-fort: #E9EBEF;

  /* Paragraphes des bandeaux d'appel à l'action. */
  --tc-sur-marine-moyen: #C6CCD6;

  /* Sous-titres de la barre de confiance. La charte spécifie explicitement
     ce gris ; c'est la seule couleur hors palette qu'elle impose. */
  --tc-sur-marine-doux: #AAAAAA;

  /* Compteur de la galerie, sur le fond sombre de l'agrandissement. */
  --tc-sur-sombre-compteur: #AAB3C0;


  /* --- Typographie ------------------------------------------------------- */
  --tc-police: 'Poppins', Arial, 'Helvetica Neue', sans-serif;

  /* --- Rythme d'espacement ---------------------------------------------- */
  --esp-1:  8px;
  --esp-2: 16px;   /* espacement interne */
  --esp-3: 24px;
  --esp-4: 32px;   /* entre éléments */
  --esp-5: 48px;
  --esp-6: 64px;   /* entre sections — mobile */
  --esp-7: 80px;   /* entre sections — desktop */

  /* --- Rayons ----------------------------------------------------------- */
  --r-btn:   8px;
  --r-carte: 12px;

  /* --- Grille ----------------------------------------------------------- */
  --largeur-max: 1200px;
  --gouttiere:   24px;

  /* --- Divers ----------------------------------------------------------- */
  --transition: 160ms ease;
}

/* Nuances calculées à partir des couleurs de marque, pour les navigateurs
   qui supportent color-mix(). Écrase les replis ci-dessus. */
@supports (color: color-mix(in srgb, red, blue)) {
  :root {
    --tc-jaune-survol: color-mix(in srgb, var(--tc-jaune) 86%, var(--tc-marine));
    --tc-texte-doux:   color-mix(in srgb, var(--tc-marine) 74%, var(--tc-blanc-chaud));
    --tc-texte-tenu:   color-mix(in srgb, var(--tc-marine) 55%, var(--tc-blanc-chaud));
  }
}


/* ==========================================================================
   02. RESET & BASE
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Décale les ancres pour ne pas passer sous l'en-tête collant. */
  scroll-padding-top: 88px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--tc-blanc-chaud);
  color: var(--tc-texte);
  font-family: var(--tc-police);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.7;          /* imposé par la charte sur tout le corps */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
}

img { height: auto; }

svg { flex: none; }

a {
  color: inherit;
  text-decoration: none;
}

button {
  font-family: inherit;
  font-size: inherit;
}

/* Le contenu ne doit jamais déborder horizontalement. */
main { overflow-x: clip; }


/* ==========================================================================
   03. TYPOGRAPHIE
   --------------------------------------------------------------------------
   Échelle de la charte :
     Overline 12px SemiBold caps +0.1em jaune
     H1 36–40px Bold 700   ·   H2 26–28px SemiBold 600
     H3 18–20px Medium 500 ·   Corps 17–18px Regular 400
     Légende 14px Light 300
   Sentence case partout — seules les overlines sont en majuscules.
   Aucun letter-spacing négatif : la charte ne le prévoit pas.
   ========================================================================== */

h1, h2, h3, h4, h5 {
  margin: 0 0 var(--esp-2);
  color: var(--tc-marine);
  line-height: 1.25;
  text-wrap: balance;        /* évite les orphelins sur les titres courts */
}

h1 {
  font-size: clamp(30px, 6vw, 40px);
  font-weight: 700;
  line-height: 1.18;
}

h2 {
  font-size: clamp(24px, 4vw, 28px);
  font-weight: 600;
}

h3 {
  font-size: 19px;
  font-weight: 500;
}

h4 {
  font-size: 17px;
  font-weight: 600;
}

p {
  margin: 0 0 var(--esp-2);
  color: var(--tc-texte-doux);
}

p:last-child { margin-bottom: 0; }

strong { font-weight: 600; }

/* Overline — le seul élément en majuscules du site.
   --------------------------------------------------------------------------
   ÉCART DE CHARTE ASSUMÉ — motif d'accessibilité.
   La charte demande l'overline en jaune #FEC63D. Or sur les deux fonds
   clairs du site, le jaune ne donne que 1,4:1 de contraste : très en
   dessous du seuil AA de 4,5:1 exigé pour un texte de 12px. Un prospect
   qui lit mal ne lit pas.
   Le jaune est donc conservé comme accent — une barre de 2px devant le
   texte, exactement le rôle que la charte lui assigne — et le texte passe
   en marine sur fond clair, en blanc sur fond sombre. L'overline reste
   reconnaissable comme « l'étiquette jaune », en devenant lisible. */
.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-1);
  margin-bottom: var(--esp-2);
  color: var(--tc-marine);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  line-height: 1.4;
  text-transform: uppercase;
}

/* La barre d'accent jaune. Décorative : elle ne porte aucune information
   que le texte ne donne pas déjà. */
.tag::before {
  content: "";
  flex: none;
  width: 18px;
  height: 2px;
  background: var(--tc-jaune);
}

/* Sur fond marine, le texte passe en blanc — le jaune y serait lisible
   (8,9:1) mais on garde un seul système pour tout le site. */
.sur-marine .tag,
.section--marine .tag,
.info-card .tag { color: #fff; }

/* Chapô de section. */
.lead {
  max-width: 62ch;
  color: var(--tc-texte-doux);
  font-size: 18px;
}

/* Légende — mentions légales, conditions, notes de prix. */
.note,
.disclaimer,
.legende {
  color: var(--tc-texte-tenu);
  font-size: 14px;
  font-weight: 300;
  line-height: 1.6;
}

.yellow { color: var(--tc-jaune); }

/* Renvoi de note de bas de page (l'astérisque du prix).
   L'astérisque ne fait que 15px de large : trop petit pour un doigt. Le
   padding élargit la zone cliquable et la marge négative annule le décalage
   qu'il provoquerait dans le titre — la cible grandit, la mise en page non. */
.renvoi {
  display: inline-block;
  padding: 6px 10px;
  margin: -6px -10px;
  color: var(--tc-jaune);
  font-size: .7em;
  font-weight: 600;
  text-decoration: none;
  vertical-align: super;
}

.renvoi:hover,
.renvoi:focus-visible { text-decoration: underline; }


/* ==========================================================================
   04. LAYOUT & UTILITAIRES
   ========================================================================== */

.wrap {
  width: 100%;
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

/* Rythme vertical entre sections : 64px mobile, 80px desktop. */
.section { padding-block: var(--esp-6); }

/* Alternance imposée : blanc chaud → vert doux → blanc chaud.
   `.soft` est conservé comme alias historique de `.section--vert`. */
.section--vert,
.section.soft { background: var(--tc-vert-doux); }

.section--marine {
  background: var(--tc-marine);
  color: #fff;
}

.section--marine h1,
.section--marine h2,
.section--marine h3,
.section--marine h4 { color: #fff; }

.section--marine p { color: var(--tc-sur-marine-doux); }

/* Section sans espace en haut — pour coller un bloc au précédent. */
.section--soude { padding-top: 0; }

.center { text-align: center; }

.center .lead { margin-inline: auto; }

/* En-tête de section : overline + titre + chapô. */
.entete-section { margin-bottom: var(--esp-5); }

.entete-section > :last-child { margin-bottom: 0; }

/* Action de fin de section (« voir tous les modèles »). */
.section-actions {
  margin: var(--esp-4) 0 0;
  text-align: center;
}

/* Grilles génériques. Mobile : une colonne. */
.grid { display: grid; gap: var(--esp-3); }

/* Images cadrées. Les hauteurs fixes sont volontaires : elles réservent
   la place et évitent les sauts de mise en page (CLS). */
.imgbox {
  width: 100%;
  background: var(--tc-vert-doux);
  border-radius: var(--r-carte);
  object-fit: cover;
}

/* Note : les variantes `.sm` (240px) et `.wide` (260px) ont été retirées.
   Elles n'étaient utilisées que sur les deux pages de formulaire, où elles
   imposaient une hauteur fixe à des images de rapport différent — la photo
   était tronquée et la carte de Wallonie perdait de la géographie. Sans
   hauteur imposée, `.imgbox` seule affiche l'image à son rapport naturel :
   jamais de recadrage. Pour un cadrage volontaire, utiliser `.split`. */

/* Visuel d'un bloc deux colonnes. On impose un rapport plutôt qu'une hauteur
   fixe : le cadrage reste prévisible et les deux colonnes s'équilibrent,
   sans jamais écraser l'image. */
.imgbox.split {
  height: auto;
  aspect-ratio: 4 / 3;
}

/* Plans d'étage : jamais recadrés, on veut le plan entier. */
.imgbox.plan {
  height: auto;
  max-height: 520px;
  padding: var(--esp-2);
  background: #fff;
  border: 1px solid var(--tc-filet);
  object-fit: contain;
}

/* Blocs deux colonnes (texte + visuel). */
.split {
  display: grid;
  gap: var(--esp-4);
  align-items: center;
}

@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; gap: var(--esp-5); }
  .split.rev .txt { order: 2; }
}


/* ==========================================================================
   05. BOUTONS & APPELS À L'ACTION
   --------------------------------------------------------------------------
   Maximum 1 CTA principal + 1 secondaire par section visuelle.
   Le principal est toujours en premier.

   ÉCART DE CHARTE ASSUMÉ — demandé par le client : la charte prévoit un CTA
   principal en marine sur texte blanc. Sur les fonds marine (hero, bandeau),
   il devenait invisible — « bleu sur bleu ». Le CTA principal passe donc en
   jaune #FEC63D + texte marine #1A2E4A, partout, pour rester cohérent.
   Contraste mesuré : 8.9:1 — largement au-delà du seuil AA (4.5:1).
   La règle « texte blanc sur jaune jamais sous 18px » n'est pas concernée :
   le texte est marine, pas blanc.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--esp-1);
  padding: 12px 24px;
  border: 1.5px solid transparent;
  border-radius: var(--r-btn);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  white-space: nowrap;   /* un libellé de CTA ne se coupe jamais en deux */
  cursor: pointer;
  transition: background-color var(--transition),
              border-color var(--transition),
              color var(--transition);
}

.btn svg {
  width: 18px;
  height: 18px;
}

/* CTA principal — jaune, texte marine. */
.btn-primary {
  background: var(--tc-jaune);
  border-color: var(--tc-jaune);
  color: var(--tc-marine);
}

.btn-primary:hover {
  background: var(--tc-jaune-survol);
  border-color: var(--tc-jaune-survol);
}

/* CTA secondaire — transparent, bordure jaune, texte marine (charte). */
.btn-ghost {
  background: transparent;
  border-color: var(--tc-jaune);
  color: var(--tc-marine);
  font-weight: 500;
}

.btn-ghost:hover { background: rgba(254, 198, 61, .12); }

/* Variante sur fond sombre : le texte du secondaire passe en blanc. */
.sur-marine .btn-ghost,

.sur-marine .btn-ghost:hover,

/* `.btn-dark` est conservé comme alias du CTA principal : l'ancien code
   l'utilisait pour les bandeaux, où le jaune est désormais la bonne réponse. */
.btn-dark {
  background: var(--tc-jaune);
  border-color: var(--tc-jaune);
  color: var(--tc-marine);
}

.btn-dark:hover {
  background: var(--tc-jaune-survol);
  border-color: var(--tc-jaune-survol);
}

/* Rangée de CTA. Sur mobile, les boutons prennent toute la largeur : une
   cible tactile pleine largeur est plus sûre qu'un bouton étroit. */
.btn-row {
  display: flex;
  flex-direction: column;
  gap: var(--esp-2);
}

.btn-row .btn { width: 100%; }

@media (min-width: 480px) {
  .btn-row { flex-direction: row; flex-wrap: wrap; }
  .btn-row .btn { width: auto; }
}

/* Lien fléché discret (cartes, fins de section). */
.link {
  display: inline-flex;
  align-items: center;
  gap: var(--esp-1);
  color: var(--tc-marine);
  font-size: 15px;
  font-weight: 600;
}

.link svg {
  width: 16px;
  height: 16px;
  color: var(--tc-jaune);
  transition: transform var(--transition);
}


/* ==========================================================================
   06. EN-TÊTE & NAVIGATION
   ========================================================================== */

/* Lien d'évitement — premier élément focusable de la page. */
.skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 100;
  padding: 12px 24px;
  background: var(--tc-jaune);
  border-radius: 0 0 var(--r-btn) var(--r-btn);
  color: var(--tc-marine);
  font-size: 15px;
  font-weight: 600;
  transform: translate(-50%, -100%);
  transition: transform var(--transition);
}

.skip-link:focus { transform: translate(-50%, 0); }

header.site {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--tc-blanc-chaud);
  border-bottom: 1px solid var(--tc-filet);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--esp-3);
  /* 80px et non 72 : sur l'échelle d'espacement de la charte, et la barre
     respire nettement mieux avec un logo de cette largeur. */
  min-height: 80px;
}

/* --- Logo ---------------------------------------------------------------
   La charte interdit de recréer le logo dans une autre police : on sert
   les fichiers officiels, jamais un wordmark retapé en CSS.
   Taille minimum digital : 120px de large. */
.logo {
  display: inline-flex;
  align-items: center;
  flex: none;
}

/* CORRECTION OPTIQUE — ne pas retirer le translateY.
   --------------------------------------------------------------------------
   Le logo est parfaitement centré dans sa boîte, et paraît pourtant trop bas.
   La raison est dans le dessin : l'icône maison occupe toute la hauteur du
   fichier (y 3→115 sur 119), alors que le mot « TopConstruct » ne va que de
   y 37 à y 113. Le centre du MOT se situe donc 16 px sous le centre de la
   boîte — et c'est le mot que l'œil compare au texte de la navigation.

   Centrer la boîte revient ainsi à faire descendre le mot. On remonte l'image
   de 16/119 de sa hauteur, soit 13.45 %, pour que le mot s'aligne sur les
   entrées de menu. Exprimé en pourcentage, le décalage suit automatiquement
   les deux tailles de logo.

   Mesuré avant correction : le mot tombait 5,1 px sous le texte du menu. */
.logo img {
  width: auto;
  height: 30px;
  transform: translateY(-13.45%);
}

@media (min-width: 640px) {
  /* 34px et non 38 : le fichier livré est recadré plus serré que le précédent
     (745×119 contre 753×132, moins de marge transparente). À 34px le mark
     visible fait la même taille qu'avant à 38px, tout en occupant une boîte
     plus étroite — d'où l'impression d'un logo mieux posé. */
  .logo img { height: 34px; }
}

/* --- Menu -------------------------------------------------------------
   Mobile : panneau replié, déplié par le bouton burger.
   Desktop : barre horizontale avec sous-menus. */
.menu {
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu > li > a {
  color: var(--tc-marine);
  font-size: 15px;
  font-weight: 500;
}

.menu > li > a:hover { color: var(--tc-jaune); }

/* Page courante — repère visuel doublé de `aria-current` dans le HTML.
   Souligné via text-decoration plutôt qu'une bordure ou une ombre interne :
   c'est la propriété prévue pour souligner un lien, elle ne décale pas la
   mise en page, et elle laisse la feuille sans aucun box-shadow — ce qui
   rend vérifiable la règle « pas d'ombre portée » de la charte. */
.menu a[aria-current="page"] {
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--tc-jaune);
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}

/* Dans un sous-menu, le repère reste un simple souligné : le décalage de 6px
   du menu principal serait à l'étroit dans une ligne de 9px de padding. */
.dropdown a[aria-current="page"] { text-decoration: underline; }

/* Bouton d'ouverture d'un sous-menu, séparé du lien parent : le lien reste
   cliquable, le sous-menu reste atteignable au clavier. */
.sub-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  background: none;
  border: 0;
  border-radius: 6px;
  color: var(--tc-marine);
  cursor: pointer;
}

.sub-toggle svg {
  width: 16px;
  height: 16px;
  transition: transform var(--transition);
}

.sub-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

/* --- Burger ------------------------------------------------------------ */
.burger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;                /* cible tactile de 44px minimum */
  height: 44px;
  background: none;
  border: 1.5px solid var(--tc-filet);
  border-radius: var(--r-btn);
  color: var(--tc-marine);
  cursor: pointer;
}

.burger svg { width: 24px; height: 24px; }

.burger:hover { border-color: var(--tc-marine); }

.nav-cta {
  display: flex;
  align-items: center;
  gap: var(--esp-2);
}

/* Le CTA de l'en-tête est masqué sur mobile : il est déjà dans le hero et
   dans le panneau de menu. */
.nav-cta .btn { display: none; }

/* --- Comportement mobile (< 1024px) ---------------------------------- */
@media (max-width: 1199px) {
  .menu {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    max-height: calc(100vh - 80px);
    padding: var(--esp-2) var(--gouttiere) var(--esp-4);
    overflow-y: auto;
    background: var(--tc-blanc-chaud);
    border-bottom: 1px solid var(--tc-filet);
  }

  .menu.open { display: block; }

  .menu > li { border-bottom: 1px solid var(--tc-filet); }

  .menu > li:last-child { border-bottom: 0; }

  .menu > li > a {
    display: block;
    padding: 14px 0;
    font-size: 17px;
  }

  /* Ligne : lien à gauche, bouton de sous-menu à droite. */
  .menu > li.has-sub {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .menu > li.has-sub > .dropdown { grid-column: 1 / -1; }

  .dropdown {
    display: none;
    margin-bottom: var(--esp-2);
    padding: 0 0 var(--esp-2) var(--esp-2);
    border-left: 2px solid var(--tc-jaune);   /* bordure d'accent, 0px de rayon */
  }

  .dropdown.open { display: block; }

  .dropdown a {
    display: block;
    padding: 10px 0;
    color: var(--tc-texte-doux);
    font-size: 16px;
  }

  .dropdown a:hover { color: var(--tc-marine); }

  /* Le CTA principal réapparaît en bas du panneau déplié. */
  .menu .menu-cta {
    padding-top: var(--esp-3);
    border-bottom: 0;
  }

  .menu .menu-cta .btn { width: 100%; }
}

/* --- Comportement desktop (≥ 1024px) ---------------------------------
   L'espacement démarre serré : entre 1024 et 1200px, la barre doit loger
   six entrées, le logo et le CTA sans jamais passer à la ligne. */
/* --- Barre horizontale : 1200px et plus -------------------------------
   Le seuil était à 1024px, et le menu n'y tenait pas : il réclamait 1134px
   pour 976 disponibles, débordait de 158px et provoquait un défilement
   horizontal de toute la page. La barre déroulante a besoin d'environ
   1180px — logo 213 + écart 24 + menu 609 + écart 24 + bouton 260, plus les
   gouttières. En dessous, on garde le menu replié.

   L'écart du menu reste à 16px (--esp-2) à TOUTES les largeurs. Le porter à
   24px au-delà de 1200px ajoutait 40px sur cinq intervalles, et le bouton
   dépassait alors de 21px la ligne d'alignement du reste de la page. */
@media (min-width: 1200px) {
  .menu {
    display: flex;
    align-items: center;
    gap: var(--esp-2);
  }

  /* Une entrée de menu ne se coupe jamais en deux lignes. */
  .menu > li > a { white-space: nowrap; }

  .menu > li {
    position: relative;
    display: flex;
    align-items: center;
    gap: 2px;
  }

  .menu > li > a { padding-block: var(--esp-1); }

  /* Le CTA n'est pas dupliqué dans la barre desktop. */
  .menu .menu-cta { display: none; }

  .burger { display: none; }

  .nav-cta .btn { display: inline-flex; }

  .dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 220px;
    padding: var(--esp-1);
    background: var(--tc-blanc-chaud);
    border: 1px solid var(--tc-filet);
    border-radius: var(--r-carte);
    /* Masqué sans `display:none` pour rester animable et accessible. */
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--transition), visibility var(--transition);
  }

  /* Ouverture à la souris, au clavier (focus-within) et au clic (JS). */
  .menu > li:hover > .dropdown,
  .menu > li:focus-within > .dropdown,
  .dropdown.open {
    opacity: 1;
    visibility: visible;
  }

  .dropdown a {
    display: block;
    padding: 9px 12px;
    border-radius: 6px;
    color: var(--tc-texte-doux);
    font-size: 15px;
    font-weight: 500;
  }

  .dropdown a:hover {
    background: var(--tc-vert-doux);
    color: var(--tc-marine);
  }
}

/* Au-delà de 1200px, la barre respire à l'espacement nominal. */
/* ==========================================================================
   07. HERO
   --------------------------------------------------------------------------
   Un voile marine à plat, jamais un dégradé (interdit par la charte).
   ========================================================================== */

/* Plus de voile sur l'image : le texte est posé sur un bloc marine opaque, à
   la manière de la fiche d'identité des pages modèles. L'image se voit donc
   telle qu'elle est, et le contraste du texte ne dépend plus de ce qu'il y a
   derrière — il est garanti par construction.

   Mobile : l'image d'abord, le bloc en dessous. Desktop : le bloc se superpose
   à gauche, sur la partie jardin — la maison et le couple, au centre-droit,
   ne sont jamais masqués. */
.hero-full { background: var(--tc-marine); }

/* La source est panoramique : 5494 × 2325, soit un rapport de 2,36.
   --------------------------------------------------------------------------
   Deux rapports, et non un seul, parce que le hero ne joue pas le même rôle
   selon la largeur.

   MOBILE — le texte est empilé SOUS l'image. Le 16/9 recadre les côtés, ce qui
   resserre le cadrage sur la maison. Au rapport naturel, l'image ne ferait que
   159 px de haut sur un écran de 375 px : un bandeau trop mince pour montrer
   quoi que ce soit. */
.hero-full-img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.hero-full-inner { width: 100%; }

.hero-full-content {
  padding: var(--esp-4) var(--gouttiere);
  background: var(--tc-marine);
  color: #fff;
}

.hero-full-content h1 { color: #fff; }

/* Le montant est l'accent de la ligne : jaune, insécable. */
.hero-full-content h1 .montant {
  color: var(--tc-jaune);
  white-space: nowrap;
}

.hero-full-content .sub {
  max-width: 52ch;
  margin: 0 0 var(--esp-4);
  color: var(--tc-sur-marine-fort);
  font-size: 18px;
}

.hero-full-content .tag { color: var(--tc-jaune); }

/* Note de prix sous les CTA. Sur fond marine opaque, plus besoin de la valeur
   éclaircie qu'imposait l'ancien voile : le gris de la charte suffit. */
.hero-full-content .note {
  margin: var(--esp-3) 0 0;
  color: var(--tc-sur-marine-doux);
}

.hero-full-content .note a { color: var(--tc-sur-marine-fort); text-decoration: underline; }

/* --- Desktop : le bloc se superpose à gauche ---------------------------
   L'image reste entière et visible ; le bloc marine occupe la partie jardin
   du visuel, à gauche, pour ne jamais recouvrir la maison ni le couple qui
   se trouvent au centre-droit. Rayon de carte et largeur bornée, comme la
   fiche d'identité des pages modèles. */
@media (min-width: 900px) {
  .hero-full { position: relative; }

  /* DESKTOP — le texte est POSÉ SUR l'image, dans un bloc marine à gauche.
     On rend ici l'image à son rapport naturel : la grande prairie de gauche
     accueille le bloc de texte sans recouvrir la maison, ce que le client
     avait demandé. Recadrer en 16/9 retirerait 25 % de la largeur, donc
     précisément cette prairie — et le car-port sur la droite. */
  .hero-full-img { aspect-ratio: 2560 / 1083; }

  .hero-full-inner {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
  }

  /* 520px, et pas davantage : la façade en brique commence à 47,3 % de la
     largeur de l'image — mesuré sur les pixels, pas estimé à l'œil. À 560px le
     bloc mordait de 24px sur le mur. 520px laisse la maison entièrement
     dégagée, ce qui est la demande. */
  .hero-full-content {
    max-width: 520px;
    padding: 28px;
    border-radius: var(--r-carte);
  }

  /* Les deux CTA tenaient à 9px près : ils passaient à la ligne. Marge interne
     à 28px et écart à 12px libèrent la place, sans toucher à la taille des
     boutons — la réduire ici les aurait désaccordés du reste du site. */
  .hero-full-content .btn-row { gap: 12px; }
}


/* ==========================================================================
   08. BARRE DE CONFIANCE & TÉMOIGNAGES
   --------------------------------------------------------------------------
   Deux sections distinctes qui se suivent : la barre de confiance sur fond
   marine, puis les témoignages sur fond vert doux.

   La barre est un composant obligatoire de la charte : fond marine imposé,
   4 piliers dans un ordre fixe. Les icônes sont servies en variante jaune,
   celle que le kit officiel destine aux fonds marine.

   ÉCARTS DE CHARTE ASSUMÉS — demandés par le client :
     · Icônes portées de 24–32px à 40px (reste dans la fourchette
       « 32–40px décoratif » de la charte).
     · Titres de pilier portés de 15px à 18px.
     · La hauteur dépasse donc les 80–100px prévus par la charte.
   ========================================================================== */

/* La section qui accueille la barre reste claire : c'est l'encadré qui porte
   le marine, pas la section. */
.confiance {
  padding-block: var(--esp-5);
  background: var(--tc-vert-doux);
}

/* --- Les 4 piliers -------------------------------------------------------
   L'encadré porte lui-même son fond marine et son rayon de 12px.

   C'est un point d'architecture, pas un choix esthétique : la barre apparaît
   sur 15 pages, tantôt dans une section vert doux, tantôt ailleurs. Si le
   marine vient de la section, le composant devient illisible dès qu'on le
   pose autre part — du texte blanc sur vert doux tombe à 1,13:1. En le
   rendant autonome, il est correct partout par construction. */
.trust {
  display: grid;
  grid-template-columns: repeat(2, 1fr);   /* grille 2×2 sur mobile (charte) */
  overflow: hidden;                        /* les filets suivent l'arrondi */
  background: var(--tc-marine);
  border-radius: var(--r-carte);
  list-style: none;
  margin: 0;
  padding: 0;
}

.trust .item {
  padding: var(--esp-3) var(--esp-2);
  text-align: center;
}

/* Filets de séparation à 0.5px, conformes à la charte.
   --------------------------------------------------------------------------
   Ils sont posés par palier, chaque palier dans sa propre media query, et
   jamais annulés par une règle de l'autre. C'est volontaire : les media
   queries n'ajoutent aucune spécificité, donc une règle mobile en
   `:nth-child()` (0,3,0) l'emporterait sur une règle desktop en
   `.trust .item` (0,2,0) et supprimerait un filet en desktop. Poser plutôt
   qu'annuler évite tout le problème. */

/* Grille 2×2 : filet vertical dans la colonne de droite, filet horizontal
   sur la rangée du bas. */
@media (max-width: 899px) {
  .trust .item:nth-child(even) { border-left: .5px solid var(--tc-filet-clair); }
  .trust .item:nth-child(n+3)  { border-top:  .5px solid var(--tc-filet-clair); }
}

/* Conteneur d'icône à hauteur fixe. C'est lui qui garantit que les quatre
   titres démarrent exactement à la même hauteur : quelle que soit l'icône
   posée dedans, la ligne de texte qui suit ne bouge pas. */
.trust .ic {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  margin-bottom: var(--esp-2);
}

/* Icônes officielles du kit TC. Leur couleur est portée par l'attribut
   `stroke` du fichier source — on ne recolore jamais en CSS.
   Taille : 48px sur mobile, 56px à partir de 900px. C'est au-delà de la
   fourchette « 32–40px décoratif » de la charte, à la demande expresse du
   client — voir l'encadré en tête de section.

   Les quatre icônes sont servies dans la viewBox native 0 0 24 24. Deux
   fichiers du kit (tc-prix-ferme, tc-label-peb-a) sont livrés en
   « -3 -3 30 30 », soit trois unités de marge intégrée : utile pour que les
   exports PNG 512px respirent, nuisible en web où la marge rétrécit le
   dessin de 20 %. On la retire côté cadrage — les tracés tiennent tous dans
   0–24, aucun n'est modifié ni recoloré. */
.trust .ic svg {
  width: 48px;
  height: 48px;
}

.trust strong {
  display: block;
  margin-bottom: 4px;
  color: #fff;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
}

.trust span {
  display: block;
  color: var(--tc-sur-marine-doux);
  font-size: 14px;
  line-height: 1.5;
}

/* --- Témoignages -------------------------------------------------------
   Section distincte de la barre de confiance, sur fond vert doux.

   Pourquoi le vert doux et pas une autre des quatre couleurs :
     · le jaune est un accent, la charte lui interdit d'être un fond
       structurel — et en texte sur fond clair il plafonne à 1,4:1 ;
     · le blanc chaud est le fond de page : la section ne se détacherait pas ;
     · le marine est déjà pris par la barre de confiance juste au-dessus ;
     · le vert doux est explicitement réservé aux « zones de réassurance »,
       ce qui est exactement la fonction d'un témoignage.

   Le texte passe donc en marine : sur fond clair, le blanc et le jaune
   n'auraient pas le contraste requis.
   ====================================================================== */

.temoignages { background: var(--tc-vert-doux); }

.temoins {
  display: grid;
  gap: var(--esp-5);
}

.temoin {
  margin: 0;
  /* Bordure d'accent à gauche : 0px de rayon, conforme à la charte. */
  padding-left: var(--esp-3);
  border-left: 2px solid var(--tc-jaune);
}

.temoin blockquote {
  margin: 0 0 var(--esp-2);
  color: var(--tc-marine);
  font-size: 18px;
  font-weight: 300;   /* Light : registre calme et rassurant */
  line-height: 1.7;
}

.temoin figcaption {
  color: var(--tc-texte-doux);
  font-size: 14px;
  line-height: 1.6;
}

.temoin figcaption strong {
  display: block;
  color: var(--tc-marine);
  font-size: 15px;
  font-weight: 600;
}

@media (min-width: 768px) {
  .temoins { grid-template-columns: repeat(2, 1fr); gap: var(--esp-6); }
}

/* Passage en 4 colonnes : les filets deviennent uniquement verticaux, et
   les icônes comme les titres montent d'un cran — il y a la place.

   Le rythme vertical est resserré : en 4 colonnes le contenu fait ~130px de
   haut, et l'empiler entre deux fois 32px de marge interne plus deux fois
   48px de marge de section donnait une bande de 300px majoritairement vide.
   16px de marge interne suffisent : les filets restent assez hauts pour
   séparer, et la bande passe à ~250px. */
@media (min-width: 900px) {
  .trust { grid-template-columns: repeat(4, 1fr); }

  .trust .item { padding: var(--esp-2) var(--esp-3); }

  /* Un filet devant chaque pilier sauf le premier — donc trois filets pour
     quatre colonnes. `.item + .item` le dit sans avoir à annuler quoi que
     ce soit sur le premier. */
  .trust .item + .item { border-left: .5px solid var(--tc-filet-clair); }

  .trust .ic     { height: 56px; }
  .trust .ic svg { width: 56px; height: 56px; }
  .trust strong  { font-size: 22px; }
  .trust span    { font-size: 15px; }
}


/* ==========================================================================
   09. CARTES MODÈLES
   ========================================================================== */

.card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
  transition: border-color var(--transition);
}

.card:hover { border-color: rgba(26, 46, 74, .30); }

/* Visuel de carte au rapport des sources (toutes en 16/9) : aucun recadrage.
   La hauteur fixe de 210px qui se trouvait ici rognait 2 % de l'image — peu,
   mais gratuit à supprimer, et le rapport suit désormais la largeur de la
   colonne au lieu d'être figé. */
.card .imgbox {
  height: auto;
  aspect-ratio: 16 / 9;
  border-radius: 0;
}

.card .body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  padding: var(--esp-3);
}

/* Le niveau de titre relève de la sémantique, la taille du style. Sur les
   pages où la grille suit directement le <h1> (nos-modeles, investir,
   modeles-invest), les intitulés sont des <h2> — sinon le plan du document
   saute un niveau — mais gardent l'échelle d'un titre de bloc. */
.card h2,
.card h3 { margin: 0; font-size: 19px; font-weight: 500; }

/* Caractéristiques (chambres, sdb, surface). */
.specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
  margin: 2px 0 var(--esp-1);
  padding: 0;
  color: var(--tc-texte-doux);
  font-size: 14px;
  list-style: none;
}

.specs li,
.specs span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.specs svg {
  width: 17px;
  height: 17px;
  color: var(--tc-marine);
  opacity: .55;
}

.cardprice {
  color: var(--tc-marine);
  font-size: 16px;
  font-weight: 600;
}

.cardprice span {
  color: var(--tc-texte-tenu);
  font-size: 13px;
  font-weight: 400;
}

.card .link { margin-top: auto; padding-top: var(--esp-1); }

.card:hover .link svg { transform: translateX(3px); }

@media (min-width: 640px) {
  .grid.c2 { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 900px) {
  .grid.c3 { grid-template-columns: repeat(3, 1fr); }
}


/* ==========================================================================
   10. ÉTAPES
   ========================================================================== */

.steps {
  display: grid;
  gap: var(--esp-3);
  list-style: none;
  margin: 0;
  padding: 0;
}

.step {
  padding: var(--esp-4) var(--esp-3);
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
}

.step .n {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: var(--esp-2);
  background: var(--tc-marine);
  border-radius: var(--r-btn);   /* 8px, comme tous les petits blocs du système */
  color: var(--tc-jaune);
  font-size: 18px;
  font-weight: 600;
}

.step h3 { margin-bottom: var(--esp-1); }

.step h3 a:hover,
.step h3 a:focus-visible { text-decoration: underline; }

.step p { margin: 0; font-size: 16px; }

@media (min-width: 720px) {
  .steps { grid-template-columns: repeat(3, 1fr); }
}


/* ==========================================================================
   11. BANDEAU CTA
   ========================================================================== */

.band {
  display: grid;
  gap: var(--esp-4);
  align-items: center;
  padding: var(--esp-5) var(--esp-4);
  background: var(--tc-marine);
  border-radius: var(--r-carte);
}

.band h2 {
  margin: 0 0 var(--esp-1);
  color: #fff;
}

.band p {
  margin: 0;
  color: var(--tc-sur-marine-moyen);
}

@media (min-width: 860px) {
  .band {
    grid-template-columns: 1.4fr auto;
    padding: var(--esp-6) var(--esp-5);
  }
}


/* ==========================================================================
   12. FORMULAIRES
   ========================================================================== */

.formwrap {
  display: grid;
  gap: var(--esp-5);
  align-items: start;
}

.formcard {
  padding: var(--esp-4) var(--esp-3);
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
}

.field { margin-bottom: var(--esp-2); }

.field label {
  display: block;
  margin-bottom: 6px;
  color: var(--tc-marine);
  font-size: 14px;
  font-weight: 500;
}

/* Marque les champs obligatoires sans compter sur la seule couleur. */
.field label .requis {
  color: var(--tc-jaune);
  font-weight: 600;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid rgba(26, 46, 74, .28);
  border-radius: var(--r-btn);
  color: var(--tc-texte);
  font: inherit;
  font-size: 16px;   /* 16px minimum : évite le zoom automatique sur iOS */
}

.field textarea {
  min-height: 120px;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--tc-marine);
  outline: 2px solid var(--tc-jaune);
  outline-offset: 1px;
}

.field .aide {
  margin: 6px 0 0;
  color: var(--tc-texte-tenu);
  font-size: 13px;
}

/* Message d'erreur d'envoi. La charte n'autorise aucune cinquième couleur :
   l'alerte se signale par la bordure d'accent jaune et par sa formulation,
   jamais par la couleur seule — ce qui est aussi la bonne pratique WCAG. */
.form-erreur {
  margin: 0 0 var(--esp-2);
  padding: var(--esp-2);
  background: var(--tc-vert-doux);
  border-left: 2px solid var(--tc-jaune);   /* bordure d'accent, 0px de rayon */
  color: var(--tc-marine);
  font-size: 15px;
  font-weight: 500;
}

.form-erreur[hidden] { display: none; }

/* Le bouton d'envoi occupe toute la largeur de la carte : c'est la dernière
   action de la page, elle doit être impossible à manquer. */
.formcard .btn[type="submit"] { width: 100%; }

/* Mention de réassurance sous le bouton d'envoi. */
.formcard .note {
  margin: var(--esp-2) 0 0;
  text-align: center;
}

/* Visuel illustratif en fin de colonne (carte de zone, photo d'appui). */
.formwrap .imgbox { margin-top: var(--esp-3); }

.two { display: grid; gap: var(--esp-2); }

@media (min-width: 560px) {
  .two { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 900px) {
  .formwrap { grid-template-columns: 1fr 1fr; }
  .formcard { padding: var(--esp-4); }
}

/* Confirmation d'envoi (injectée par main.js). */
.form-ok {
  padding: var(--esp-4) var(--esp-3);
  background: var(--tc-vert-doux);
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
  color: var(--tc-texte-doux);
  text-align: center;
}

.form-ok .ic {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
  margin: 0 auto var(--esp-2);
  background: var(--tc-jaune);
  border-radius: 50%;
  color: var(--tc-marine);
}

.form-ok .ic svg { width: 28px; height: 28px; }

.form-ok strong {
  display: block;
  margin-bottom: 6px;
  color: var(--tc-marine);
  font-size: 19px;
  font-weight: 600;
}


/* ==========================================================================
   13. CONTENUS ÉDITORIAUX
   ========================================================================== */

/* En-tête de page intérieure. */
.phead {
  padding-block: var(--esp-5);
  background: var(--tc-blanc-chaud);
  border-bottom: 1px solid var(--tc-filet);
}

.phead p { max-width: 62ch; margin: 0; }

/* --- Sommaire d'une page longue ---------------------------------------
   Quand plusieurs rubriques cohabitent sur une même page, le lecteur doit
   voir d'emblée ce qu'elle contient et pouvoir sauter à la bonne section.
   Sans ça, regrouper des pages remplace un clic de trop par un défilement
   à l'aveugle — on déplace le problème au lieu de le régler. */
.sommaire {
  margin-top: var(--esp-4);
  padding-top: var(--esp-3);
  border-top: 1px solid var(--tc-filet);
}

.sommaire h2 {
  margin: 0 0 var(--esp-2);
  color: var(--tc-texte-tenu);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.sommaire ol {
  display: flex;
  flex-direction: column;
  gap: var(--esp-1);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: sommaire;
}

.sommaire a {
  display: inline-flex;
  align-items: baseline;
  gap: var(--esp-1);
  padding: 4px 0;
  border-bottom: 2px solid transparent;   /* bordure d'accent, 0px de rayon */
  color: var(--tc-marine);
  font-size: 16px;
  font-weight: 500;
}

/* Numérotation portée par le CSS : l'ordre est déjà dans le <ol>, on ne le
   redit pas dans le texte du lien. */
.sommaire li { counter-increment: sommaire; }

.sommaire a::before {
  content: counter(sommaire) ".";
  color: var(--tc-jaune);
  font-weight: 600;
}

.sommaire a:hover { border-bottom-color: var(--tc-jaune); }

/* Variante sans numéros, pour les pages dont les rubriques ne sont pas
   des étapes successives. */
.sommaire--libre a::before { content: "→"; }

@media (min-width: 640px) {
  .sommaire ol { flex-direction: row; flex-wrap: wrap; gap: var(--esp-4); }
}

.breadcrumb {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: var(--esp-2);
  color: var(--tc-texte-doux);
  font-size: 14px;
  font-weight: 500;
}

.breadcrumb svg { width: 16px; height: 16px; color: var(--tc-jaune); }

.breadcrumb:hover,
.breadcrumb a:hover { color: var(--tc-marine); }

/* Bande du fil d'Ariane, au-dessus du bandeau photo d'une fiche modèle.
   Remplace un `style="padding-top:16px"` en ligne. */
.fil-ariane { padding-top: var(--esp-2); }

.fil-ariane .breadcrumb { margin-bottom: var(--esp-2); }

/* Texte long. */
.prose { max-width: 70ch; }

.prose p { font-size: 17px; }

.prose strong { color: var(--tc-marine); }

.prose h2 { margin-top: var(--esp-5); }

.prose h3 { margin-top: var(--esp-4); }

.prose ul,
.prose ol { color: var(--tc-texte-doux); padding-left: var(--esp-3); }

.prose li { margin-bottom: var(--esp-1); }

/* --- Document légal ----------------------------------------------------
   Une page de conditions compte une quinzaine de sections numérotées. Les
   titrer à 28px (échelle H2 de la charte) noierait le texte sous les titres.
   On conserve donc le niveau <h2> — c'est le plan réel du document, et les
   lecteurs d'écran s'en servent pour naviguer — mais on lui applique
   l'échelle H3 de la charte. C'est un choix typographique, pas sémantique. */
.doc-legal { max-width: 860px; }

.doc-legal h2 {
  margin: var(--esp-4) 0 var(--esp-1);
  font-size: 19px;
  font-weight: 600;
}

.doc-legal h2:first-child { margin-top: 0; }

.doc-legal p { font-size: 16px; }

/* Dans un texte juridique, un lien doit être identifiable sans la couleur. */
.doc-legal a {
  color: var(--tc-marine);
  font-weight: 500;
  text-decoration: underline;
}

/* Liste à coches. */
.checklist {
  list-style: none;
  margin: var(--esp-3) 0 0;
  padding: 0;
}

.checklist li {
  display: flex;
  gap: var(--esp-2);
  align-items: flex-start;
  margin-bottom: var(--esp-2);
  color: var(--tc-texte-doux);
  font-size: 16px;
}

.checklist svg {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 5px;
  color: var(--tc-jaune);
}

/* Blocs de réassurance. */
.feat { display: grid; gap: var(--esp-3); }

.feat .f {
  padding: var(--esp-3);
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
}

.feat .f h2,
.feat .f h3 {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: var(--esp-2);
  font-size: 17px;
  font-weight: 600;
}

/* Icône jaune sur pastille marine.
   --------------------------------------------------------------------------
   Les icônes de cette section sont jaunes, à la demande du client. Sur le
   fond blanc de la carte, le jaune ne donne que 1,57:1 — un aplat pâle,
   illisible. La pastille marine derrière l'icône remonte le contraste à
   8,7:1.

   Ce n'est pas un motif inventé pour l'occasion : c'est exactement `.step .n`,
   employé pour les étapes de /votre-projet et /investir. Même taille de
   rayon, même couple de couleurs. La règle ⑤ de la charte — « pas de fond
   coloré derrière une icône, sauf la barre de confiance » — est donc déjà
   assouplie ailleurs sur le site ; on reste cohérent plutôt que d'ajouter
   une troisième façon de présenter une icône.

   36px et non 44px comme `.step .n` : il y a huit cartes ici, contre trois
   étapes. Une pastille plus petite garde la liste compacte. */
.feat .f h2 svg,
.feat .f h3 svg {
  flex: none;
  box-sizing: border-box;
  width: 36px;
  height: 36px;
  padding: 7px;
  background: var(--tc-marine);
  border-radius: var(--r-btn);
}

.feat .f p { margin: 0; font-size: 16px; }

/* Ce qui est inclus / non inclus. */
.inclus { display: grid; gap: var(--esp-3); }

.inclus .blk {
  padding: var(--esp-3);
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
}

.inclus h3,
.inclus h4 {
  display: flex;
  gap: var(--esp-2);
  align-items: center;
  margin: 0 0 var(--esp-2);
}

/* Accent jaune : ces icônes sont décoratives (aria-hidden) et flanquent un
   titre marine qui porte tout le sens. Sur fond clair le jaune ne donne que
   1,6:1 — inacceptable pour une icône porteuse d'information, acceptable pour
   un ornement de marque. Les icônes qui aident réellement à lire (specs d'un
   modèle, garanties) restent en marine. */
.inclus h3 svg,
.inclus h4 svg {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--tc-jaune);
}

.inclus ul {
  margin: 0;
  padding-left: 18px;
  color: var(--tc-texte-doux);
  font-size: 15px;
}

.inclus li { margin-bottom: 5px; }

.nope {
  margin-top: var(--esp-3);
  padding: var(--esp-3);
  background: var(--tc-vert-doux);
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
}

.nope h3,
.nope h4 {
  display: flex;
  gap: var(--esp-2);
  align-items: center;
  margin: 0 0 var(--esp-2);
}

.nope h3 svg,
.nope h4 svg { flex: none; width: 22px; height: 22px; color: var(--tc-jaune); }

.nope ul {
  margin: 0;
  padding-left: 18px;
  color: var(--tc-texte-doux);
  font-size: 15px;
}


/* FAQ. La liste est plus étroite que la grille : une réponse de six lignes
   qui court sur 1200px devient pénible à lire. */
.faq-liste {
  max-width: 820px;
  margin-inline: auto;
}

details.faq {
  margin-bottom: var(--esp-2);
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
}

details.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--esp-2);
  padding: var(--esp-2) var(--esp-3);
  color: var(--tc-marine);
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}

details.faq summary::-webkit-details-marker { display: none; }

details.faq summary::after {
  content: "+";
  flex: none;
  color: var(--tc-jaune);
  font-size: 26px;
  font-weight: 400;
  line-height: 1;
}

details.faq[open] summary::after { content: "\2013"; }

details.faq .ans {
  padding: 0 var(--esp-3) var(--esp-3);
  color: var(--tc-texte-doux);
  font-size: 16px;
}

@media (min-width: 720px) {
  /* `.nope ul` est une liste ordinaire : le multi-colonnes lui convient. */
  .nope ul { columns: 2; column-gap: var(--esp-4); }

  /* `.feat` et `.inclus` sont des GRILLES (`display: grid`), et la propriété
     `columns` n'a aucun effet sur un conteneur de grille — elle était
     silencieusement ignorée. Résultat : les huit garanties de /topconstruct
     et les sept blocs « ce que comprend le prix » des douze fiches modèles
     s'empilaient sur une seule colonne en desktop, produisant un mur de
     cartes là où deux colonnes étaient prévues.

     Le passage à `grid-template-columns` corrige réellement la mise en page.

     On garde l'étirement par défaut (`align-items: stretch`) : ces cartes ont
     une bordure visible, et deux cartes voisines de hauteurs différentes
     laissent un décroché disgracieux. À hauteur égale, chaque rangée forme une
     ligne nette. */
  .feat,
  .inclus {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--esp-3);
  }
}


/* ==========================================================================
   14. FICHES MODÈLES
   ========================================================================== */

/* Étiquette PEB. Les couleurs du label énergétique sont réglementaires :
   elles ne relèvent pas de la palette de marque. C'est le seul vert du site
   en dehors du vert doux de la charte, et il est assumé — le vert porte ici
   une information normée (A = meilleure classe), que le jaune de la charte
   contredirait puisqu'il désigne une classe moyenne sur l'échelle PEB.

   Le vert d'origine était #23A04E : sur du texte blanc de 13px, il ne donnait
   que 3,38:1 là où WCAG AA exige 4,5:1 pour du texte courant — 13px en
   SemiBold ne relève pas du « grand texte », qui commence à 18,66px en gras.
   Il a été assombri à #1A8040, la teinte la plus proche qui atteigne le seuil
   (4,99:1). Ne pas le réclaircir vers la teinte officielle : le badge
   redeviendrait non conforme. */
.peb {
  display: inline-flex;
  align-items: stretch;
  overflow: hidden;
  border-radius: 5px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  line-height: 1;
}

.peb .l {
  display: flex;
  align-items: center;
  padding: 6px 9px;
  background: var(--tc-marine);
  color: #fff;
}

.peb .a {
  display: flex;
  align-items: center;
  padding: 6px 15px 6px 9px;
  background: #1A8040;
  color: #fff;
  clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%);
}

/* Bandeau photo + fiche d'identité du modèle.
   --------------------------------------------------------------------------
   Le visuel est servi au rapport 16/9, celui des sources. L'ancienne version
   imposait une hauteur fixe de 520px : sur un écran de 1440px, cela écrasait
   une image 2560×1440 en 1440×520 et jetait **36 % de sa hauteur** — toit et
   sol coupés. C'était le « coupé par le frame » du retour client.

   Mobile : l'image d'abord, la fiche en dessous — elle ne masque jamais la
   maison. Desktop : la fiche se superpose en bas à gauche, ce qui « combine
   la photo et le texte » comme demandé, sans rien recadrer. */
.showcase { background: var(--tc-marine); }

/* Le bandeau accepte une <img> seule, ou une <picture> quand la fiche change
   de visuel selon la largeur — cas de TC01, seule fiche concernée. Sans le
   second sélecteur, l'image d'une <picture> n'est plus enfant direct de
   .showcase et perdrait toute sa mise en forme. */
.showcase > img,
.showcase > picture > img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;   /* les sources sont déjà en 16/9 : aucune perte */
}

.showcase > picture { display: block; }

/* Bandeau panoramique des 12 fiches modèles, en desktop seulement.
   ---------------------------------------------------------------------------
   Les visuels fournis pour les bandeaux sont en 2,64 (3464×1312) et non en
   16/9 comme le reste du site. En dessous du seuil, c'est le visuel 16/9
   d'origine de la fiche qui est servi — voir la balise « picture » de chaque
   fiche : le rapport commun s'applique alors tel quel, et cette règle ne fait
   rien.

   ⚠ CE SEUIL DOIT RESTER ÉGAL À CELUI DÉCLARÉ DANS LES 12 FICHES. S'ils
   divergent, il existe une plage de largeurs où le navigateur sert le visuel
   16/9 tandis que le CSS lui impose le rapport 2,64 : l'image y perd un tiers
   de sa hauteur. Les fiches sont générées par
   .claude/placer-heros-modeles.py, dont la constante SEUIL fait foi.

   Pourquoi 1280px : la fiche d'identité se superpose au bandeau et y est
   centrée verticalement ; plus haute que lui, elle débordait sur la section
   suivante. Hauteurs mesurées dans le navigateur — 402px sur dix fiches,
   440px sur TC05-invest et 463px sur TC09-invest, les fiches investisseurs
   portant une ligne de rendement en plus. Au rapport 2,64, un bandeau atteint
   463px à partir de 1223px de large : 1280px est le premier seuil courant
   au-dessus, avec 21px de marge sur la fiche la plus haute.

   Si une carte gagne une ligne, refaire le calcul :
       largeur minimale = hauteur de la carte × 1920 / 727 */
@media (min-width: 1280px) {
  .showcase > picture > img.pano { aspect-ratio: 1920 / 727; }
}

.info-card {
  padding: var(--esp-3);
  background: var(--tc-marine);
  color: #fff;
}

/* Le CTA secondaire de la fiche héritait du texte marine de `.btn-ghost`,
   posé sur une carte marine : contraste 1:1, bouton invisible. Sur fond
   sombre, il passe en blanc — la bordure jaune porte déjà l'accent. */
.info-card .btn-ghost { color: #fff; }

.info-card .btn-ghost:hover { background: rgba(255, 255, 255, .12); }

@media (min-width: 900px) {
  .showcase { position: relative; }


  /* Fiche centrée verticalement, et non collée en bas. Au rapport 16/9 le
     bandeau atteint 810px sur un écran de 1440 : alignée en bas, la fiche
     faisait passer son propre CTA sous la ligne de flottaison. Centrée, le
     bouton reste visible sans défiler — et l'image n'est toujours pas
     recadrée. */
  .showcase .sc-inner {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
  }

  .info-card {
    max-width: 470px;
    border-radius: var(--r-carte);
  }
}

.info-card h1 { margin: var(--esp-1) 0 var(--esp-2); color: #fff; }

.info-card .peb { margin-bottom: var(--esp-1); }

.ic-specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--esp-2);
  margin: var(--esp-2) 0;
  padding: 0;
  color: var(--tc-sur-marine-moyen);
  font-size: 14px;
  list-style: none;
}

.ic-specs li,
.ic-specs span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.ic-specs svg { width: 17px; height: 17px; color: var(--tc-jaune); }

.sc-price {
  color: #fff;
  font-size: 24px;
  font-weight: 600;
}

.sc-price .yellow { color: var(--tc-jaune); }

.sc-price small {
  display: block;
  color: var(--tc-sur-marine-doux);
  font-size: 13px;
  font-weight: 300;
}

.info-card .btn-row { margin-top: var(--esp-3); }

.info-card .note { margin: var(--esp-1) 0 0; color: var(--tc-sur-marine-doux); }

/* --- CTA collant de la fiche modèle ------------------------------------
   Demandé par le client : « Ce modèle vous intéresse ? Parlons de votre
   projet », collant si possible.

   Il n'apparaît qu'une fois le bandeau photo passé — tant que la fiche
   d'identité et son bouton sont à l'écran, un second CTA serait redondant —
   et s'efface à l'approche du bandeau CTA final, pour la même raison.
   L'affichage est piloté par main.js via un IntersectionObserver.
   `visibility` accompagne l'opacité : sans elle, la barre resterait
   cliquable une fois invisible. */
.cta-collant {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  padding: var(--esp-2) 0;
  background: var(--tc-marine);
  border-top: .5px solid var(--tc-filet-clair);
  opacity: 0;
  visibility: hidden;
  transform: translateY(100%);
  transition: opacity var(--transition), visibility var(--transition),
              transform var(--transition);
}

.cta-collant.visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Mobile : tout empilé, le bouton pleine largeur.
   En répartissant la ligne horizontalement, le bouton (flex: none, 261px) ne
   laissait que 67px au prix, qui se cassait sur six lignes — 161px de barre,
   soit un cinquième de l'écran occupé en permanence. */
.cta-collant .wrap {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--esp-1);
}

.cta-collant .btn { width: 100%; }

/* Le libellé long n'a pas la place ; la mention sous le prix répète le nom du
   modèle, qui est déjà le titre de la page. */
.cta-collant .cc-titre { display: none; }

.cta-collant .cc-prix {
  margin: 0;
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.3;
}

/* La mention répète le nom du modèle, qui est déjà le titre de la page :
   masquée sur mobile pour ne pas doubler la hauteur de la barre. */
.cta-collant .cc-prix small {
  display: none;
  color: var(--tc-sur-marine-doux);
  font-size: 13px;
  font-weight: 300;
}

/* Dès qu'il y a la place, la barre repasse sur une ligne et retrouve son
   libellé et sa mention. */
@media (min-width: 720px) {
  .cta-collant .wrap {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--esp-3);
  }

  .cta-collant .btn { width: auto; flex: none; }

  .cta-collant .cc-titre {
    display: block;
    margin: 0;
    color: #fff;
    font-size: 17px;
    font-weight: 500;
  }

  .cta-collant .cc-prix { text-align: right; }

  .cta-collant .cc-prix small { display: block; }
}

/* Le pied de page ne doit pas rester masqué par la barre. */
body:has(.cta-collant.visible) footer.site { padding-bottom: 96px; }

/* Le bouton flottant des cookies se décale pour ne pas passer dessous. */
body:has(.cta-collant.visible) .cookie-fab { bottom: 88px; }


/* Galerie de la fiche modèle.
   Elle contient désormais TOUTES les vues du modèle, y compris celle du
   bandeau : c'est le seul endroit où l'on voit l'ensemble des photos, et
   cliquer sur l'une d'elles ouvre la visionneuse qui les parcourt toutes.

   Rapport 16/9 plutôt qu'une hauteur fixe : les sources sont toutes en 16/9,
   donc aucun recadrage, et les vignettes suivent la largeur de colonne. */
.mgallery { display: grid; gap: var(--esp-2); }

.mgallery img {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-carte);
  object-fit: cover;
  cursor: zoom-in;
}

@media (min-width: 820px) {
  /* Le `height: 520px` qui se trouvait ici annulait l'aspect-ratio du
     bandeau photo — une hauteur explicite l'emporte toujours sur lui — et
     recadrait 56 % de l'image. Le rapport 16/9 défini plus haut suffit. */
  /* Deux vignettes par rangée, de taille identique. La règle `.full` qui
     étalait la première sur toute la largeur n'a plus d'objet : la galerie
     contient maintenant les deux vues, à présenter à égalité. */
  .mgallery { grid-template-columns: 1fr 1fr; }
}


/* ==========================================================================
   15. GALERIE & LIGHTBOX
   ========================================================================== */

.gallery { display: grid; gap: var(--esp-2); }

@media (min-width: 640px) {
  .gallery { grid-template-columns: 1fr 1fr; }
}

img.zoomable { cursor: zoom-in; }

.lb {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--esp-4);
  background: rgba(26, 46, 74, .94);
  cursor: zoom-out;
}

.lb img {
  width: auto;
  max-width: 96%;
  max-height: 90%;
  background: #fff;
  border-radius: var(--r-btn);
  object-fit: contain;
}

.lb-x {
  position: absolute;
  top: var(--esp-2);
  right: var(--esp-3);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 0;
  border-radius: var(--r-btn);
  color: #fff;
  font-size: 34px;
  font-weight: 300;
  line-height: 1;
  cursor: pointer;
}

.lb-x:hover { background: rgba(255, 255, 255, .14); }

.lb-cap {
  position: absolute;
  bottom: var(--esp-5);
  left: 0;
  right: 0;
  padding-inline: 72px;   /* dégage les flèches de navigation */
  color: var(--tc-sur-marine-fort);
  font-size: 14px;
  text-align: center;
}

/* --- Navigation entre les images ---------------------------------------
   Le client demande de pouvoir défiler de gauche à droite. Trois entrées :
   ces deux boutons, les flèches du clavier, et le balayage tactile (géré
   dans main.js). Les boutons n'existent que s'il y a plus d'une image. */
.lb-nav {
  position: absolute;
  top: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  background: rgba(255, 255, 255, .14);
  border: 0;
  border-radius: 50%;
  color: #fff;
  cursor: pointer;
  transform: translateY(-50%);
  transition: background-color var(--transition);
}

.lb-nav:hover { background: rgba(255, 255, 255, .28); }

.lb-nav svg { width: 24px; height: 24px; }

.lb-prev { left: var(--esp-2); }
.lb-next { right: var(--esp-2); }

/* Position dans la galerie. Décoratif : l'information est déjà portée par
   l'aria-label du dialogue, l'annoncer deux fois serait redondant. */
.lb-compteur {
  position: absolute;
  bottom: var(--esp-2);
  left: 0;
  right: 0;
  margin: 0;
  color: var(--tc-sur-sombre-compteur);
  font-size: 13px;
  font-variant-numeric: tabular-nums;   /* le compteur ne doit pas sautiller */
  text-align: center;
}

@media (min-width: 720px) {
  .lb-prev { left: var(--esp-4); }
  .lb-next { right: var(--esp-4); }
}


/* ==========================================================================
   16. PIED DE PAGE
   ========================================================================== */

footer.site {
  padding: var(--esp-6) 0 var(--esp-3);
  background: var(--tc-marine);
  color: var(--tc-sur-marine-moyen);
  font-size: 15px;
}

.fgrid {
  display: grid;
  gap: var(--esp-4);
  margin-bottom: var(--esp-5);
}

footer.site .logo { margin-bottom: var(--esp-2); }

footer.site .logo img { height: 34px; }

footer.site p { color: var(--tc-sur-marine-doux); }

/* Baseline sous le logo du pied de page. */
.footer-intro { max-width: 34ch; }

footer h2 {
  margin: 0 0 var(--esp-2);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}

footer ul { list-style: none; margin: 0; padding: 0; }

footer li { margin-bottom: var(--esp-1); }

footer a:hover,
footer a:focus-visible { color: var(--tc-jaune); }

/* « Gérer les cookies » est un bouton (il ouvre une modale, il ne navigue
   pas) mais il vit dans une liste de liens : il doit en adopter l'allure. */
footer .ck-text {
  padding: 0;
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  text-align: left;
  text-decoration: none;
}

footer .ck-text:hover { color: var(--tc-jaune); }

.fbottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--esp-2);
  padding-top: var(--esp-3);
  border-top: .5px solid var(--tc-filet-clair);
  color: var(--tc-sur-marine-doux);
  font-size: 13px;
}

/* Mentions légales et note de prix.
   --------------------------------------------------------------------------
   PAS DE DÉCLARATION `color` ICI, et c'est volontaire.

   La règle portait `color: #8A96A6`, qui n'a jamais rien produit : la
   déclaration `footer.site p` plus haut a une spécificité de (0,1,2) —
   un élément, une classe, un élément — contre (0,1,1) pour `footer
   .disclaimer`. Elle l'emportait donc, et la note s'affichait en #AAAAAA.

   La déclaration morte a été retirée plutôt que renforcée : #8A96A6 sur le
   marine ne donne que 4,56:1, à peine au-dessus du seuil AA de 4,5:1, et sur
   du texte de 12px — le plus petit du site. La teinte héritée (#AAAAAA,
   5,89:1) est plus lisible.

   Si un jour la note doit vraiment être plus discrète, il faut à la fois
   monter la spécificité (`footer.site .disclaimer`) ET vérifier le contraste
   de la nouvelle teinte. Reposer une simple `color` ici serait sans effet. */
footer .disclaimer {
  margin-top: var(--esp-3);
  font-size: 12px;
}

/* Cible du renvoi de note : signale visuellement l'arrivée. */
footer .disclaimer:target {
  padding-left: var(--esp-2);
  border-left: 2px solid var(--tc-jaune);
  color: var(--tc-sur-marine-fort);
}

@media (min-width: 600px) {
  .fgrid { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 960px) {
  .fgrid { grid-template-columns: 1.6fr 1fr 1fr 1fr; }
}


/* ==========================================================================
   17. COOKIES (RGPD)
   ========================================================================== */

.cookie-banner {
  position: fixed;
  left: var(--esp-2);
  right: var(--esp-2);
  bottom: var(--esp-2);
  z-index: 300;
  display: none;
  max-width: 460px;
  padding: var(--esp-3);
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: var(--r-carte);
}

.cookie-banner.show { display: block; }

/* Dès qu'il y a de la place, le bandeau s'ancre à droite : le contenu du
   hero est aligné à gauche, il ne doit jamais être recouvert — surtout pas
   le CTA principal, qui est vu en premier. */
@media (min-width: 720px) {
  .cookie-banner { left: auto; }
}

.cookie-banner h2 { margin: 0 0 6px; font-size: 17px; }

.cookie-banner p {
  margin: 0 0 var(--esp-2);
  color: var(--tc-texte-doux);
  font-size: 14px;
}

.cookie-banner p a {
  color: var(--tc-marine);
  font-weight: 600;
  text-decoration: underline;
}

.cookie-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--esp-1);
}

.cookie-actions .btn { padding: 10px 18px; font-size: 15px; }

.ck-text {
  padding: 10px 6px;
  background: none;
  border: 0;
  color: var(--tc-texte-doux);
  font-size: 14px;
  font-weight: 500;
  text-decoration: underline;
  cursor: pointer;
}

.ck-text:hover { color: var(--tc-marine); }

.cookie-modal {
  position: fixed;
  inset: 0;
  z-index: 310;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--esp-2);
  background: rgba(26, 46, 74, .55);
}

.cookie-modal.show { display: flex; }

.cookie-card {
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow-y: auto;
  padding: var(--esp-3);
  background: #fff;
  border-radius: var(--r-carte);
}

.cookie-card h2 { margin: 0 0 6px; font-size: 21px; }

.cookie-card .sub {
  margin: 0 0 var(--esp-2);
  color: var(--tc-texte-doux);
  font-size: 14px;
}

.ck-cat {
  display: flex;
  justify-content: space-between;
  gap: var(--esp-2);
  padding: var(--esp-2) 0;
  border-top: 1px solid var(--tc-filet);
}

.ck-cat h3 { margin: 0 0 3px; font-size: 16px; font-weight: 600; }

.ck-cat p { margin: 0; color: var(--tc-texte-doux); font-size: 14px; }

/* Interrupteur. `aria-checked` porte l'état, la classe porte le visuel. */
.ck-switch {
  position: relative;
  flex: none;
  width: 46px;
  height: 26px;
  margin-top: 4px;
  background: rgba(26, 46, 74, .25);
  border: 0;
  border-radius: 20px;
  cursor: pointer;
  transition: background-color var(--transition);
}

.ck-switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 50%;
  transition: left var(--transition);
}

.ck-switch.on { background: var(--tc-marine); }

.ck-switch.on::after { left: 23px; }

.ck-switch.lock { opacity: .55; cursor: not-allowed; }

.cookie-card .cookie-actions {
  justify-content: flex-end;
  margin-top: var(--esp-3);
}

/* Bouton flottant de réouverture des préférences. */
.cookie-fab {
  position: fixed;
  left: var(--esp-2);
  bottom: var(--esp-2);
  z-index: 295;
  display: none;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  background: #fff;
  border: 1px solid var(--tc-filet);
  border-radius: 50%;
  color: var(--tc-marine);
  cursor: pointer;
}

.cookie-fab.show { display: flex; }

.cookie-fab:hover { background: var(--tc-vert-doux); }

.cookie-fab svg { width: 24px; height: 24px; }


/* ==========================================================================
   18. ACCESSIBILITÉ, MOUVEMENT RÉDUIT & IMPRESSION
   ========================================================================== */

/* Anneau de focus unique et toujours visible. `outline` n'est pas une ombre
   portée : la règle « pas d'ombre » de la charte n'est pas enfreinte. */
:focus-visible {
  outline: 3px solid var(--tc-jaune);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Sur fond jaune, l'anneau jaune serait invisible : on le passe en marine. */
.btn-primary:focus-visible,
.btn-dark:focus-visible,
.skip-link:focus-visible { outline-color: var(--tc-marine); }

/* Réservé aux lecteurs d'écran. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Respect du réglage système « réduire les animations ». */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* Contraste renforcé : on épaissit les filets et on assombrit le texte doux. */
@media (prefers-contrast: more) {
  :root {
    --tc-filet: rgba(26, 46, 74, .4);
    --tc-texte-doux: var(--tc-marine);
  }
}

@media print {
  .skip-link,
  header.site,
  .cookie-banner,
  .cookie-modal,
  .cookie-fab,
  .burger,
  .btn { display: none !important; }

  body { background: #fff; color: #000; font-size: 12pt; }

  /* Le voile a disparu du hero ; la règle reste au cas où un ancien gabarit
     en contiendrait encore un. */
  .hero-full-scrim { display: none; }

  .section { padding-block: 16pt; }

  a::after { content: " (" attr(href) ")"; font-size: 9pt; }
}
