/* =========================================================================
   B&C Développement — feuille de styles du site
   -------------------------------------------------------------------------
   Charte : bleu nuit #13182E · vert/or #988E1B · gris-bleu #E4EEF0 · bleu ardoise #3B506B
   Typo : Helvetica Now (dès licence web acquise), sinon Inter (auto-hébergée, libre)

   Une seule feuille pour tout le site, chargée par inc/header.php.

   COMMENT S'Y RETROUVER
   - Couleurs, polices et dimensions communes sont des « variables » déclarées
     une seule fois en section 2 (:root). Pour changer une couleur de la
     charte partout, on modifie la variable, pas chaque règle.
   - Pour trouver le style d'un élément : repérer sa classe (class="…") dans
     le gabarit PHP (dossiers pages/ et inc/), puis la rechercher ici (Cmd + F).
   - Les sections suivent l'ordre dans lequel elles ont été ajoutées au fil du
     projet, pas l'ordre des pages : utiliser le sommaire ci-dessous. Pour
     sauter à une section, rechercher son numéro et son titre, par exemple
     « 13. Parcours ».
   - Quand deux règles visent le même élément, c'est la plus précise qui gagne
     (.a .b l'emporte sur .b), puis, à précision égale, la plus basse dans le
     fichier. Plusieurs « ajustements » en fin de section reposent là-dessus :
     ils sont signalés.

   NOMMAGE DES CLASSES (convention dite « BEM »)
   - bloc             un composant autonome : .hero, .btn, .lot-card
   - bloc__element    une partie de ce composant : .hero__title, .lot-card__surface
   - bloc--variante   une version modifiée : .btn--gold, .section--navy
   - is-…             un état ajouté ou retiré par le JavaScript (assets/js/main.js) :
                      .is-visible, .is-open, .is-hl (surbrillance), .is-scrolled…
   - Hors convention : .reveal (apparition), .vp-… (plans des villas),
     .eco-… (schéma locatif), .b / .c / .k (formes des pictos solaires).

   PAGES ET GABARITS (nom employé dans ce fichier → fichier PHP)
   accueil → pages/accueil.php · La promotion → pages/promotion.php ·
   Le développement → pages/qui-sommes-nous.php · Les réalisations →
   pages/programmes.php · La foncière → pages/location.php ·
   page programme → pages/programme.php (une page par programme de
   data/programmes.php) · page lot → pages/lot.php · guide → pages/guide.php ·
   article du guide → pages/guide-article.php · contact, mentions légales,
   confidentialité, 404 → pages/<nom>.php.
   En-tête et pied de page de toutes les pages : inc/header.php, inc/footer.php.

   UNITÉS ET FONCTIONS À CONNAÎTRE
   - rem : multiple de la taille de texte de base (1rem = 16px) ;
     em : multiple de la taille du texte de l'élément lui-même.
   - vw / vh : % de la largeur / hauteur de la fenêtre (4vw = 4 % de la largeur).
   - ch : largeur d'un caractère ; sert à limiter la longueur des lignes.
   - fr : une « part » de l'espace dans une grille (1fr 1fr = deux colonnes
     égales ; 1.2fr .8fr = 60 % / 40 %).
   - clamp(MIN, IDÉAL, MAX) : la valeur IDÉAL (souvent en vw) suit la largeur
     de l'écran, sans descendre sous MIN ni dépasser MAX. Exemple :
     clamp(64px, 9vw, 120px) = 9 % de la largeur d'écran, entre 64 et 120px.
   - calc() : petit calcul, par exemple calc(var(--header-h) + 40px).
   - rgba(19,24,46,.86) : couleur avec transparence (ici bleu nuit à 86 %).
     rgba(19,24,46,…) = bleu nuit, rgba(152,142,27,…) = vert/or,
     rgba(59,80,107,…) = bleu ardoise.
   - z-index : ordre d'empilement des éléments superposés (le plus grand passe
     devant). Valeurs du site : 100 en-tête fixe ; 200 visionneuse d'images
     et lien d'évitement ; -1 à 5 pour des décors à l'intérieur d'un bloc.
   - clip-path: polygon(…) : découpe un élément selon une forme (coins coupés,
     toits, chevrons, triangles), en listant les points de son contour.
   - cubic-bezier(.2,.7,.2,1) : courbe d'animation rapide au départ puis
     douce à l'arrivée, utilisée dans tout le fichier.

   LARGEURS D'ÉCRAN (media queries)
   - max-width: 1100px : petit ordinateur portable, tablette à l'horizontale
   - max-width: 960px  : tablette ; le menu devient le bouton « burger »
   - max-width: 900px / 800px : tablette à la verticale ; colonnes empilées
   - max-width: 700px / 640px / 600px : téléphone (grand ou à l'horizontale)
   - max-width: 520px  : téléphone
   - min-width: 801px  : tout écran plus large qu'une tablette à la verticale
   - hover: hover      : appareils avec souris ; les effets de survol ne
     s'appliquent pas aux écrans tactiles, où ils resteraient « bloqués »
   - prefers-reduced-motion : réglage système « réduire les animations »
     (accessibilité) ; le site coupe alors ses animations

   SOMMAIRE
    1. Polices
    2. Variables (:root) : couleurs, polices, dimensions
    3. Base : réglages généraux des balises HTML
    4. Utilitaires : accessibilité et conteneurs
    5. Typographie
    6. Boutons et liens fléchés
    7. En-tête et menu principal ..................... toutes les pages
    8. Héros (grand bandeau d'ouverture de page) ..... accueil, La promotion,
                                                       Le développement, page programme
    9. Sections, colonnes et citations ............... toutes les pages
   10. Mosaïque de chiffres .......................... accueil
   11. Cartes ........................................ accueil, Le développement
   12. Cartes « publics » ............................ La promotion
   13. Parcours d'entreprise : les hangars ........... La promotion
   14. Schéma de l'écosystème locatif et photos ...... La foncière
   15. Avant / après IGN 1950-2024 ................... accueil
   16. Fondateurs .................................... Le développement
   17. Liste des programmes .......................... Les réalisations
   18. Fiche programme : éléments communs ............ page programme
   19. Bandeau d'appel à l'action .................... presque toutes les pages
   20. Offres locatives, contact, textes légaux ...... La foncière, contact,
                                                       mentions, confidentialité
   21. Pied de page .................................. toutes les pages
   22. Apparitions au défilement ..................... toutes les pages
   23. Adaptation aux écrans et réduction des animations
   24. Partenaires (logos) et encart BREEAM .......... page programme
   25. Pictos des étapes solaires .................... page programme (Horizon 50)
   26. ADN Villas d'entreprise : plans schématiques .. page programme
   27. Fiche programme : blocs Horizon 50 ............ page programme
       27.1 Site stratégique · 27.2 Coup d'œil et plan interactif ·
       27.3 Décret tertiaire · 27.4 Parc autonome · 27.5 Grille des lots
   28. Bandeaux photo pleine largeur ................. page programme
   29. Plan de masse stylisé (SVG) ................... page programme
   30. Grille des lots — parc livré .................. page programme
   31. Galerie et visionneuse ........................ page programme, page lot
   32. Le guide ...................................... guide, article du guide
   33. Page lot ...................................... page lot
   34. Blocs plan + texte ............................ page programme
   35. Plans SVG : compléments ....................... page programme
   36. Tableaux des articles du guide ................ article du guide
   37. Page de destination publicitaire .............. /villas-entreprise-horizon-50 et /merci
   38. Bandeau cookies ............................... toutes les pages (si un outil est configuré)
   ========================================================================= */

/* ---------- 1. Polices ----------
   Pages : toutes. Fichiers .woff2 dans assets/fonts/ (hébergés sur le site,
   aucun appel à un service extérieur). Une déclaration @font-face par graisse :
   400 normal, 400 italique, 500, 600, 700.
   font-display: swap : le texte s'affiche tout de suite dans une police de
   secours, puis bascule sur Inter dès qu'elle est chargée (jamais de texte
   invisible pendant le chargement).
   « BC Stencil » (Big Shoulders Stencil) sert aux grands chiffres : voir --font-num.
   Les fichiers 400 et 600 sont aussi « préchargés » par inc/header.php :
   si on les renomme, mettre à jour les deux fichiers. */
@font-face { font-family: "Inter"; src: url("../fonts/inter-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-latin-400-italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-latin-500-normal.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-latin-600-normal.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Inter"; src: url("../fonts/inter-latin-700-normal.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "BC Stencil"; src: url("../fonts/big-shoulders-stencil-display-latin-600-normal.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }

/* ---------- 2. Variables (:root) ----------
   Pages : toutes. Une variable s'écrit --nom et s'utilise avec var(--nom).
   Changer une valeur ici la change partout où la variable est utilisée.
   Attention : quelques couleurs sont écrites « en dur » plus bas (codes #…
   et rgba(…)), à reprendre à la main si la charte change. */
:root {
  --navy: #13182E; /* bleu nuit de la charte : en-tête, pied de page, sections sombres, petits titres */
  --navy-2: #1B2140; /* bleu nuit un peu plus clair : survol du bouton .btn--navy */
  --gold: #988E1B; /* vert/or de la charte : boutons principaux, puces, grands chiffres, surtitres sur fond sombre, contour du focus clavier */
  --gold-text: #726A14; /* même teinte assombrie, pour les PETITS textes et liens or sur fond clair : contraste 5,5:1 sur blanc et 4,7:1 sur gris-bleu (le minimum d'accessibilité est 4,5:1 ; --gold n'atteint que 3,4:1). Sert aussi de fond aux éléments or qui portent du texte blanc (boutons, badges, en-têtes de tableau). Ne pas l'utiliser comme texte sur fond sombre. */
  --gold-dark: #5F5811; /* or encore plus foncé : survol des boutons or */
  --gold-light: #C4BD82; /* or éclairci (hors charte) : chiffres sur fond sombre, bandeau d'appel à l'action */
  --gold-pale: #DCD8B4; /* or très pâle : encadrés « plus », ligne survolée dans les grilles de lots */
  --ice: #E4EEF0; /* gris-bleu de la charte : fonds des sections claires (.section--ice), encadrés */
  --slate: #3B506B; /* bleu ardoise de la charte : grands titres, liens */
  --slate-text: #4C5E77; /* ardoise un peu plus claire : couleur du texte courant */
  --white: #FFFFFF;
  --line: rgba(59, 80, 107, .18); /* filets de séparation : bleu ardoise à 18 % d'opacité */

  --font: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif; /* police du texte ; les suivantes servent de secours si Inter ne se charge pas */
  --font-num: "motor-stencil", "BC Stencil", "Inter", sans-serif; /* police des grands chiffres ; « motor-stencil » n'est chargée nulle part dans le site, c'est donc « BC Stencil » qui s'affiche */

  --header-h: 96px; /* hauteur de l'en-tête fixe (76px sous 960px, section 23) ; sert aussi à décaler le contenu sous l'en-tête */
  --container: 1200px; /* largeur maximale du contenu, sans les marges latérales */
  --gutter: clamp(16px, 4vw, 48px); /* marge latérale : 4 % de la largeur d'écran, jamais moins de 16px ni plus de 48px */
  --radius: 6px; /* arrondi des angles (cartes, images, encadrés) */
}

/* ---------- 3. Base : réglages généraux des balises HTML ----------
   Pages : toutes. Ces règles visent directement les balises (html, body, a,
   h1…) et donnent l'apparence par défaut, avant toute classe.
   box-sizing: border-box : la largeur indiquée inclut les marges intérieures
   et la bordure (calculs de mise en page plus simples).
   scroll-padding-top : quand on suit un lien vers une ancre (#lot-A…), la
   page s'arrête 16px sous l'en-tête fixe au lieu de glisser dessous.
   overflow-x: hidden sur body : empêche un décor qui déborde (cercles des
   cartes, etc.) de créer un défilement horizontal sur téléphone.
   img display: block : supprime le petit espace vide sous les images. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) + 16px); }
body { margin: 0; font-family: var(--font); font-size: 16px; line-height: 1.75; color: var(--slate-text); background: var(--white); -webkit-font-smoothing: antialiased; overflow-x: hidden; }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--slate); text-underline-offset: 3px; }
a:hover { color: var(--gold); }
h1, h2, h3, h4 { color: var(--slate); line-height: 1.15; margin: 0 0 .6em; font-weight: 400; }
h3 { font-size: 1.15rem; font-weight: 600; color: var(--navy); }
p { margin: 0 0 1.1em; }
strong { font-weight: 600; }
address { font-style: normal; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; } /* contour or visible lors de la navigation au clavier (touche Tab), pas au clic de souris ; indispensable à l'accessibilité, ne pas supprimer */

/* ---------- 4. Utilitaires : accessibilité et conteneurs ----------
   Pages : toutes.
   .visually-hidden : texte invisible à l'écran mais lu par les lecteurs
   d'écran (ex. « Bâtiment A — voir les surfaces » sur les pastilles du plan).
   .skip-link : lien « Aller au contenu » pour les utilisateurs du clavier ;
   caché au-dessus de l'écran (top: -60px), il apparaît quand il reçoit le
   focus. z-index 200 : au-dessus de l'en-tête. */
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link { position: absolute; left: 16px; top: -60px; z-index: 200; background: var(--white); color: var(--navy); padding: 10px 16px; border-radius: var(--radius); }
.skip-link:focus { top: 16px; }

/* .container : boîte centrée qui limite le contenu à --container (1200px),
   plus les marges latérales --gutter de chaque côté.
   .narrow : variante plus étroite pour les textes longs. La règle
   .container.narrow (section 32) la remplace partout (820px au lieu de 860px).
   .center : centre le texte et le bloc. */
.container { width: 100%; max-width: calc(var(--container) + 2 * var(--gutter)); margin: 0 auto; padding: 0 var(--gutter); }
.narrow { max-width: calc(860px + 2 * var(--gutter)); }
.center { text-align: center; margin-left: auto; margin-right: auto; }

/* ---------- 5. Typographie ----------
   Pages : toutes. Styles de titres réutilisables, indépendants de la balise
   (un h2 peut porter .h-display, un p peut porter .eyebrow…).
   .eyebrow : petit surtitre or en capitales au-dessus d'un titre.
   .h-display : grand titre de section ; la partie en <strong> passe en gras.
   .h-medium / .h-small : titre moyen / petit titre en capitales.
   .lead : paragraphe d'introduction un peu plus grand.
   max-width en ch : limite la longueur des lignes (22ch ≈ 22 caractères). */
.eyebrow { display: block; font-size: .8rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--gold-text); margin: 0 0 .9rem; line-height: 1.4; }
.hero .eyebrow, .section--navy .eyebrow { color: var(--gold); } /* sur fond bleu nuit, l'or de la charte est lisible (5,2:1) ; l'or foncé ne le serait pas */
.h-display { font-size: clamp(1.9rem, 3.4vw, 2.75rem); font-weight: 400; color: var(--slate); max-width: 22ch; }
.h-display strong { display: inline; font-weight: 600; }
.h-medium { font-size: clamp(1.3rem, 2.2vw, 1.75rem); color: var(--slate); max-width: 36ch; }
.h-small { font-size: .85rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--navy); margin-bottom: 1rem; }
.h-small--gold { color: var(--gold-text); margin-top: 2rem; }
.lead { font-size: 1.05rem; max-width: 70ch; }
.lead-italic { font-style: italic; font-size: .98rem; }

