/*
Theme Name: Valeurs Immo Theme
Theme URI: https://valeurs-immo.fr
Author: Anthony Thiong-sion
Description: Thème premium Single Page Application pour Valeurs Immo
Version: 3.14.4
*/

/* ==========================================================================
   POLICES — hébergées dans le thème (assets/fonts)
   Elles venaient de fonts.googleapis.com. Voir valeurs_immo_enqueue_scripts()
   pour le pourquoi : c'était la première cause de lenteur mesurée du site.

   Trois fichiers seulement, parce que les deux familles sont des polices
   VARIABLES : un seul fichier couvre toute la plage de graisses. D'où les
   déclarations en intervalle (font-weight: 300 700) au lieu d'une règle par
   graisse. Sous-ensemble « latin » de Google, qui couvre le français entier,
   y compris « œ » (U+0153) et « € » (U+20AC).

   font-display: swap — le texte s'affiche aussitôt dans la police de secours et
   bascule quand le fichier arrive. Sans cela, un titre peut rester invisible
   jusqu'à trois secondes sur réseau lent.

   POUR CHANGER DE POLICE : remplacer les fichiers, pas seulement ces règles, et
   mettre à jour les deux <link rel="preload"> de valeurs_immo_head_seo().
   ========================================================================== */
@font-face {
    font-family: 'Outfit';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('assets/fonts/outfit-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Playfair Display';
    font-style: normal;
    font-weight: 500 700;
    font-display: swap;
    src: url('assets/fonts/playfair-display-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Playfair Display';
    font-style: italic;
    font-weight: 500 600;
    font-display: swap;
    src: url('assets/fonts/playfair-display-italic-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   VARIABLES & RESET
   ========================================================================== */
:root {
    --primary: #0A1128;      /* Deep Navy */
    --primary-light: #162650;
    --secondary: #D4AF37;    /* Premium Gold */
    /* Or assombri, reserve au texte pose sur fond clair : #D4AF37 n y atteint que
       1,94:1 de contraste, sous le minimum WCAG de 3:1 pour du grand texte.
       Sur fond sombre, on garde --secondary.
       #856A12 depuis la 3.12.0 : l'ancienne valeur #8A6E15 faisait 4,49:1 sur le
       fond de page --bg-base, soit JUSTE SOUS le seuil de 4,5:1 exige pour du texte
       courant — c'est d'ailleurs le chiffre qu'annonçait ce commentaire, sans en
       tirer la conséquence. Lighthouse le relevait sur chaque lien des pages de
       prestation. Nouvelle valeur : 4,77:1 sur --bg-base, 5,16:1 sur blanc.
       L'écart de teinte est imperceptible à l'œil. */
    --secondary-dark: #856A12;
    --secondary-light: #F3E5AB;
    --text-dark: #1E293B;
    --text-light: #F8FAFC;
    --bg-base: #F4F6F9;
    --bg-white: #FFFFFF;
    --glass-bg: rgba(255, 255, 255, 0.05);
    --glass-border: rgba(255, 255, 255, 0.1);
    --shadow-soft: 0 20px 40px rgba(0,0,0,0.05);
    --shadow-hover: 0 30px 60px rgba(0,0,0,0.12);
    --transition: all 0.6s cubic-bezier(0.16, 1, 0.3, 1);

    /* --- DOCTRINE DE LARGEUR ET DE HAUTEUR (audit responsive) --- */

    /* Plafond unique du contenu. C'était déjà celui de .section-container ;
       il devient une valeur nommée pour que la navbar puisse s'y caler. */
    --vi-max: 1400px;

    /* Gouttière unique. 4.375rem = 70px = 5% de 1400 EXACTEMENT : sous 1400px
       le rendu est identique à l'ancien au pixel près, au-delà la gouttière
       cesse de croître. C'est LE correctif central : `padding: 4rem 5%` résolvait
       son pourcentage sur la fenêtre alors que la boîte est bornée à 1400px, si
       bien que le contenu RÉTRÉCISSAIT quand l'écran s'élargissait —
       1260px à 1410, 1209 à 1920, 1057 à 3440, 889 à 5120. Mesuré, pas déduit.
       Plancher à 1.25rem : 5% de 320px ne faisait que 16px de marge. */
    --vi-gutter: clamp(1.25rem, 5vw, 4.375rem);

    /* Hauteur réelle de la barre fixe : 1.5rem + logo 72px + 1.5rem = 120px.
       Le hero en réservait 112 : 8px de moins que la barre, alors que son
       commentaire affirmait le contraire. Redéfini à 84px sous 768px. */
    --vi-nav-h: 120px;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* NB : pas de scroll-behavior:smooth ici. En CSSOM View, behavior:'auto'
   signifie « suivre la propriete CSS », donc window.scrollTo(0,0) heritait de
   ce defilement anime : le retour en haut se superposait au fondu d'entree, a
   travers un hero en background-attachment:fixed. Le routeur est desormais seul
   maitre du defilement et demande explicitement le lissage quand il le veut. */

body {
    font-family: 'Outfit', sans-serif;
    color: var(--text-dark);
    background-color: var(--bg-base);
    line-height: 1.6;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, .serif {
    font-family: 'Playfair Display', serif;
}

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

ul { list-style: none; }

/* Custom Scrollbar */
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--bg-base); }
::-webkit-scrollbar-thumb { background: var(--secondary); border-radius: 10px; }

/* ==========================================================================
   NAVIGATION
   ========================================================================== */
/* Restreint a la barre de navigation : le selecteur d element "nav" touchait aussi
   le <nav> du pied de page, qui heritait alors de position:fixed;top:0. */
#navbar {
    position: fixed;
    top: 0; left: 0; width: 100%;
    z-index: 1000;
    padding: 1.5rem 5%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition: var(--transition);
}

#navbar.scrolled {
    background: rgba(10, 17, 40, 0.98);
    backdrop-filter: blur(20px);
    padding: 1rem 5%;
    box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}

/* Logo : coloré par défaut (sur le hero), blanc au scroll (sur la navbar navy).
   Les deux images sont superposées et se croisent en fondu. */
.logo {
    position: relative;
    display: inline-block;
    line-height: 0;
}

.logo-img {
    height: 72px;
    width: auto;
    display: block;
    filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.35));
    transition: height 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                opacity 0.45s ease,
                transform 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                filter 0.5s ease;
}

.logo:hover .logo-img {
    transform: translateY(-2px) scale(1.03);
}

/* Au scroll, la navbar se compacte. Le logo reste blanc dans tous les cas. */
#navbar.scrolled .logo-img { height: 54px; }

.nav-links {
    display: flex;
    gap: 2.5rem;
    align-items: center;
}

.nav-links a {
    color: var(--text-light);
    font-weight: 500;
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    position: relative;
    transition: color 0.3s;
}

.nav-links a::after {
    content: '';
    position: absolute;
    bottom: -6px; left: 0;
    width: 0%; height: 2px;
    background: var(--secondary);
    transition: width 0.3s ease;
}

.nav-links a:hover, .nav-links a.active-link {
    color: var(--secondary);
}
.nav-links a:hover::after, .nav-links a.active-link::after {
    width: 100%;
}

/* C'est desormais un <button> : sous 768 px, .nav-links est en display:none et
   ce declencheur est le SEUL acces au menu. Tant qu'il etait un <div>, il n'etait
   pas focusable : aucun lien de navigation n'etait atteignable au clavier ni au
   lecteur d'ecran, donc aucune des 7 autres sections. */
.menu-toggle {
    display: none;
    color: var(--text-light);
    font-size: 2rem;
    cursor: pointer;
    z-index: 1001;
    background: none;
    border: 0;
    font-family: inherit;
    line-height: 1;
    padding: 0.25rem 0.5rem;
}

/* --- Bouton EXTRANET client -------------------------------------------------
   Lien EXTERNE vers le portail ICS (domaine séparé) : volontairement placé dans
   .nav-links pour apparaître aussi dans le menu mobile, mais stylé en bouton
   plein pour se distinguer des ancres de navigation. */
.nav-links a.nav-extranet {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.65rem 1.5rem;
    border: 2px solid var(--secondary);
    border-radius: 50px;
    background: var(--secondary);
    color: var(--primary);
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 6px 18px rgba(212, 175, 55, 0.28);
    transition: background 0.3s ease,
                color 0.3s ease,
                transform 0.4s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.4s ease;
}

/* Le soulignement animé est réservé aux ancres de menu. */
.nav-links a.nav-extranet::after { content: none; }

.nav-links a.nav-extranet:hover,
.nav-links a.nav-extranet:focus-visible {
    background: transparent;
    color: var(--secondary);
    transform: translateY(-3px);
    box-shadow: 0 12px 26px rgba(212, 175, 55, 0.38);
}