/* ---------- 6. Boutons et liens fléchés ----------
   Pages : toutes. Un bouton = .btn + une variante de couleur :
   .btn--gold (principal, fond or) · .btn--light (fond blanc) ·
   .btn--outline-light (contour blanc, sur fond sombre) · .btn--outline
   (contour ardoise, sur fond clair) · .btn--navy (déclaré en section 12).
   .btn--sm : version compacte (bouton de l'en-tête).
   min-height 52px : zone de clic confortable au doigt.
   Sous 640px, tous les boutons prennent toute la largeur (section 23).
   .link-arrow : lien texte en capitales (« Découvrir → »). */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .5em; min-height: 52px; padding: 14px 30px; border-radius: 4px; font-family: var(--font); font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; text-decoration: none; border: 1.5px solid transparent; cursor: pointer; transition: background .2s, color .2s, border-color .2s; }
.btn--sm { min-height: 40px; padding: 10px 18px; }
.btn--light { background: var(--white); color: var(--navy); border-color: var(--white); }
.btn--light:hover { background: var(--ice); color: var(--navy); }
.btn--outline-light { background: transparent; color: var(--white); border-color: rgba(255,255,255,.85); }
.btn--outline-light:hover { background: var(--white); color: var(--navy); }
.btn--gold { background: var(--gold-text); color: var(--white); border-color: var(--gold-text); } /* or foncé : texte blanc lisible (5,5:1) */
.btn--gold:hover { background: var(--gold-dark); border-color: var(--gold-dark); color: var(--white); } /* survol : encore plus foncé */
.btn--outline { background: transparent; color: var(--slate); border-color: var(--slate); }
.btn--outline:hover { background: var(--slate); color: var(--white); }
.btn-row { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 2rem; }
.link-arrow { font-size: .74rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--navy); text-decoration: none; }
.link-arrow:hover { color: var(--gold); }

/* ---------- 7. En-tête et menu principal ----------
   Pages : toutes (inc/header.php).
   L'en-tête est fixe (position: fixed) : il reste en haut pendant le
   défilement. z-index 100 : au-dessus du contenu, sous la visionneuse (200).
   .site-header--over : en-tête en dégradé transparent, posé sur la photo du
   héros. Activé par 'hero_dark' => true en tête des gabarits accueil,
   promotion, qui-sommes-nous et programme.
   .is-scrolled : ajoutée par le JavaScript après 40px de défilement ;
   l'en-tête redevient bleu nuit plein, avec une ombre.
   Le bouton « burger » (.nav-toggle) et le menu plein écran du téléphone
   sont réglés en section 23 (sous 960px). */
.site-header { position: fixed; inset: 0 0 auto 0; z-index: 100; height: var(--header-h); background: var(--navy); transition: background .3s, box-shadow .3s; } /* inset: 0 0 auto 0 = collé en haut, à gauche et à droite */
.site-header--over { background: linear-gradient(180deg, rgba(19,24,46,.85) 0%, rgba(19,24,46,.45) 65%, rgba(19,24,46,0) 100%); }
.site-header.is-scrolled { background: var(--navy); box-shadow: 0 2px 20px rgba(0,0,0,.15); }
.site-header__inner { height: 100%; max-width: calc(1360px + 2 * var(--gutter)); margin: 0 auto; padding: 0 var(--gutter); display: flex; align-items: center; justify-content: space-between; gap: 24px; } /* l'en-tête va jusqu'à 1360px de large, plus que le contenu (1200px) */
.site-header__logo img { height: 46px; width: auto; }
.site-nav { display: flex; align-items: center; gap: 44px; }
.site-nav ul { display: flex; gap: 22px; list-style: none; margin: 0; padding: 0; }
.site-nav ul a { color: var(--white); text-decoration: none; font-size: .8rem; text-transform: uppercase; letter-spacing: .02em; padding: 6px 0; border-bottom: 1px solid transparent; }
.site-nav ul a:hover, .site-nav ul a[aria-current="page"] { border-bottom-color: var(--gold); color: var(--white); }
.nav-toggle { display: none; background: none; border: 0; padding: 10px; cursor: pointer; } /* bouton burger : masqué sur grand écran */
.nav-toggle__bar { display: block; width: 26px; height: 2px; background: var(--white); margin: 5px 0; transition: transform .25s, opacity .25s; }
/* L'en-tête fixe ne prend pas de place dans la page : on décale le contenu
   de sa hauteur pour qu'il ne passe pas dessous… sauf sur les pages dont la
   photo d'ouverture doit justement remonter sous l'en-tête transparent.
   body:has(.site-header--over) = « body qui contient un en-tête transparent ».
   .page-accueil et .page-programme sont des classes de <body> données par
   'body_class' dans ces deux gabarits. */
main { padding-top: var(--header-h); }
.page-accueil main, .page-programme main, body:has(.site-header--over) main { padding-top: 0; }

/* ---------- 8. Héros (grand bandeau d'ouverture de page) ----------
   Pages : accueil (.hero--home), La promotion et Le développement
   (.hero--page), page programme (.hero--programme).
   .hero contient .hero__bg (photo de fond + voile bleu nuit) puis le texte.
   isolation: isolate + z-index: -1 sur .hero__bg : la photo passe derrière
   le texte, sans passer derrière le fond de la page.
   Le voile .hero__bg::after est un bleu nuit à 86 % d'opacité : c'est lui qui
   rend le texte blanc lisible. Le baisser éclaircit la photo mais réduit la
   lisibilité. */
.hero { position: relative; color: var(--white); background: var(--navy); overflow: hidden; isolation: isolate; }
.hero__bg { position: absolute; inset: 0; z-index: -1; }
.hero__bg-img { width: 100%; height: 100%; object-fit: cover; }
.hero__bg::after { content: ""; position: absolute; inset: 0; background: rgba(19, 24, 46, .86); }
.hero__title { color: var(--white); font-size: clamp(2.1rem, 4.4vw, 3.6rem); font-weight: 400; line-height: 1.08; max-width: 15ch; margin-bottom: 1.6rem; }
.hero__title strong { display: block; font-weight: 600; }
.hero__title .eyebrow { margin-bottom: 1rem; }
h1 .eyebrow::before { content: "— "; } /* tiret « — » ajouté automatiquement devant un surtitre placé dans un h1 */
.hero__text { max-width: 46ch; font-size: .98rem; color: rgba(255,255,255,.9); }
/* Accueil : au moins toute la hauteur de l'écran (100vh) et jamais moins de 720px ; le texte commence sous l'en-tête (+ 40px). */
.hero--home { min-height: max(720px, 100vh); display: flex; align-items: center; padding: calc(var(--header-h) + 40px) 0 80px; }
.hero__grid { display: grid; grid-template-columns: 1.2fr .8fr; gap: 64px; align-items: center; } /* deux colonnes : texte (1.2 part) et visuel (0.8 part) */
.hero__visual img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.hero--home .container { max-width: calc(1360px + 2 * var(--gutter)); }
.hero--home .hero__grid { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: clamp(40px, 4vw, 72px); } /* minmax(0, …) : une image ou un mot très long ne peut pas élargir sa colonne */
.hero--home .hero__visual img { aspect-ratio: 3 / 2; object-position: 40% 50%; box-shadow: 0 24px 60px rgba(0,0,0,.35); } /* object-position : partie de la photo gardée visible quand elle est recadrée */
.hero--page { min-height: 560px; display: flex; align-items: flex-end; padding: calc(var(--header-h) + 80px) 0 80px; }
.hero--page .hero__title { max-width: 20ch; }
.hero--programme { min-height: max(560px, 72vh); display: flex; align-items: flex-end; padding: calc(var(--header-h) + 60px) 0 56px; } /* page programme : 72 % de la hauteur d'écran, au moins 560px ; texte calé en bas */
.hero--programme .hero__bg::after { background: linear-gradient(180deg, rgba(19,24,46,.25) 0%, rgba(19,24,46,.35) 45%, rgba(19,24,46,.85) 100%); } /* voile en dégradé : clair en haut (photo visible), foncé en bas (sous le texte) */
.hero__prog { display: flex; justify-content: space-between; align-items: flex-end; gap: 32px; }
.hero__title--prog { font-size: clamp(1.8rem, 3.4vw, 2.6rem); max-width: 22ch; margin: 1.2rem 0 .6rem; }
.hero__address { text-align: right; margin: 0; font-size: .85rem; }
.hero__address dt { text-transform: uppercase; letter-spacing: .08em; font-size: .72rem; opacity: .8; }
.hero__address dd { margin: 4px 0 0; font-weight: 600; }
/* Petit utilitaire d'image : .rounded (angles arrondis). */
.rounded { border-radius: var(--radius); }

/* ---------- 9. Sections, colonnes et citations ----------
   Pages : toutes.
   .section : grand bloc vertical de page, avec des marges haut et bas de
   64px (téléphone) à 120px (grand écran).
   Fonds : --white, --ice (gris-bleu), --navy (bleu nuit, texte clair).
   Sur une page programme, la clé 'bg' d'un bloc de data/programmes.php
   choisit ce fond. --tight / --flush : marge du haut réduite / supprimée.
   .page-head : en-tête simple des pages sans photo (contact, réalisations,
   guide, mentions…). */
.section { padding: clamp(64px, 9vw, 120px) 0; }
.section--tight { padding-top: 48px; }
.section--flush { padding-top: 0; }
.section--white { background: var(--white); }
.section--ice { background: var(--ice); }
.section--navy { background: var(--navy); color: rgba(255,255,255,.85); }
.section--navy .h-display, .section--navy h3 { color: var(--white); }
.page-head { padding: 72px 0 24px; }
.page-head .h-display { max-width: 24ch; }

/* .split : deux colonnes égales, texte + image (empilées sous 960px).
   --top : aligne en haut au lieu de centrer ; --reverse : image à gauche
   (order: -1 la fait passer avant le texte sans toucher au HTML).
   .cols-2 : contenu sur deux colonnes (accueil, La promotion). */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 6vw, 96px); align-items: center; }
.split--top { align-items: start; }
.split--reverse .split__media { order: -1; }
.split__text { max-width: 560px; }
.split__text h3 { margin-top: 2rem; color: var(--slate); font-size: 1.2rem; }
.split__media { display: grid; gap: 24px; }
.split__media figure { margin: 0; }
.split__media figcaption { font-size: .8rem; font-style: italic; margin-top: 8px; }
.cols-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; margin-top: 1.5rem; }

/* Citations : .quote-inline (phrase en italique gras dans le texte, accueil) ;
   .quote-box (encadré gris-bleu, La foncière et page programme ; il devient
   blanc sur une section gris-bleu pour rester visible). */
.quote-inline { margin: 1.4rem 0; padding: 0; font-style: italic; font-weight: 600; color: var(--slate); }
.quote-inline p { margin: 0; }
.quote-box { margin: 2rem 0; padding: 28px 32px; background: var(--ice); border-radius: var(--radius); font-style: italic; color: var(--slate); }
.section--ice .quote-box { background: var(--white); }
.quote-box p { margin: 0 0 .8rem; }
.quote-box footer { color: var(--gold-text); font-weight: 600; font-size: .9rem; }

/* ---------- 10. Mosaïque de chiffres ----------
   Pages : accueil (« chiffres clés »).
   Grille de 6 colonnes × 3 rangées de 200px. Dans pages/accueil.php, chaque
   tuile reçoit une couleur (.stat-tile--slate, --ice…, 3e valeur de chaque
   ligne du tableau $stats) et un numéro de position (.stat-tile--1 à --7,
   d'après son rang). Ces numéros placent les tuiles : « grid-column: 3 / 7 »
   = de la ligne verticale 3 à la ligne 7, soit 4 colonnes de large.
   Ajouter un 8e chiffre demande donc une nouvelle règle de placement.
   Sous 960px, la mosaïque devient une simple grille de 2 colonnes
   (section 23, avec !important pour annuler ces placements). */
.stats-mosaic { padding: 0 var(--gutter); }
.stats-mosaic__grid { list-style: none; margin: 0 auto; padding: 0; max-width: var(--container); display: grid; grid-template-columns: repeat(6, 1fr); grid-template-rows: repeat(3, 200px); }
.stat-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 24px; }
.stat-tile__num { font-family: var(--font-num); font-weight: 600; font-size: clamp(2.6rem, 4.6vw, 4.4rem); line-height: 1; color: var(--white); }
.stat-tile__label { margin-top: 10px; font-size: .7rem; letter-spacing: .04em; text-transform: uppercase; color: rgba(255,255,255,.85); max-width: 22ch; }
.stat-tile--gold-light { background: var(--gold-light); }
.stat-tile--gold-light .stat-tile__num, .stat-tile--gold-light .stat-tile__label { color: var(--navy); } /* bleu nuit sur or clair : le blanc y était illisible */
.stat-tile--slate { background: var(--slate); }
.stat-tile--ice { background: var(--ice); }
.stat-tile--ice .stat-tile__num, .stat-tile--ice .stat-tile__label { color: var(--slate); }
.stat-tile--navy { background: var(--navy); }
.stat-tile--white { background: var(--white); }
.stat-tile--white .stat-tile__num { color: var(--gold); } /* or de la charte : lisible pour un très grand chiffre (3,4:1) ; l’or clair ne l’était pas */
.stat-tile--white .stat-tile__label { color: var(--slate); }
.stat-tile--gold { background: var(--gold-text); } /* or foncé : la légende blanche y reste lisible */
.stat-tile--1 { grid-column: 1; grid-row: 1; }
.stat-tile--2 { grid-column: 2; grid-row: 1; }
.stat-tile--3 { grid-column: 3 / 7; grid-row: 1 / 3; }
.stat-tile--4 { grid-column: 1 / 3; grid-row: 2 / 4; justify-content: flex-end; padding-bottom: 48px; }
.stat-tile--5 { grid-column: 3; grid-row: 3; }
.stat-tile--6 { grid-column: 4 / 6; grid-row: 3; }
.stat-tile--7 { grid-column: 6; grid-row: 3; }