.nav-extranet__icon {
    font-size: 0.85em;
    line-height: 1;
    transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.nav-links a.nav-extranet:hover .nav-extranet__icon {
    transform: translate(2px, -2px);
}

/* ==========================================================================
   GLOBAL SPA PAGE STYLES
   ========================================================================== */
/* NB : sélecteur restreint à <section> pour ne PAS toucher <body class="page">
   (WordPress ajoute la classe "page" au body de toute Page). */
section.page {
    display: none;
    min-height: 100vh;
    /* Plus d'opacity:0 ni de transform au repos : l'etat normal d'une section
       affichee est l'etat normal. L'animation ne vit que sur .is-entering, posee
       par le routeur. Effet de bord recherche : au premier rendu, #page-home
       (qui porte .active en dur dans le HTML) est peinte immediatement, sans
       fondu — or un element dont un ancetre est a opacite 0 n'est pas candidat
       LCP. Ce correctif ne peut donc qu'ameliorer le LCP. */
}

section.page.active {
    display: block;
}

/* Fondu d'ENTREE seul. Aucune phase de sortie : la section sortante est coupee
   net, dans la meme tache que l'affichage de la suivante. Consequences : jamais
   deux sections a la fois dans l'arbre d'accessibilite (deux <h2>, deux
   formulaires), et jamais zero section affichee — l'ancien setTimeout laissait
   un trou de 240 ms qu'un onglet passe en arriere-plan pouvait figer.
   Le passage display:none -> block redemarre l'animation tout seul : plus besoin
   de forcer un reflow (void offsetWidth), qui etait une lecture de layout
   synchrone dans le chemin de l'interaction. */
/* On n anime JAMAIS la <section> elle-meme. Un translateY sur le bloc entier
   decale aussi la bande bleue de l en-tete : il restait 16 px de fond clair
   sous la navbar pendant toute la transition, et l opacite partant de 0
   delavait le bleu nuit vers ce meme fond clair. Resultat : un flash blanc en
   haut de page a chaque changement de section.
   On n anime donc que ce qui repose deja sur le fond clair. La bande bleue,
   elle, est peinte opaque des la premiere image. Le titre qu elle contient a
   sa propre animation (fadeInUP, sur .page-header h2). */
section.page.is-entering .section-container,
section.page.is-entering .hero-content {
    animation: vi-contenu-in 0.34s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes vi-contenu-in {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}

/* Filet de panne : si app.js n'a pas confirme son demarrage, le chien de garde
   du pied de page pose html.no-spa et le document redevient un long one-page
   lisible, plutot qu'un site ampute de toutes les sections sauf une. */
html.no-spa section.page { display: block !important; }
html.no-spa section.page.is-entering { animation: none !important; }

.page-header {
    /* `height` était une hauteur IMPOSÉE sur une boîte en flex centrée : dès que
       le titre dépassait (écran bas, zoom texte, titre long), le surplus partait
       pour moitié AU-DESSUS de l'origine du document, là où aucun défilement ne
       va le chercher. C'est une perte de contenu, pas un défaut cosmétique. */
    height: auto;

    /* Plafond à 26rem = 416px. La bande ne contient qu'un h2 borné à 4rem, soit
       une ligne de 102px. 60vh non borné donnait 564px sur un 1080p et 780px sur
       un 3440x1440 : un aplat vide à 87% pour un seul titre. */
    min-height: min(60vh, 26rem);

    /* `center / cover no-repeat` posé ici une fois pour toutes : chaque section
       ne fournit plus que son background-image, le cadrage est commun. */
    background: var(--primary) center / cover no-repeat;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    position: relative;

    /* La bande n'avait AUCUN rembourrage (`* { padding: 0 }`) : le titre était
       centré dans 60vh, donc passait SOUS la barre fixe dès que 0,6 x hauteur
       tombait sous 216px — tout téléphone en paysage. La réserve haute est
       désormais supérieure à la barre par construction. Latéralement, la bande
       était le seul bloc de premier niveau sans gouttière : un titre long
       touchait les bords de l'écran. */
    padding: calc(var(--vi-nav-h, 120px) + 1.5rem) var(--vi-gutter, 5vw) 2rem;

    margin-bottom: 4rem;
}

.page-header::after {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: radial-gradient(circle at center, rgba(212, 175, 55, 0.15) 0%, transparent 70%);
}

/* Voile sombre — indispensable, pas décoratif. Le titre des bandeaux est en or
   (#D4AF37) : posé directement sur une photo claire, son contraste s'effondre
   sous le seuil lisible. Ce voile ramène le fond au bleu nuit de la charte quelle
   que soit l'image, donc le contraste du titre est constant d'une section à
   l'autre. Il se peint AVANT ::after : la lueur dorée reste par-dessus, et le
   titre (z-index 2, l.283) par-dessus les deux.
   Dégradé plutôt qu'aplat : le haut est moins chargé, ce qui laisse respirer la
   barre de navigation fixe qui le surplombe. */
.page-header::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: linear-gradient(rgba(10, 17, 40, 0.78), rgba(10, 17, 40, 0.90));
}

/* --------------------------------------------------------------------------
   UNE IMAGE PAR SECTION
   Auparavant une seule section sur sept portait une image (Services), et les
   six autres se partageaient trois bleus différents posés en style inline
   (var(--primary), #162650, #0A1128) — trois valeurs pour un même rôle, donc
   trois façons de ne pas être uniforme.
   Les images sont ici en CSS et non plus dans le HTML : une media query peut
   les atteindre, un style inline non.
   Chaque bandeau reprend l'image de la carte « Nos métiers » correspondante :
   le visiteur qui clique une carte retrouve la même photo en arrivant. La
   cohérence n'est pas décorative, elle confirme qu'il est au bon endroit.
   Chargement : ces sections sont en display:none tant qu'on ne les visite pas,
   et un navigateur ne télécharge pas l'image de fond d'un élément masqué. Le
   poids initial de la page ne bouge donc pas d'un octet.
   -------------------------------------------------------------------------- */
#page-acheter    .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/expertise-1-800.webp'); }
#page-syndic     .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/expertise-4-800.webp'); }
#page-services   .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/hero-accueil.webp'); }

/* Agence et Contact : la médiathèque ne contient aucune autre photo exploitable
   (la seule restante est une image de synthèse en portrait clair, inutilisable
   ici). Ces deux pages parlent du cabinet et du lieu : elles reprennent donc la
   vue de Montpellier de l'accueil, recadrée différemment pour ne pas donner
   l'impression d'un copier-coller. À remplacer dès qu'il existe de vraies
   photos du cabinet, de l'équipe ou de Lavérune — plus crédibles qu'une banque
   d'images, et bien meilleures pour le référencement local. */
#page-agence     .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/hero-accueil.webp'); background-position: center 22%; }
#page-contact    .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/hero-accueil.webp'); background-position: center 78%; }

.page-header h2 {
    font-size: clamp(1.9rem, 6.5vw, 4rem);
    color: var(--secondary);
    z-index: 2;
    animation: fadeInUP 0.5s ease;
}

.section-container {
    max-width: var(--vi-max, 1400px);
    margin: 0 auto;
    /* Le 5% se résolvait sur la largeur du BLOC CONTENEUR — section.page, donc
       la fenêtre entière — jamais sur le max-width de l'élément. En border-box,
       5% de 3440 retirait 172px DE CHAQUE CÔTÉ des 1400 :
         1410 -> 1260px | 1920 -> 1209 | 2560 -> 1145 | 3440 -> 1057 | 5120 -> 889
       Le contenu se stabilise désormais à 1260px pour toute fenêtre plus large. */
    padding: 4rem var(--vi-gutter, 5vw);
}

/* Section Titles */
.section-title {
    text-align: center;
    margin-bottom: 5rem;
}

.section-title h2 {
    font-size: clamp(1.9rem, 5.5vw, 3.5rem);
    color: var(--primary);
    position: relative;
    display: inline-block;
}

.section-title h2::after {
    content: '';
    position: absolute;
    width: 60px; height: 3px;
    background: var(--secondary);
    bottom: -15px; left: 50%;
    transform: translateX(-50%);
}

/* Buttons */
.btn {
    display: inline-block;
    padding: 1rem 2.5rem;
    border-radius: 50px;
    font-weight: 600;
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: 1.5px;
    transition: var(--transition);
    cursor: pointer;
    border: 2px solid var(--secondary);
    text-align: center;
}

.btn-primary {
    background: var(--secondary);
    color: var(--primary);
}

.btn-primary:hover {
    background: transparent;
    color: var(--secondary);
    transform: translateY(-5px);
    box-shadow: 0 15px 30px rgba(212, 175, 55, 0.3);
}

.btn-outline {
    background: transparent;
    color: var(--secondary);
}

.btn-outline:hover {
    background: var(--secondary);
    color: var(--primary);
}

/* ==========================================================================
   SPECIFIC PAGES
   ========================================================================== */

/* --- PAGE: HOME --- */
#page-home .hero {
    /* Même faute que .page-header, aux conséquences pires : sur un écran bas la
       pile du hero réclame plus que la vue, et le surplus partait pour moitié
       sous la barre, pour moitié au-dessus de l'origine du document. Mesuré à
       844x390 : contenu de 408px pour une boîte de 390px, rogné aux deux bouts.
       On garde 100vh et non 100svh : section.page reste en 100vh, une seule
       unité de hauteur dans tout le thème. */
    height: auto;
    min-height: 100vh;
    background: linear-gradient(rgba(10, 17, 40, 0.6), rgba(10, 17, 40, 0.8)), url('https://valeurs-immo.fr/wp-content/uploads/2026/09/hero-accueil.webp') center/cover no-repeat fixed;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    /* 120 + 24 = 144px, contre 112px auparavant — soit 8px SOUS la barre.
       Latéralement on garde 2rem : .hero-content est borné à 1000px et centré,
       la gouttière du site ne changerait rien au-dessus de 1140px et lui ferait
       perdre 19px par côté à 1024px, là où elle mord vraiment. */
    padding: calc(var(--vi-nav-h, 120px) + 1.5rem) 2rem 3rem;
}

.hero-content {
    max-width: 1000px;
}

/* Entrée échelonnée : chaque enfant du hero apparaît en cascade. */
.hero-content > * {
    opacity: 0;
    animation: fadeInUP 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
}
.hero-content > *:nth-child(1) { animation-delay: 0.15s; }
.hero-content > *:nth-child(2) { animation-delay: 0.32s; }
.hero-content > *:nth-child(3) { animation-delay: 0.49s; }
.hero-content > *:nth-child(4) { animation-delay: 0.66s; }

/* SAUF le H1 et son surtitre, visibles dès le premier rendu (3.13.1).
   Le H1 est l'élément LCP de l'accueil : un élément en opacity:0 n'est pas
   compté comme affiché, si bien que le fondu (0,32 s de délai + 0,9 s) fixait à
   lui seul la date du LCP. Mesuré le 24/09/2026 sur une copie locale, trois
   passages chacun : avec le fondu, LCP observé ~2,1 s ; sans, ~0,3 s. L'effet
   s'était aggravé quand le H1 a gagné une ligne en 3.13.0 (« à Lavérune, près de
   Montpellier ») : score mobile 97 -> 91-93. Le paragraphe et les boutons gardent
   leur cascade. */
.hero-content > h1,
.hero-content > .hero-kicker {
    opacity: 1;
    animation: none;
}

/* L'animation ci-dessus redemarre a chaque bascule display:none -> block, donc a
   chaque retour sur l'accueil : ~1,5 s avant que le H1 soit pleinement visible.
   app.js pose .has-entered une fois la cascade jouee, pour ne la voir qu'une fois. */
.hero-content.has-entered > * {
    animation: none;
    opacity: 1;
}

/* Le H1 porte desormais le metier et la ville : plus long que l ancienne ligne
   decorative, il passe en taille fluide et en blanc, l or restant au surtitre. */
.hero h1 {
    font-size: clamp(1.9rem, 4.4vw, 3.4rem);
    color: var(--text-light);
    text-shadow: 0 10px 30px rgba(0,0,0,0.8);
    line-height: 1.15;
    margin-bottom: 2rem;
}

/* Surtitre : la ligne de marque historique, conservee au-dessus du H1.
   Selecteur a deux classes pour passer devant ".hero p" (font-size et margin). */
.hero .hero-kicker {
    font-family: 'Playfair Display', Georgia, serif;
    font-style: italic;
    font-weight: 500;
    font-size: clamp(1.3rem, 2.8vw, 2.1rem);
    color: var(--secondary);
    margin-bottom: 0.75rem;
    text-shadow: 0 6px 20px rgba(0,0,0,0.75);
}

.hero p {
    font-size: 1.6rem;
    color: var(--text-light);
    margin-bottom: 3.5rem;
    font-weight: 300;
}

/* (Historique, du temps des quatre cartes ; disposition actuelle plus bas.)
   Quatre cartes : seuls 4, 2 ou 1 colonnes donnent des rangees completes.
   Trois colonnes laissent toujours une carte seule sur la deuxieme ligne.
   Or repeat(auto-fit, minmax(300px, 1fr)) produisait exactement cela sur TOUT
   le desktop : le conteneur est plafonne a 1400 px, soit 1260 px utiles apres
   les 5 % de marge interieure, quand quatre colonnes de 300 px plus trois
   gouttieres de 40 px en reclament 1320. La quatrieme colonne etait donc
   inatteignable et l orpheline permanente.
   On fixe explicitement les trois dispositions, en partant du mobile. */
.activities-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2.5rem;
}

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

/* 3.14.3 : CINQ cartes (la cinquième mène à Valeur Enseignement Plus).
   En deux colonnes, la dernière, seule sur sa rangée, est centrée à la largeur
   d'une colonne plutôt que collée à gauche. */
@media (min-width: 700px) and (max-width: 1239.98px) {
    .activities-grid > :last-child:nth-child(odd) {
        grid-column: 1 / -1;
        justify-self: center;
        width: calc((100% - 2.5rem) / 2);
    }
}

/* 1240 et non 1280 : les media features s'évaluent sur le bloc conteneur initial,
   qui EXCLUT la barre de défilement. Le document étant plus haut que l'écran,
   une barre est toujours là (10px imposés par ::-webkit-scrollbar, 12 à 17 sous
   Firefox) : sur un écran de 1280px réels la largeur évaluée vaut 1270 au mieux,
   et le palier large n'était JAMAIS atteint. Depuis la 3.14.3, les cinq cartes
   y tiennent sur une rangée : gouttière et marges intérieures resserrées, titre
   un peu plus petit pour que « copropriétés » tienne sur une ligne dès 1240 px. */
@media (min-width: 1240px) {
    .activities-grid {
        grid-template-columns: repeat(5, 1fr);
        gap: 1.5rem;
    }
    .activities-grid .activity-content { padding: 2rem 1.25rem; }
    .activities-grid .activity-content h3 { font-size: 1.4rem; }
}

.activity-card {
    background: var(--bg-white);
    border-radius: 20px;
    overflow: hidden;
    box-shadow: var(--shadow-soft);
    transition: var(--transition);
    cursor: pointer;
    group: hover;
}

.activity-card:hover {
    transform: translateY(-15px);
    box-shadow: var(--shadow-hover);
}

.activity-img-wrapper {
    /* Hauteur figée à 280px alors que la carte varie de 619px de large (1 colonne)
       à 246px (4 colonnes) : le rapport parcouru allait de 2,21:1 à 0,84:1 pour
       une source en 3:2. object-fit:cover jetait de 22 à 44% de l'image, et en
       4 colonnes sur grand écran la vignette passait carrément en PORTRAIT. */
    height: auto;
    overflow: hidden;
    position: relative;
}

.activity-img-wrapper img {
    /* Le rapport est porté par l'IMG et non par le cadre : la hauteur du cadre
       devient celle de son enfant, et aucune hauteur en pourcentage n'a à se
       résoudre contre une hauteur dérivée d'aspect-ratio. Recadrage ramené de
       22-44% à 0,06% (source 1,5009, boîte 1,5000) à TOUTE largeur. */
    width: 100%; height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    transition: var(--transition);
    /* 3.14.3 : en ligne (inline), l'image de la 5e carte laissait 7,6 px de cadre
       sous elle. En bloc : 0 px partout. */
    display: block;
}

/* La vignette seule (l'<img> du cadre), pas le logo du bas de la carte
   Valeur Enseignement Plus. */
.activity-card:hover .activity-img-wrapper img { transform: scale(1.1); }

.activity-content {
    padding: 2.5rem 2rem;
    text-align: center;
}

.activity-content h3 {
    color: var(--primary);
    font-size: 1.6rem;
    margin-bottom: 1rem;
}

/* --- Carte Valeur Enseignement Plus (3.14.3 ; au milieu des cinq depuis la
   3.14.4) ------------------------------------------------------------------
   Pas d'emblème sur la photo (retiré à la demande de Guillaume : doublon avec
   le logo du bas de carte). La carte à deux liens de la 3.14.2 (« Petites
   copropriétés » avec son propre logo) a été retirée en 3.14.4, avec ses
   règles. */

/* Le « + » doré du nom, comme dans le logo de la formation. */
.activity-card__plus {
    color: var(--secondary-dark);
    margin-left: 2px;
}

/* Logo de la formation en bas de carte (emblème au-dessus du nom, comme sur
   valeurs-enseignement.fr), à la place de l'adresse du site. Ce n'est pas un
   lien à part : la carte entière est le lien, et le logo s'allume au survol
   de la carte. Au palier cinq colonnes, la zone utile descend à 164 px (1240
   px) : marges latérales en clamp (pourcentage de cette zone), max-width et
   retour à la ligne évitent tout débordement, y compris avec l'espacement de
   texte agrandi (WCAG 1.4.12). */
.lien-formation {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
    max-width: 100%;
    margin-top: 1.25rem;
    padding: 0.6rem clamp(0.4rem, calc((100% - 172px) / 2), 1.1rem) 0.55rem;
    border: 1px solid var(--secondary-light);
    border-radius: 14px;
    color: var(--primary);
    transition: border-color 0.3s, background-color 0.3s;
}

.activity-card--formation:hover .lien-formation {
    border-color: var(--secondary);
    background-color: var(--bg-base);
}

.lien-formation img {
    width: 72px;
    height: auto;
}

.lien-formation__nom {
    font-family: 'Playfair Display', serif;
    font-style: italic;
    font-weight: 600;
    font-size: 1.05rem;
    line-height: 1.1;
}

.lien-formation__nom b {
    color: var(--secondary-dark);
    font-style: normal;
    font-weight: 700;
    margin-left: 2px;
}

/* --- PAGE: ACHETER / LOUER ---------------------------------------------
   L ancien jeu de regles « Real Estate Gallery » vivait ici sans markup qui
   l utilise. Il est remplace par le bloc « BIENS DU PARTENAIRE » en fin de
   fichier. On le supprime plutot que de le laisser dormir : son height:300px
   sur .property-image l emportait sur l aspect-ratio du nouveau bloc, et les
   photos se retrouvaient etirees hors de leur proportion.
   -------------------------------------------------------------------------- */

/* --- PAGE: ESTIMATION & SYNDIC (Forms) --- */
.form-container {
    background: var(--bg-white);
    max-width: 800px;
    margin: 0 auto;
    padding: 4rem;
    border-radius: 24px;
    box-shadow: var(--shadow-hover);
}

.form-group {
    margin-bottom: 2rem;
}

.form-group label {
    display: block;
    margin-bottom: 0.8rem;
    color: var(--primary);
    font-weight: 600;
    font-size: 1.1rem;
}

.form-control {
    width: 100%;
    padding: 1.2rem;
    border: 2px solid #E2E8F0;
    border-radius: 12px;
    font-family: inherit;
    font-size: 1rem;
    transition: var(--transition);
    background: var(--bg-base);
}

.form-control:focus {
    outline: none;
    border-color: var(--secondary-dark);
    background: var(--bg-white);
    box-shadow: 0 0 0 4px rgba(212, 175, 55, 0.1);
}