/* ---------- 11. Cartes ----------
   .cards-3 + .fold-card : accueil (cartes à coin coupé).
   .cards-4 + .pole-card : Le développement (cartes des pôles du groupe, avec logo).
   Le coin coupé en haut à droite de .fold-card est dessiné par clip-path :
   le contour suit la carte en remplaçant le coin par une diagonale de 44px. */
.cards-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; margin-top: 3rem; }
.cards-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; margin-top: 2.5rem; }
.fold-card { background: var(--white); padding: 32px 28px 30px; clip-path: polygon(0 0, calc(100% - 44px) 0, 100% 44px, 100% 100%, 0 100%); display: flex; flex-direction: column; }
.fold-card__num { font-size: .75rem; font-weight: 600; color: var(--navy); margin-bottom: 18px; }
.fold-card__img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; margin-bottom: 26px; }
.fold-card__kicker { font-size: .85rem; letter-spacing: .1em; text-transform: uppercase; color: var(--slate); margin: 0 0 .3rem; }
.fold-card__title { font-size: 1rem; margin-bottom: 1rem; }
.fold-card p { font-size: .9rem; }
.fold-card .link-arrow { margin-top: auto; padding-top: 8px; } /* margin-top: auto pousse le lien en bas de la carte */
.pole-card { background: var(--white); border-radius: var(--radius); padding: 32px; }
.pole-card { border: 1px solid var(--line); display: flex; flex-direction: column; } /* suite de la règle .pole-card de la ligne précédente (les deux s'additionnent) */
.pole-card__logo-link { display: flex; align-items: center; height: 56px; margin-bottom: 1.4rem; }
.pole-card__logo { height: 36px; width: auto; max-width: 100%; object-fit: contain; object-position: left center; transition: transform .3s; }
.pole-card__logo--tagline { height: 54px; } /* logo avec slogan : plus haut pour rester lisible */
a.pole-card__logo-link:hover .pole-card__logo { transform: scale(1.05); }
.pole-card__kicker { font-size: .75rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--gold-text); margin-bottom: .4rem; }
.pole-card p { font-size: .9rem; }
.pole-card .link-arrow, .pole-card__soon { margin-top: auto; font-size: .75rem; }
.pole-card__soon { font-style: italic; }

/* ---------- 12. Cartes « publics » (chefs d'entreprise / collectivités) ----------
   Pages : La promotion. Deux grandes cartes : bleu nuit (entreprises) et or
   (collectivités).
   ::after dessine le grand cercle décoratif qui déborde en haut à droite :
   overflow: hidden le coupe au bord de la carte, z-index: -1 + isolation le
   placent derrière le texte.
   La coche des listes est dessinée en CSS : ::before = pastille ronde,
   ::after = petit rectangle dont on ne garde que deux bords, tourné de 45°. */