/* --------------------------------------------------------------------------
   FORMULAIRES — CONTACT FORM 7
   Les gabarits CF7 réutilisent .form-group / .form-control / .btn du thème ;
   ce bloc ne style que ce que CF7 ajoute autour (sections, radios, erreurs).
   -------------------------------------------------------------------------- */
.wpcf7 { margin: 0; }
.wpcf7 .wpcf7-form-control-wrap { display: block; }

/* Deux champs côte à côte (empilés sur mobile). */
.form-row {
    display: grid;
    /* La rangée se décidait sur la largeur de la FENÊTRE (bascule à 768px) alors
       qu'elle vit dans trois conteneurs de largeurs très différentes. Sur la page
       Contact à 1025px elle disposait de 387px : deux champs de 177px, soit 135px
       de zone de frappe — une adresse e-mail y défile. auto-fit la fait dépendre
       de son CONTENEUR, sans media query. Deux colonnes exigent 2 x 16rem + 2rem
       = 544px de rangée. min(100%, 16rem) empêche tout débordement si la rangée
       est plus étroite que 16rem. Deux enfants seulement : aucun état 3 colonnes. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
    gap: 2rem;
}

/* Regroupement thématique de champs. */
.form-section + .form-section {
    margin-top: 1rem;
    padding-top: 2.5rem;
    border-top: 1px solid #E2E8F0;
}

.form-section-title {
    font-size: 1.5rem;
    color: var(--primary);
    margin-bottom: 2rem;
}

/* Carte blanche du formulaire de contact. */
.vi-form-card {
    background: var(--bg-white);
    padding: 4rem;
    border-radius: 24px;
    box-shadow: var(--shadow-soft);
}

/* Boutons radio et cases à cocher. */
.wpcf7 .wpcf7-list-item { margin: 0 2rem 0 0; display: inline-block; }
.wpcf7 .wpcf7-list-item-label { color: var(--text-dark); font-weight: 500; }
.wpcf7 input[type="radio"],
.wpcf7 input[type="checkbox"] {
    accent-color: var(--secondary);
    margin-right: 0.5rem;
    vertical-align: middle;
}

/* Consentement RGPD. */
.form-consent {
    margin: 2rem 0;
    font-size: 0.95rem;
    color: #64748B;
}
.form-consent .wpcf7-list-item { margin: 0; display: block; }

/* Bouton d'envoi pleine largeur (classe posée dans le gabarit CF7). */
.wpcf7 .btn-full { width: 100%; margin-top: 1rem; }
.wpcf7 input[type="submit"] { font-family: inherit; }

/* Erreurs de validation. */
.wpcf7 .wpcf7-not-valid-tip {
    color: #DC2626;
    font-size: 0.9rem;
    margin-top: 0.5rem;
}
.wpcf7 .form-control.wpcf7-not-valid {
    border-color: #DC2626;
    background: #FEF2F2;
}

/* Bandeau de réponse après envoi. */
.wpcf7 .wpcf7-response-output {
    margin: 2rem 0 0;
    padding: 1.2rem 1.5rem;
    border: 2px solid #E2E8F0;
    border-radius: 12px;
    font-weight: 500;
}
.wpcf7 form.sent .wpcf7-response-output {
    border-color: #16A34A;
    background: #F0FDF4;
    color: #15803D;
}
.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output {
    border-color: #DC2626;
    background: #FEF2F2;
    color: #B91C1C;
}

.wpcf7 .wpcf7-spinner { margin: 0 0 0 1rem; }

/* --- PAGE: AGENCE --- */
.agency-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    align-items: center;
}

.agency-image {
    border-radius: 30px;
    overflow: hidden;
    box-shadow: var(--shadow-hover);
}

.agency-image img {
    width: 100%;
    height: auto;
    display: block;
}

.agency-text p {
    font-size: 1.2rem;
    color: #475569;
    margin-bottom: 1.5rem;
}

.quote-block {
    margin-top: 3rem;
    /* 96px de rembourrage latéral figés sur une boîte de 252px à 280px de
       fenêtre, soit 38% du bloc perdu en marge. 5vw atteint 48px dès 960px :
       au-dessus, le rendu est identique au pixel. */
    padding: clamp(1.5rem, 5vw, 3rem);
    background: var(--primary);
    border-radius: 20px;
    color: var(--secondary);
    /* 28,8px figés dans une colonne de 241px à 375px : 17 caractères par ligne.
       À 280px le mot « essentielle » est plus large que la colonne et se coupe.
       Cette citation avait échappé à la passe de clamp() qui a traité .bloc-titre. */
    font-size: clamp(1.15rem, 3.5vw, 1.8rem);
    line-height: 1.4;
    text-align: center;
}

/* --- PAGE: CONTACT --- */
.contact-grid {
    display: grid;
    grid-template-columns: 1fr 1.5fr;
    gap: 4rem;
}

.contact-card {
    background: var(--primary);
    color: var(--text-light);
    padding: 4rem 3rem;
    border-radius: 24px;
    box-shadow: var(--shadow-hover);
}

.contact-card h3 {
    color: var(--secondary);
    font-size: 2.5rem;
    margin-bottom: 2rem;
}

.contact-item {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    margin-bottom: 2rem;
    font-size: 1.2rem;
}