.audience { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin-top: 3rem; }
.audience-card { position: relative; overflow: hidden; border-radius: 10px; padding: clamp(28px, 4vw, 48px); display: flex; flex-direction: column; gap: 1rem; transition: transform .4s cubic-bezier(.2,.7,.2,1), box-shadow .4s; isolation: isolate; }
.audience-card::after { content: ""; position: absolute; z-index: -1; width: 70%; aspect-ratio: 1; right: -22%; top: -30%; border-radius: 50%; opacity: .14; transition: transform .6s cubic-bezier(.2,.7,.2,1); }
.audience-card--entreprise { background: var(--navy); color: rgba(255,255,255,.88); }
.audience-card--entreprise::after { background: var(--gold); }
.audience-card--collectivite { background: var(--gold); color: var(--navy); }
.audience-card--collectivite::after { background: var(--white); opacity: .22; }
.audience-card__icon { width: 56px; height: 56px; fill: none; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; transition: transform .5s cubic-bezier(.2,.7,.2,1); }
.audience-card--entreprise .audience-card__icon { stroke: var(--gold-light); }
.audience-card--collectivite .audience-card__icon { stroke: var(--navy); }
.audience-card__kicker { margin: 0; font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.audience-card--entreprise .audience-card__kicker { color: var(--gold-light); }
.audience-card__title { margin: 0; font-size: clamp(1.6rem, 2.6vw, 2.2rem); font-weight: 400; line-height: 1.12; color: inherit; }
.audience-card--entreprise .audience-card__title { color: var(--white); }
.audience-card__title span { display: block; font-weight: 700; }
.audience-card__list { list-style: none; margin: .4rem 0 0; padding: 0; display: grid; gap: .7rem; }
.audience-card__list li { position: relative; padding-left: 30px; font-size: .95rem; line-height: 1.5; }
.audience-card__list li::before { content: ""; position: absolute; left: 0; top: .15em; width: 18px; height: 18px; border-radius: 50%; background: currentColor; opacity: .18; }
.audience-card__list li::after { content: ""; position: absolute; left: 6px; top: calc(.15em + 4px); width: 5px; height: 9px; border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.audience-card--entreprise .audience-card__list li::after { border-color: var(--gold-light); }
.audience-card__foot { margin-top: auto; padding-top: 1.4rem; display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; border-top: 1px solid currentColor; border-top-color: rgba(127,127,127,.35); } /* currentColor puis gris semi-transparent : filet visible sur les deux couleurs de carte */
.audience-card__stat { margin: 0; font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; }
.audience-card__stat strong { display: block; font-family: var(--font-num); font-size: 2.6rem; line-height: 1; letter-spacing: 0; }
.audience-card--entreprise .audience-card__stat strong { color: var(--gold-light); }
/* Bouton bleu nuit (La promotion, page lot), rangé ici plutôt qu'en section 6. */
.btn--navy { background: var(--navy); color: var(--white); border-color: var(--navy); }
.btn--navy:hover { background: var(--navy-2); color: var(--white); }
/* Effets de survol réservés aux appareils avec souris (voir « hover: hover » en tête de fichier). */
@media (hover: hover) {
  .audience-card:hover { transform: translateY(-6px); box-shadow: 0 24px 48px rgba(19,24,46,.22); }
  .audience-card:hover::after { transform: scale(1.25) translate(-6%, 6%); }
  .audience-card:hover .audience-card__icon { transform: translateY(-4px) rotate(-4deg); }
}
@media (max-width: 900px) { .audience { grid-template-columns: 1fr; } } /* jusqu'à 900px : cartes l'une sous l'autre */

/* ---------- 13. Parcours d'entreprise : les hangars qui grandissent ----------
   Pages : La promotion (section bleu nuit « Le parcours d'entreprise »).
   Quatre silhouettes de bâtiments (.hangar--1 à --4, numérotées par la boucle
   PHP) se chevauchent, de la plus petite à la plus grande. Tout est en % de
   la zone .hangars, dont les proportions sont fixes (aspect-ratio 1164 / 627) :
   le dessin reste identique à toutes les tailles d'écran.
   - left / width / height : position et taille de chaque hangar dans la zone ;
   - z-index : chaque hangar passe devant le suivant, plus grand ;
   - --roof : hauteur de la pente du toit ; clip-path découpe le rectangle en
     forme de maison (pointe au milieu du haut : « 50% 0 »).
   Le titre (.hangars-head) est posé en haut à gauche, par-dessus le dessin.
   Sous 640px, les hangars deviennent une simple pile de bandes (section 23). */
.section--hangars { padding-bottom: 0; overflow: hidden; }
.hangars-wrap { position: relative; }
.hangars-head { position: absolute; top: 0; left: var(--gutter); width: 44%; z-index: 5; }
.hangars-title { color: var(--white); font-size: clamp(1rem, 1.6vw, 1.35rem); font-weight: 400; text-transform: uppercase; letter-spacing: .01em; line-height: 1.35; max-width: 32ch; }
.hangars-title strong { display: block; margin-top: 1.2em; color: var(--gold); font-weight: 700; }
.hangars { list-style: none; margin: 0; padding: 0; position: relative; aspect-ratio: 1164 / 627; width: 100%; }
.hangar {
  --roof: 16%;
  position: absolute; bottom: 0;
  clip-path: polygon(0 var(--roof), 50% 0, 100% var(--roof), 100% 100%, 0 100%);
  transform-origin: 50% 100%;
  transition: transform .45s cubic-bezier(.2,.7,.2,1), filter .45s;
  display: flex; justify-content: center; text-align: center; cursor: default;
}
.hangar--1 { left: 0.6%;  width: 17.8%; height: 34%; background: #464F68; z-index: 4; --roof: 19%; }
.hangar--2 { left: 9.5%;  width: 27%;   height: 53%; background: #6B7186; z-index: 3; --roof: 17%; }
.hangar--3 { left: 22.9%; width: 43.1%; height: 75%; background: #E6EDF0; z-index: 2; --roof: 18%; }
.hangar--4 { left: 44.5%; width: 54.9%; height: 97.6%; background: var(--white); z-index: 1; --roof: 14.5%; }
.hangar__label { padding-top: calc(var(--roof) + 4%); } /* le texte commence sous la pente du toit */
.hangar--1 .hangar__label { padding-top: 20%; } /* exception pour le plus petit hangar */
/* le texte se place dans la partie visible (non recouverte par le hangar précédent) */
.hangar--2 .hangar__label { padding-left: 34%; }
.hangar--3 .hangar__label { padding-left: 32%; }
.hangar--4 .hangar__label { padding-left: 40%; }
.hangar h3 { font-size: clamp(.7rem, 1.75vw, 1.35rem); font-weight: 400; text-transform: uppercase; line-height: 1.15; margin: 0 0 .15em; color: inherit; max-width: 12ch; }
.hangar__size { margin: 0; font-size: clamp(.7rem, 1.7vw, 1.3rem); font-weight: 700; }
.hangar__desc { margin: .5em auto 0; font-size: clamp(.62rem, .95vw, .9rem); line-height: 1.4; max-width: 24ch; opacity: .85; }
.hangar--2 .hangar__desc { opacity: 1; } /* sur le gris moyen du 2e hangar, le texte reste en blanc plein pour rester lisible */
.hangar__label { padding-left: 6%; padding-right: 6%; } /* marges gauche et droite ; les padding-left des hangars 2 à 4 ci-dessus restent prioritaires (sélecteurs plus précis) */
.hangar--3 h3, .hangar--4 h3 { max-width: 18ch; }
.hangar--1, .hangar--2 { color: var(--white); }
.hangar--3, .hangar--4 { color: var(--slate); }
@media (hover: hover) {
  .hangar:hover { transform: scale(1.045); filter: brightness(1.06); }
}
/* Les bâtiments « poussent » à l'apparition, du plus petit au plus grand.
   Le JavaScript ajoute .reveal à .hangars, puis .is-visible quand la zone
   arrive à l'écran. Ici, on annule le fondu général de .reveal (section 22)
   et on le remplace par une croissance verticale depuis le sol : scaleY(.0001)
   = hauteur quasi nulle, transform-origin « 50% 100% » (réglé plus haut) =
   le bas du hangar reste fixe. animation-delay décale chaque hangar de 0,15 s.
   Seulement si l'utilisateur n'a pas demandé à réduire les animations. */
@keyframes hangar-rise { from { transform: scaleY(.0001); } to { transform: none; } }
@media (prefers-reduced-motion: no-preference) {
  .hangars.reveal { opacity: 1; transform: none; }
  .hangars.reveal:not(.is-visible) .hangar { transform: scaleY(.0001); }
  .hangars.is-visible .hangar { animation: hangar-rise .8s cubic-bezier(.2,.7,.2,1) both; }
  .hangars.is-visible .hangar--2 { animation-delay: .15s; }
  .hangars.is-visible .hangar--3 { animation-delay: .3s; }
  .hangars.is-visible .hangar--4 { animation-delay: .45s; }
}

/* ---------- 14. Schéma de l'écosystème locatif et photos ----------
   Pages : La foncière (pages/location.php).
   14.1 Le schéma est un dessin SVG écrit directement dans le gabarit
   (viewBox 800 × 670). Les tailles en px ci-dessous sont des unités de ce
   dessin, pas des pixels d'écran : elles rapetissent avec lui. C'est pourquoi
   elles sont agrandies sous 640px, sinon le texte deviendrait illisible.
   Les flèches (.eco-arc) se « dessinent » à l'apparition : le trait est
   traité comme un tiret de 400 unités (plus long que chaque arc) ; décaler
   ce tiret de 400 (stroke-dashoffset) le cache, revenir à 0 le révèle.
   Les 4 arcs démarrent l'un après l'autre (animation-delay). */
.eco { margin: 0 auto; max-width: 760px; text-align: center; }
.eco__svg { width: 100%; height: auto; display: block; overflow: visible; font-family: var(--font); }
.eco-surface { font-size: 30px; font-weight: 700; }
.eco-bail { font-size: 19px; font-weight: 400; }
.eco-kicker { font-size: 15px; font-weight: 700; letter-spacing: .12em; fill: var(--gold); }
.eco-center { font-size: 34px; font-weight: 600; fill: var(--navy); }
.eco-arc { fill: none; stroke: var(--gold); stroke-width: 3; stroke-linecap: round; }
.eco-node { transition: transform .4s cubic-bezier(.2,.7,.2,1); cursor: default; } /* chaque bulle grossit au survol autour de son centre (transform-origin écrit dans le SVG) */
@media (hover: hover) { .eco-node:hover { transform: scale(1.07); } }
.eco__legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 16px; margin-top: 1.2rem; font-size: .9rem; color: var(--slate-text); }
.eco-chip { display: inline-flex; gap: .5em; align-items: baseline; padding: 8px 16px; border-radius: 999px; background: var(--ice); }
.eco-chip strong { color: var(--navy); }
.eco-chip--369 { background: var(--gold-pale); }
.eco__note { flex-basis: 100%; font-style: italic; font-size: .85rem; }
@media (prefers-reduced-motion: no-preference) {
  .eco-arc { stroke-dasharray: 400; stroke-dashoffset: 0; }
  .reveal:not(.is-visible) .eco-arc { stroke-dashoffset: 400; }
  .is-visible .eco-arc { animation: eco-draw 1s ease .3s both; }
  .is-visible .eco-arc--2 { animation-delay: .55s; }
  .is-visible .eco-arc--3 { animation-delay: .8s; }
  .is-visible .eco-arc--4 { animation-delay: 1.05s; }
}
@keyframes eco-draw { from { stroke-dashoffset: 400; } to { stroke-dashoffset: 0; } }
@media (max-width: 640px) { .eco-surface { font-size: 36px; } .eco-bail { font-size: 21px; } .eco-kicker { font-size: 17px; } }

/* 14.2 Deux photos côte à côte sous le schéma (une seule colonne sous 640px). */
.foncier-photos { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; margin-top: clamp(48px, 6vw, 80px); }
.foncier-photos figure { margin: 0; }
.foncier-photos img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.foncier-photos figcaption { font-size: .8rem; font-style: italic; margin-top: 8px; }
@media (max-width: 640px) { .foncier-photos { grid-template-columns: 1fr; } }

/* ---------- 15. Avant / après IGN 1950-2024 « Promoteur issu de la terre » ----------
   Pages : accueil. Fonctionne avec le JavaScript (bloc 4 de main.js).
   Deux photos aériennes superposées : 1950 dessous (.terre__img--avant),
   2024 dessus (.terre__img--apres). La variable --mix (de 0 à 1), modifiée
   par le curseur, règle l'opacité de la photo 2024 et des étiquettes
   « 1950 » / « 2024 ». Sans JavaScript, var(--mix, 1) vaut 1 : on voit 2024.
   aspect-ratio 1045 / 1279 = proportions exactes des photos ; le tracé SVG
   de la route de Meaux (même viewBox) se superpose ainsi au bon endroit.
   Animation à l'apparition : .is-anim cache la route et son étiquette ;
   .is-drawing dessine la route (le tracé a pathLength="1", d'où un tiret de
   longueur 1) puis fait apparaître l'étiquette après 1,2 s. */
.terre { margin: 0; }
.terre__stack { position: relative; border-radius: var(--radius); overflow: hidden; aspect-ratio: 1045 / 1279; background: var(--ice); }
.terre__repere { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.terre__route, .terre__route-halo { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.terre__route-halo { stroke: rgba(255,255,255,.85); stroke-width: 13; filter: drop-shadow(0 1px 3px rgba(19,24,46,.55)); }
.terre__route { stroke: var(--gold); stroke-width: 7; stroke-dasharray: 1; stroke-dashoffset: 0; }
.terre.is-anim .terre__route { stroke-dashoffset: 1; }
.terre.is-anim .terre__label { opacity: 0; transition: opacity .5s 1.2s; }
.terre.is-drawing .terre__label { opacity: 1; }
.terre.is-drawing .terre__route { animation: terre-draw 1.4s ease-out both; }
@keyframes terre-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
/* Étiquette « Route de Meaux » : left / top en % de la photo désignent un point
   de la route ; translate(-50%, -100%) pose la pointe de l'étiquette sur ce
   point, rotate(-8deg) suit l'inclinaison de la route. À ajuster si la photo change. */
.terre__label { position: absolute; left: 47%; top: 40.5%; transform: translate(-50%, -100%) rotate(-8deg); padding: 5px 10px; border-radius: 999px; background: var(--navy); color: var(--white); font-size: .68rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; box-shadow: 0 2px 8px rgba(19,24,46,.35); pointer-events: none; }
.terre__label::after { content: ""; position: absolute; left: 50%; top: 100%; width: 2px; height: 10px; margin-left: -1px; background: var(--navy); } /* petite tige sous l'étiquette, qui pointe vers la route */
.terre__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.terre__img--apres { opacity: var(--mix, 1); }
.terre__tag { position: absolute; top: 14px; padding: 6px 12px; border-radius: 999px; font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; transition: opacity .2s; }
.terre__tag--avant { left: 14px; background: var(--white); color: var(--navy); opacity: calc(1 - var(--mix, 1)); }
.terre__tag--apres { right: 14px; background: var(--navy); color: var(--white); opacity: var(--mix, 1); }
.terre__control { display: flex; align-items: center; gap: 12px; margin-top: 14px; font-size: .75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--slate); }
.terre__control input { flex: 1; accent-color: var(--gold); min-width: 0; } /* accent-color : couleur or du curseur ; min-width: 0 l'empêche de déborder sur petit écran */
.terre figcaption { margin-top: 10px; font-size: .82rem; font-style: italic; }
.terre__src { display: block; font-style: normal; font-size: .72rem; margin-top: 4px; }


/* ---------- 16. Fondateurs ----------
   Pages : Le développement (pages/qui-sommes-nous.php).
   Deux fondateurs côte à côte ; pour chacun, photo de 200px + texte.
   Empilés sous 960px ; photo au-dessus du texte sous 640px. */
.founders { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; margin-bottom: 3rem; }
.founder { display: grid; grid-template-columns: 200px 1fr; gap: 28px; align-items: start; }
.founder__photo { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--radius); }
.founder__name { font-size: 1.4rem; font-weight: 600; color: var(--navy); }
.founder__name span { display: block; font-size: .8rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--gold-text); margin-top: .4rem; }


/* ---------- 17. Liste des programmes ----------
   Pages : Les réalisations (pages/programmes.php) ; .badge sert aussi dans le
   héros des pages programme.
   Une ligne par programme (.prog-row) : photo + texte. Une ligne sur deux
   (nth-child(even) = rangs pairs), la photo passe à droite (order: 2), d'où
   l'alternance. Sous 960px, la photo est toujours au-dessus.
   .badge : pastille de statut ; sa variante vient du 'status' du programme
   dans data/programmes.php : badge--lancement (or, style de base),
   badge--livre (ardoise), badge--en-cours (or clair). */
.prog-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 40px; }
.prog-row { display: grid; grid-template-columns: 1.3fr 1fr; background: var(--white); border-radius: var(--radius); overflow: hidden; }
.prog-row:nth-child(even) .prog-row__media { order: 2; }
.prog-row__img { width: 100%; height: 100%; min-height: 340px; object-fit: cover; transition: transform .6s; } /* la photo remplit toute la hauteur de la ligne, 340px au minimum */
.prog-row__media { overflow: hidden; display: block; }
.prog-row:hover .prog-row__img { transform: scale(1.03); }
.prog-row__body { padding: clamp(28px, 4vw, 56px); display: flex; flex-direction: column; align-items: flex-start; justify-content: center; }
.prog-row__title { font-size: clamp(2rem, 3.6vw, 3rem); line-height: 1.02; font-weight: 400; margin: 1.2rem 0 1rem; }
.prog-row__title a { color: var(--slate); text-decoration: none; }
.prog-row__title a:hover { color: var(--gold); }
.prog-row__city { font-size: .8rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--navy); margin-bottom: .5rem; }
.prog-row__text { font-size: .92rem; }
.badge { display: inline-block; padding: 7px 14px; border-radius: 999px; font-size: .66rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; background: var(--gold-text); color: var(--white); }
.badge--livre { background: var(--slate); }
.badge--en-cours { background: var(--gold-light); color: var(--navy); }

/* ---------- 18. Fiche programme : éléments communs ----------
   Pages : page programme (pages/programme.php). Quelques éléments servent
   ailleurs : .check-list et .plus-box dans des articles du guide, .gallery
   sur la page lot.
   .stats-band : bandeau bleu nuit de 4 chiffres sous le héros (un sur deux
   en blanc, les autres en or clair).
   .prog-detail : texte + colonne latérale. .check-list : liste à puces or.
   .partners : intervenants sur fond bleu nuit.
   .steps : étapes numérotées 01, 02, 03 (sur fond bleu nuit).
   .gallery : grille de photos (complétée en section 31).
   .access-list : temps d'accès. .prog-nav : liens vers le programme
   précédent / suivant, en bas de page. */
.stats-band { background: var(--navy); padding: 36px 0; }
.stats-band__grid { list-style: none; margin: 0 auto; display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; text-align: center; }
.stats-band__num { display: block; font-family: var(--font-num); font-weight: 600; font-size: clamp(1.8rem, 3vw, 2.6rem); line-height: 1.1; color: var(--gold-light); text-transform: uppercase; }
.stats-band li:nth-child(even) .stats-band__num { color: var(--white); }
.stats-band__label { display: block; font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; color: rgba(255,255,255,.75); margin-top: 6px; }
.prog-detail { display: grid; grid-template-columns: 1.4fr 1fr; gap: clamp(32px, 6vw, 96px); }
.plus-box { background: var(--gold-pale); border-radius: var(--radius); padding: 24px 28px; margin-top: 2rem; font-style: italic; color: var(--slate); }
.plus-box p { margin: 0; }
.check-list { list-style: none; margin: 0; padding: 0; }
.check-list li { position: relative; padding: 8px 0 8px 22px; font-weight: 600; color: var(--navy); border-bottom: 1px solid var(--line); }
.check-list li::before { content: ""; position: absolute; left: 0; top: 18px; width: 8px; height: 8px; border-radius: 50%; background: var(--gold); } /* top 18px : puce alignée sur la première ligne du texte */
.partners { list-style: none; margin: 0; padding: 24px; background: var(--navy); border-radius: var(--radius); display: grid; gap: 10px; }
.partners li { color: var(--white); font-size: .85rem; letter-spacing: .04em; text-transform: uppercase; padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,.12); }
.partners li:last-child { border-bottom: 0; }
.wide-image img { width: 100%; max-height: 640px; object-fit: cover; }
.steps { list-style: none; margin: 3rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
.steps li { border-top: 1px solid rgba(255,255,255,.25); padding-top: 24px; }
.steps__num { font-family: var(--font-num); font-size: 3rem; color: var(--gold-light); display: block; line-height: 1; margin-bottom: 1rem; }
.steps p { font-size: .9rem; }
.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.access-list { list-style: none; margin: 0; padding: 0; }
.access-list li { display: flex; justify-content: space-between; gap: 24px; align-items: center; padding: 18px 0; border-bottom: 1px solid var(--line); }
.access-list strong { display: block; color: var(--navy); }
.access-list li span:first-child { font-size: .88rem; }
.access-list__time { font-family: var(--font-num); font-size: 1.6rem; color: var(--gold); white-space: nowrap; }
.prog-nav { display: flex; justify-content: space-between; gap: 16px; padding-top: 24px; padding-bottom: 48px; font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.prog-nav a { text-decoration: none; color: var(--slate); }

/* ---------- 19. Bandeau d'appel à l'action (« Prendre contact ») ----------
   Pages : bas de presque toutes les pages. HTML produit par la fonction
   cta_band() de inc/functions.php ; fond or clair, fin du titre en blanc. */
.cta-band { background: var(--gold-light); padding: clamp(56px, 7vw, 88px) 0; }
.cta-band__inner { display: flex; align-items: center; justify-content: space-between; gap: 32px; flex-wrap: wrap; }
.cta-band__title { font-size: clamp(1.5rem, 2.6vw, 2.1rem); color: var(--slate); margin: 0; max-width: 28ch; }
.cta-band__title strong { color: var(--navy); font-weight: 600; } /* bleu nuit sur or clair (9,1:1) ; le blanc était illisible (1,9:1) */
.cta-band__actions { display: flex; flex-wrap: wrap; gap: 16px; }
.cta-band .btn--outline-light { color: var(--navy); border-color: var(--navy); } /* sur l'or clair du bandeau, bouton au contour bleu nuit (le blanc était illisible) */
.cta-band .btn--outline-light:hover { background: var(--navy); color: var(--white); }

/* ---------- 20. Offres locatives, contact, textes légaux ----------
   20.1 Offres : La foncière (pages/location.php). Une carte par offre de
   data/offres.php ; .empty-state = message « aucune disponibilité » quand
   la liste est vide. */
.offres { list-style: none; margin: 2.5rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.offre-card { background: var(--white); border-radius: var(--radius); overflow: hidden; }
.offre-card__img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.offre-card__body { padding: 24px; }
.offre-card__type { font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--gold-text); margin-bottom: .3rem; }
.offre-card__meta { font-size: .85rem; }
.offre-card__facts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 1rem 0; font-size: .85rem; }
.offre-card__facts dt { font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; }
.offre-card__facts dd { margin: 0; font-weight: 600; color: var(--navy); }
.empty-state { margin-top: 2.5rem; background: var(--white); border-radius: var(--radius); padding: 40px; max-width: 760px; }

/* 20.2 Contact (pages/contact.php) : coordonnées à gauche, formulaire à droite. */
.contact-grid { display: grid; grid-template-columns: 1fr 1.2fr; gap: clamp(32px, 6vw, 80px); align-items: start; }
.contact-list { list-style: none; margin: 2rem 0 0; padding: 0; }
.contact-list li { padding: 16px 0; border-bottom: 1px solid var(--line); font-size: .92rem; }
.contact-list strong { display: block; font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--gold-text); }
.contact-form-wrap { background: var(--white); border-radius: var(--radius); padding: clamp(24px, 4vw, 44px); }
.contact-form { display: grid; gap: 18px; }
.contact-form label { display: grid; gap: 6px; font-size: .8rem; font-weight: 600; color: var(--navy); }
.contact-form input, .contact-form select, .contact-form textarea { width: 100%; font: inherit; font-size: 1rem; font-weight: 400; color: var(--navy); padding: 12px 14px; border: 1px solid var(--line); border-radius: 4px; background: var(--white); }
/* Champ en cours de saisie : bordure or et halo or transparent à la place du contour par défaut. */
.contact-form input:focus, .contact-form select:focus, .contact-form textarea:focus { border-color: var(--gold); outline: none; box-shadow: 0 0 0 3px rgba(152,142,27,.18); }
.contact-form .check { grid-template-columns: auto 1fr; align-items: start; font-weight: 400; } /* case à cocher du consentement : case à gauche, texte à droite */
.contact-form .check input { width: auto; margin-top: 4px; }
.contact-form button { justify-self: start; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.hp { position: absolute; left: -9999px; } /* champ piège anti-robot, placé hors de l'écran : un humain le laisse vide, un robot le remplit et son envoi est refusé (inc/contact-handler.php) */
.form-errors { background: #FBEDEA; color: #8A2B1A; border-radius: 4px; padding: 16px 20px; font-size: .9rem; } /* fond rose pâle, texte rouge brique : erreurs du formulaire */
.form-errors ul { margin: 0; padding-left: 1.2rem; }
.form-success { padding: 12px 0; }

/* 20.3 .prose : intertitres des textes longs (mentions légales, confidentialité).
   .img-missing : rayures affichées par la fonction img() de inc/functions.php
   quand une photo est introuvable (repère visuel : fichier à ajouter). */
.prose h2 { font-size: .9rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--navy); margin-top: 2.2rem; }
.img-missing { background: repeating-linear-gradient(45deg, var(--ice), var(--ice) 10px, #d5e1e4 10px, #d5e1e4 20px); aspect-ratio: 4 / 3; border-radius: var(--radius); }

/* ---------- 21. Pied de page ----------
   Pages : toutes (inc/footer.php). 4 colonnes : présentation (plus large)
   puis 3 listes de liens ; 2 colonnes sous 960px, 1 sous 640px. */
.site-footer { background: var(--navy); color: rgba(255,255,255,.7); font-size: .85rem; padding: 72px 0 28px; }
.site-footer__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 40px; }
.site-footer__brand img { height: 54px; width: auto; margin-bottom: 20px; }
.site-footer__brand p { max-width: 32ch; }
.site-footer__title { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--white); margin-bottom: 1.2rem; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.site-footer a { color: rgba(255,255,255,.7); text-decoration: none; }
.site-footer a:hover { color: var(--gold-light); }
.site-footer__bottom { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-top: 56px; padding-top: 24px; border-top: 1px solid rgba(255,255,255,.15); font-size: .78rem; }
.site-footer__bottom p { margin: 0; }

/* ---------- 22. Apparitions au défilement ----------
   Pages : toutes. Le JavaScript (bloc 3 de main.js) ajoute .reveal aux blocs
   de contenu : ils sont d'abord invisibles et 18px plus bas, puis
   .is-visible les fait apparaître en 0,7 s quand ils arrivent à l'écran.
   Sans JavaScript, ou si l'utilisateur a demandé à réduire les animations,
   .reveal n'est jamais ajoutée : tout reste visible. */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .7s ease, transform .7s ease; }
.reveal.is-visible { opacity: 1; transform: none; }

/* ---------- 23. Adaptation aux écrans (responsive) et réduction des animations ----------
   Pages : toutes. Règles qui ne s'appliquent que sous une certaine largeur
   d'écran (d'autres sections ont aussi les leurs).
   Les !important l'emportent sur des règles plus précises écrites plus haut
   (placements de la mosaïque, tailles des hangars). */
/* Jusqu'à 1100px (petit portable, tablette à l'horizontale) : menu resserré, cartes des pôles sur 2 colonnes. */
@media (max-width: 1100px) {
  .site-nav { gap: 24px; }
  .site-nav ul { gap: 16px; }
  .cards-4 { grid-template-columns: 1fr 1fr; }
}
/* Jusqu'à 960px (tablette et téléphone) :
   - en-tête moins haut (76px) et menu « burger » ;
   - le menu devient un panneau plein écran bleu nuit, invisible (opacity 0 +
     visibility hidden, donc aussi inaccessible au clavier) tant que <body>
     n'a pas la classe .nav-open, posée par le JavaScript ;
   - les trois barres du burger forment une croix : la 1re et la 3e se
     rejoignent au centre (7px = 5px d'écart + 2px d'épaisseur) et pivotent
     de 45°, celle du milieu disparaît ;
   - les mises en page à plusieurs colonnes passent sur une colonne (deux
     pour les cartes, offres et galeries). */
@media (max-width: 960px) {
  :root { --header-h: 76px; }
  .site-header__logo img { height: 38px; }
  .nav-toggle { display: block; position: relative; z-index: 2; } /* z-index 2 : le bouton reste au-dessus du panneau ouvert, pour pouvoir le refermer */
  .site-nav { position: fixed; inset: 0; background: var(--navy); flex-direction: column; justify-content: center; gap: 40px; opacity: 0; visibility: hidden; transition: opacity .25s, visibility .25s; }
  .site-nav ul { flex-direction: column; align-items: center; gap: 22px; }
  .site-nav ul a { font-size: 1.05rem; }
  .nav-open .site-nav { opacity: 1; visibility: visible; }
  .nav-open { overflow: hidden; } /* la page ne défile plus derrière le menu ouvert */
  .nav-open .nav-toggle__bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-open .nav-toggle__bar:nth-child(2) { opacity: 0; }
  .nav-open .nav-toggle__bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .hero__grid, .split, .cols-2, .prog-detail, .contact-grid, .founders { grid-template-columns: 1fr; }
  .hero__visual { display: none; } /* photo du héros d'accueil masquée sur tablette et téléphone */
  .split--reverse .split__media { order: 0; }
  .cards-3, .offres, .gallery { grid-template-columns: 1fr 1fr; }
  .prog-row { grid-template-columns: 1fr; }
  .prog-row:nth-child(even) .prog-row__media { order: 0; }
  .prog-row__img { min-height: 240px; aspect-ratio: 16 / 9; }
  .stats-band__grid { grid-template-columns: 1fr 1fr; row-gap: 32px; }
  .steps { grid-template-columns: 1fr; }
  .site-footer__grid { grid-template-columns: 1fr 1fr; }
  .stats-mosaic__grid { grid-template-columns: 1fr 1fr; grid-template-rows: none; }
  .stat-tile { grid-column: auto !important; grid-row: auto !important; min-height: 180px; padding-bottom: 24px !important; justify-content: center !important; } /* !important : annule les placements .stat-tile--1 à --7 (section 10) */
  .stat-tile--3 { grid-column: 1 / -1 !important; }
  .hero__prog { flex-direction: column; align-items: flex-start; }
  .hero__address { text-align: left; }
}
/* Jusqu'à 640px (téléphone) :
   - hangars : le dessin superposé devient une pile de bandes de largeur
     croissante (55 %, 70 %, 85 %, 100 %) ;
   - tout passe sur une colonne ; boutons sur toute la largeur. */
@media (max-width: 640px) {
  .hangars-head { position: static; width: auto; margin-bottom: 2rem; }
  .hangars { aspect-ratio: auto; display: grid; gap: 10px; padding-bottom: 0; }
  .hangar { position: relative; left: auto !important; bottom: auto; height: auto !important; min-height: 120px; --roof: 26px !important; padding-bottom: 16px; }
  .hangar__label, .hangar--1 .hangar__label { padding-top: 40px; padding-left: 6% !important; }
  .hangar--1 { width: 55% !important; } .hangar--2 { width: 70% !important; } .hangar--3 { width: 85% !important; } .hangar--4 { width: 100% !important; }
  .hangar h3, .hangar__size { font-size: .9rem; max-width: none; }
  .hangar__desc { font-size: .82rem; }
  .cards-3, .cards-4, .offres, .gallery, .form-row, .site-footer__grid { grid-template-columns: 1fr; }
  .founder { grid-template-columns: 1fr; }
  .founder__photo { max-width: 260px; }
  .hero--home { min-height: auto; padding-top: calc(var(--header-h) + 56px); }
  .btn { width: 100%; }
  .btn-row { flex-direction: column; }
  .cta-band__actions { width: 100%; }
  .prog-nav { flex-direction: column; text-align: center; }
  .access-list__time { font-size: 1.3rem; }
}
/* Réglage système « réduire les animations » (personnes sensibles au
   mouvement) : coupe toutes les transitions, animations et le défilement animé. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- 24. Partenaires (logos) et encart BREEAM ----------
   Pages : page programme (section « Le projet », id="projet" ; encart BREEAM
   si la clé 'breeam' est remplie dans data/programmes.php).
   Logos sur 2 colonnes ; s'ils sont en nombre impair, le dernier prend toute
   la largeur (li:last-child:nth-child(odd)). */
.partners-logos { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.partners-logos li { background: var(--white); border-radius: var(--radius); padding: 18px 14px 12px; display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 10px; min-height: 120px; box-shadow: 0 1px 0 rgba(19,24,46,.06); transition: transform .3s, box-shadow .3s; }
.partners-logos li:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(19,24,46,.10); }
.partners-logos img { height: 62px; max-width: 100%; width: auto; object-fit: contain; flex: 1 1 auto; align-self: center; margin: auto 0; } /* object-fit: contain : logo entier, sans déformation */
.partners-logos span { font-size: .66rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--slate); text-align: center; }
.partners-logos li:last-child:nth-child(odd) { grid-column: 1 / -1; }
.breeam { display: grid; grid-template-columns: minmax(180px, 300px) 1fr; gap: 56px; align-items: center; background: var(--ice); border-left: 4px solid var(--gold); border-radius: var(--radius); padding: 48px; } /* logo carré à gauche (180 à 300px), texte à droite, filet or à gauche */
.breeam__logo { background: var(--white); border-radius: var(--radius); padding: 28px; display: flex; align-items: center; justify-content: center; aspect-ratio: 1; }
.breeam__logo img { width: 100%; height: auto; }
.breeam__list { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px 24px; }
.breeam__list li { position: relative; padding: 6px 0 6px 22px; font-size: .9rem; font-weight: 600; color: var(--navy); }
.breeam__list li::before { content: ""; position: absolute; left: 0; top: 14px; width: 10px; height: 2px; background: var(--gold); }
@media (max-width: 800px) { /* jusqu'à 800px : logo au-dessus du texte */
  .breeam { grid-template-columns: 1fr; gap: 28px; padding: 28px 22px; }
  .breeam__logo { max-width: 200px; }
  .breeam__list { grid-template-columns: 1fr; }
}

/* ---------- 25. Pictos des étapes solaires (brochure Horizon 50) ----------
   Pages : page programme d'Horizon 50 (bloc des étapes, section 18 .steps).
   Les pictos SVG sont produits par step_icons() dans inc/functions.php :
   3 pictos par étape. .is-on = équipement déjà installé (plein, blanc),
   .is-off = équipement à venir (pointillés). Formes : .b = panneau, socle ou
   borne ; .k = lignes des cellules ou éclair ; .c = câble de la borne.
   --irve : variante « borne de recharge ».
   Au survol d'une étape, les pictos à venir sautillent (step-pop). */
.steps__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 1rem; }
.steps__head .steps__num { margin-bottom: 0; }
.step-icons { display: flex; align-items: flex-end; gap: 6px; }
.step-icons svg { height: 40px; width: auto; overflow: visible; }
.step-icons--irve svg { height: 44px; }
.step-icons .b, .step-icons .c, .step-icons .k { stroke-linejoin: round; stroke-linecap: round; }
.step-icons .is-on .b { fill: var(--white); stroke: var(--white); stroke-width: 1.5; }
.step-icons .is-on .k { fill: none; stroke: var(--navy); stroke-width: 2; }
.step-icons--irve .is-on .k { fill: var(--navy); stroke: none; }
.step-icons .is-on .c { fill: none; stroke: var(--white); stroke-width: 3; }
.step-icons .is-off .b, .step-icons .is-off .c, .step-icons .is-off .k { fill: none; stroke: rgba(255,255,255,.55); stroke-width: 1.2; stroke-dasharray: 1.5 2.5; }
.steps li:hover .step-icons .is-off { animation: step-pop .6s ease both; }
.steps li:hover .step-icons .is-off:nth-child(3) { animation-delay: .12s; }
@keyframes step-pop { 50% { transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .steps li:hover .step-icons .is-off { animation: none; } }

/* ---------- 26. ADN Villas d'entreprise : plans schématiques ----------
   Pages : page programme des Villas d'entreprise (3 petits plans côte à côte).
   Les plans SVG sont produits par villa_plan() dans inc/functions.php.
   .vp-… = couleurs des zones : --on (zone mise en avant, bleu nuit), --mute,
   --soft, --grey (zones secondaires), .vp-lines (hachures), .vp-dash
   (pointillés blancs qui défilent au survol : -32 = 2 × (9 + 7), deux motifs
   tiret + espace, pour une boucle sans à-coup). */
.villa-plans { margin-top: 3.5rem; padding-bottom: 4rem; }
.villa-plans__lead { font-size: 1.05rem; font-weight: 600; color: var(--navy); margin-bottom: 2rem; }
.villa-plans__lead u { text-underline-offset: 4px; }
.villa-plans__grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }
.villa-plan { width: 100%; height: auto; display: block; filter: drop-shadow(0 6px 10px rgba(19,24,46,.12)); transition: transform .35s ease; }
.villa-plans__item:hover .villa-plan { transform: translateY(-4px) scale(1.02); }
.villa-plans__item p { font-size: .9rem; margin-top: 1.2rem; color: var(--slate); }
.villa-plans__item strong { color: var(--navy); }
.vp-on { fill: var(--navy); }
.vp-mute { fill: #C4C1A6; }
.vp-soft { fill: #CFCDBD; }
.vp-grey { fill: #9A9A9C; }
.vp-lines { fill: none; stroke-width: 1.5; }
.vp-lines--on-grey { stroke: var(--navy); }
.vp-lines--on-soft { stroke: #9AA0A8; }
.vp-lines--on-navy { stroke: #6C7390; }
.vp-sep { stroke: var(--navy); stroke-width: 2; }
.vp-dash { fill: none; stroke: var(--white); stroke-width: 4; stroke-dasharray: 9 7; }
.villa-plans__item:hover .vp-dash { animation: vp-march 1s linear infinite; }
@keyframes vp-march { to { stroke-dashoffset: -32; } }
.vp-dot { fill: var(--gold); }
.vp-num { fill: var(--white); font: 700 24px var(--font); text-anchor: middle; }
.vp-lbl { fill: var(--white); font: 700 30px var(--font); letter-spacing: .02em; text-anchor: middle; }
@media (max-width: 800px) {
  .villa-plans__grid { grid-template-columns: 1fr; gap: 32px; }
  .villa-plan { max-width: 420px; }
}
@media (prefers-reduced-motion: reduce) { .villa-plans__item:hover .vp-dash { animation: none; } .villa-plans__item:hover .villa-plan { transform: none; } }
.vp-lbl--start { text-anchor: start; }

/* =========================================================
   27. Fiche programme — blocs issus de la brochure Horizon 50
   Pages : page programme ; chaque bloc n'apparaît que si sa clé est remplie
   dans data/programmes.php ('site', 'coup_oeil', 'decret', 'parc', 'lots'
   ou 'parc_lots').
   .ico : pictos d'accès produits par access_icon() (inc/functions.php).
   ========================================================= */
.ico { width: 30px; height: 30px; flex: none; }

/* 27.1 Le Val d'Europe, site stratégique : liste d'atouts + carte. */
.site-strat { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 56px; align-items: center; }
.site-strat__list { list-style: none; margin: 2rem 0 0; padding: 0; display: grid; gap: 4px; }
.site-strat__list li { display: flex; gap: 16px; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--line); color: var(--gold); }
.site-strat__list span { font-size: .88rem; color: var(--slate); }
.site-strat__list strong { display: block; color: var(--navy); font-size: .95rem; }
.site-strat__map { margin: 0; background: var(--white); border-radius: var(--radius); padding: 20px; box-shadow: 0 10px 30px rgba(19,24,46,.08); }
.site-strat__map img { width: 100%; height: auto; display: block; }

/* 27.2 Coup d'œil + plan de masse interactif.
   .lot-plan : le plan (image ou dessin SVG). Sur une image, chaque bâtiment
   est une pastille ronde (.lot-plan__spot) placée par left / top en %
   (valeurs de 'lots_plan' dans data/programmes.php) ;
   translate(-50%, -50%) centre la pastille sur ce point.
   .is-hl : surbrillance posée par le JavaScript quand on survole la ligne
   correspondante de la grille des lots (et inversement).
   --off : bâtiment non disponible (voile clair) ; --loc : lot à louer (section 33). */
.coup-oeil { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 6fr); gap: 56px; align-items: center; }
.coup-oeil__quote { margin: 1.5rem 0 2rem; padding: 0; font-style: italic; font-size: 1.15rem; color: var(--slate); }
.coup-oeil__quote p { margin: 0; }
.coup-oeil__points { list-style: none; margin: 0; padding: 0; }
.coup-oeil__points a { display: block; padding: 16px 0 16px 26px; border-bottom: 1px solid var(--line); text-decoration: none; position: relative; transition: padding .25s; }
.coup-oeil__points a::before { content: ""; position: absolute; left: 0; top: 22px; width: 10px; height: 10px; background: var(--navy); }
.coup-oeil__points a:hover { padding-left: 34px; } /* au survol, le texte se décale légèrement vers la droite */
.coup-oeil__points strong { display: block; color: var(--navy); text-transform: uppercase; font-size: .85rem; letter-spacing: .04em; }
.coup-oeil__points span { font-size: .85rem; color: var(--slate); }
.coup-oeil__plan { margin: 0; }
.coup-oeil__plan figcaption { font-size: .78rem; color: var(--slate); margin-top: .8rem; font-style: italic; }
.lot-plan { position: relative; border-radius: var(--radius); overflow: hidden; box-shadow: 0 10px 30px rgba(19,24,46,.10); }
.lot-plan__img { width: 100%; height: auto; display: block; }
.lot-plan__spot { position: absolute; width: 8.2%; aspect-ratio: 1; transform: translate(-50%, -50%); border-radius: 50%; border: 3px solid transparent; transition: border-color .2s, transform .2s, box-shadow .2s; }
a.lot-plan__spot:hover, a.lot-plan__spot:focus-visible, .lot-plan__spot.is-hl { border-color: var(--gold); transform: translate(-50%, -50%) scale(1.18); box-shadow: 0 0 0 6px rgba(152,142,27,.25); outline: none; }
.lot-plan__spot--off { background: rgba(228,238,240,.55); cursor: not-allowed; }

/* 27.3 Décret tertiaire : frise de 3 flèches (2030, 2040, 2050).
   Chaque étape est découpée en chevron par clip-path (pointe à droite,
   encoche à gauche, 22px) ; margin-right: -14px les emboîte. La première n'a
   pas d'encoche. .is-reached = objectif atteint (la dernière étape, en or). */
.decret { margin-top: 2.5rem; }
.decret__label { font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--gold-light); margin-bottom: .8rem; }
.decret__steps { list-style: none; margin: 0; padding: 0; display: flex; max-width: 640px; }
.decret__step { flex: 1; position: relative; padding: 14px 10px 14px 34px; background: #E7E6DE; color: var(--navy); clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 50%, calc(100% - 22px) 100%, 0 100%, 22px 50%); margin-right: -14px; text-align: center; }
.decret__step:first-child { clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 50%, calc(100% - 22px) 100%, 0 100%); padding-left: 14px; border-radius: 6px 0 0 6px; }
.decret__step:nth-child(2) { background: var(--gold-pale); }
.decret__step.is-reached { background: var(--gold-text); color: var(--white); }
.decret__step span { display: block; font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; }
.decret__step strong { font-family: var(--font-num); font-size: 1.9rem; font-weight: 400; line-height: 1.1; }
.decret__note { margin-top: 1rem; font-weight: 600; color: var(--white); }
.decret__note::before { content: "✓"; display: inline-grid; place-items: center; width: 22px; height: 22px; margin-right: 10px; border-radius: 50%; background: var(--white); color: var(--gold); font-size: .8rem; } /* coche dans une pastille blanche, devant la note */

/* 27.4 Un parc autonome et labellisé : liste à pictos (case blanche de 96px + texte sur fond ardoise) et photo. */
.parc { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 56px; align-items: center; }
.parc__list { list-style: none; margin: 2rem 0 0; padding: 0; border-radius: var(--radius); overflow: hidden; }
.parc__list li { display: grid; grid-template-columns: 96px 1fr; align-items: center; background: var(--slate); color: var(--white); border-bottom: 1px solid rgba(255,255,255,.18); }
.parc__list li:last-child { border-bottom: 0; }
.parc__icon { display: grid; place-items: center; align-self: stretch; background: var(--white); color: var(--navy); padding: 14px; border-right: 1px solid var(--line); }
.parc__icon .ico { width: 40px; height: 40px; }
.parc__icon img { width: 58px; height: auto; }
.parc__list p { margin: 0; padding: 20px 24px; font-size: .9rem; }
.parc__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }


/* 27.5 Grille des lots (tableau des surfaces).
   Titre et bouton à gauche (.lots__head) restent visibles pendant qu'on fait
   défiler le tableau (position: sticky ; top 110px = sous l'en-tête fixe).
   scroll-margin-top: 120px : quand on clique sur un lot du plan (#lot-A), la
   ligne s'arrête sous l'en-tête au lieu de passer dessous.
   :target = ligne visée par l'adresse (#lot-A) : surlignée. */
.lots { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 7fr); gap: 56px; align-items: start; }
.lots__head { position: sticky; top: 110px; }
.lots__head .btn { margin-top: 1rem; }
.lots__table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.lots__table thead th { background: var(--gold-text); color: var(--white); font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 14px 10px; text-align: right; }
.lots__table thead th:first-child { text-align: left; border-radius: var(--radius) 0 0 0; }
.lots__table thead th:last-child { border-radius: 0 var(--radius) 0 0; }
.lots__table tbody th, .lots__table td { padding: 12px 10px; text-align: right; border-bottom: 1px solid var(--line); }
.lots__table tbody th { text-align: left; font-family: var(--font-num); font-size: 1.25rem; font-weight: 400; color: var(--navy); }
.lots__table tbody tr { transition: background .2s; scroll-margin-top: 120px; }
.lots__table tbody tr:nth-child(even) { background: #F6F7F2; }
.lots__table tbody tr:hover, .lots__table tbody tr.is-hl, .lots__table tbody tr:target { background: var(--gold-pale); }
.lots__table td strong { color: var(--navy); }
.lots__cta a { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--gold-text); text-decoration: none; white-space: nowrap; }
.lots__cta a:hover { color: var(--navy); }
.lots__note { font-size: .75rem; font-style: italic; color: var(--slate); margin-top: .8rem; }