.contact-item svg {
    color: var(--secondary);
    width: 30px; height: 30px;
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
footer {
    background: var(--primary);
    color: var(--text-light);
    text-align: center;
    padding: 4rem 5%;
    border-top: 1px solid rgba(255,255,255,0.05);
    margin-top: 5rem;
}

/* --------------------------------------------------------------------------
   PIED DE PAGE — coordonnées visibles (NAP)
   -------------------------------------------------------------------------- */
.footer-inner {
    max-width: 900px;
    margin: 0 auto;
}

.footer-logo {
    display: inline-block;
    margin-bottom: 2rem;
}
.footer-logo img { height: 55px; width: auto; display: block; }

.footer-nap {
    font-style: normal;
    line-height: 2;
    color: #CBD5E1;
    margin-bottom: 2rem;
}
.footer-nap strong { color: var(--secondary); font-weight: 600; }
.footer-nap a { color: var(--text-light); border-bottom: 1px solid rgba(212, 175, 55, 0.4); }
.footer-nap a:hover { color: var(--secondary); border-bottom-color: var(--secondary); }

.footer-links {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 1rem 2rem;
    margin-bottom: 2.5rem;
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 1.5px;
}
.footer-links a { color: #94A3B8; transition: color 0.3s; }
.footer-links a:hover { color: var(--secondary); }

/* --- Liens vers les pages autonomes --------------------------------------
   Bloc distinct de .footer-links, qui ne contient que des ancres de la SPA.
   Les melanger induirait en erreur : une ancre fait defiler, un lien de page
   charge un autre document. Deux comportements, deux groupes. */
.footer-pages {
    margin-bottom: 2.5rem;
    padding-bottom: 2.5rem;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}

.footer-pages__titre {
    color: var(--secondary);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    margin-bottom: 1.1rem;
}

.footer-pages ul {
    list-style: none;
    padding: 0;
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.8rem 1.8rem;
    font-size: 0.95rem;
}

.footer-pages a { color: #94A3B8; transition: color 0.3s; }
.footer-pages a:hover { color: var(--secondary); }

/* --- Informations légales -------------------------------------------------
   Même traitement que .footer-pages, et pour la même raison : ce sont des liens
   de document, pas des ancres. Elles vivaient auparavant dans .footer-legal, la
   ligne de copyright, en 0,9 rem gris foncé : illisibles en pratique. Ici le
   lien est souligné, parce qu'une mention légale se cherche du regard et doit
   se donner à voir comme un lien, pas comme du texte de bas de page. */
.footer-legales {
    margin-bottom: 1.5rem;
}

.footer-legales ul {
    list-style: none;
    padding: 0;
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.6rem 1.8rem;
    font-size: 0.95rem;
}

.footer-legales a {
    color: #94A3B8;
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: color 0.3s;
}

.footer-legales a:hover { color: var(--secondary); }

.footer-legal {
    /* #94A3B8 et non plus #64748B : sur le bleu nuit du pied de page, l'ancien gris
       ne faisait que 3,93:1 pour un texte de 14 px (seuil : 4,5:1). Même valeur
       que les autres liens du pied de page, 7,29:1. */
    color: #94A3B8;
    font-size: 0.9rem;
    padding-top: 2rem;
    border-top: 1px solid rgba(255,255,255,0.06);
}

.footer-legal a {
    color: #94A3B8;
    border-bottom: 1px solid rgba(212, 175, 55, 0.3);
}

.footer-legal a:hover { color: var(--secondary); border-bottom-color: var(--secondary); }

/* --------------------------------------------------------------------------
   PAGE 404
   Pas de classe "page" ici : app.js masque toute section.page au chargement.
   -------------------------------------------------------------------------- */
.page-404 {
    min-height: 100vh;
    display: flex;
    align-items: center;
    text-align: center;
    background: var(--primary);
    color: var(--text-light);
}

.page-404 .section-container { max-width: 640px; }

.page-404__code {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: clamp(5rem, 18vw, 11rem);
    line-height: 1;
    color: var(--secondary);
    opacity: 0.25;
    margin-bottom: -1rem;
}

.page-404 h1 {
    font-size: clamp(2rem, 5vw, 3rem);
    color: var(--text-light);
    margin-bottom: 1.5rem;
}

.page-404__texte {
    color: #CBD5E1;
    font-size: 1.15rem;
    margin-bottom: 3rem;
}

.page-404 .btn-group {
    display: flex;
    gap: 1.5rem;
    justify-content: center;
    flex-wrap: wrap;
}

/* La 404 est déjà sur fond navy : pas d'écart clair entre elle et le pied de page. */
.page-404 + footer { margin-top: 0; }

/* Sur la 404 (WordPress ajoute la classe error404 au body), la navbar est posée sur
   un fond navy dès le chargement : on force le logo blanc, le logo couleur ayant des
   parties navy qui disparaîtraient. */

/* ==========================================================================
   ANIMATIONS & MEDIA QUERIES
   ========================================================================== */
@keyframes fadeInUP {
    from { opacity: 0; transform: translateY(40px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Chaîne mesurée à 1025px, premier pixel où la grille repassait en 2 colonnes :
     .contact-grid 1fr 1.5fr, gap 4rem -> colonne 1 = 0,4 x (922,5 - 64) = 343,4
     .contact-card padding 4rem 3rem   -> intérieur = 247,4px
     .contact-item : svg 30 + gap 24   -> 193,4px pour le texte
   « bonjour@valeurs-immo.fr » à 1.2rem en réclame ~220 : l'adresse se coupait.
   À 1024px la même carte disposait de 816px : une division par 3,3 pour UN pixel
   de fenêtre. À 1200px elle offre 253px de texte, l'adresse tient. */
@media (max-width: 1200px) {
    .agency-split, .contact-grid { grid-template-columns: 1fr; }
}

/* Nav resserrée pour laisser la place au bouton Extranet.
   Seuil porté de 1024 à 1344 px. Largeurs MESURÉES sur le site déployé, avec
   les huit liens (Syndic ajouté) et le logo :
       rangée en taille pleine ... 1170 px
   La barre dispose de 0,9 × la fenêtre. Il lui faut donc 1300 px de fenêtre
   pour tenir tout juste, et 1345 px pour garder 40 px de marge. D'où le seuil.
   Une première tentative à 1259 px reposait sur une simulation en injectant un
   <a> nu : elle sous-estimait la rangée de 38 px, et la barre débordait encore
   de 17 px à 1280 et de 35 px à 1260. Les chiffres ci-dessus, eux, sont relevés
   sur la page livrée. Le débordement était invisible : body{overflow-x:hidden}
   (l.49) l'avalait, emportant le bouton Extranet, dernier de la rangée. */
@media (max-width: 1344px) {
    .nav-links { gap: 1.5rem; }
    .nav-links a { font-size: 0.9rem; letter-spacing: 1.2px; }
    .nav-links a.nav-extranet { padding: 0.55rem 1.15rem; }
}

/* ==========================================================================
   MENU DÉROULANT — seuil mesuré, et non conventionnel.
   Largeurs MESURÉES sur le site déployé, huit liens plus le logo :
       rangée en taille pleine ... 1170 px  ->  tient à partir de 1300 px
       rangée resserrée .........  943 px  ->  tient à partir de 1048 px
   Sous 1048 px, même resserrée, la rangée ne rentre plus : il faut basculer en
   menu déroulant. Le seuil est posé à 1092 et non à 1048 pour conserver 40 px
   de marge — à 1061 px la marge mesurée n'était que de 13 px, sous l'écart de
   rendu des glyphes d'Outfit d'un navigateur à l'autre.
   On bascule donc sur toute la plage ≤ 1092 px, et non au 768 px habituel : le
   seuil suit l'arithmétique du contenu, pas la convention.
   Aucune modification de app.js : le <button id="mobile-menu"> existe à toutes
   les largeurs (header.php) et son gestionnaire (app.js l.295) ne teste ni
   largeur ni matchMedia.
   ========================================================================== */
@media (max-width: 1092px) {
    .menu-toggle { display: block; }
    .nav-links {
        position: absolute;
        top: 100%; left: 0; width: 100%;
        background: var(--primary);
        flex-direction: column;
        /* La gouttiere du site : les liens du panneau tombent sur la meme
           verticale que le logo au-dessus d'eux. */
        padding: 2rem var(--vi-gutter, 5vw);
        display: none;
        box-shadow: 0 24px 48px rgba(10, 17, 40, 0.35);
        /* Le panneau est en position:absolute dans un ancetre position:fixed : il
           ne contribue PAS a la region de debordement defilable de la fenetre. Sur
           un telephone en paysage il mesure ~411px sous une barre de 84px, et les
           dernieres destinations etaient purement inatteignables - ni au doigt, ni
           a la molette, ni au clavier. On lui rend son propre defilement. */
        max-height: calc(100vh - var(--vi-nav-h, 120px) - 1rem);
        overflow-y: auto;
        overscroll-behavior: contain;
        /* overflow-y:auto force overflow-x en `auto` : un enfant plus large que le
           panneau deborderait des DEUX cotes a cause du align-items:center herite,
           et le cote gauche serait inatteignable. `safe` ne bascule en flex-start
           qu'en cas de debordement reel ; non reconnu, la declaration est ignoree. */
        align-items: safe center;
    }
    .nav-links.show { display: flex; }
    /* En colonne la place ne manque plus : les liens retrouvent leur taille. */
    .nav-links a { font-size: 1rem; letter-spacing: 1.5px; }
    .nav-links a.nav-extranet { margin-top: 0.5rem; padding: 0.85rem 2rem; }
    /* Entre 769 et 1060 px la barre n'a aucun fond au repos (seuls .scrolled et
       le bloc ≤768 en posent un) : sans cette règle, le panneau bleu nuit
       flotterait sous une barre transparente. Si :has() n'est pas reconnu, la
       règle entière est ignorée et l'on retombe sur l'ancien rendu. */
    #navbar:has(.nav-links.show) { background: var(--primary); }
}

@media (max-width: 768px) {
    #navbar { padding: 1rem 5%; background: var(--primary); }
    .hero p { font-size: 1.15rem; line-height: 1.5; margin-bottom: 2.5rem; }
    .hero .hero-kicker { margin-bottom: 0.4rem; }
    /* 128px de reserve pour une barre mobile qui n'en mesure que 84 : 44px d'ecran
       gaspilles, precisement sur les appareils qui en ont le moins. */
    #page-home .hero { padding: calc(var(--vi-nav-h, 84px) + 1.5rem) 1.5rem 2.5rem; }
    /* `height` doit disparaitre : il resterait en conflit avec le height:auto de
       la regle de base. Et min-height doit etre redeclare, sinon le mobile
       heriterait du min(60vh, 26rem) et la bande GRANDIRAIT de 133px. */
    .page-header { min-height: min(40vh, 18rem); }
    .form-container { padding: 2rem; }
    .form-row { grid-template-columns: 1fr; gap: 0; }
    .vi-form-card { padding: 2rem; }
    /* navbar navy en permanence sur mobile -> logo blanc en permanence */
    .logo-img { height: 52px; }
    #navbar.scrolled .logo-img { height: 46px; }
}

/* ==========================================================================
   SCROLL REVEAL (classe ajoutée par app.js -> aucun masquage si JS absent)
   ========================================================================== */
.js-reveal {
    opacity: 0;
    transform: translateY(32px);
    transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}

.js-reveal.is-visible {
    opacity: 1;
    transform: none;
}

/* ==========================================================================
   ACCESSIBILITÉ : respect de « réduire les animations »
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
    .hero-content > *,
    .js-reveal {
        opacity: 1 !important;
        transform: none !important;
    }
    section.page.is-entering .section-container,
    section.page.is-entering .hero-content { animation: none !important; }
}

/* Au survol, .btn-primary devient transparent avec un texte or. Sur le fond blanc
   des cartes de formulaire, cet or tombe a 1,94:1 : on y bascule sur l or assombri. */
.form-container .btn-primary:hover,
.vi-form-card .btn-primary:hover {
    color: var(--secondary-dark);
    border-color: var(--secondary-dark);
}

/* --------------------------------------------------------------------------
   TITRES DE BLOC — tailles fluides
   Ces titres portaient leur taille en style en ligne (2 à 3 rem), donc hors de
   portée des media queries. Sur un écran de 375 px, « Reprenez la main sur votre
   copropriété à Montpellier » s'affichait en 48 px sur 4 lignes, soit 307 px de
   haut — 38 % de l'écran pour un seul titre. Les bornes hautes des clamp()
   reprennent exactement les anciennes valeurs : le rendu desktop est inchangé.
   -------------------------------------------------------------------------- */
.bloc-titre {
    font-size: clamp(1.55rem, 5.2vw, 2.5rem);
    line-height: 1.2;
}
.bloc-titre--xl { font-size: clamp(1.7rem, 6vw, 3rem); }
.bloc-titre--sm { font-size: clamp(1.4rem, 4.6vw, 2rem); }

/* --------------------------------------------------------------------------
   AUCUNE OFFRE DISPONIBLE — section Acheter (Louer retirée en 3.14.0)
   Remplace les grilles d'annonces. Carte blanche centrée, sur le fond clair
   du site : l'or y est donc l'or assombri, l'or de la charte n'atteignant
   que 1,94:1 de contraste sur ce fond.
   -------------------------------------------------------------------------- */
.aucune-offre {
    max-width: 720px;
    margin: 0 auto;
    text-align: center;
    background: var(--bg-white);
    border-radius: 24px;
    padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 5vw, 3.5rem);
    box-shadow: var(--shadow-soft);
}

.aucune-offre__marque {
    color: var(--secondary-dark);
    font-size: clamp(1.5rem, 4.5vw, 2rem);
    line-height: 1;
    margin-bottom: 1.5rem;
}

.aucune-offre h3 {
    color: var(--primary);
    margin-bottom: 1.5rem;
}

.aucune-offre__texte {
    color: #475569;
    font-size: 1.1rem;
    line-height: 1.75;
    margin-bottom: 2.5rem;
}

.aucune-offre .btn-group {
    display: flex;
    gap: 1.25rem;
    justify-content: center;
    flex-wrap: wrap;
}

.aucune-offre .btn-outline,
.aucune-offre .btn-primary:hover {
    color: var(--secondary-dark);
    border-color: var(--secondary-dark);
}

.aucune-offre .btn-outline:hover {
    background: var(--secondary-dark);
    color: var(--bg-white);
}

/* --------------------------------------------------------------------------
   LIENS VERS LES PAGES DE PRESTATION, depuis les sections de l'accueil
   Ce sont les liens qui relient l'accueil — la page la plus forte du site — aux
   pages qui doivent se positionner, avec une ancre qui dit de quoi parle la page
   cible. Ils doivent donc se voir comme des liens : or assombri, souligné, et une
   flèche qui annonce qu'on change de page. La flèche est décorative, portée par
   ::after : le lecteur d'écran n'en lit rien.
   -------------------------------------------------------------------------- */
.lien-detail {
    color: var(--secondary-dark);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-thickness: 1px;
    transition: color 0.3s;
}

.lien-detail::after {
    content: " \2192";
    /* Texte de remplacement vide : la flèche est décorative, un lecteur d'écran
       ne doit pas la lire. Le navigateur qui ignore cette syntaxe garde la
       ligne précédente. */
    content: " \2192" / "";
    text-decoration: none;
    display: inline-block;
    margin-left: 0.15em;
    transition: transform 0.3s;
}

.lien-detail:hover { color: var(--primary); }
.lien-detail:hover::after { transform: translateX(3px); }

.lien-detail-ligne {
    margin-top: 1.5rem;
    font-size: 1.05rem;
}

/* --------------------------------------------------------------------------
   ACCESSIBILITÉ — utilitaires
   Le thème n'avait aucun de ces éléments : ni classe pour lecteur d'écran, ni
   lien d'évitement, et :focus-visible n'était défini que pour le bouton Extranet.
   -------------------------------------------------------------------------- */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Lien d'évitement : masqué hors focus, il apparaît à la première tabulation. */
.skip-link {
    position: absolute;
    left: 1rem; top: -6rem;
    z-index: 2000;
    background: var(--bg-white);
    color: var(--primary);
    padding: 0.75rem 1.25rem;
    border-radius: 4px;
    font-weight: 600;
    transition: top 0.2s;
}
.skip-link:focus { top: 1rem; }

/* Anneau de focus lisible aussi bien sur la navbar bleu nuit que sur fond clair. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--bg-white);
    outline-offset: 2px;
    box-shadow: 0 0 0 6px var(--primary);
    border-radius: 2px;
}

/* Cible de focus PROGRAMMATIQUE (le titre de la section entrante) : pas de
   contour, l'utilisateur n'a pas tabulé jusque-là, il a cliqué un lien. */
section.page > .page-header > h2:focus,
#page-home h1:focus { outline: none; box-shadow: none; }


/* ==========================================================================
   RAIL DE COMPOSITION - LA NAVBAR REJOINT LE CONTENU
   Position en fin de fichier IMPOSEE : #navbar (1,0,0) doit battre le
   `padding: 1rem 5%` du bloc <=768, et #navbar.scrolled (1,1,0) le raccourci de
   la regle .scrolled. A specificite egale, seul l'ordre source departage.
   ========================================================================== */

/* Sous 768px la barre mesure 84px et non 120 : le token suit, et avec lui la
   reserve haute du hero et de la bande d'en-tete. Une seule verite. */
@media (max-width: 768px) {
    :root { --vi-nav-h: 84px; }
}

/* Le fond, l'ombre et le flou de la barre restent pleine largeur - c'est ce qui
   fait l'etat .scrolled. Seule sa reserve interieure se cale sur la colonne de
   contenu.
   `100%` et NON `100vw` : pour un element position:fixed le bloc conteneur est
   la zone d'affichage HORS barre de defilement, exactement la base sur laquelle
   .section-container calcule sa marge automatique. 100vw inclurait les 10px de
   la barre et decalerait de 5px.
   Alignement verifie, bord gauche du logo contre bord gauche du contenu :
     1024 ->   51,2 /   51,2      1920 ->  325,0 /  325,0
     1400 ->   70,0 /   70,0      2560 ->  645,0 /  645,0
     1440 ->   85,0 /   85,0      3440 -> 1085,0 / 1085,0
   Ecart nul partout. AVANT correctif : 255px d'ecart a 1920, 1015px a 3440,
   1855px a 5120 - la barre partait dans les coins pendant que le contenu restait
   au centre. C'est precisement ce que le client decrivait par « le site s'etire
   trop et ne garde pas une mise en page normale de site web ».
   Sous 1400px le second terme est negatif et max() retombe sur la gouttiere :
   le rendu mobile et tablette ne bouge pas. */
#navbar,
#navbar.scrolled {
    padding-inline: max(
        var(--vi-gutter, 5vw),
        calc((100% - var(--vi-max, 1400px)) / 2 + var(--vi-gutter, 5vw))
    );
}


/* --------------------------------------------------------------------------
   MESURES DE LECTURE
   Contrepartie OBLIGATOIRE du passage des grilles a une colonne jusqu'a 1200px :
   sans elles on echangerait une carte contact ecrasee contre des paragraphes de
   112 caracteres par ligne - un defaut pour un autre.
   -------------------------------------------------------------------------- */

/* En deux colonnes la grille bornait deja la mesure ; en une colonne plus rien
   ne la borne et le paragraphe atteint 96 caracteres a 1024px, 112 a 1200px.
   44rem = 704px soit ~73 caracteres. Regle INERTE en deux colonnes : la colonne
   agence vaut 598px a 1410px comme a 3440px. Elle n'agit donc QUE dans la plage
   ou le defaut existe. */
.agency-text p,
.contact-card p { max-width: 44rem; }

/* Page Services : le conteneur est plafonne a 1000px par un style en ligne et le
   corps est a 1.2rem. Apres le rail, la colonne se fige a 860px, soit ~90
   caracteres. On borne le DESCENDANT et non le conteneur : aucune modification
   HTML, aucun !important. Pas de media query - la longueur de ligne est MAXIMALE
   vers 1000px de fenetre et decroit ensuite, un scope en min-width aurait laisse
   le pire cas non corrige. */
#page-services .section-container > div > p { max-width: 45rem; }

/* La carte contact est le SEUL bloc a fond du theme sans surcharge de
   rembourrage : 3rem lateral, soit 96px, restaient constants de 5120px jusqu'au
   Galaxy Fold. A 320px cela consomme 33% de la carte et il ne reste que 192px,
   quand l'adresse e-mail et son icone en reclament ~250. Les bornes hautes sont
   atteintes des 800px de fenetre : au-dessus, rendu inchange. */
.contact-card { padding: clamp(2rem, 8vw, 4rem) clamp(1.25rem, 6vw, 3rem); }


/* --------------------------------------------------------------------------
   .btn-group : LA REGLE DE BASE MANQUANTE
   Le theme ne stylait ce composant que par contexte (.page-404 et .aucune-offre).
   Le groupe du hero restait un bloc nu contenant deux inline-block separes par le
   seul blanc du code source, soit ~4px : des qu'ils passaient a la ligne - c'est
   a dire sur tout telephone, les deux boutons reclamant ~520px - les deux
   pastilles se touchaient. 1.25rem n'est pas un choix esthetique : c'est
   exactement la valeur deja utilisee par le theme pour ce meme composant.
   Les deux regles contextuelles sont en (0,2,0) : elles gardent leurs valeurs,
   celle-ci n'atteint que le hero.
   -------------------------------------------------------------------------- */
.btn-group {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1.25rem;
}


/* --------------------------------------------------------------------------
   ECRANS BAS - la seule famille d'ecrans que le theme ignorait totalement.
   Le fichier ne contenait AUCUNE media query de hauteur ni d'orientation : les
   cinq blocs existants etaient tous indexes sur la largeur. Or sur un telephone
   en paysage c'est la hauteur qui manque, et les clamp() etant bornes en vw, la
   largeur abondante commandait une typographie de grand ecran.
   -------------------------------------------------------------------------- */

/* Barre compacte. Scope en min-width:769px pour ne JAMAIS remonter le logo
   mobile, deja a 52px, jusqu'a 60px. Le seuil de 500px n'attrape que des
   appareils en paysage (390, 428, 430px de haut) et jamais un portable : un
   1366x768 maximise conserve environ 630px de vue.
   0.5rem x 2 + 60 = 76px, valeur que le token declare : la reserve haute du hero
   et de la bande suit automatiquement, et l'on recupere 44px sur chacun. */
@media (min-width: 769px) and (max-height: 500px) {
    :root { --vi-nav-h: 76px; }
    #navbar,
    #navbar.scrolled { padding-block: 0.5rem; }
    .logo-img,
    #navbar.scrolled .logo-img { height: 60px; }
}

/* Rythme vertical resserre. 640px attrape aussi bien un telephone en paysage
   qu'un 1366x768 maximise (~630px de vue). On recupere 32px sur la marge de la
   bande et 48px par section, sans toucher a la gouttiere laterale :
   padding-block ne touche que l'axe de bloc, la valeur horizontale survit. */
@media (max-height: 640px) {
    .page-header { margin-bottom: 2rem; }
    .section-container { padding-block: 2.5rem; }
}


/* --------------------------------------------------------------------------
   ACCESSIBILITE - un fond attache a la fenetre EST un mouvement.
   background-attachment n'est ni une animation ni une transition : aucune des
   declarations universelles du bloc prefers-reduced-motion ne peut l'atteindre.
   C'etait le seul mouvement qui survivait a « reduire les animations », et le
   hero pouvant desormais depasser 100vh, c'est aussi le seul cas ou le cadrage
   du fond se recalcule. Le calque degrade est deja en `scroll`, aucun effet de
   bord.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    #page-home .hero { background-attachment: scroll; }
}
/* --------------------------------------------------------------------------
   BIENS DU PARTENAIRE — section « Acheter »
   Les annonces affichées sont celles de Julien Gondrand (LGM Immobilier).
   Le bandeau d'attribution n'est pas décoratif : Valeurs'Immo n'est pas
   mandataire de ces biens, et le visiteur doit le comprendre avant de cliquer.
   -------------------------------------------------------------------------- */

.partenaire {
    background: var(--bg-white);
    border-radius: 24px;
    border-left: 4px solid var(--secondary-dark);
    padding: clamp(1.75rem, 4vw, 2.75rem) clamp(1.5rem, 4vw, 3rem);
    box-shadow: var(--shadow-soft);
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.partenaire__mention {
    color: var(--secondary-dark);
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    margin-bottom: 0.6rem;
}

.partenaire__titre {
    color: var(--primary);
    margin-bottom: 1.1rem;
}

.partenaire__texte {
    color: #475569;
    font-size: 1.05rem;
    line-height: 1.75;
    max-width: 68ch;
}

.partenaire__texte--fin {
    margin-top: 0.9rem;
}

.partenaire__texte a {
    color: var(--secondary-dark);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* --- La grille -----------------------------------------------------------
   L'ancien réglage repeat(auto-fit, minmax(350px, 1fr)) laissait la grille
   monter à 4 colonnes au-delà de 1600 px : sur un écran large, les cartes
   s'étiraient bien au-delà d'une largeur lisible. On plafonne donc le nombre
   de colonnes par paliers explicites, cohérents avec la bascule à 1200 px
   retenue partout ailleurs dans le thème.
   -------------------------------------------------------------------------- */
.property-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.5rem, 3vw, 2.5rem);
    list-style: none;
    margin: 0;
    padding: 0;
}

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

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

/* --- La carte ------------------------------------------------------------ */
.property-card {
    position: relative;               /* support de la zone cliquable étendue */
    display: flex;
    flex-direction: column;
    background: var(--bg-white);
    border-radius: 20px;
    overflow: hidden;
    box-shadow: var(--shadow-soft);
    transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.property-card:hover {
    transform: translateY(-8px);
    box-shadow: var(--shadow-hover);
}

/* Le survol ne doit pas déplacer les cartes pour qui a demandé moins
   d'animation : la règle du thème s'applique ici aussi. */
@media (prefers-reduced-motion: reduce) {
    .property-card,
    .property-card:hover { transition: none; transform: none; }
    .property-card:hover .property-image img { transform: none; }
}

.property-image {
    position: relative;
    aspect-ratio: 4 / 3;              /* réserve la place : aucun décalage au chargement */
    background-color: #E2E8F0;
    overflow: hidden;
}

.property-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}

.property-card:hover .property-image img {
    transform: scale(1.06);
}

/* Le badge est posé sur la photo : il lui faut une laisse. « Local commercial »
   fait 16 caractères et, sans max-width, la pastille traversait la vignette sur
   un écran de 360 px. */
.property-badge {
    position: absolute;
    top: 14px;
    left: 14px;
    max-width: calc(100% - 28px);
    background: var(--primary);
    color: var(--bg-white);
    padding: 0.4rem 1rem;
    border-radius: 30px;
    font-weight: 600;
    font-size: 0.8rem;
    line-height: 1.3;
    letter-spacing: 0.04em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.property-info {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: clamp(1.25rem, 2.5vw, 1.75rem);
}

.property-price {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: clamp(1.5rem, 3.4vw, 1.9rem);
    font-weight: 700;
    color: var(--primary);
    line-height: 1.2;
}

.property-city {
    color: var(--secondary-dark);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-top: 0.35rem;
}

.property-title {
    font-size: 1.02rem;
    font-weight: 600;
    line-height: 1.45;
    color: var(--text-dark);
    margin-top: 0.75rem;
}

.property-title a {
    color: inherit;
    text-decoration: none;
}

/* La carte entière est cliquable, mais le lien reste porté par le titre :
   un seul lien par carte dans l'arbre d'accessibilité, et un intitulé qui a
   du sens hors contexte grâce à son aria-label (titre + « voir l'annonce… »).
   Depuis la 3.13.3, PAS de span .sr-only dans le titre : il faisait partie du
   texte des 14 titres, que les moteurs lisent. */
.property-title a::after {
    content: "";
    position: absolute;
    inset: 0;
}

.property-card:focus-within {
    outline: 3px solid var(--secondary-dark);
    outline-offset: 3px;
}

.property-title a:focus-visible {
    outline: none;                    /* l'anneau est porté par la carte */
}

/* Les caractéristiques sont séparées par l'espacement seul. Un séparateur en
   ::before se retrouvait orphelin en début de ligne dès que la liste passait
   sur deux lignes — ce qui arrive dès qu'un bien a un terrain. */
.property-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.1rem;
    list-style: none;
    margin: 1rem 0 0;
    padding: 1rem 0 0;
    border-top: 1px solid #E2E8F0;
    color: #64748B;
    font-size: 0.92rem;
}

.property-meta li {
    white-space: nowrap;
}

.property-fees {
    margin-top: 0.75rem;
    color: #64748B;
    font-size: 0.82rem;
}

/* --- Étiquettes DPE / GES ------------------------------------------------
   Couleurs de l'échelle réglementaire française, du vert (A) au rouge (G).
   Le texte est sombre sur les classes claires : du blanc sur le jaune D ne
   passerait pas le seuil de contraste, quand bien même c'est courant sur les
   portails d'annonces.
   -------------------------------------------------------------------------- */
.property-dpe {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.9rem;
}

.etiquette {
    display: inline-flex;
    align-items: baseline;
    gap: 0.3rem;
    padding: 0.28rem 0.6rem;
    border-radius: 6px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: #1A2E05;
    background: #E2E8F0;
}

.etiquette strong {
    font-size: 0.86rem;
    font-weight: 800;
}

.etiquette--a { background: #A8E6B8; }
.etiquette--b { background: #BEE9A8; }
.etiquette--c { background: #DCEFA2; }
.etiquette--d { background: #F7EDA0; }
.etiquette--e { background: #FAD9A0; }
.etiquette--f { background: #F8C2A0; }
.etiquette--g { background: #F6B0AC; }

/* Mention imposée au mot près pour les logements classés F ou G. Elle doit se
   voir : on lui donne le rouge de l'échelle, pas un gris de bas de page. */
.property-passoire {
    margin-top: 0.6rem;
    padding: 0.35rem 0.6rem;
    border-radius: 6px;
    background: #F6B0AC;
    color: #4A0D0A;
    font-size: 0.78rem;
    font-weight: 600;
}

/* Mentions réglementaires de la carte : dépenses d'énergie, charges de
   copropriété. Volontairement discrètes — elles doivent être lisibles, pas
   dominer la vignette. Elles sont poussées en bas de carte pour que les
   caractéristiques restent alignées d'une carte à l'autre. */
.property-mentions {
    margin-top: auto;
    padding-top: 0.9rem;
    /* #64748B et pas un gris plus clair : à 0,74 rem on est sous les 18,5 px,
       donc c'est du texte normal au sens WCAG et il faut 4,5:1. Ce gris tient
       4,76:1 sur blanc ; le gris bleuté plus clair essayé d'abord tombait à 3,7. */
    color: #64748B;
    font-size: 0.74rem;
    line-height: 1.55;
}

.property-mentions p + p {
    margin-top: 0.3rem;
}

/* --- Mentions de bas de section ------------------------------------------ */
.property-source {
    margin-top: clamp(2rem, 4vw, 3rem);
    color: #64748B;
    font-size: 0.86rem;
    line-height: 1.7;
    max-width: 82ch;
}

.property-source a {
    color: var(--secondary-dark);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.property-source__lien {
    display: inline-block;
    margin-top: 0.6rem;
    font-weight: 600;
}


/* ==========================================================================
   PAGES AUTONOMES INDEXABLES
   ==========================================================================
   Gabarit page.php. Ces pages sont des documents ordinaires : pas de
   section.page, donc pas de routeur, pas d'animation d'entree, et un contenu
   qui s'affiche meme sans JavaScript.

   Tout est porte ici par .vi-contenu et ses descendants, parce que le contenu
   vient de l'editeur WordPress : on ne maitrise pas le balisage produit, on ne
   peut donc pas compter sur des classes. On style les BALISES, dans une portee
   fermee, pour ne rien deborder sur le reste du site.
   ========================================================================== */

/* --- Bandeau de titre -----------------------------------------------------
   .page-header ne stylait que h2, parce que la SPA n'a qu'un seul h1 (l'accueil)
   et que ses sept sections sont des h2. Une page autonome, elle, porte un vrai
   h1 : sans cette regle il heritait de la taille par defaut du navigateur, en
   noir sur une photo sombre. On reprend a l'identique les valeurs du h2. */
.page-header h1 {
    font-size: clamp(1.9rem, 6.5vw, 4rem);
    color: var(--secondary);
    z-index: 2;
    animation: fadeInUP 0.5s ease;
    max-width: 22ch;
}

/* Une image par page, comme pour les sections de la SPA : le visiteur qui
   arrive depuis la carte « Nos metiers » correspondante retrouve la meme photo.
   Les deux pages legales restent sur l'aplat bleu nuit — leur illustrer un
   bandeau serait du decor sans intention. */
.vi-p-syndic-de-copropriete-montpellier  .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/expertise-4-800.webp'); }
.vi-p-changer-de-syndic-montpellier      .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/expertise-2-800.webp'); }
/* 3.14.0 : bandeaux des pages ajoutées en 3.13. Jusqu'ici leur image était
   préchargée en priorité haute (clé 'image' du catalogue) sans être affichée :
   un téléchargement pour rien. Même photo que leur carte de l'accueil. */
.vi-p-syndic-petite-copropriete-montpellier      .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/expertise-3-800.webp'); }
.vi-p-syndic-copropriete-saint-jean-de-vedas     .page-header,
.vi-p-syndic-copropriete-pignan                  .page-header,
.vi-p-syndic-copropriete-ouest-montpellier       .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/expertise-4-800.webp'); }
.vi-p-vendre-appartement-copropriete-montpellier .page-header { background-image: url('https://valeurs-immo.fr/wp-content/uploads/2026/09/expertise-1-800.webp'); }

/* Le bandeau des pages autonomes ouvre le document : sa marge basse de 4rem
   ferait double emploi avec le rembourrage de .section-container. */
.vi-autonome .page-header { margin-bottom: 0; }

/* --- Fil d'Ariane --------------------------------------------------------- */
.vi-fil {
    font-size: 0.9rem;
    /* #5E6D83 : le fil d'Ariane est posé sur --bg-base, où #64748B ne faisait que
       4,40:1 pour du texte de 14 px. Celui-ci tient 4,86:1. */
    color: #5E6D83;
    margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}

.vi-fil a {
    color: var(--secondary-dark);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.vi-fil a:hover { color: var(--primary); }

.vi-fil__sep { margin: 0 0.5rem; }

/* --- Corps editorial ------------------------------------------------------
   Mesure bornee a 72ch. Le conteneur monte a 1260px sur grand ecran : une ligne
   de texte courant y atteindrait 180 caracteres, ou l'oeil perd le debut de la
   ligne suivante. La limite ne s'applique qu'au texte, pas aux tableaux. */
.vi-contenu {
    max-width: 72ch;
    color: var(--text-dark);
    font-size: clamp(1rem, 2.4vw, 1.08rem);
    line-height: 1.8;
}

.vi-contenu > * + * { margin-top: 1.4rem; }

.vi-contenu h2 {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: clamp(1.5rem, 4.2vw, 2.1rem);
    color: var(--primary);
    line-height: 1.25;
    margin-top: 3.2rem;
}

.vi-contenu h3 {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: clamp(1.2rem, 3.2vw, 1.45rem);
    color: var(--secondary-dark);
    line-height: 1.3;
    margin-top: 2.4rem;
}

/* Le premier titre du contenu suit immediatement le fil d'Ariane : sa marge
   haute de 3.2rem y creuserait un trou sans raison. */
.vi-contenu > h2:first-child,
.vi-contenu > h3:first-child { margin-top: 0; }

/* Le reset global pose `ul { list-style: none }` pour les grilles de cartes de
   la SPA. Dans du texte redige, une liste sans puce ni retrait n'est plus une
   liste : on la retablit, strictement dans cette portee. */
.vi-contenu ul,
.vi-contenu ol {
    padding-left: 1.5rem;
    list-style: disc;
}

.vi-contenu ol { list-style: decimal; }

.vi-contenu li { margin-top: 0.6rem; }

.vi-contenu li::marker { color: var(--secondary-dark); }

/* Meme logique pour les liens : `a { color: inherit; text-decoration: none }`
   rendait indistinguable un lien au fil du texte. */
.vi-contenu a {
    color: var(--secondary-dark);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.vi-contenu a:hover { color: var(--primary); }

.vi-contenu strong { color: var(--primary); font-weight: 600; }

.vi-contenu blockquote {
    border-left: 3px solid var(--secondary);
    padding-left: 1.5rem;
    font-style: italic;
    color: #475569;
}

.vi-contenu table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}

.vi-contenu th,
.vi-contenu td {
    border: 1px solid #E2E8F0;
    padding: 0.75rem 1rem;
    text-align: left;
}

.vi-contenu th { background: var(--bg-base); color: var(--primary); font-weight: 600; }

/* --- Liste de définitions : l'identité de l'éditeur ------------------------
   Deux colonnes dès qu'il y a la place, une seule sur mobile. Le terme est mis
   en petites capitales grises et la valeur en corps normal : sur une page de
   mentions légales, c'est la VALEUR qu'on vient chercher, pas l'étiquette.
   -------------------------------------------------------------------------- */
.vi-contenu .vi-identite {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 1.5rem;
    margin: 0;
    padding: clamp(1.25rem, 3vw, 1.75rem) clamp(1rem, 3vw, 1.75rem);
    background: var(--bg-white);
    border-radius: 16px;
    border-left: 3px solid var(--secondary-dark);
    box-shadow: var(--shadow-soft);
}

@media (min-width: 620px) {
    .vi-contenu .vi-identite { grid-template-columns: minmax(10rem, 14rem) 1fr; }
}

.vi-contenu .vi-identite dt {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #64748B;
    padding-top: 0.75rem;
}

.vi-contenu .vi-identite dd {
    margin: 0;
    padding-top: 0.2rem;
    color: var(--text-dark);
}

@media (min-width: 620px) {
    .vi-contenu .vi-identite dd { padding-top: 0.7rem; }
}

/* Le premier couple ne doit pas décoller du bord haut de la carte. */
.vi-contenu .vi-identite dt:first-of-type,
.vi-contenu .vi-identite dd:first-of-type { padding-top: 0; }

.vi-maj {
    /* Même fond que le fil d'Ariane, même correction de contraste. */
    color: #5E6D83;
    font-size: 0.9rem;
}

/* --- Maillage vers les autres prestations --------------------------------- */
.vi-connexes { margin-top: clamp(3rem, 7vw, 5rem); }

.vi-connexes h2 {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: clamp(1.4rem, 3.6vw, 1.9rem);
    color: var(--primary);
    margin-bottom: 1.8rem;
}

.vi-connexes__liste {
    list-style: none;
    padding: 0;
    display: grid;
    /* auto-fit + minmax : 1 colonne sur telephone, 2 sur tablette, 3 au-dela,
       sans une seule media query et sans palier arbitraire. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: 1.25rem;
}

.vi-connexes__liste a {
    display: block;
    height: 100%;
    background: var(--bg-white);
    border: 1px solid #E2E8F0;
    border-left: 3px solid var(--secondary);
    border-radius: 6px;
    padding: 1.4rem 1.5rem;
    transition: var(--transition);
}

.vi-connexes__liste a:hover {
    box-shadow: var(--shadow-soft);
    transform: translateY(-4px);
    border-color: var(--secondary);
}

.vi-connexes__nom {
    display: block;
    font-weight: 600;
    color: var(--primary);
    margin-bottom: 0.5rem;
}

.vi-connexes__desc {
    display: block;
    font-size: 0.88rem;
    line-height: 1.6;
    color: #64748B;
}

/* --- Appel a l'action -----------------------------------------------------
   Fond bleu nuit, et ce n'est pas un choix decoratif : .btn-outline est en
   --secondary (#D4AF37), qui ne tient pas le contraste sur fond clair. Sur ce
   fond, les deux boutons de la charte fonctionnent tels quels. */
.vi-cta {
    margin-top: clamp(3rem, 7vw, 5rem);
    background: var(--primary);
    border-radius: 10px;
    padding: clamp(2rem, 6vw, 3.5rem);
    text-align: center;
}

.vi-cta h2 {
    font-family: 'Playfair Display', Georgia, serif;
    font-size: clamp(1.5rem, 4.2vw, 2.1rem);
    color: var(--secondary);
    margin-bottom: 1rem;
}

.vi-cta p {
    color: var(--text-light);
    max-width: 46ch;
    margin: 0 auto 2rem;
    line-height: 1.8;
}

/* --- 3.13.0 : secteurs et guides -------------------------------------------
   Phrase de l'accueil qui mène aux pages de secteur. Mêmes liens soulignés
   et même or assombri que dans le contenu des pages : #856A12 tient 4,5:1 sur
   le fond clair, l'or de la charte non. */
.vi-secteurs-accueil {
    margin-top: 1rem;
    font-size: 1.05rem;
    line-height: 1.8;
}

.vi-secteurs-accueil a {
    color: var(--secondary-dark);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.vi-secteurs-accueil a:hover { color: var(--primary); }

/* Plusieurs rangées de pages se suivent désormais dans le pied de page
   (prestations, secteurs, guides). Un filet entre chacune alourdit : on ne le
   garde que sous la dernière. */
.footer-pages:has(+ .footer-pages) {
    margin-bottom: 1.8rem;
    padding-bottom: 0;
    border-bottom: 0;
}

/* Date de mise à jour d'un guide ou d'une page de secteur, juste sous le fil
   d'Ariane. */
.vi-fil + .vi-maj { margin-top: -0.6rem; margin-bottom: 1.6rem; }

/* Tableaux de chiffres (guides, secteurs) : sur téléphone, un tableau de six
   colonnes déborde. On le laisse défiler DANS son cadre plutôt que d'élargir la
   page entière, ce qui ferait défiler tout le document horizontalement. Au-delà
   de 760 px le tableau garde son affichage normal, pleine largeur. */
@media (max-width: 760px) {
    .vi-contenu table {
        display: block;
        max-width: 100%;
        overflow-x: auto;
    }
}

.vi-contenu caption {
    caption-side: top;
    text-align: left;
    font-weight: 600;
    color: var(--primary);
    padding-bottom: 0.6rem;
}