/* Jusqu'à 900px : blocs 27.1 à 27.5 sur une colonne ; le titre de la grille ne reste plus collé. */
@media (max-width: 900px) {
  .site-strat, .coup-oeil, .parc, .lots { grid-template-columns: 1fr; gap: 36px; }
  .lots__head { position: static; }
}
/* Jusqu'à 600px (téléphone) : le tableau ne tient plus en largeur. On masque
   sa ligne de titres et chaque ligne devient une petite fiche en grille ; le
   nom de chaque colonne est réaffiché au-dessus de la valeur grâce à
   l'attribut data-label des cellules (content: attr(data-label)). */
@media (max-width: 600px) {
  .decret__step { padding-left: 26px; }
  .decret__step strong { font-size: 1.4rem; }
  .lots__table thead { display: none; }
  .lots__table, .lots__table tbody, .lots__table tr { display: block; }
  .lots__table tr { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 16px; padding: 14px 12px; border-bottom: 1px solid var(--line); }
  .lots__table tbody th { grid-column: 1 / -1; border: 0; padding: 0 0 6px; }
  .lots__table td { border: 0; padding: 2px 0; text-align: left; font-size: .85rem; }
  .lots__table td::before { content: attr(data-label); display: block; font-size: .65rem; text-transform: uppercase; letter-spacing: .05em; color: var(--slate); }
  .lots__cta { grid-column: 1 / -1; padding-top: 8px !important; }
}
/* Ajustement : nom du lot en Inter gras plutôt qu'en police à chiffres (remplace la police de la règle « .lots__table tbody th » plus haut). */
.lots__table tbody th { font-family: var(--font); font-weight: 700; font-size: 1.05rem; }
/* Encart BREEAM (section 24) qui porte aussi .container : largeur limitée à celle du contenu. */
.container.breeam { width: calc(100% - 2 * var(--gutter)); max-width: var(--container); }
/* Complète la règle 600px ci-dessus : fiches sur 3 colonnes, lien du lot sur la même ligne que son nom. */
@media (max-width: 600px) {
  .lots__table tr { grid-template-columns: repeat(3, 1fr); gap: 4px 12px; padding: 12px 10px; }
  .lots__table tbody th { grid-column: 1 / 2; align-self: center; }
  .lots__table td.lots__cta { grid-column: 2 / -1; grid-row: 1; text-align: right; padding: 0 !important; align-self: center; }
}

/* ---------- 28. Bandeaux photo pleine largeur ----------
   Pages : page programme (après « Le projet » et avant la grille des lots).
   Photo légèrement agrandie (scale 1.06) qui revient à sa taille en 1,6 s
   quand le JavaScript (bloc 6) ajoute .is-in à l'apparition.
   ::after : triangle blanc dans un coin (en bas à droite ; en bas à gauche pour
   --avant_lots), qui fait la jonction avec la section suivante. */
.photo-band { margin: 0; position: relative; overflow: hidden; background: var(--navy); }
.photo-band__img { width: 100%; height: clamp(300px, 46vw, 720px); object-fit: cover; display: block; transform: scale(1.06); transition: transform 1.6s cubic-bezier(.2,.7,.2,1); }
.photo-band.is-in .photo-band__img { transform: scale(1); }
.photo-band::after { content: ""; position: absolute; right: 0; bottom: 0; width: clamp(60px, 9vw, 140px); aspect-ratio: 1; background: var(--white); clip-path: polygon(100% 0, 100% 100%, 0 100%); }
.photo-band--avant_lots::after { left: 0; right: auto; clip-path: polygon(0 0, 100% 100%, 0 100%); }
/* Grande image « solaire » d'Horizon 50 : même hauteur que les bandeaux, dégradé vers le bleu nuit en bas pour enchaîner avec la section suivante. */
.wide-image--solaire img { height: clamp(300px, 46vw, 720px); max-height: none; }
.wide-image--solaire { position: relative; }
.wide-image--solaire::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 30%; background: linear-gradient(to bottom, transparent, var(--navy)); pointer-events: none; }
#projet .partners-logos li { box-shadow: 0 0 0 1px var(--line); } /* contour fin des logos dans la section « Le projet » */
@media (prefers-reduced-motion: reduce) { .photo-band__img { transform: none; transition: none; } }
.partners-logos img[src*="val-europe-fields"] { height: 104px; } /* réglage propre à ce logo, repéré par son nom de fichier */

/* ---------- 29. Plan de masse stylisé (SVG) ----------
   Pages : page programme des Villas d'entreprise III, de l'Îlot route de
   Meaux et du Parc du Villenoy (dessins dans pages/partials/plan-….php).
   Chaque classe .lot-svg__… colore une famille de formes du dessin : routes,
   pelouses, parkings (__stalls), haies, toits, panneaux solaires (__pv)…
   Les tailles de texte sont des unités du dessin (voir 14.1).
   .lot-svg__bat : lien autour d'un bâtiment ; au survol, au clavier ou en
   surbrillance (.is-hl), son toit passe en or.
   transform-box: fill-box : la pastille (__dot) grossit autour de son propre
   centre, et non autour du coin du dessin. */
.lot-plan:has(.lot-svg) { background: #EEF2EA; } /* fond vert pâle quand le plan est un dessin SVG (« .lot-plan qui contient un .lot-svg ») */
.lot-svg { display: block; width: 100%; height: auto; font-family: var(--font); }
.lot-svg__road { fill: #D3D8DD; }
.lot-svg__grass { fill: #CFDDB8; }
.lot-svg__street { fill: var(--white); font-size: 30px; font-weight: 700; letter-spacing: .14em; }
.lot-svg__parcel { fill: #CFDDB8; }
.lot-svg__drive { fill: #E8ECEE; }
.lot-svg__stalls { stroke: #C3CBD2; stroke-width: 2; fill: none; }
.lot-svg__hedge { fill: none; stroke: #8FAA6A; stroke-width: 10; stroke-linejoin: round; }
.lot-svg__roof { fill: var(--navy); transition: fill .25s; }
.lot-svg__pv { fill: var(--slate); }
.lot-svg__pv-line { stroke: #6B7F99; stroke-width: 1.2; fill: none; }
.lot-svg__cell { stroke: rgba(255,255,255,.28); stroke-width: 2; }
.lot-svg__dot { fill: var(--gold); transition: transform .25s; transform-box: fill-box; transform-origin: center; }
.lot-svg__num { fill: var(--white); font-size: 28px; font-weight: 700; text-anchor: middle; pointer-events: none; }
.lot-svg__north path { fill: var(--navy); }
.lot-svg__north text { fill: var(--navy); font-size: 22px; font-weight: 700; text-anchor: middle; }
.lot-svg__bat { cursor: pointer; outline: none; } /* pas de contour : le focus clavier est signalé par le toit or (ligne suivante) */
.lot-svg__bat:hover .lot-svg__roof, .lot-svg__bat:focus-visible .lot-svg__roof, .lot-svg__bat.is-hl .lot-svg__roof { fill: var(--gold); }
.lot-svg__bat:hover .lot-svg__dot, .lot-svg__bat.is-hl .lot-svg__dot { fill: var(--navy); transform: scale(1.15); }

/* ---------- 30. Grille des lots — parc livré (groupes dépliables) ----------
   Pages : page programme des parcs livrés (clé 'parc_lots').
   Un bâtiment = un <tbody class="lots__group">. S'il compte plusieurs
   cellules, un bouton .lots__toggle (+ / –) affiche ou masque le <tbody
   class="lots__sub"> qui suit (attribut hidden, géré par le JavaScript, bloc 7).
   Un groupe sur deux est légèrement teinté (nth-of-type(even)). */
.lots__table--parc tbody.lots__group > tr > th { font-size: 1rem; }
.lots__table--parc .lots__tag { display: block; font-family: var(--font); font-size: .66rem; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--slate); margin-top: 2px; }
.lots__table--parc tbody.lots__group.is-hl tr, .lots__table--parc tbody.lots__group:hover tr, .lots__table--parc tbody.lots__group:target tr { background: var(--gold-pale); }
.lots__table--parc tbody tr:nth-child(even) { background: transparent; }
.lots__table--parc tbody.lots__group:nth-of-type(even) tr { background: rgba(255,255,255,.55); }
.lots__table--parc { background: var(--white); border-radius: var(--radius); overflow: hidden; }
.lots__toggle { all: unset; cursor: pointer; font-weight: 700; color: var(--navy); display: inline-flex; align-items: center; gap: 8px; } /* all: unset retire tout le style par défaut du bouton : il ressemble à du texte */
.lots__toggle::after { content: "+"; display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--gold); color: var(--white); font-size: .9rem; transition: transform .25s; }
.lots__toggle[aria-expanded="true"]::after { content: "–"; } /* le signe suit l'état ouvert / fermé indiqué par aria-expanded */
.lots__toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; } /* contour clavier remis ici, car all: unset l'a supprimé */
.lots__count { font-size: .7rem; font-weight: 600; color: var(--gold-text); }
.lots__sub tr th { padding-left: 28px; font-family: var(--font); font-weight: 500; font-size: .85rem; color: var(--slate); }
.lots__sub tr td { font-size: .82rem; color: var(--slate); }
.lots__sub tr { background: #FAFAF6; }
@media (max-width: 600px) {
  .lots__table--parc tbody { display: block; }
  .lots__table--parc tbody[hidden] { display: none; } /* nécessaire : le display: block ci-dessus annulerait l'attribut hidden */
  .lots__sub tr th { padding-left: 0; }
}

/* ---------- 31. Galerie « En images » et visionneuse ----------
   Pages : page programme (galerie, plans), page lot (plans, photos).
   Chaque vignette est un lien vers la grande image ; le JavaScript (bloc 9)
   l'ouvre dans la visionneuse au lieu de quitter la page.
   .gallery__zoom : rond « + » dessiné en CSS (deux barres ::before et ::after),
   visible au survol ou au focus clavier.
   .gallery--mosaic : mosaïque, quand le programme a au moins 6 photos.
   grid-auto-flow: dense comble les trous ; la 1re photo occupe 2 colonnes ×
   2 rangées ; au-delà de 800px, les photos 4, 5 et 6 sont placées plus bas. */
.gallery { margin-top: 2rem; }
.gallery__item { position: relative; display: block; overflow: hidden; border-radius: var(--radius); cursor: zoom-in; background: var(--ice); }
.gallery .gallery__img { width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; transition: transform .6s cubic-bezier(.2,.7,.2,1), filter .3s; }
.gallery__item:hover .gallery__img, .gallery__item:focus-visible .gallery__img { transform: scale(1.05); }
.gallery__item:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.gallery__zoom { position: absolute; right: 14px; bottom: 14px; width: 40px; height: 40px; border-radius: 50%; background: rgba(19,24,46,.75); opacity: 0; transform: scale(.8); transition: opacity .25s, transform .25s; }
.gallery__zoom::before, .gallery__zoom::after { content: ""; position: absolute; left: 50%; top: 50%; background: var(--white); transform: translate(-50%, -50%); }
.gallery__zoom::before { width: 16px; height: 2px; }
.gallery__zoom::after { width: 2px; height: 16px; }
.gallery__item:hover .gallery__zoom, .gallery__item:focus-visible .gallery__zoom { opacity: 1; transform: none; }
.gallery--mosaic { grid-template-columns: repeat(3, 1fr); grid-auto-rows: clamp(150px, 19vw, 250px); grid-auto-flow: dense; gap: 16px; }
.gallery--mosaic .gallery__img { aspect-ratio: auto; }
.gallery--mosaic .gallery__item:nth-child(1) { grid-column: 1 / 3; grid-row: span 2; }
.gallery--mosaic .gallery__item:nth-child(6) { grid-column: 2 / 4; grid-row: span 2; }
@media (max-width: 800px) {
  .gallery--mosaic { grid-template-columns: 1fr 1fr; grid-auto-rows: 160px; gap: 10px; }
  .gallery--mosaic .gallery__item:nth-child(1), .gallery--mosaic .gallery__item:nth-child(6) { grid-column: 1 / -1; grid-row: span 2; }
}
/* Visionneuse : fenêtre plein écran créée par le JavaScript (absente du HTML).
   z-index 200 : au-dessus de l'en-tête. 3 colonnes : bouton précédent (64px),
   image, bouton suivant (64px). .is-open fait monter l'opacité (fondu
   d'ouverture). [hidden] est remis en display: none, car display: grid
   l'annulerait. */
.lightbox { position: fixed; inset: 0; z-index: 200; background: rgba(10,13,26,.94); display: grid; grid-template-columns: 64px 1fr 64px; align-items: center; padding: 24px; opacity: 0; transition: opacity .25s; }
.lightbox.is-open { opacity: 1; }
.lightbox[hidden] { display: none; }
.lightbox__fig { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 14px; max-height: 100%; }
.lightbox__img { max-width: 100%; max-height: calc(100vh - 140px); object-fit: contain; border-radius: 4px; box-shadow: 0 20px 60px rgba(0,0,0,.4); } /* 140px réservés pour la légende, le compteur et les marges */
.lightbox__cap { color: rgba(255,255,255,.85); font-size: .88rem; text-align: center; max-width: 70ch; }
.lightbox__count { color: var(--gold-light); font-size: .72rem; letter-spacing: .1em; font-weight: 700; }
.lightbox__btn { appearance: none; border: 0; background: rgba(255,255,255,.08); color: var(--white); width: 52px; height: 52px; border-radius: 50%; font-size: 1.5rem; cursor: pointer; display: grid; place-items: center; transition: background .2s; }
.lightbox__btn:hover, .lightbox__btn:focus-visible { background: var(--gold); outline: none; } /* survol ou focus clavier : fond or (tient lieu de contour) */
.lightbox__close { position: absolute; top: 18px; right: 18px; }
/* Jusqu'à 700px : image sur toute la largeur, boutons précédent / suivant centrés en bas de l'écran. */
@media (max-width: 700px) {
  .lightbox { grid-template-columns: 1fr; padding: 60px 10px 90px; }
  .lightbox__prev, .lightbox__next { position: absolute; bottom: 20px; }
  .lightbox__prev { left: calc(50% - 64px); } .lightbox__next { right: calc(50% - 64px); }
}
/* Au-delà de 800px : photos 4 et 5 empilées à gauche, 6 en grand à droite ;
   la 8e, si c'est la dernière, s'étale sur 2 colonnes pour finir sans trou. */
@media (min-width: 801px) {
  .gallery--mosaic .gallery__item:nth-child(4) { grid-column: 1; grid-row: 3; }
  .gallery--mosaic .gallery__item:nth-child(5) { grid-column: 1; grid-row: 4; }
  .gallery--mosaic .gallery__item:nth-child(6) { grid-column: 2 / 4; grid-row: 3 / 5; }
  .gallery--mosaic .gallery__item:nth-child(8):last-child { grid-column: span 2; }
}

/* ---------- 32. Le guide ----------
   Pages : guide (pages/guide.php : rubriques et cartes d'articles) et article
   du guide (pages/guide-article.php). .guide-article__back, __body et
   .guide-faq servent aussi sur la page lot.
   .guide-card--draft / .guide-article__draft : article programmé ou
   brouillon, visible seulement en mode test (NOINDEX_ALL).
   .guide-faq : questions dépliables (<details> / <summary>) ; le « + »
   devient « – » quand la question est ouverte ([open]). */
.guide-themes { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 2rem; }
.guide-themes a { padding: 9px 16px; border-radius: 999px; background: var(--white); color: var(--navy); font-size: .78rem; font-weight: 600; text-decoration: none; border: 1px solid var(--line); transition: background .2s, color .2s; }
.guide-themes a:hover { background: var(--navy); color: var(--white); }
.guide-section + .guide-section { padding-top: 0; } /* deux rubriques qui se suivent : pas de double marge entre elles */
.guide-section__head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 40px; align-items: end; margin-bottom: 2rem; border-top: 1px solid var(--line); padding-top: 2.5rem; }
.guide-section__head p { margin: 0; color: var(--slate); }
.guide-cards { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 20px; } /* autant de colonnes de 260px minimum que la largeur le permet */
.guide-card a { display: flex; flex-direction: column; height: 100%; padding: 26px 24px 22px; background: var(--ice); border-radius: var(--radius); text-decoration: none; border-top: 3px solid var(--gold); transition: transform .3s, box-shadow .3s; }
.guide-card a:hover { transform: translateY(-4px); box-shadow: 0 14px 30px rgba(19,24,46,.10); }
.guide-card__title { font-size: 1.08rem; line-height: 1.35; color: var(--navy); margin: .6rem 0 1.2rem; flex: 1; }
.guide-card__meta { font-size: .75rem; color: var(--slate); }
.guide-card__more { margin-top: .8rem; font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--navy); }
.guide-card--draft a { border-top-color: var(--line); background: #F2F4F5; }
.container.narrow { max-width: calc(820px + 2 * var(--gutter)); } /* largeur des textes longs : 820px ; remplace la valeur de .narrow (section 4) */
.guide-article__back { display: inline-block; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--gold-text); text-decoration: none; margin-bottom: 1.2rem; }
.guide-article__meta { font-size: .8rem; color: var(--slate); margin-top: 1.2rem; }
.guide-article__draft { display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 3px; background: var(--gold-pale); color: var(--navy); font-size: .68rem; font-weight: 700; text-transform: uppercase; }
.guide-article__hero { margin: -40px auto 0; position: relative; } /* marge négative : l'image remonte de 40px */
.guide-article__body { font-size: 1.02rem; line-height: 1.75; }
.guide-article__body h2 { font-size: 1.45rem; color: var(--navy); margin: 2.4rem 0 .8rem; }
.guide-article__body h3 { font-size: 1.1rem; color: var(--navy); margin: 1.8rem 0 .6rem; }
.guide-article__body a { color: var(--gold-text); }
.guide-faq { margin-top: 3rem; }
.guide-faq details { border-bottom: 1px solid var(--line); padding: 14px 0; }
.guide-faq summary { cursor: pointer; font-weight: 600; color: var(--navy); list-style: none; display: flex; justify-content: space-between; gap: 16px; } /* list-style: none masque le triangle par défaut de <summary>, remplacé par « + » */
.guide-faq summary::-webkit-details-marker { display: none; } /* Safari ignore list-style: none : sans cette règle, il ajoute son propre triangle à côté du « + » */
.guide-faq summary::after { content: "+"; color: var(--gold); font-weight: 700; }
.guide-faq details[open] summary::after { content: "–"; }
.guide-faq details p { margin: .6rem 0 0; }
.guide-links { margin-top: 3rem; padding: 24px 28px; background: var(--ice); border-radius: var(--radius); }
.guide-links ul { list-style: none; margin: .6rem 0 0; padding: 0; }
.guide-links li { padding: 6px 0; }
.guide-links a { color: var(--navy); font-weight: 600; text-decoration: none; }
@media (max-width: 800px) { .guide-section__head { grid-template-columns: 1fr; gap: 10px; } }
/* Ajustement pour les cartes avec extrait : c'est l'extrait, et non plus le titre, qui s'étire (remplace flex et la marge de la règle plus haut). */
.guide-card__title { flex: 0; margin-bottom: .6rem; }
.guide-card__excerpt { font-size: .85rem; color: var(--slate); margin: 0 0 1rem; flex: 1; }

/* ---------- 33. Page lot ----------
   Pages : page lot (pages/lot.php ; un lot de data/lots.php, textes longs
   dans content/lots/).
   .lot-head : titre + carte récapitulative bleu nuit (.lot-card : statut,
   surface, bouton). .lot-figs : bande de 6 chiffres clés (3 puis 2 par ligne
   sur petit écran, filets de séparation ajustés en conséquence).
   .lot-plan-fig : plan cliquable, ouvert dans la visionneuse (aussi utilisé
   sur la page programme).
   .lot-reading : texte sur deux colonnes de 340px minimum (une seule si la
   place manque) ; break-inside: avoid évite de couper un paragraphe.
   .lot-side : colonne latérale qui reste visible au défilement (sticky).
   .lot-sub__… : bâtiment divisé en cellules. .lot-others__list : autres lots. */
.lot-head { padding: 56px 0 56px; }
.lot-head__grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(260px, 4fr); gap: 56px; align-items: end; margin-top: .6rem; }
.lot-head__title { margin-bottom: 1rem; }
.lot-card { background: var(--navy); color: var(--white); border-radius: var(--radius); padding: 28px; box-shadow: 0 20px 40px rgba(19,24,46,.18); }
.lot-card__status { display: flex; justify-content: space-between; font-size: .78rem; font-weight: 600; margin: 0 0 1rem; padding-bottom: .8rem; border-bottom: 1px solid rgba(255,255,255,.15); }
.lot-card__status span { color: var(--gold-light); text-transform: uppercase; letter-spacing: .08em; font-size: .68rem; }
.lot-card__surface { font-family: var(--font-num); font-size: 3.4rem; line-height: 1; margin: 0 0 .5rem; color: var(--gold-light); }
.lot-card__sub { font-size: .85rem; opacity: .85; margin-bottom: 1.4rem; }
.lot-card .btn { width: 100%; }
.lot-card__pdf { display: block; text-align: center; margin-top: .8rem; color: var(--white); font-size: .8rem; }
.lot-figs { background: var(--white); border-bottom: 1px solid var(--line); }
.lot-figs__grid { list-style: none; margin: 0 auto; display: grid; grid-template-columns: repeat(6, 1fr); }
.lot-figs__grid li { padding: 26px 12px; border-left: 1px solid var(--line); text-align: center; }
.lot-figs__grid li:first-child { border-left: 0; }
.lot-figs__num { display: block; font-family: var(--font-num); font-size: 1.7rem; color: var(--navy); }
.lot-figs__label { display: block; font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; color: var(--slate); margin-top: .3rem; }
.lot-plan-fig { margin: 2.2rem 0 0; }
.lot-plan-fig__link { position: relative; display: block; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); background: var(--white); cursor: zoom-in; box-shadow: 0 16px 40px rgba(19,24,46,.08); }
.lot-plan-fig__img { width: 100%; height: auto; display: block; transition: transform .6s cubic-bezier(.2,.7,.2,1); }
.lot-plan-fig__link:hover .lot-plan-fig__img { transform: scale(1.015); }
.lot-plan-fig__zoom { position: absolute; right: 16px; bottom: 16px; background: var(--navy); color: var(--white); font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; padding: 10px 16px; border-radius: 999px; }
.lot-plan-fig figcaption { font-size: .78rem; font-style: italic; color: var(--slate); margin-top: .7rem; }
.lot-plan-fig--second { margin-top: 3rem; }
.lot-reading { columns: 2 340px; column-gap: 48px; margin-top: 2.4rem; font-size: 1rem; line-height: 1.75; }
.lot-reading p { break-inside: avoid; margin-top: 0; }
.lot-body { display: grid; grid-template-columns: minmax(0, 7fr) minmax(260px, 4fr); gap: 56px; align-items: start; }
.lot-side { position: sticky; top: 110px; background: var(--white); border-radius: var(--radius); padding: 26px; }
.lot-side__table { width: 100%; border-collapse: collapse; font-size: .85rem; margin: .6rem 0 1.4rem; }
.lot-side__table th { text-align: left; font-weight: 500; color: var(--slate); padding: 9px 0; border-bottom: 1px solid var(--line); }
.lot-side__table td { text-align: right; font-weight: 700; color: var(--navy); padding: 9px 0; border-bottom: 1px solid var(--line); }
.lot-side .btn { width: 100%; }
.lot-side__more { margin: 1rem 0 0; font-size: .82rem; }
.lot-side__more a { color: var(--navy); font-weight: 600; text-decoration: none; }
@media (max-width: 900px) {
  .lot-head__grid, .lot-body { grid-template-columns: 1fr; gap: 28px; }
  .lot-side { position: static; }
  .lot-figs__grid { grid-template-columns: repeat(3, 1fr); }
  .lot-figs__grid li:nth-child(4) { border-left: 0; }
  .lot-figs__grid li:nth-child(n+4) { border-top: 1px solid var(--line); }
}
@media (max-width: 520px) { .lot-figs__grid { grid-template-columns: repeat(2, 1fr); } .lot-figs__grid li { border-left: 0 !important; border-top: 1px solid var(--line); } .lot-card__surface { font-size: 2.6rem; } }
.lot-sub__title { margin-top: 3rem; }
.lot-sub__table { max-width: 720px; }
.lot-sub__table thead th { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--gold-text); text-align: right; }
.lot-sub__table thead th:first-child, .lot-sub__table tbody th { text-align: left; }
.lot-sub__gallery { grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 1.6rem; }
.lot-sub__gallery .gallery__img { aspect-ratio: 1.41; object-fit: contain; background: var(--white); }
.lot-sub__label { position: absolute; left: 10px; bottom: 10px; background: var(--navy); color: var(--white); font-size: .68rem; font-weight: 700; padding: 5px 10px; border-radius: 999px; }
.lot-others__list { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
.lot-others__list a { display: block; padding: 16px 18px; background: var(--ice); border-radius: var(--radius); text-decoration: none; border-left: 3px solid var(--gold); transition: transform .2s; }
.lot-others__list a:hover { transform: translateY(-3px); }
.lot-others__list strong { display: block; color: var(--navy); }
.lot-others__list span { font-size: .78rem; color: var(--slate); }
@media (max-width: 800px) { .lot-sub__gallery { grid-template-columns: 1fr 1fr; } }
/* Lots à louer : pastille ardoise sur le plan de la page programme (27.2) et lien .lots__loc sous la grille des lots, vers la page du lot. */
.lot-plan__spot--loc { border-color: var(--slate); background: rgba(59,80,107,.12); }
.lot-plan__spot--loc:hover, .lot-plan__spot--loc:focus-visible { border-color: var(--gold); transform: translate(-50%, -50%) scale(1.18); outline: none; }
.lots__loc { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 16px; margin-top: 1.4rem; padding: 18px 22px; border-radius: var(--radius); background: var(--ice); border-left: 3px solid var(--slate); text-decoration: none; color: var(--navy); transition: transform .2s; }
.lots__loc:hover { transform: translateY(-2px); }
.lots__loc span { font-size: .85rem; color: var(--slate); }

/* ---------- 34. Blocs plan + texte ----------
   Pages : page programme (clé 'blocs' de data/programmes.php).
   Texte (5 parts) + image ou plan (6 parts). --rev : texte à droite.
   --wide (option 'wide') : une seule colonne, texte au-dessus de l'image.
   .bloc__figs : chiffres sur 2 colonnes séparées par des filets. */
.bloc { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 56px; align-items: start; }
.bloc--rev .bloc__text { order: 2; }
.bloc__text > p { margin: 0 0 1rem; }
.bloc__figs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; margin: 1.6rem 0; border-top: 1px solid var(--line); }
.bloc__figs div { padding: 14px 0; border-bottom: 1px solid var(--line); }
.bloc__figs div:nth-child(odd) { padding-right: 16px; }
.bloc__figs dt { font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; color: var(--slate); }
.bloc__figs dd { margin: .2rem 0 0; font-family: var(--font-num); font-size: 1.35rem; color: var(--navy); }
.bloc__list-title { font-size: .85rem; text-transform: uppercase; letter-spacing: .05em; color: var(--navy); margin: 1.6rem 0 .6rem; }
.bloc__note { font-size: .78rem; font-style: italic; color: var(--slate); }
.bloc__media { margin: 0; }
.bloc__media figcaption { font-size: .78rem; font-style: italic; color: var(--slate); margin-top: .7rem; }
.bloc__media2 { margin-top: 2rem; }
@media (max-width: 900px) {
  .bloc { grid-template-columns: 1fr; gap: 32px; }
  .bloc--rev .bloc__text { order: 0; }
}
.bloc--wide { grid-template-columns: 1fr; gap: 40px; }
.bloc--wide .bloc__text { max-width: 860px; }
/* ---------- 35. Plans SVG : compléments ----------
   Pages : page programme de l'Îlot route de Meaux et du Parc du Villenoy.
   Complète la section 29 : parcelles (__plot), maison existante en
   pointillés (__house), accès (__access), espaces verts (__epp-line,
   __label), petites tailles de texte (--sm). */
.lot-svg__plot { fill: #F4F1E4; stroke: var(--gold); stroke-width: 3; transition: fill .25s; }
.lot-svg__bat:hover .lot-svg__plot, .lot-svg__bat.is-hl .lot-svg__plot { fill: #E9E3C6; }
.lot-svg__house { fill: none; stroke: var(--slate); stroke-width: 3; stroke-dasharray: 10 7; }
.lot-svg__drive--lot { stroke: #C3CBD2; stroke-width: 2; }
.lot-svg__epp-line { stroke: #8FAA6A; stroke-width: 2; }
.lot-svg__label { fill: #4E6B33; font-size: 26px; font-weight: 700; text-anchor: middle; }
.lot-svg__num--sm { font-size: 24px; }
.lot-svg__access { stroke: var(--gold); stroke-width: 8; }
.lot-svg__label--sm { font-size: 20px; }
.lot-svg__road--light { fill: #E2E5E2; }
/* ---------- 36. Tableaux des articles du guide ----------
   Pages : article du guide (et textes de la page lot). Jusqu'à 700px, un
   tableau trop large défile horizontalement dans son cadre au lieu
   d'élargir toute la page. */
@media (max-width: 700px) {
  .guide-article__body table { display: block; max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ---------- 37. Page de destination publicitaire ----------
   pages/horizon-50-landing.php et horizon-50-merci.php. L'en-tête est réduit (inc/header.php,
   $meta['landing']) : téléphone et bouton vers le formulaire à la place du menu. */
.site-header__landing { display: flex; align-items: center; gap: 20px; }
.site-header__tel { color: var(--white); font-weight: 600; font-size: .9rem; text-decoration: none; white-space: nowrap; }
.site-header__tel:hover { color: var(--gold-light); }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 1.6rem; }
.hero--landing .hero__text { max-width: 52ch; font-size: 1.05rem; }
.landing-offre { align-items: start; }
.landing-offre .check-list { margin: 1.4rem 0; }
.landing-form { box-shadow: 0 18px 40px rgba(19,24,46,.12); scroll-margin-top: calc(var(--header-h) + 16px); } /* scroll-margin-top : l’ancre #contact s’arrête sous l’en-tête fixe */
.landing-form h2 { margin-top: 0; }
.landing-form__intro { font-size: .92rem; margin: .4rem 0 1.4rem; }
#contact { scroll-margin-top: var(--header-h); }
.landing-merci { padding-top: calc(var(--header-h) + 72px); padding-bottom: 88px; }
.landing-merci .hero__actions { margin: 2rem 0 1.4rem; }
.landing-merci__tel a { color: var(--gold-text); font-weight: 600; }
@media (max-width: 600px) {
  .site-header__tel { display: none; } /* sur téléphone, le numéro reste accessible dans la page (boutons « Appeler ») */
  .hero__actions .btn { width: 100%; }
}

.landing-prix { margin: -0.4rem 0 1.2rem; font-size: 1.15rem; color: var(--navy); }
.landing-prix strong { color: var(--gold-text); }
.landing-villas { max-width: 640px; }

/* Atouts énergie (centrale photovoltaïque, borne IRVE) : un éclair remplace la puce, puis un trait de
   surligneur vert-or se dessine de gauche à droite derrière le texte, suivi d'un reflet de lumière.
   L'animation part quand la liste apparaît à l'écran (classe .is-visible posée par assets/js/main.js
   sur le bloc .reveal). Sans animation (JavaScript absent ou « réduire les animations » activé),
   le surlignage s'affiche directement, sans mouvement. */
.atout-energie { --attente: 5s; } /* délai avant le début de l'animation, une fois la liste à l'écran : le temps de commencer à lire */
.check-list li.atout-energie::before { content: none; } /* la puce ronde est remplacée par l'éclair */
.atout-energie__eclair { position: absolute; left: -1px; top: 50%; width: 13px; height: 19px; transform: translateY(-50%); fill: var(--gold); }
.atout-energie__texte { position: relative; padding: 0 .2em; background: linear-gradient(100deg, rgba(152,142,27,.32), rgba(152,142,27,.14)) no-repeat 0 88% / 100% 58%; } /* le dégradé couvre la moitié basse du texte, comme un coup de surligneur */
.reveal .atout-energie__texte { background-size: 0% 58%; }
/* La transition n'existe qu'à l'état visible : le surlignage disparaît instantanément au chargement, puis se dessine après l'attente. */
.reveal.is-visible .atout-energie__texte { background-size: 100% 58%; transition: background-size .9s cubic-bezier(.65, 0, .35, 1) calc(var(--attente) + .5s); }
.reveal.is-visible .atout-energie + .atout-energie .atout-energie__texte { transition-delay: calc(var(--attente) + .9s); } /* la deuxième ligne suit la première */
.reveal.is-visible .atout-energie__eclair { animation: eclair-apparition .6s calc(var(--attente) + .3s) forwards; } /* forwards : l'éclair reste visible pendant l'attente, puis rebondit */
.reveal.is-visible .atout-energie + .atout-energie .atout-energie__eclair { animation-delay: calc(var(--attente) + .7s); }
.reveal.is-visible .atout-energie__texte::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(100deg, transparent 35%, rgba(255,255,255,.75) 50%, transparent 65%) no-repeat; background-size: 250% 100%; background-position: 160% 0; animation: reflet 1.1s calc(var(--attente) + 1.9s) ease-in-out both; } /* reflet : une bande claire traverse le surlignage une seule fois */
@keyframes eclair-apparition {
  0%   { opacity: 0; transform: translateY(-50%) scale(.3) rotate(-25deg); }
  60%  { opacity: 1; transform: translateY(-50%) scale(1.3) rotate(6deg); }
  100% { opacity: 1; transform: translateY(-50%) scale(1); }
}
@keyframes reflet { to { background-position: -60% 0; } }
@media (prefers-reduced-motion: reduce) {
  .reveal .atout-energie__texte { background-size: 100% 58%; transition: none; }
  .reveal.is-visible .atout-energie__eclair { animation: none; }
  .reveal.is-visible .atout-energie__texte::after { content: none; }
}

/* ---------- 38. Bandeau cookies ----------
   inc/footer.php et assets/js/consentement.js. Fixé en bas de l'écran, sans bloquer la lecture.
   Les deux boutons ont exactement le même style : refuser doit être aussi simple qu'accepter. */
.cookies { position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 200; display: flex; justify-content: center; pointer-events: none; }
.cookies[hidden] { display: none; }
.cookies__inner { pointer-events: auto; max-width: 760px; background: var(--white); color: var(--slate-text); border-radius: var(--radius); box-shadow: 0 12px 40px rgba(19,24,46,.25); padding: 22px 26px; display: grid; gap: 10px; }
.cookies__titre { margin: 0; font-weight: 700; color: var(--navy); }
.cookies__texte { margin: 0; font-size: .86rem; line-height: 1.5; }
.cookies__texte a { color: var(--gold-text); }
.cookies__actions { display: flex; flex-wrap: wrap; gap: 12px; justify-content: flex-end; }
.site-footer__cookies { all: unset; cursor: pointer; text-decoration: underline; } /* bouton présenté comme les liens voisins */
.site-footer__cookies:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
