/* ==========================================================================
   COGESTIM — INVENTAIRE COMPOSANTS & CTA (mapping composant → tokens)
   --------------------------------------------------------------------------
   Dépend de cogestim-design-tokens.css (charger AVANT ce fichier).
   Chaque composant NE référence QUE des tokens : aucune valeur en dur.
   Sert de contrat pour décliner les pages suivantes sans réintroduire
   d'incohérences. Les cas non tranchés renvoient à COGESTIM-DESIGN-REFERENCE.md.

   NB : ce fichier RÉ-ÉCRIT les composants existants en version tokenisée.
   Il ne remplace pas encore cogestim-base.css sur les pages en ligne — c'est
   la cible de refactor. Les écarts avec le code actuel sont notés « était : ».

   ⭑ §0 — RÈGLE DE GOUVERNANCE (toutes pages, tous widgets, futurs templates
   WordPress) : une page ou un composant hôte (widget, carte, panneau) qui
   consomme un composant LIBRARY (.link, .btn, .circle-cta,
   .field--boxed, .consent, .card…) le POSITIONNE via son propre
   conteneur (marges, gap, alignement) mais ne redéfinit JAMAIS son apparence
   (couleur, fond, bordure, ombre, taille) par une règle locale ou un reset
   générique trop large qui l'atteindrait par accident. Si un ajustement
   d'apparence semble nécessaire, c'est un signal qu'il manque une variante
   ou une taille au composant LIBRARY lui-même (ex. §A4 .circle-cta) —
   on l'y ajoute, on ne la patch pas au point d'usage.
   PRÉFÉRER le scope EXPLICITE POSITIF : donner leurs propres règles
   autonomes (font/color/cursor/background/border) aux boutons internes
   d'un composant hôte, plutôt qu'un reset générique par sélecteur de type
   (`button{…}`) même assorti d'exclusions `:not(...)`. Piège vécu deux fois
   sur le même fichier (passe 8, widget) : un `button{background:none}`
   trop large écrasait `.circle-cta` faute d'exclusion ; la version corrigée
   `button:not(.circle-cta):not(.btn)` a semblé régler le problème mais
   CHAQUE `:not()` ajoute un cran de spécificité au sélecteur qui le porte —
   la règle « corrigée » est devenue plus spécifique que `.cw-fab` elle-même
   et lui a écrasé son fond opaque en silence. Un composant hôte qui
   s'auto-suffit (aucune propriété non posée, donc aucun besoin de reset
   partagé) élimine la classe de bug entière plutôt que de la déplacer.
   ========================================================================== */

/* ==========================================================================
   A. CTA — SYSTÈME À DEUX NIVEAUX DE CASSE (règle projet CLAUDE.md §CTA)
   1. CTA court « voir tout / parcourir / nav » — CAPITALES (.link.caps)
   2. Lien-phrase d'action dans le contenu     — casse de phrase (.link)
   Ne JAMAIS mettre un CTA d'action long en capitales.
   ========================================================================== */

/* --- A1 · Lien-CTA (FORME PAR DÉFAUT du site) -----------------------------
   Texte + trait + flèche en dégradé de marque. Casse de phrase.
   Ex. « Lancer l'estimation », « Découvrir le groupe ». */
.link{
  display:inline-flex; align-items:center; gap:var(--space-5);
  font-family:var(--font-sans); font-weight:var(--fw-medium); font-size:var(--cog-fs-cta);
  letter-spacing:var(--ls-cta);
  border:0; background-color:transparent; padding:0 0 var(--space-2);
  background-image:var(--grad); -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
  position:relative; cursor:pointer;
  transition:gap var(--dur-fast) ease;
}
.link::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--grad); transform:scaleX(1); transform-origin:left;
  transition:transform .35s var(--ease-out), background var(--dur-fast) ease;
}
.link:hover{ gap:var(--space-7); }
/* Focus clavier (amendement 26/08, planche « États interactifs ») : trou
   d'inventaire — aucune règle .link:focus-visible n'existait. :focus-visible
   exclusivement (jamais au clic souris), tokens existants uniquement. */
.link:focus-visible{ outline:none; box-shadow:var(--cog-focus-ring); border-radius:2px; }
/* Boîte du glyphe : CARRÉE 14×14, alignée sur le viewBox 24×24 de arrow-right
   (Lucide). Corrigé le 27/07 : l'ancienne boîte 16×9 (héritée d'un SVG 16×9
   disparu) écrasait l'icône à 9×9 — fût réduit à un filet invisible, seule la
   pointe restait lisible et le CTA se lisait comme un chevron. Les pages ne
   redéclarent plus de taille (ni inline, ni .ar). */
.link svg{ width:14px; height:14px; flex-shrink:0; fill:none; }
/* Dégradé de marque sur le glyphe. Le <defs id="cogcta"> requis 1×/page DOIT
   être en gradientUnits="userSpaceOnUse" (x1=0 → x2=24, l'espace du viewBox) :
   en objectBoundingBox (défaut), le fût horizontal M5 12h14 a une bbox de
   hauteur 0, le dégradé dégénère et le fût n'est PAS peint — seule la pointe
   sort, et le CTA se lit comme un chevron (bug corrigé le 27/07). */
.link svg path{ stroke:url(#cogcta); }

/* Modificateur CAPS : CTA « voir tout / parcourir » — CAPITALES 13px */
.link.caps{ font-size:var(--cog-fs-cta-caps); letter-spacing:var(--ls-cta-caps); text-transform:uppercase; }

/* Modificateur sm : CTA texte en contexte dense (accordéon agences, FAQ) — 13.5px */
.link.sm{ font-size:var(--cog-fs-sm); }

/* Conteneur de fin de section — centre un .link.caps unique (Projets-neufs). Invisible si vide. */
.sec-foot{display:flex;justify-content:center;margin-top:clamp(32px,3.4vw,48px)}

/* Modificateur invert : sur fond sombre — tout en clair. Souligné blanc
   TOUJOURS (repos a70, hover 100%), quels que soient les autres modificateurs
   combinés (caps, primary) — arbitrage 27/07, plus de dégradé sur photo. */
.link.invert{ background-image:none; color:var(--color-text-on-dark); -webkit-text-fill-color:var(--color-text-on-dark); }
.link.invert::after{ background:var(--on-dark-a70); }
.link.invert svg path{ stroke:var(--color-text-on-dark); }
.link.invert:hover{ color:var(--cog-white); -webkit-text-fill-color:var(--cog-white); }
.link.invert:hover::after{ background:var(--color-text-on-dark); }

/* --- A2 · Bouton pilule PLEIN (.btn) — USAGE RESTREINT --------------------
   Soumission de formulaire / action primaire de fiche ou modale UNIQUEMENT.
   Jamais en CTA de hero / section / carte (là : utiliser .link).
   Consomme : --grad-45, --shadow-btn, --radius-pill. */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--space-4);
  font-family:var(--font-sans); font-weight:var(--fw-semibold); font-size:var(--cog-fs-cta); letter-spacing:var(--ls-cta);
  padding:17px 30px; border-radius:var(--radius-pill); cursor:pointer;
  border:1px solid transparent; color:var(--cog-white); position:relative; overflow:hidden;
  background-image:var(--grad-45); background-size:140% 140%; background-position:0% 50%;
  transition:background-position var(--dur-slow) ease, box-shadow var(--dur-base) ease, transform var(--dur-fast) ease;
  box-shadow:var(--shadow-btn);
}
.btn:hover{ background-position:100% 50%; box-shadow:var(--shadow-btn-hover); transform:translateY(-1px); }
/* Focus clavier (amendement 26/08, planche « États interactifs ») : trou
   d'inventaire — combine l'ombre bouton existante et l'anneau canonique. */
.btn:focus-visible{ outline:none; box-shadow:var(--shadow-btn), var(--cog-focus-ring); }
.btn svg{ width:16px; height:10px; stroke:currentColor; fill:none; stroke-width:1.4; flex-shrink:0; }
.btn.lg{ padding:20px 38px; font-size:var(--cog-fs-cap); }   /* variante inutilisée à ce jour ; 15px arrondi au cran --cog-fs-cap (14.5px, écart imperceptible) plutôt qu'un nouveau token pour du code mort */
.btn.sm{ padding:14px 24px; }   /* variante compacte — barres sticky mobiles et contextes à hauteur contrainte (fiche-bien) */

/* --- A3 · .btn-o — SUPPRIMÉ passe 8 (convergence formulaires) -------------
   Grep confirmé : 0 usage sur les 4 pages. Réintroduction facile depuis
   l'historique si un besoin de pilule-contour apparaît. */

/* --- A4 · .circle-cta — COMPOSANT UNIQUE pour tout bouton circulaire ------
   ⭑ Passe de normalisation (03/07) : .o-circle et .o-circle--toggle
   fusionnés dans .circle-cta — un seul composant, un seul nom, sur les 5
   pages. Diamètre UNIQUE 44px (--cog-control-md), desktop ET mobile, jamais
   plus petit (la variante .sm et l'ancienne distinction sm/md par contexte
   sont abandonnées : source d'incohérence constatée entre pages). Contour
   1px de la même couleur de trait, fond transparent, même remplissage
   dégradé au survol partout, icône centrée optiquement, même graisse de
   trait (1.4px) sur les deux glyphes.
   Deux glyphes seulement, selon la sémantique — ne jamais les croiser :
   · flèche ←/→ (svg par défaut, .flip pour l'inverse) = NAVIGATION vers une
     autre page/vue (carousels, lignes de service, bouton Retour) ;
   · +/− (.bar ci-dessous) = DISCLOSURE : ouvrir/fermer SUR PLACE (accordéon
     FAQ, accordéon agences, accordéon caractéristiques). La barre verticale
     se masque via [aria-expanded="true"] sur le bouton parent.
   Réservé à la navigation + actions secondaires ; jamais pour la soumission
   de formulaire (.btn pilule exclusivement, voir §A2).

   ⭑ DEUX LANGAGES D'ANIMATION DISTINCTS (même cercle, comportement différent
   selon le glyphe qu'il porte) :
   · Flèche (nav) — hover : la flèche translate de 3px dans son sens
     (translateX inversé pour .flip) EN PLUS du remplissage dégradé de fond ;
     active/press : léger scale-down du bouton (.96). C'est LA référence
     directionnelle, à ne jamais appliquer à un toggle.
   · Toggle +/− (disclosure) — hover : UNIQUEMENT le remplissage de fond
     (::before), JAMAIS de translation, un toggle ne glisse pas comme un
     lien de nav ; l'état ouvert se lit sur le glyphe lui-même, qui morphe
     de + à − (barre verticale masquée) en ~200ms.
   Consomme : --color-border-strong, --grad, --radius-full, --cog-control-md. */
.circle-cta{
  position:relative; width:var(--cog-control-md); height:var(--cog-control-md);
  border:1px solid var(--color-border-strong); border-radius:var(--radius-full);
  display:inline-flex; align-items:center; justify-content:center; overflow:hidden;
  transition:border-color var(--dur-base) ease, transform var(--dur-fast) var(--ease-out); flex-shrink:0;
  background:transparent; color:var(--color-text);
}
.circle-cta::before{
  content:""; position:absolute; inset:0; background:var(--grad);
  transform:scale(0); transform-origin:center; border-radius:var(--radius-full);
  transition:transform var(--dur-slow) var(--ease-pop); z-index:0;
}
.circle-cta:hover{ border-color:transparent; color:var(--cog-white); }
.circle-cta:hover::before{ transform:scale(1.05); }
.circle-cta:focus-visible{ outline:none; box-shadow:var(--cog-focus-ring); }
.circle-cta svg{ position:relative; z-index:1; width:var(--icon-sm); height:var(--icon-sm); stroke:currentColor; fill:none; stroke-width:1.4; transition:transform var(--dur-fast) var(--ease-out); }
.circle-cta.invert{ border-color:var(--color-text-on-dark); color:var(--color-text-on-dark); }
.circle-cta.invert:hover{ color:var(--cog-white); border-color:transparent; }
/* Variante remplie — CTA PRIMAIRE uniquement (ex. barre de recherche IA du
   héro Home) : fond dégradé signature toujours visible, jamais transparent,
   indépendamment du fond hôte (photo, sombre...). N'est PAS le composant nav/
   disclosure standard — réservé aux cas où le cercle EST le CTA principal. */
.circle-cta.filled{
  border-color:transparent; color:var(--cog-white);
  background-image:var(--grad-45); background-size:140% 140%; background-position:0% 50%;
  box-shadow:var(--shadow-btn);
  transition:border-color var(--dur-base) ease, transform var(--dur-fast) var(--ease-out), box-shadow .35s ease, background-position var(--dur-slow) ease;
}
.circle-cta.filled:hover{ box-shadow:var(--shadow-btn-hover); background-position:100% 50%; }
.circle-cta.filled:hover::before{ transform:scale(0); }
/* Réutilise l'asset flèche standard en sens inverse (retour/précédent) —
   un seul SVG, jamais un second asset « flèche gauche » dessiné à part. */
.circle-cta.flip svg{ transform:scaleX(-1); }
/* Animation directionnelle (flèche = nav uniquement, jamais sur un toggle,
   qui n'a pas de <svg> mais un .bar). Translation au hover + scale-down au
   press ; .flip conserve son mirroring et translate dans l'autre sens. */
.circle-cta:hover svg{ transform:translateX(3px); }
.circle-cta.flip:hover svg{ transform:scaleX(-1) translateX(3px); }
.circle-cta:active:has(svg){ transform:scale(.96); }
/* Glyphe +/− (disclosure) — icône à taille FIXE (16px / trait 1.4px),
   jamais une taille héritée du conteneur, pour que le même + rende
   identique dans tous les cercles quel que soit l'endroit du site. Hover :
   aucune translation, seulement le remplissage de fond hérité ci-dessus. */
.circle-cta .bar{
  position:relative; z-index:1; width:16px; height:1.4px; background:currentColor; border-radius:1px;
}
.circle-cta .bar::after{
  content:""; position:absolute; left:50%; top:50%; width:1.4px; height:16px;
  background:currentColor; border-radius:1px; transform:translate(-50%,-50%);
  transition:transform .2s var(--ease-out), opacity .2s var(--ease-out);
}
[aria-expanded="true"] .circle-cta .bar::after{ transform:translate(-50%,-50%) scaleY(0); opacity:0; }
/* Cas où aria-expanded est porté par le .circle-cta lui-même (bouton = le
   cercle, ex. toggle agences Home) plutôt que par un parent (ex. .acc-head,
   .faq-q, .mfq) : même règle, sélecteur direct pour couvrir les deux
   structures sans dupliquer le marquage. Piloté uniquement par
   aria-expanded — jamais par une classe .open côté JS — pour que le glyphe
   soit correct dès le premier rendu (rangée ouverte par défaut = "−" sans
   transition au chargement, la transition ne joue qu'aux interactions
   suivantes puisqu'elle est sur .bar::after, pas sur un état d'entrée).
   ⭑ RÉFÉRENCE CANONIQUE DU TRAIT (sobre, alignée sur Fiche-bien §Caractéristiques
   détaillées, seule source — ne jamais re-normaliser sur une autre page) :
   border 1px solid var(--color-border-strong) ; glyphe (flèche ou +/−) en
   stroke-width 1.4px, currentColor ; flèche 16×10 ; barre + 16×1.4 (barre
   verticale identique en 1.4×16, superposée) ; cercle 44px (--cog-control-md)
   partout, desktop et mobile. Aucune variante plus grasse ou plus petite. */
.circle-cta[aria-expanded="true"] .bar::after{ transform:translate(-50%,-50%) scaleY(0); opacity:0; }

/* --- A4bis · .circle-cta--toggle — variante DISCLOSURE dédiée -------------
   ⭑ Passe uniformisation toggles (03/07) : les toggles +/− (accordéons
   agences Home, FAQ Acheter/Courtage, caractéristiques Fiche-bien) ne
   partagent plus le hover de nav/CTA (.circle-cta de base : fill dégradé
   plein + glyphe blanc). Un toggle n'est jamais un CTA primaire — son
   hover reste SOBRE : léger fill neutre (--rule, même token que les
   filets du site), trait légèrement renforcé, glyphe qui reste dans
   l'encre (jamais blanc). Repos strictement identique à .circle-cta
   (44px, bordure 1px --color-border-strong, trait 1.4px).
   Ne s'applique QU'aux toggles ; flèches de nav et CTA ronds (.filled,
   .invert, .arr, sans classe sur une nav) restent sur le hover magenta
   de base, hors de cette règle.
   ⭑ AMENDEMENT 26/08 (planche « États interactifs », option 2 retenue par
   Luis) : fill hover repassé de --paper-warm à --rule, PARTOUT (toggle
   direct + relais ci-dessous). Constat 26/08 : sur fond .warm, l'ancien
   fill --paper-warm se camouflait sur son propre fond hôte — l'affordance
   de remplissage disparaissait, seule la bordure restait lisible. --rule
   reste dans l'échelle neutre existante (aucun token inventé) et contraste
   sur fond blanc ET warm. */
.circle-cta--toggle:hover{ border-color:var(--color-text); color:var(--color-text); }
.circle-cta--toggle::before{ background:var(--rule); }
.circle-cta--toggle:hover::before{ transform:scale(1); }
.circle-cta--toggle:hover .bar,
.circle-cta--toggle:hover .bar::after{ background:currentColor; }

/* Relais générique (décision Luis 26/08, standardisation hover toggle) : quand
   le .circle-cta--toggle est nesté dans un bouton/conteneur parent plus large —
   cf. pointer-events:none posé localement par chaque bloc consommateur
   (faq/style.css, prestations-detaillees/style.css) pour .faq-q/.expC-btn, ou
   simplement une zone cliquable plus large que le cercle (.ag-head, cursor:pointer,
   clic géré en JS sur toute la ligne — accordéon agences Home) — le survol du
   parent doit reproduire EXACTEMENT l'état hover certifié ci-dessus, mêmes
   tokens, aucune valeur nouvelle. Source unique : tout bloc qui nest le
   toggle ajoute son sélecteur ici, jamais de relais dupliqué en style.css de
   bloc. Complété 26/08 (constat Luis) : .ag-head manquait à ce relais — la
   ligne entière est hoverable/cliquable (cursor:pointer, listener JS sur
   .ag-head), mais seul le survol du cercle lui-même déclenchait l'affordance
   avant cet ajout. */
.faq-q:hover .circle-cta--toggle,
.expC-btn:hover .circle-cta--toggle,
.ag-head:hover .circle-cta--toggle{ border-color:var(--color-text); color:var(--color-text); }
.faq-q:hover .circle-cta--toggle::before,
.expC-btn:hover .circle-cta--toggle::before,
.ag-head:hover .circle-cta--toggle::before{ transform:scale(1); }
.faq-q:hover .circle-cta--toggle .bar,
.faq-q:hover .circle-cta--toggle .bar::after,
.expC-btn:hover .circle-cta--toggle .bar,
.expC-btn:hover .circle-cta--toggle .bar::after,
.ag-head:hover .circle-cta--toggle .bar,
.ag-head:hover .circle-cta--toggle .bar::after{ background:currentColor; }

/* --- A5 · Focus clavier — .faq-q / .gal-tab (amendement 26/08, planche
   « États interactifs ») : trous d'inventaire. .faq-q — le glyphe +/- interne
   est pointer-events:none (décoratif), le vrai contrôle cliquable est le
   bouton .faq-q lui-même, qui n'avait aucune règle :focus-visible (le halo
   du toggle interne ne peut jamais s'activer puisqu'il n'est pas focusable).
   .gal-tab (Fiche-bien, galerie Photos/Carte) : même trou, même anneau. */
.faq-q:focus-visible{ outline:none; box-shadow:var(--cog-focus-ring); border-radius:2px; }
.gal-tab:focus-visible{ outline:none; box-shadow:var(--cog-focus-ring); }


/* --- A6 · .link.primary — modificateur documenté (pas de fusion) ----------
   Action recommandée au sein d'un groupe de liens-CTA de poids visuel égal
   (ex. état de recherche vide : 3 liens, un seul mis en avant). Reste un
   .link — casse de phrase, jamais de CTA d'action long en capitales.
   Copie locale dupliquée dans 2.Acheter.html purgée le 27/07 — .link.primary
   n'existe plus qu'ici.
   NB audit : « .link.discover » (Home, accordéon agences) n'est PAS un
   variant visuel — c'est un utilitaire de mise en page (margin-top:auto)
   mal nommé, sans rapport avec le système de CTA. Rien à documenter ici. */
.link.primary{ color:var(--color-primary); }
.link.primary::after{ height:2px; background:var(--grad); }

/* Combinaisons canoniques (27/07) : .invert.caps (aucun réglage propre,
   caps ne touche pas la couleur) et .invert.primary (le souligné et le
   texte restent blancs — invert prime sur primary, jamais le dégradé rouge
   sur une photo). Sélecteur combiné = spécificité supérieure, gagne sur
   .link.invert et .link.primary pris séparément. */
.link.invert.primary{ color:var(--color-text-on-dark); -webkit-text-fill-color:var(--color-text-on-dark); }
.link.invert.primary::after{ height:2px; background:var(--on-dark-a70); }
.link.invert.primary:hover{ color:var(--cog-white); -webkit-text-fill-color:var(--cog-white); }
.link.invert.primary:hover::after{ background:var(--color-text-on-dark); }

/* ==========================================================================
   B. LIENS TEXTE (navigation & listes)
   ========================================================================== */

/* --- B1 · Lien de navigation (header) — soulignement rouge animé ---------- */
.navlist a{ position:relative; padding:8px 0; color:var(--color-text);
  font-family:var(--font-sans); font-size:var(--cog-fs-cta); font-weight:var(--fw-medium); }
.navlist a::after{
  content:""; position:absolute; left:0; right:0; bottom:2px; height:1px; background:var(--color-primary);
  transform:scaleX(0); transform-origin:left; transition:transform var(--dur-base) var(--ease-out);
}
.navlist a:hover, .navlist a.active{ color:var(--color-primary); }
.navlist a:hover::after, .navlist a.active::after{ transform:scaleX(1); }

/* --- B2 · Lien de pied de page — soulignement rouge sur fond ink ---------- */
.fcol-new a{ font-family:var(--font-sans); font-size:var(--cog-fs-cta); color:var(--color-text-on-dark);
  position:relative; display:inline-block; transition:color var(--dur-fast) ease; }
.fcol-new a::after{ content:""; position:absolute; left:0; right:0; bottom:-2px; height:1px;
  background:var(--color-primary); transform:scaleX(0); transform-origin:left; transition:transform .35s ease; }
.fcol-new a:hover{ color:var(--color-primary); }
.fcol-new a:hover::after{ transform:scaleX(1); }

/* ==========================================================================
   C. CARTES
   ⚠ Rayon de carte incohérent d'une page à l'autre — voir .md §5.
   ========================================================================== */

/* --- C1 · Fiche-bien (page Acheter) — angles VIFS -------------------------
   Consomme : --color-bg, --color-border, --shadow-card.
   §5 : une fiche-bien n'est JAMAIS arrondie (angles vifs, 0). */
.card{
  position:relative; display:flex; flex-direction:column;
  background:var(--color-bg); border:1px solid var(--color-border); border-radius:0;
  overflow:hidden;
  transition:box-shadow var(--dur-base) ease, transform var(--dur-base) ease, border-color var(--dur-base) ease;
}
.card:hover{ box-shadow:var(--shadow-card); transform:translateY(-4px); }
.card.is-vendu{ opacity:.72; }
.card.is-vendu:hover{ transform:none; }
.card-price{ font-family:var(--font-sans); font-weight:var(--fw-semibold); font-size:var(--cog-fs-price-card); letter-spacing:-.015em; color:var(--color-text); }
.card-loc{ font-family:var(--font-sans); font-size:var(--cog-fs-sm); color:var(--color-text-body); }
.card-loc svg{ stroke:var(--color-primary); }
.card-title{ font-family:var(--font-sans); font-weight:var(--fw-medium); font-size:var(--cog-fs-card-title); color:var(--color-text); }
.card-specs{ border-top:1px solid var(--color-border-soft); }

/* --- C2 · Carte promo sombre (« Estimation ») ------------------------------
   Cadre marqué + calque dégradé sur image sombre. Extrait 28/07 depuis 2.Acheter/
   Projets-neufs (verbatim identique, valeur certifiée en page) — remplace le brouillon
   tokenisé (--color-border-strong/--color-text-on-dark) jamais consommé par une page.
   ⚠ Projet-neuf-detail.html : variante colonne actée 28/07, consignée en modificateur
   .card-promo--col (§C2b, suite de ce bloc) — min-height:auto au lieu de 100%. */
.card-promo{position:relative;display:flex;flex-direction:column;justify-content:center;gap:14px;padding:clamp(28px,2.3vw,38px) clamp(26px,2.1vw,34px);overflow:hidden;border:1px solid var(--ink);color:var(--paper-warm);min-height:100%}
.card-promo .promo-bg{position:absolute;inset:0;z-index:0}
.card-promo .promo-bg img{width:100%;height:100%;object-fit:cover}
.card-promo .promo-bg::after{content:"";position:absolute;inset:0;background:linear-gradient(160deg,rgba(26,26,31,.58) 0%,rgba(26,26,31,.9) 84%)}
.card-promo > *{position:relative;z-index:1}
.card-promo .lab{color:rgba(240,235,227,.72)}
.card-promo h3{font-family:var(--sans);font-weight:300;font-size:clamp(23px,1.6vw,29px);line-height:1.13;letter-spacing:-.01em;color:var(--paper-warm);margin:0;max-width:15ch;text-wrap:balance}
.card-promo h3 .em{color:var(--paper-warm)}
.card-promo p{margin:0;font-size:var(--cog-fs-cap);line-height:1.6;color:rgba(240,235,227,.85);max-width:32ch}
.card-promo .promo-cta{display:flex;flex-direction:column;gap:14px;margin-top:8px;align-items:flex-start}

/* --- C2b · Modificateur colonne (Projet-neuf-detail.html, amendement 28/07) ---
   Contexte à hauteur non contrainte (colonne libre plutôt que cellule de grid pleine
   hauteur) : min-height:auto au lieu de 100%. */
.card-promo--col{min-height:auto}

/* --- C3 · Carte souple / panneau (réponse hero, modales) ------------------
   Consomme : --radius-sm. (Cartes « douces » alignées sur --radius-sm.) */

/* ==========================================================================
   D. BADGES & PASTILLES
   ========================================================================== */

/* --- D1 · Badge de statut d'annonce (coin haut-gauche de la fiche) --------
   Base commune ; la couleur vient d'un token de statut.
   Variantes : neuf / projet / reserve / vendu / vente. */
.card-badge{
  position:absolute; left:16px; top:16px; z-index:3;
  font-family:var(--font-sans); font-size:var(--cog-fs-2xs); font-weight:var(--fw-semibold);
  letter-spacing:.13em; text-transform:uppercase;
  padding:7px 12px; color:var(--cog-white);
}
.card-badge.neuf   { background-image:var(--status-neuf); }                                /* « Nouveauté » — dégradé marque */
/* .card-badge.projet supprimé (21/07) : mort, aucun bien ne l'utilisait ; anatomie
   divergente (bordure+texte coloré) du reste des badges (fond plein+texte blanc). */
.card-badge.reserve{ background:var(--status-reserve); }                                  /* « RÉSERVÉ »   — noir charte (§11) */
.card-badge.vendu  { background:var(--status-vendu); }                                    /* « Vendu/Loué » — gris désaturé (§11) */
.card-badge.vente  { background:var(--status-vente); backdrop-filter:blur(4px); }         /* « À vendre »   — neutre marque (§11) */

/* Voile + label sur photo pour biens réservés / vendus */
.card.is-reserve .card-shade, .card.is-vendu .card-shade{ display:flex; }
.card-shade{ position:absolute; inset:0; z-index:2; display:none; align-items:center; justify-content:center; background:var(--status-scrim); }
.card-shade span{ font-family:var(--font-sans); font-weight:var(--fw-semibold); font-size:var(--cog-fs-cta-caps);
  letter-spacing:.16em; text-transform:uppercase; color:var(--cog-white);
  border:1px solid var(--white-a70); padding:9px 18px; }

/* --- D2 · Pastilles d'info sur photo (compteur, vidéo) --------------------
   Consomme : --ink-a55, --radius-pill. */
.card-count, .card-video{
  position:absolute; z-index:2; font-family:var(--font-sans); font-size:var(--cog-fs-xs); font-weight:var(--fw-semibold);
  letter-spacing:.04em; color:var(--cog-white); background:var(--ink-a55);
  backdrop-filter:blur(4px); border-radius:var(--radius-pill);
}

/* --- D3 · Puce / chip de filtre (Courtage : villes) -----------------------
   Contour, hover rouge. Consomme : --color-border, --color-primary. */
.ville-chip{
  font-family:var(--font-sans); font-size:var(--cog-fs-sm); font-weight:var(--fw-medium); color:var(--color-text);
  padding:11px 20px; border:1px solid var(--color-border);
  transition:border-color var(--dur-fast) ease, color var(--dur-fast) ease, background var(--dur-fast) ease;
}
.ville-chip:hover{ border-color:var(--color-primary); color:var(--color-primary); background:var(--primary-a04); }
/* Focus clavier (amendement 26/08, planche « États interactifs ») : trou
   d'inventaire — famille distincte de .tf-chip (nav SEO, pas filtre), même
   anneau canonique. */
.ville-chip:focus-visible{ outline:none; box-shadow:var(--cog-focus-ring); }

/* --- D4 · Badge de confiance (footer : USPI / ISO) ------------------------
   Texte + puce rouge. Consomme : --color-text-on-dark, --color-primary. */

/* --- D5 · Pastille de disponibilité (widget) — SEUL état « success » ------
   Consomme : --color-success / --color-success-soft. Voir .md §7. */

/* ==========================================================================
   — LIBRARY — CHAMPS DE FORMULAIRE & CONSENTEMENT (passe 8 : convergence
   formulaires + boutons de soumission)
   --------------------------------------------------------------------------
   Variante UNIQUE de champ sur tout le site (décision 17/07) :
     .field--boxed — bordure fine, --radius-sm, léger fond de remplissage.
   Label CAPS TOUJOURS visible au-dessus du champ (jamais un placeholder
   seul — un placeholder disparaît à la saisie et casse l'accessibilité).
   Focus : --cog-focus-ring (cadre sur 4 côtés, le halo s'y ancre
   naturellement). Zéro valeur en dur, jamais une variante ad hoc par page.
   (.field--underline supprimée le 17/07 — tous les formulaires basculés.)
   ========================================================================== */

/* --- L1 · Label de champ — commun aux deux variantes ----------------------
   Consomme : --cog-fs-xs, --cog-ls-field-lab, --fw-semibold, --color-text-muted. */
.field-lab{
  display:block; margin-bottom:var(--space-3); padding-top:var(--space-5);
  font-family:var(--font-sans); font-size:var(--cog-fs-xs); font-weight:var(--fw-semibold);
  letter-spacing:var(--cog-ls-field-lab); text-transform:uppercase; color:var(--color-text-muted);
}

/* --- L2 · Sélecteur natif — chevron partagé par les deux variantes --------
   NB : un data-URI ne peut pas consommer var() ; le stroke ci-dessous est
   une COPIE figée de --color-text-muted (#6E6E76). Si la primitive change,
   resynchroniser ce chevron (grep "field-in select" au prochain audit
   couleur). Corrige au passage le stroke #8A8A92 (ex-valeur, périmée depuis
   le renommage --cog-ink-mute → trouvé dans widget + fiche). */
select.field-in{
  appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:28px;
  background-repeat:no-repeat; background-position:right 2px center;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='5 8 14 8'%3E%3Cpath d='m6 9 6 6 6-6' fill='none' stroke='%236E6E76' stroke-width='1.6'/%3E%3C/svg%3E");
}
textarea.field-in{ resize:vertical; min-height:80px; line-height:1.5; }

/* --- L3 · .field--boxed — variante unique de champ (tout le site) ---------
   Décision 17/07 : seule variante de champ. Bordure fine + --radius-sm +
   léger fond de remplissage. Focus = --cog-focus-ring (halo carré ancré sur
   les 4 côtés). Ne pas réintroduire de variante soulignée ni de focus local.
   Consomme : --color-bg, --color-border, --radius-sm, --cog-focus-ring. */
.field--boxed{ display:flex; flex-direction:column; gap:var(--space-3); }
/* Option --space-2 (6px) écartée (2026-07-22) : gain imperceptible sur le gap
   label–champ, la respiration entre label et champ est préservée à 9px. */
.field--boxed .field-in{
  width:100%; font-family:var(--font-sans); font-size:var(--cog-fs-field); color:var(--color-text);
  background:var(--color-bg); border:1px solid var(--color-border); border-radius:var(--radius-sm);
  padding:12px 14px; outline:0;
  transition:border-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}
/* Correction 27/07 (audit 2.6) : la shorthand `background` ci-dessus efface le
   chevron posé en §L2. Restauré ici pour TOUS les selects boxés du site —
   remplace la redéclaration locale qui vivait dans Agence-Lausanne. Chevron
   aligné sur le padding boxé (14px). Même data-URI figé qu'en §L2. */
/* .field--boxed select.field-in — chevron : généralisé à button.field-in en §L20
   (extraction field-select, 31/07) pour couvrir la variante à choix custom. */
.field--boxed .field-in::placeholder{ color:var(--color-text-muted); }
.field--boxed .field-in:focus{ border-color:var(--color-text); box-shadow:var(--cog-focus-ring); }

/* --- L5 · .consent — case de consentement nLPD ----------------------------
   Obligatoire sur TOUT formulaire collectant des données personnelles.
   Non pré-cochée par défaut (le HTML ne doit jamais poser `checked`).
   Wording canonique (copie exacte, ne pas reformuler par page) :
     "J'accepte que mes données soient traitées pour répondre à ma demande,
     conformément à la politique de confidentialité."
   Consomme : --color-border, --grad-45, --color-text-body, --color-primary,
   --cog-focus-ring. */
.consent{ display:flex; gap:var(--space-4); align-items:flex-start; margin:var(--space-2) 0 var(--space-6); }
.consent input{
  appearance:none; -webkit-appearance:none; width:19px; height:19px; flex-shrink:0; margin-top:1px;
  border:1px solid var(--color-border); border-radius:var(--radius-sm); cursor:pointer; position:relative;
  transition:border-color .2s ease, background .2s ease;
}
.consent input:checked{ background-image:var(--grad-45); border-color:transparent; }
.consent input:checked::after{
  content:""; position:absolute; left:6px; top:2px; width:5px; height:10px;
  border:solid var(--cog-white); border-width:0 2px 2px 0; transform:rotate(45deg);
}
.consent input:focus-visible{ outline:none; box-shadow:var(--cog-focus-ring); }
.consent label{ font-family:var(--font-sans); font-size:var(--cog-fs-legal); line-height:1.5; color:var(--color-text-body); }
.consent label a{ color:var(--color-primary); text-decoration:underline; text-underline-offset:2px; }

/* --- L6 · États validés 16/07 (§4.5.7 erreur de champ · §4.4 submit désactivé) —
   ajout de synchronisation : la règle était verrouillée dans la bibliothèque mais
   n'existait que dans Estimation-Funnel. Consomme : --color-error, --cog-fs-legal. */
.field--boxed.err .field-in{ border-color:var(--color-error); }
.field-msg{ display:none; font-family:var(--font-sans); font-size:var(--cog-fs-legal); color:var(--color-error); margin:var(--space-2) 0 0; }
.field--boxed.err .field-msg{ display:block; }
/* Formulaires câblés (lot routing 2/7) : honeypot masqué + erreur d'envoi (même registre que .field-msg). */
.field-hp{ position:absolute; left:-10000px; width:1px; height:1px; overflow:hidden; }
.form-error{ font-family:var(--font-sans); font-size:var(--cog-fs-legal); color:var(--color-error); margin:0; }
.btn[disabled]{ opacity:.32; pointer-events:none; }

/* ==========================================================================
   — LIBRARY — EXTRACTIONS 21/07 (décision : aucun composant en double copie)
   .card (vivait en 3 copies : Acheter / Fiche-bien / Courtage .sold-grid),
   marché local §2.21 (Courtage / Estimation), chips filtre .tf-chip,
   notes §2.6bis (vivaient dans le funnel), figures-band §2.20 (anatomie
   unique flex + .fb-sep — décision 21/07, variante --xl pour Home).
   Décision 21/07 : tout rond interactif = --cog-control-md (44px).
   ========================================================================== */

/* --- L7 · .card — carte de bien -------------------------------------------- */
.card{position:relative;display:flex;flex-direction:column;background:var(--paper);border:1px solid var(--rule);border-radius:0;overflow:hidden;transition:box-shadow .4s ease,transform .4s ease,border-color .4s ease}
.card:hover{box-shadow:var(--shadow-card);transform:translateY(-4px);border-color:var(--rule)}
.card-link{position:absolute;inset:0;z-index:1}
/* Focus clavier (amendement 26/08, planche « États interactifs ») : trou
   d'inventaire réel — sans cette règle, une carte entière n'affiche AUCUN
   repère au clavier (le lien plein cadre est invisible). Anneau canonique
   en INSET (même alpha --cog-ink-a05) : .card a overflow:hidden et des
   angles vifs bord-à-bord en grille, un anneau extérieur serait rogné. */
.card-link:focus-visible{outline:none;box-shadow:inset 0 0 0 3px var(--cog-ink-a05)}
.card-ph{position:relative;aspect-ratio:3/2.15;overflow:hidden;background:var(--paper-deep)}
.card-ph img{width:100%;height:100%;object-fit:cover;transition:transform 1.3s cubic-bezier(.2,.7,.2,1)}
.card:hover .card-ph img{transform:scale(1.05)}
.card-shade{position:absolute;inset:0;z-index:2;display:none;align-items:center;justify-content:center;background:var(--status-scrim)}
.card-shade span{font-family:var(--font-sans);font-weight:600;font-size:var(--cog-fs-sm);letter-spacing:.16em;text-transform:uppercase;color:var(--cog-white);border:1px solid rgba(255,255,255,.7);padding:9px 18px}
.card.is-reserve .card-shade,.card.is-vendu .card-shade{display:flex}
.card-badge{position:absolute;left:16px;top:16px;z-index:3;font-family:var(--font-sans);font-size:var(--cog-fs-2xs);font-weight:600;letter-spacing:.13em;text-transform:uppercase;padding:7px 12px;color:var(--cog-white)}
.card-badge.vente{background:var(--status-vente);backdrop-filter:blur(4px)}
.card-badge.neuf{background-image:var(--status-neuf)}
.card-badge.reserve{background:var(--status-reserve)}
.card-badge.vendu{background:var(--status-vendu)}
.card-badge.excl{background-image:var(--grad-45)}
.card-badge.rare{background:var(--cog-ink)} /* « Objet rare » — figé 21/07, usage éditorial */
.card-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:3;width:var(--cog-control-md);height:var(--cog-control-md);border-radius:var(--radius-full);background:rgba(250,250,247,.9);backdrop-filter:blur(6px);display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--cog-ink-a05);opacity:0;transition:opacity .3s ease,background .3s ease,transform .3s ease;cursor:pointer} /* 44px — arbitrage 21/07 : tout rond interactif = --cog-control-md */
.card-nav.prev{left:14px}
.card-nav.next{right:14px}
.card:hover .card-nav{opacity:1}
.card-nav:hover{background:var(--cog-white);transform:translateY(-50%) scale(1.06)}
.card-nav svg{width:var(--icon-sm);height:var(--icon-sm);stroke:var(--icon-strong);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
@media (hover:none){.card-nav{opacity:.92}}
.card-count{position:absolute;right:14px;bottom:14px;z-index:2;font-family:var(--font-sans);font-size:var(--cog-fs-xs);font-weight:600;letter-spacing:.04em;color:var(--cog-white);background:rgba(26,26,31,.55);backdrop-filter:blur(4px);padding:5px 9px;border-radius:var(--radius-pill)}
.card-video{position:absolute;left:14px;bottom:14px;z-index:2;display:inline-flex;align-items:center;gap:6px;font-family:var(--font-sans);font-size:var(--cog-fs-xs);font-weight:600;letter-spacing:.04em;color:var(--cog-white);background:rgba(26,26,31,.55);backdrop-filter:blur(4px);padding:5px 10px 5px 8px;border-radius:var(--radius-pill)}
.card-video svg{width:var(--icon-sm);height:var(--icon-sm);color:var(--cog-white)}
.card-body{padding:22px 24px;display:flex;flex-direction:column;gap:9px;flex:1}
.card-price{font-family:var(--font-sans);font-weight:600;font-size:var(--cog-fs-price-card);letter-spacing:-.015em;color:var(--ink);line-height:1.1}
.card-price .pm{font-size:var(--cog-fs-sm);font-weight:500;color:var(--ink-mute);letter-spacing:.02em}
/* Repli « Prix sur demande » des cartes de biens (17/09,
   cogestim_property_card_price_html()). Hérite de .card-price : même
   emplacement, même corps, même poids que le montant qu'il remplace — seule la
   couleur passe en --ink-soft, pour distinguer une absence d'information d'un
   montant réel sans créer un second niveau de hiérarchie. Le letter-spacing
   négatif de .card-price est neutralisé : il est calibré pour des chiffres,
   pas pour du texte courant. Règle distincte de
   `.card--projet .card-price .price-free` (cartes projet : corps plus petit,
   contexte « Dès CHF » propre aux promotions). */
.card-price .price-free{letter-spacing:0;color:var(--ink-soft)}
.card-loc{font-family:var(--font-sans);font-size:var(--cog-fs-sm);color:var(--ink-soft);display:flex;align-items:center;gap:7px}
/* Ligne de situation (lot situation 13/10) : sous la localité, alignée sur son texte (icône + gap 7px), même registre que .card-dist. */
.card-sit{font-family:var(--font-sans);font-size:var(--cog-fs-sm);color:var(--ink-mute);line-height:1.4;margin-top:-6px;padding-left:calc(var(--icon-sm) + 7px)}
.card-loc svg{width:var(--icon-sm);height:var(--icon-sm);stroke:var(--icon-accent);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
.card-title{font-family:var(--font-sans);font-weight:500;font-size:var(--cog-fs-cap);color:var(--ink);line-height:1.32;margin:2px 0 0}
.card-specs{display:flex;gap:18px;flex-wrap:wrap;padding-top:14px;margin-top:4px;border-top:1px solid var(--rule-soft)}
.card-specs .sp{display:flex;align-items:center;gap:7px;font-family:var(--font-sans);font-size:var(--cog-fs-sm);color:var(--ink-soft)}
.card-specs .sp svg{width:var(--icon-sm);height:var(--icon-sm);stroke:var(--icon-muted);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.card-specs .sp b{font-weight:600;color:var(--ink)}
.card-broker{display:flex;align-items:center;gap:12px;margin-top:auto;padding-top:16px}
.card-broker .av{width:40px;height:40px;border-radius:var(--radius-full);overflow:hidden;flex-shrink:0;background:var(--paper-deep);display:inline-flex;align-items:center;justify-content:center}
.card-broker .av img{width:100%;height:100%;object-fit:cover;object-position:center 12%}
.card-broker .av .mono{font-family:var(--font-sans);font-weight:600;font-size:var(--cog-fs-cta);letter-spacing:.02em;color:var(--ink-soft)}
.card-broker .bk{display:flex;flex-direction:column;line-height:1.25;min-width:0}
.card-broker .bk .bn{font-family:var(--font-sans);font-weight:600;font-size:var(--cog-fs-sm);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card-broker .bk .br{font-family:var(--font-sans);font-size:11.5px;color:var(--ink-mute);letter-spacing:.02em}
.card-contact{position:relative;z-index:2;margin-left:auto;flex-shrink:0;width:var(--cog-control-md);height:var(--cog-control-md);border-radius:var(--radius-full);border:1px solid var(--rule);display:inline-flex;align-items:center;justify-content:center;transition:border-color .3s ease,background .3s ease,color .3s ease;color:var(--ink)}
.card-contact svg{width:var(--icon-md);height:var(--icon-md);stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.card-contact:hover{border-color:transparent;background-image:var(--grad-45);color:var(--cog-white)}
.card.is-vendu{opacity:.72}
.card.is-vendu:hover{transform:none}

/* --- L8 · Chips de filtre — famille « Filtrer » (§4.5.8) ------------------- */
.team-filter{display:flex;flex-wrap:wrap;gap:10px;margin:0}
.tf-chip{font-family:var(--font-sans);font-weight:500;font-size:var(--cog-fs-cta-caps);letter-spacing:.02em;color:var(--ink-soft);padding:9px 18px;border:1px solid var(--rule);border-radius:var(--radius-pill);cursor:pointer;background:transparent;transition:color .3s ease,border-color .3s ease,background .3s ease}
.tf-chip:hover{border-color:var(--ink);color:var(--ink)}
.tf-chip.on{background:var(--ink);border-color:var(--ink);color:var(--cog-white)}
/* Focus clavier (amendement 26/08, planche « États interactifs ») : trou
   d'inventaire — anneau canonique. Incohérence tf-chip (hover ink) vs
   ville-chip (hover primary) constatée et tracée dans la même planche :
   deux familles distinctes (Filtrer vs Nav SEO), non fusionnées, arbitrage
   de terminologie reporté — pas d'action dans cette passe. */
.tf-chip:focus-visible{outline:none;box-shadow:var(--cog-focus-ring)}

/* --- L9 · Marché local §2.21 ----------------------------------------------- */
.price-card{display:flex;flex-direction:column}
.price-card .ttl{font-family:var(--font-sans);font-weight:500;font-size:var(--cog-fs-h4);color:var(--ink);margin:0}
.price-asof{font-family:var(--font-sans);font-size:var(--cog-fs-xs);letter-spacing:.04em;color:var(--ink-mute);margin:var(--space-4) 0 0}
.price-card .market-filter{margin:var(--space-12) 0 0}
/* .mp-bar — rangée d'outils unique (chips + sélecteur de type), patron
   .res-bar/.res-tools §L17 transposé au bloc marché (portage planche
   Marche-prix-selecteur-type-bien.html, variante A, 15/09). Aucune valeur
   nouvelle : gap --space-6, rythme vertical --space-12 déjà ci-dessus. */
.mp-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--space-6);flex-wrap:wrap;margin-top:var(--space-12)}
.price-card .mp-bar .market-filter{flex:1 1 auto;margin-top:0}
/* Sélecteur de type : .sf.has-chev/.field-select §L20 (swap 15/09, constat
   vivant — remplace le .sort-wrap posé le matin même, liste native non
   stylable). .sf porte déjà padding-bottom:6px (§L17) : neutralisé ici, la
   rangée .mp-bar n'a pas la respiration verticale des panneaux De/À. */
.mp-bar .sf{flex:0 0 auto;padding-bottom:0}
@media (max-width:560px){.mp-bar .sf{width:100%}}
.market-row{display:flex;align-items:stretch;gap:0;margin-top:var(--space-16);padding:var(--space-4) 0;transition:opacity .22s ease,transform .22s ease}
.market-row.is-switching{opacity:0;transform:translateY(6px)}
.market-col{flex:1;min-width:112px;display:flex;flex-direction:column;gap:var(--space-7);padding:0 clamp(16px,2vw,26px);border-right:1px solid var(--rule)}
.market-col:first-child{padding-left:0}
.market-col:last-child{border-right:none;padding-right:0}
.market-col .kicker{font-family:var(--font-sans);font-size:var(--cog-fs-xs);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);font-weight:600}
.market-col .lbl-sub{font-family:var(--font-sans);font-size:var(--cog-fs-sm);color:var(--ink-soft);margin-top:2px}
.market-col .val{font-family:var(--font-sans);font-weight:300;font-size:clamp(32px,3.1vw,48px);line-height:.95;letter-spacing:-.015em;color:var(--ink);white-space:nowrap;margin-top:2px}
.market-col .val small{font-size:var(--cog-fs-lab);color:var(--ink-soft);font-weight:400;letter-spacing:0;margin-left:3px}
.market-spark{display:block;width:56px;height:18px;margin-top:var(--space-3);stroke:var(--color-success);opacity:.9}
.market-spark polyline{stroke-dasharray:100;stroke-dashoffset:0}
.market-col .tr{display:inline-flex;align-items:baseline;gap:3px;font-family:var(--font-sans);font-size:var(--cog-fs-body);color:var(--ink-mute)}
.market-col .tr svg{width:10px;height:10px;stroke:var(--color-success);fill:none;stroke-width:1.7;flex:0 0 auto;align-self:center}
.market-col .tr .tr-plus{color:var(--color-success);font-weight:500}
.market-col .tr .cu{color:var(--ink);font-weight:500}
.market-col .per{font-family:var(--font-sans);font-size:var(--cog-fs-2xs);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-mute)}
@media (prefers-reduced-motion: no-preference){
  .market-row:not(.is-visible) .market-spark polyline{stroke-dashoffset:100}
  .market-row.is-visible .market-spark polyline{transition:stroke-dashoffset .8s cubic-bezier(.2,.7,.2,1)}
  .market-row.is-visible .market-col:nth-child(1) .market-spark polyline{transition-delay:.05s}
  .market-row.is-visible .market-col:nth-child(2) .market-spark polyline{transition-delay:.15s}
  .market-row.is-visible .market-col:nth-child(3) .market-spark polyline{transition-delay:.25s}
  .market-row.is-visible .market-col:nth-child(4) .market-spark polyline{transition-delay:.35s}
  .market-row.is-visible .market-col:nth-child(5) .market-spark polyline{transition-delay:.45s}
  .market-row:not(.is-visible) .tr svg{opacity:0;transform:translateY(5px)}
  .market-row.is-visible .tr svg{opacity:1;transform:translateY(0);transition:opacity .4s ease,transform .4s ease}
  .market-row.is-visible .market-col:nth-child(1) .tr svg{transition-delay:.5s}
  .market-row.is-visible .market-col:nth-child(2) .tr svg{transition-delay:.6s}
  .market-row.is-visible .market-col:nth-child(3) .tr svg{transition-delay:.7s}
  .market-row.is-visible .market-col:nth-child(4) .tr svg{transition-delay:.8s}
  .market-row.is-visible .market-col:nth-child(5) .tr svg{transition-delay:.9s}
}
@media (max-width:700px){
  .market-row{display:grid;grid-template-columns:1fr 1fr;gap:22px 20px}
  .market-col{border-right:none;padding:0}
  .market-col.canton{grid-column:1/-1}
}
.market-consolidation{margin-top:30px;padding:26px 0;border-top:1px solid var(--rule);display:flex;flex-direction:column;gap:12px}
.market-consolidation .kicker{font-family:var(--font-sans);font-size:var(--cog-fs-xs);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);font-weight:600}
.market-consolidation .empty-txt{font-family:var(--font-sans);font-style:italic;font-size:15px;color:var(--ink-soft);line-height:1.6;margin:0;max-width:48ch}
.price-legend{font-family:var(--font-sans);font-style:italic;font-size:var(--cog-fs-cta-caps);color:var(--ink-soft);margin-top:var(--space-8);max-width:54ch}

/* --- L10 · Notes §2.6bis (pattern A / pattern B) --------------------------- */
.note-a{display:flex;gap:8px;align-items:flex-start;background:var(--paper);border-left:2px solid var(--rule);border-radius:0;padding:7px 12px;margin-top:6px}
.note-a svg{width:16px;height:16px;stroke:var(--icon-muted);fill:none;stroke-width:1.6;flex:0 0 auto;margin-top:1px}
.note-a span,.note-a p{font-family:var(--font-sans);font-size:var(--cog-fs-legal);line-height:1.5;color:var(--ink-mute);margin:0}
.note-a b{color:var(--ink);font-weight:600}
.note-b{display:flex;gap:8px;align-items:flex-start;margin-top:14px}
.note-b svg{width:16px;height:16px;stroke:var(--icon-muted);fill:none;stroke-width:1.6;flex:0 0 auto;margin-top:1px}
.note-b span{font-family:var(--font-sans);font-size:var(--cog-fs-legal);line-height:1.5;color:var(--ink-mute);margin:0}

/* --- L11bis · Réassurance — pattern unique .garantie §2.20bis (décision 22/07,
   base .tb-item Estimation) + 2 dérivés autorisés (.garantie--carte, liste-bénéfices
   déjà couverte par co-checklist/start-feats/aug-feats/why-item, non touchée ici).
   La sécurité des données reste .note-a + icône lock — jamais un bloc garantie. ------ */
.garantie-row{display:flex;align-items:flex-start;gap:0}
.garantie{flex:1;display:flex;gap:16px;padding:0 clamp(16px,2.2vw,26px)}
.garantie:first-child{padding-left:0}
.garantie:last-child{padding-right:0}
.garantie svg{width:var(--icon-lg);height:var(--icon-lg);stroke:var(--icon-muted);fill:none;stroke-width:var(--icon-stroke);flex-shrink:0;margin-top:2px}
/* Exceptions doctrinales certifiées 22/07 : pin localisation (5.Estimation l.298) + check validation (l.308) — ne pas supprimer */
.garantie svg.ic-accent{stroke:var(--icon-accent)}
.garantie svg.ic-strong{stroke:var(--icon-strong)}
.garantie-txt b{display:block;font-family:var(--font-sans);font-weight:600;font-size:15px;color:var(--ink)}
.garantie-txt span{display:block;font-family:var(--font-sans);font-size:13.5px;color:var(--ink-soft);line-height:1.55;margin-top:5px}
.garantie-sep{width:1px;background:var(--rule);align-self:stretch;flex-shrink:0}
@media (max-width:920px){.garantie-row{flex-wrap:wrap;gap:24px 0}.garantie-sep{display:none}.garantie{flex:0 0 calc(50% - 12px);padding:0}}
@media (max-width:560px){.garantie{flex:0 0 100%}}
/* Dérivé carte (ex. .helpers Acheter) : même anatomie icône+titre+phrase, empilée verticalement dans une carte au lieu d'une rangée.
   Extraction 27/07 (décision « aucun composant en double copie ») : l'anatomie complète
   de la carte, qui vivait en local dans Acheter (§CTA secondaires), devient la source
   unique — Acheter et Carrière la consomment sans la redéclarer. Positionnement (grille,
   fond de la variante photo) reste au conteneur de page. */
.garantie--carte{display:flex;flex-direction:column;gap:var(--space-5);padding:var(--space-8);background:var(--paper-warm);border:1px solid transparent;transition:box-shadow .4s ease,transform .4s ease,border-color .4s ease}
/* Le dérivé carte n'est pas dans une rangée à séparateurs : il annule les retraits de
   bord de `.garantie:first-child`/`:last-child` (sinon la 1ʳᵉ carte d'une grille perd
   son padding gauche). */
.garantie--carte:first-child,.garantie--carte:last-child{padding:var(--space-8)}
.garantie--carte svg{margin-top:0}
.garantie--carte .hico{width:44px;height:44px;border-radius:var(--radius-full);background:var(--cog-white);display:inline-flex;align-items:center;justify-content:center}
.garantie--carte .hico svg{width:var(--icon-lg);height:var(--icon-lg);stroke:var(--icon-strong);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.garantie--carte h4{margin:0;font-family:var(--font-sans);font-weight:600;font-size:var(--cog-fs-body);color:var(--ink)}
.garantie--carte p{margin:0;font-size:var(--cog-fs-sm);line-height:1.5;color:var(--ink-soft)}
.garantie--carte .arrow{margin-top:auto;font-family:var(--font-sans);font-size:var(--cog-fs-lab);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:currentColor;display:inline-flex;align-items:center;gap:8px;transition:gap .3s ease}
.garantie--carte:hover .arrow{gap:14px}
.garantie--carte .arrow svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
/* Variante photo : la pastille d'icône est remplacée par une photo pleine largeur,
   angles vifs, format portrait 4/5 (même format que .svc/.tc). */
.garantie--carte.has-photo{padding:0;gap:0;overflow:hidden}
.garantie--carte.has-photo:first-child,.garantie--carte.has-photo:last-child{padding:0}
.garantie--carte .gc-ph{position:relative;aspect-ratio:4/5;background:var(--paper-deep);overflow:hidden}
.garantie--carte .gc-ph img,.garantie--carte .gc-ph image-slot{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform 1.3s cubic-bezier(.2,.7,.2,1)}
.garantie--carte:hover .gc-ph img,.garantie--carte:hover .gc-ph image-slot{transform:scale(1.05)}
.garantie--carte .gc-body{padding:var(--space-8);display:flex;flex-direction:column;gap:var(--space-5)}

/* --- L6 · aug-row — texte+image générique (motif Courtage, porté depuis le <style>
   inline de design/pages/Agence-Lausanne.html:156-164, verbatim). Consommé par
   cogestim/intro-2col (05/08). */
.aug-row{display:grid;grid-template-columns:1.02fr .98fr;background:var(--paper);border:1px solid var(--rule);overflow:hidden;margin-top:8px}
.aug-row .img{position:relative;min-height:clamp(280px,30vw,420px);overflow:hidden;background:var(--paper-deep)}
.aug-row .img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform 1.8s cubic-bezier(.2,.7,.2,1)}
.aug-row:hover .img img{transform:scale(1.035)}
/* Variante logo/document (opt-in, champ ACF image_logo) : image entière sur fond blanc, sans rognage ni zoom au survol. Défaut = cover inchangé. */
.aug-row--logo .img{background:var(--cog-white)}
.aug-row--logo .img img{object-fit:contain;padding:clamp(16px,3vw,40px);box-sizing:border-box}
.aug-row--logo:hover .img img{transform:none}
.aug-row .body{padding:clamp(32px,4vw,60px);display:flex;flex-direction:column;gap:15px;justify-content:center}
.aug-row .body h3{margin:2px 0 0;max-width:22ch}
.aug-row .body p{margin:0;color:var(--ink-soft);font-size:15px;line-height:1.65;max-width:52ch}
@media (max-width:920px){.aug-row{grid-template-columns:1fr}.aug-row .img{min-height:240px}}
/* Pastille play optionnelle (bloc intro-2col, champ vidéo) — même pastille que .video-card .play-ic ; absente tant que le champ est vide */
.aug-row .img .play-ic{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;width:64px;height:64px;border:0;border-radius:var(--radius-full);background:rgba(255,255,255,.88);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background .3s ease,transform .3s ease}
.aug-row .img .play-ic svg{width:var(--icon-lg);height:var(--icon-lg);color:var(--icon-strong);margin-left:3px}
.aug-row:hover .img .play-ic{background:#fff;transform:translate(-50%,-50%) scale(1.06)}

/* --- L16 · Hover des CARTES DE CONTENU — règle unique (décision 27/07) -----------
   Une carte de contenu (bien, réassurance en carte, média, offre, bloc texte+image)
   au survol : ombre --shadow-card + translateY(-4px), photo en zoom lent 1.05, et
   FILET INCHANGÉ (--rule). Jamais de cadre --ink : le cadre noir est réservé aux
   CONTRÔLES (chips de filtre, cartes de sélection, toggles, pager, fermeture de
   modale, boutons fantômes), où il signale un état d'interaction. Modèle de
   référence : .card (§L7). Toute nouvelle carte reprend ce hover, jamais un autre. */
.garantie--carte:hover,.aug-row:hover,.video-card:hover{box-shadow:var(--shadow-card);transform:translateY(-4px);border-color:var(--rule)}

/* --- L11 · figures-band §2.20 — anatomie unique (décision 21/07 : flex + .fb-sep ;
   l'anatomie grid/border-left de Home est écartée, motif : une seule structure DOM).
   Taille unique décision 22/07 : la variante --xl est écartée (motif : uniformité
   totale du composant, aucun écart de taille entre pages) — Home passe en standard. */
.figures-band{padding:clamp(56px,6vw,96px) 0;background:var(--paper);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.fb-head{margin-bottom:clamp(40px,4vw,60px);display:flex;justify-content:space-between;align-items:baseline;gap:24px;flex-wrap:wrap}
.fb-head .ttl{font-family:var(--font-sans);font-style:italic;font-weight:400;font-size:var(--cog-fs-body-lg);color:var(--ink-soft);max-width:46ch;letter-spacing:.005em}
.fb-row{display:flex;align-items:stretch;justify-content:space-between;gap:clamp(16px,2vw,32px);flex-wrap:wrap}
.fb-item{display:flex;flex-direction:column;gap:10px;flex:1;min-width:130px}
.fb-item .n{font-family:var(--font-sans);font-weight:300;font-size:clamp(30px,2.8vw,46px);line-height:.9;letter-spacing:-.02em;color:var(--ink);white-space:nowrap}
.fb-item .n sup{font-size:var(--cog-fs-sup);vertical-align:.5em;font-weight:300}
.fb-item .l{font-family:var(--font-sans);font-size:var(--cog-fs-xs);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);line-height:1.5;display:flex;flex-direction:column}
.fb-item .l b{color:var(--ink-soft);font-weight:500;letter-spacing:.14em;margin-bottom:3px}
.fb-sep{width:1px;background:var(--rule);align-self:stretch;flex-shrink:0;margin:4px 0}
@media (max-width:920px){.fb-sep{display:none}.fb-item{flex:0 0 calc(50% - 12px);padding:8px 0}}
@media (max-width:560px){.fb-item{flex:0 0 100%}}

/* --- L12 · Témoignages grille 3col §2.23/L11b (extraction 23/07 : vivait en
   3 copies verbatim — Estimation-Funnel / 3.Courtage / 5.Estimation — décision
   « aucun composant en double copie » ; valeurs de référence reprises de
   3.Courtage.html, source déclarée par 5.Estimation. .vt-src (étoiles + mention
   Google) PROMU élément optionnel du composant (amendement 23/07, voir biblio
   §2.23) : consommé par Courtage ET Estimation-résultat, plus de copie locale.
   Reste local : Estimation `.vt-avatar-initials` uniquement. */
.vtesti{display:flex;margin-top:8px}
.vt-card{flex:1;display:flex;flex-direction:column;gap:16px;padding:0 clamp(28px,3.4vw,52px)}
.vt-card:first-child{padding-left:0}
.vt-card:last-child{padding-right:0}
.vt-card + .vt-card{border-left:1px solid var(--rule)}
/* Emoji dans une citation (lot B-2) : styles emoji WP dequeués (functions.php), règle core reprise ici, scopée au registre. */
.vtesti img.emoji{width:1em;height:1em;vertical-align:-0.1em}
.vt-glyph{font-family:var(--sans);font-weight:300;font-style:italic;font-size:72px;line-height:1;height:40px;background-image:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.vt-quote{font-family:var(--sans);font-style:italic;font-weight:400;font-size:clamp(18px,1.5vw,22px);line-height:1.45;color:var(--ink);margin:0;text-wrap:pretty}
.vt-meta{margin-top:auto;padding-top:22px;display:flex;align-items:center;gap:14px}
.vt-avatar{width:56px;height:56px;aspect-ratio:1;border-radius:var(--radius-full);overflow:hidden;flex-shrink:0;object-fit:cover}
.vt-avatar img{width:100%;height:100%;object-fit:cover}
.vt-meta .name{font-family:var(--sans);font-weight:500;font-size:16px;color:var(--ink)}
.vt-meta .role{font-family:var(--sans);font-size:12.5px;color:var(--ink-soft);margin-top:4px}
.vt-meta .role b{color:var(--ink);font-weight:500}
/* Élément optionnel §2.23 (amendement 23/07) : source Google sous la carte. */
.vt-src{font-family:var(--sans);font-size:11.5px;letter-spacing:.04em;color:var(--ink-mute);margin-top:8px}
.vt-src .stars{color:var(--color-rating);letter-spacing:1px}
/* 17/10 (lot B-2, amendement géométrie hors atelier) : bascule en colonne à ≤1100px au lieu de 920px — 4 cartes en ligne ne tiennent plus (ligne .vt-src sur 2 lignes à 1024px). */
@media (max-width:1100px){.vtesti{flex-direction:column}.vt-card{padding:0}.vt-card + .vt-card{border-left:0;border-top:1px solid var(--rule);padding-top:clamp(32px,5vw,44px);margin-top:clamp(32px,5vw,44px)}}

/* --- L13 · Graphique de tendance §2.37 `.trend-chart` (ajout 23/07) --------
   2 séries max, sans remplissage : marque `--red`, neutre `--rule`, trame
   `--rule-soft`. Consomme la même anatomie SVG que les sparklines §2.21. */
.trend-chart{display:block;width:100%}
.trend-chart .grid line{stroke:var(--rule-soft);stroke-width:1}
.trend-chart polyline{fill:none;stroke-width:2;vector-effect:non-scaling-stroke;stroke-linejoin:round;stroke-linecap:round}
.trend-chart .c-accent{stroke:var(--red)}
.trend-chart .c-neutral{stroke:var(--rule)}

/* --- L14 · Heatmap prix/m² §2.38 (ajout 23/07) -----------------------------
   4 paliers `color-mix(in srgb, var(--ink) X%, transparent)`, X = 12/30/52/78 ;
   pastilles de légende à angles vifs (rayon 0) ; pin « Votre bien » = exception
   localisation `--icon-accent`. */
.heat-you{position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);display:inline-flex;align-items:center;gap:6px;background:var(--cog-white);border:1px solid var(--rule);border-radius:var(--radius-pill);padding:6px 12px;font-family:var(--font-sans);font-size:12.5px;color:var(--ink)}
.heat-you svg{width:14px;height:14px;stroke:var(--icon-accent);fill:none;stroke-width:1.6}
.heat-legend{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;margin-top:14px;font-family:var(--font-sans);font-size:12px;color:var(--ink-soft)}
.heat-legend b{font-weight:600;color:var(--ink);margin-right:2px}
.heat-legend span{display:inline-flex;align-items:center;gap:8px}
.heat-legend i{width:14px;height:14px;border-radius:0;display:inline-block}

/* --- L15 · .tel-block — bloc téléphone direct §2.14bis (extraction 27/07,
   audit 2.3 : vivait en double copie Agence-Lausanne / 5.Estimation).
   Anatomie de référence : Agence-Lausanne ; l'icône adopte la couleur du texte
   adjacent (doctrine icônes 17/07) — currentColor, jamais --icon-accent. */
.tel-block{margin-top:14px}
.tel-block .lbl{display:block;font-family:var(--font-sans);font-size:var(--cog-fs-xs);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-mute)}
.tel-block .tel-num{display:inline-flex;align-items:center;gap:9px;margin-top:6px;font-family:var(--font-sans);font-weight:500;font-size:20px;letter-spacing:-.005em;color:var(--ink);transition:color .3s ease}
.tel-block .tel-num svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.6;flex-shrink:0}
.tel-block .tel-num:hover{color:var(--red)}
.tel-block .hours{margin:8px 0 0;font-family:var(--font-sans);font-size:12.5px;color:var(--ink-mute);line-height:1.6}
.tel-block .alt{margin:16px 0 0;font-family:var(--font-sans);font-size:12.5px;color:var(--ink-soft)}

/* --- L17 · EXTRACTION 28/07 (2.Acheter + Agence-Lausanne, aucune valeur modifiée) --------- */

/* .crumb — fil d'Ariane (source : Agence-Lausanne, verbatim identique dans la page) */
.crumb{padding:clamp(14px,1.6vw,20px) 0 0}
.crumb ol{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-family:var(--sans);font-size:13px;color:var(--ink-mute)}
.crumb a{color:var(--ink-mute);transition:color .3s ease}
.crumb a:hover{color:var(--red)}
.crumb li[aria-current]{color:var(--ink);font-weight:500}
.crumb .sep{color:var(--rule);font-size:12px}

/* .crumb-band — bande du fil posé SOUS un hero (variante b) quand la section qui suit a
   un fond propre (correctif 20/10, rejet UI « bande blanche » Courtage/Vevey/Pully) : le
   fil appartient à cette section. La bande reprend son fond et son filet haut ; la
   section, qui suit immédiatement, perd le sien (un seul filet, AU-DESSUS du fil).
   Modificateur posé par page.php d'après le bloc suivant (pas de :has()). Valeurs =
   celles des sections hôtes, aucune nouvelle. Section suivante blanche : pas de bande. */
.crumb-band--figures{background:var(--paper);border-top:1px solid var(--rule)}
.crumb-band--figures + .figures-band{border-top:0}
.crumb-band--warm{background:var(--paper-warm)}

/* .est-hero.has-crumb — fil d'Ariane en 1re ligne d'un hero .est-hero (variante c,
   source : Profil-courtier, patron .search-entry 31/07). REMONTÉ de cogestim-courtier.css
   (lot fil d'Ariane 20/10, valeurs inchangées) : partagé par le profil courtier et le
   hero-estimation de /estimer/. padding-top = celui de .search-entry (le padding propre
   de .crumb absorbe le haut) ; écart crumb → grille = margin-top de .hero-est
   (5.Estimation). Préfixe `section` : les deux hôtes posent .est-hero{padding:…} en
   (0,2,0) — .courtier-page .est-hero et .wp-block-cogestim-hero-estimation.est-hero —
   la règle doit l'emporter quel que soit l'ordre de chargement des feuilles. */
section.est-hero.has-crumb{padding-top:clamp(4px,.6vw,8px)}
section.est-hero.has-crumb .hero2-grid{margin-top:clamp(28px,3.2vw,38px)}

/* .search-entry — entrée de page recherche directe (source : 2.Acheter). Padding
   haut réduit (correction 31/07) : héberge désormais .crumb (§L17) en 1re ligne du
   bandeau — le padding-top propre de .crumb absorbe le haut, ce padding ne sert
   plus que de respiration crumb–eyebrow (positionnement par conteneur, pas de
   restyle de .crumb : cf. précédent .fr-panel/.field-lab). Fond : EXCEPTION
   DOCUMENTÉE à la règle des trois niveaux (16/07) — décision produit du 31/07,
   ne pas rouvrir sans nouveau signal produit. Le bandeau éditorial des listings
   porte --paper-warm par identité certifiée (et non --paper comme le voudrait la
   règle générale des bandeaux d'entrée de page) ; testé puis annulé le 31/07
   après passage en --paper (rendu jugé non conforme à l'identité attendue). */
.search-entry{background:var(--paper-warm);padding:clamp(4px,.6vw,8px) 0 clamp(18px,2.2vw,28px);border-bottom:1px solid var(--rule-soft)}
.search-entry h1{font-family:var(--sans);font-weight:300;font-size:clamp(28px,3.2vw,44px);line-height:1.04;letter-spacing:-.015em;color:var(--ink);margin:10px 0 0;max-width:40ch;text-wrap:balance}
.search-entry .sub{margin:10px 0 0;font-family:var(--sans);font-weight:400;font-size:clamp(15px,1.2vw,17px);color:var(--ink-soft);max-width:none}

/* .res-bar/.res-count/.res-tools — barre résultats (source : 2.Acheter) */
.res-bar{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:22px}
.res-count{font-family:var(--sans);font-size:var(--cog-fs-field);color:var(--ink-soft)}
.res-count b{font-family:var(--sans);font-weight:600;font-size:var(--cog-fs-h4);color:var(--ink);letter-spacing:-.01em}
.res-tools{display:flex;align-items:center;gap:14px;flex-wrap:wrap}

/* .sort-wrap — tri (source : 2.Acheter). Chevron de disclosure ajouté (31/07,
   amendement bibliothèque) : tout contrôle qui ouvre une liste porte le chevron —
   l'absence ici était une lacune, pas un choix (cf. fiche de consignation session
   composants filtre). En inline-flex avec gap:8px : le pseudo-élément se place
   en flux, dernier item de la rangée (pas de positionnement absolu comme
   .sf.has-chev::after, qui vit dans un conteneur à ancrage différent). Le
   padding-right:16px réservé au chevron sur .sort-wrap select/.fs-sort-btn est
   retiré (redondant, le chevron est désormais hors du flux de texte du select). */
.sort-wrap{position:relative;display:inline-flex;align-items:center;gap:8px;border:1px solid var(--rule);border-radius:var(--radius-pill);padding:10px 18px}
.sort-wrap label{font-family:var(--sans);font-size:var(--cog-fs-lab);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-mute)}
.sort-wrap select{border:0;outline:0;background:transparent;font-family:var(--sans);font-size:var(--cog-fs-cta);font-weight:600;color:var(--ink);cursor:pointer;-webkit-appearance:none;appearance:none}
.sort-wrap::after{content:"";width:7px;height:7px;border-right:1.6px solid var(--ink-mute);border-bottom:1.6px solid var(--ink-mute);transform:rotate(45deg);flex-shrink:0;pointer-events:none}
/* Anneau de focus clavier (audit accessibilité 15/09, conservé après le swap
   .field-select du bloc marché — bénéficie toujours au .sort-wrap d'Acheter/
   projets-neufs) : .sort-wrap select pose outline:0, sans cet anneau le
   contrôle n'a aucun retour clavier — lacune du même ordre que le chevron
   ajouté le 31/07. Anneau canonique --cog-focus-ring, aucune valeur nouvelle. */
.sort-wrap:focus-within{box-shadow:var(--cog-focus-ring)}

/* .map-toggle — bascule carte (source : 2.Acheter) */
.map-toggle{display:inline-flex;align-items:center;gap:10px;border:1px solid var(--rule);border-radius:var(--radius-pill);padding:9px 16px 9px 18px;font-family:var(--sans);font-size:var(--cog-fs-cta-caps);font-weight:600;color:var(--ink);transition:border-color .3s ease,color .3s ease}
.map-toggle:hover{border-color:var(--ink)}
.map-toggle .sw{width:38px;height:21px;border-radius:var(--radius-pill);background:var(--rule);position:relative;transition:background .3s ease}
.map-toggle .sw::after{content:"";position:absolute;top:2px;left:2px;width:17px;height:17px;border-radius:var(--radius-full);background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.2);transition:transform .3s ease}
.map-toggle.on .sw{background-image:var(--grad)}
.map-toggle.on .sw::after{transform:translateX(17px)}

/* .ph-empty — COMPOSANT UNIQUE placeholder « visuel à venir » (créé 28/07) : trame 135° +
   fond --paper-deep + badge .mono, anatomie unique pour tout emplacement vide. .map-panel
   consomme cette anatomie via sélecteur combiné (aucune valeur changée sur 2.Acheter).
   .card--projet .card-ph.is-empty (Projets-neufs.html) unifié 28/07 (micro-passe de
   clôture) : classe .ph-empty ajoutée en page, seul gap:12px (vs 14px ici) conservé en
   override local — divergence de 2px, non fusionnée silencieusement. */
.ph-empty,.map-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;background:repeating-linear-gradient(135deg,transparent 0 16px,rgba(26,26,31,.03) 16px 17px),var(--paper-deep);text-align:center;padding:24px}
.ph-empty .mono,.map-placeholder .mono{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:var(--cog-fs-xs);letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft);background:var(--paper);padding:7px 12px;border:1px solid var(--rule)}
.ph-empty p,.map-placeholder p{margin:0;font-size:var(--cog-fs-cta);color:var(--ink-soft);max-width:40ch}

/* .map-panel — conteneur carte, off par défaut (source : 2.Acheter) */
/* Avenant 2 (08/10) : hauteur du panneau en vh plafonnée, plus d'aspect-ratio 21/7 (bandeau 3:1
   trop bas pour cadrer un amas de pins). Desktop min(72vh,820px) ; mobile ≤720px min(60vh,520px).
   La hauteur change à l'affichage (toggle, resize) → invalidate() côté cogestim-listing.js. */
.map-panel{margin-bottom:32px;overflow:hidden;border:1px solid var(--rule);height:min(72vh,820px);position:relative}
.map-panel[hidden]{display:none} /* `hidden` = seule source de visibilité (plus de .show, passe 5 filtre rayon) */
.map-panel .map-placeholder{position:absolute;inset:0}
/* Carte des résultats (Leaflet, cogestim-funnel-map.js showMany) : z-index:1 = contexte
   d'empilement propre, les panes Leaflet (jusqu'à 1000) ne passent pas sur l'en-tête. */
.map-panel .map-canvas{position:absolute;inset:0;z-index:1;background:var(--paper-deep)}
.map-panel .leaflet-control-attribution{font-family:var(--sans);font-size:10px;color:var(--ink-mute);background:color-mix(in srgb,var(--cog-white) 85%,transparent);padding:1px 6px}
.map-panel .leaflet-control-attribution a{color:var(--ink-soft)}
@media (max-width:720px){.map-panel{height:min(60vh,520px)}}

/* .promo-banner — bandeau pub compact intercalé (source : 2.Acheter) */
.promo-banner{grid-column:1/-1;display:flex;justify-content:center;padding:clamp(4px,1vw,12px) 0}
.promo-banner .pb-inner{display:grid;grid-template-columns:300px 1fr auto;align-items:stretch;width:min(100%,820px);background-image:var(--grad-45);color:#fff;overflow:hidden;border:0;box-shadow:0 20px 44px -30px rgba(168,10,46,.5)}
.promo-banner .pb-img{position:relative;overflow:hidden;min-height:138px}
.promo-banner .pb-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.promo-banner .pb-text{padding:20px clamp(22px,2vw,30px);display:flex;flex-direction:column;justify-content:center;gap:7px}
.promo-banner .lab{color:rgba(255,255,255,.78);font-size:var(--cog-fs-2xs)}
.promo-banner h3{font-family:var(--sans);font-weight:300;font-size:clamp(19px,1.5vw,24px);line-height:1.12;letter-spacing:-.01em;color:var(--paper-warm);margin:0;max-width:22ch}
.promo-banner h3 .em{color:var(--paper-warm)}
.promo-banner p{margin:0;font-size:var(--cog-fs-sm);line-height:1.5;color:rgba(255,255,255,.9);max-width:44ch}
.promo-banner .pb-cta{display:flex;align-items:center;padding:0 clamp(24px,2.2vw,34px);white-space:nowrap}
/* Anti-tremblement (13/10) : .link:hover ouvre le gap de --space-5 à --space-7,
   donc le lien s'élargit ; en colonne `auto` de .pb-inner, cet élargissement
   rétrécit la colonne texte (1fr) → h3/p se recoupent. Règle .link:hover
   certifiée INTACTE : la boîte du lien garde sa largeur (marge droite négative,
   synchrone au gap) et un translateX rend le geste d'origine (flèche fixe, le
   libellé recule). Aucun effet au repos. Mobile (1 colonne) : inchangé. */
@media (min-width:761px){
  .promo-banner .pb-cta .link{transition:gap var(--dur-fast) ease,margin-right var(--dur-fast) ease,transform var(--dur-fast) ease}
  .promo-banner .pb-cta .link:hover{margin-right:calc(var(--space-5) - var(--space-7));transform:translateX(calc(var(--space-5) - var(--space-7)))}
}
@media (max-width:760px){
  .promo-banner .pb-inner{grid-template-columns:1fr}
  .promo-banner .pb-img{min-height:120px}
  .promo-banner .pb-text{padding-bottom:6px}
  .promo-banner .pb-cta{padding:0 24px 22px}
}

/* .promo-banner.is-sobre — modificateur (amendement 26/08, Agence-Lausanne) :
   bandeau de déviation « Projets neufs » sur page agence, sans colonne image
   (bandeau générique canton, pas de photo de promotion précise) et 2 sorties
   au lieu d'1. N'annule pas .promo-banner--2cta (contexte listing) : .is-sobre
   cible spécifiquement l'usage page agence. */
.promo-banner.is-sobre .pb-inner{grid-template-columns:1fr auto;width:min(100%,820px)}
.promo-banner.is-sobre .pb-text{padding:clamp(24px,2.6vw,34px) clamp(26px,3vw,40px)}
.promo-banner.is-sobre h3{max-width:30ch}
.promo-banner.is-sobre .pb-cta{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:12px;padding:0 clamp(26px,2.8vw,40px)}
@media (max-width:760px){
  .promo-banner.is-sobre .pb-inner{grid-template-columns:1fr}
  .promo-banner.is-sobre .pb-cta{padding:0 24px 24px}
}

/* --- L18 · .field-range — champ de filtre à panneau de bornes (extraction 31/07,
   audit field-range vs bibliothèque) : slot NU (aucune bordure propre), même dessin
   que Transaction ou Type de bien — libellé CAPS, valeur de synthèse, UN seul chevron
   (celui de .sf.has-chev, jamais de glyphe ajouté). Le panneau ancré consomme
   .field--boxed (§L3, variante unique de champ) et .link (« Effacer ») sans les
   restyler. --fr-panel-w et --z-popover : constantes de composant (design-tokens.css).
   Anatomie de .fr-panel partagée avec .field-suggest (§L19, cousin autocomplétion). */
.fr-trigger{
  border:0;outline:0;background:transparent;font-family:var(--font-sans);font-size:var(--cog-fs-sf-value);font-weight:500;color:var(--ink);
  width:100%;padding:0 18px 0 0;text-align:left;line-height:1.35;cursor:pointer;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.fr-trigger.is-empty{color:var(--ink-mute);font-weight:400}
.fr-trigger:focus-visible{box-shadow:var(--cog-focus-ring)}
.field-range[data-open="true"].has-chev::after,.field-select[data-open="true"].has-chev::after{transform:rotate(-135deg);bottom:12px}
.field-range .fr-panel,.field-suggest .fr-panel,.field-select .fr-panel{
  display:none;position:absolute;z-index:var(--z-popover);top:calc(100% + var(--space-4));left:0;width:var(--fr-panel-w);
  background:var(--cog-white);border:1px solid var(--rule);border-radius:var(--radius-sm);
  box-shadow:var(--shadow-float);padding:var(--space-2) var(--space-6) var(--space-6);
}
/* Correctif technique 31/07 : combinateur ENFANT (>) plutôt que descendant.
   .field-range héberge des .field-select imbriqués (les pickers De/À compacts,
   §L20) dont le .fr-panel vit plusieurs niveaux plus bas dans le DOM (.fr-panel
   > .fr-row > .field--boxed > .fr-panel imbriqué). Un sélecteur descendant
   (espace) faisait matcher LES DEUX paliers à la fois : ouvrir le panneau
   Pièces/Prix/Surface (data-open="true" sur .field-range) forçait aussi
   l'affichage des panneaux De/À imbriqués, même fermés (data-open="false" sur
   leur propre .field-select). Le combinateur enfant restreint la règle au
   .fr-panel qui est l'enfant DIRECT du composant ouvert — chaque palier
   d'imbrication reste piloté par son propre data-open. */
.field-range[data-open="true"] > .fr-panel,.field-suggest[data-open="true"] > .fr-panel,.field-select[data-open="true"] > .fr-panel{display:block}
.field-range.fr-end .fr-panel,.field-select.fr-end .fr-panel{left:auto;right:0}
.fr-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-5)}
.fr-clear{margin-top:var(--space-6);cursor:pointer}

/* --- L19 · .field-suggest — champ de filtre à autocomplétion (session 31/07),
   cousin de .field-range : même anatomie de panneau (.fr-panel §L18). Affordance
   de recherche : ce slot N'utilise PAS .sf.has-chev — la loupe canonique du set
   (même tracé que .mfb-l svg / .empty .eico svg) remplace le chevron pour signaler
   la saisie libre avant tout clic ; icône informative nue, --icon-muted (adopte la
   couleur du placeholder adjacent, doctrine icônes §17/07). Liste de suggestions
   filtrées à la saisie (localités puis « NPA — Localité »), surlignage du fragment
   saisi (<mark>), navigation clavier, état « Aucune localité ». */
.fs-input{
  box-sizing:border-box;border:1px solid transparent;border-radius:var(--radius-sm);outline:0;background:transparent;font-family:var(--font-sans);font-size:var(--cog-fs-sf-value);font-weight:500;color:var(--ink);
  width:100%;padding:0 22px 0 0;cursor:text;
}
.fs-input::placeholder{color:var(--ink-mute);font-weight:400}
.fs-input:focus{border-color:var(--color-text);box-shadow:var(--cog-focus-ring)}
.field-suggest{position:relative}
.field-suggest .fs-search{position:absolute;right:2px;bottom:11px;width:var(--icon-sm);height:var(--icon-sm);stroke:var(--icon-muted);fill:none;stroke-width:var(--icon-stroke);pointer-events:none}
.fs-list{list-style:none;margin:0;padding:0;max-height:280px;overflow-y:auto}
.fs-item{display:block;padding:var(--space-3) var(--space-4);border-radius:var(--radius-sm);font-family:var(--font-sans);font-size:var(--cog-fs-sm);color:var(--ink-soft);cursor:pointer}
.fs-item mark{background:transparent;color:var(--ink);font-weight:600}
.fs-item .fs-npa{color:var(--ink-mute);font-size:var(--cog-fs-2xs);letter-spacing:.04em}
.fs-item[aria-selected="true"],.fs-item:hover{background:var(--rule-soft)}
.fs-empty{padding:var(--space-4);font-family:var(--font-sans);font-size:var(--cog-fs-sm);color:var(--ink-mute)}
@media (max-width:720px){
  .fr-trigger,.fs-input{font-size:var(--cog-fs-sf-value-mobile)}
  .field-range .fr-panel,.field-suggest .fr-panel,.field-select .fr-panel{width:100%}
  .field-range.fr-end .fr-panel,.field-select.fr-end .fr-panel{left:0;right:auto}
}

/* --- L20 · .field-select — champ à choix unique (session 31/07), cousin de
   .field-range/.field-suggest : anatomie de panneau partagée avec .fr-panel.
   Remplace tout <select> natif visible du site (liste d'options du navigateur,
   hors design system) : le <select> réel reste dans le DOM (API .value/.options,
   compatibilité formulaire) mais visuellement masqué (.fs-native) — un bouton
   (.fr-trigger en barre, .field-in dans les panneaux De/À) et un .fr-panel ancré
   portent l'affichage. Option active : graisse + --ink (pas de coche — évite
   toute collision avec --icon-accent, réservé pin de localisation/validation).
   Survol/actif : --rule-soft, même traitement que .field-suggest §L19. */
/* Correctif technique 31/07 : durcissement opacity:0 + pointer-events:none.
   Le clip 0×0 seul ne suffit pas quand plusieurs .fs-native se superposent
   dans des panneaux imbriqués (.field-select compact des pickers De/À,
   §L20/§L18) : sans opacity:0, un reliquat de rendu natif (chrome de focus,
   affordance OS) pouvait subsister sur 1px ; sans pointer-events:none, ce
   pixel restait cliquable et pouvait intercepter un clic destiné au bouton
   custom superposé. tabindex="-1" (posé en JS) reste seul responsable de
   sortir l'élément du parcours clavier — ce correctif ne touche que le
   rendu/hit-testing pointeur. */
.fs-native{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;padding:0;margin:-1px;opacity:0;pointer-events:none}
.fs-opt-list{list-style:none;margin:0;padding:0;max-height:280px;overflow-y:auto}
.fs-opt{padding:var(--space-3) var(--space-4);border-radius:var(--radius-sm);font-family:var(--font-sans);font-size:var(--cog-fs-sm);color:var(--ink-soft);cursor:pointer}
.fs-opt[aria-selected="true"]{color:var(--ink);font-weight:600}
.fs-opt:hover:not([aria-disabled="true"]),.fs-opt.is-active:not([aria-disabled="true"]){background:var(--rule-soft)}
.fs-opt[aria-disabled="true"]{color:var(--ink-mute);cursor:not-allowed;opacity:.5}
.field--boxed.field-select{position:relative}
.field-select.fs-compact .fr-panel{width:auto;min-width:100%;z-index:calc(var(--z-popover) + 1)}
.field--boxed button.field-in{text-align:left;cursor:pointer}
.field--boxed select.field-in,.field--boxed button.field-in{
  padding-right:38px;
  background-repeat:no-repeat; background-position:right 14px center;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='5 8 14 8'%3E%3Cpath d='m6 9 6 6 6-6' fill='none' stroke='%236E6E76' stroke-width='1.6'/%3E%3C/svg%3E");
}
.sort-wrap .fs-sort-btn{border:0;outline:0;background:transparent;font-family:var(--sans);font-size:var(--cog-fs-cta);font-weight:600;color:var(--ink);cursor:pointer}

/* --- .sf — slot nu de barre (patron 2.Acheter, page-local — pas encore extrait
   en LIBRARY sous ce nom, référencé en commentaire aux lignes 836/902/936
   ci-dessus mais jamais défini : lacune comblée ici, socle consommé par
   .pn-searchbar). Label CAPS, chevron ::after sur .has-chev (positionnement
   absolu, ancrage différent de .sort-wrap::after qui est en flux). */
.sf{position:relative;display:flex;flex-direction:column;gap:6px;padding-bottom:6px;min-width:0}
.sf>label,.sf>.fr-lab{font-family:var(--sans);font-size:var(--cog-fs-2xs);font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-mute)}
.sf.has-chev::after{content:"";position:absolute;right:2px;bottom:15px;width:7px;height:7px;border-right:1.6px solid var(--ink-mute);border-bottom:1.6px solid var(--ink-mute);transform:rotate(45deg);pointer-events:none}
.sf .fr-trigger{width:100%;padding:0 18px 0 0;text-align:left}

/* --- .sb-go — bouton de soumission, verbatim §2.10 (2.Acheter). Toujours
   présent même si les champs filtrent/naviguent déjà en direct (constat
   réel sur la barre Acheter, arbitrage 1 de la planche Projets neufs). */
.sb-go{
  width:var(--cog-control-md);height:var(--cog-control-md);border-radius:var(--radius-full);border:1px solid transparent;color:#fff;
  background-image:var(--grad-45);background-size:150% 150%;background-position:0 50%;
  display:inline-flex;align-items:center;justify-content:center;align-self:end;flex-shrink:0;
  box-shadow:var(--shadow-btn);transition:background-position .5s ease,transform .3s ease,box-shadow .35s ease;
}
.sb-go:hover{background-position:100% 50%;transform:translateY(-1px);box-shadow:var(--shadow-btn-hover)}
.sb-go svg{width:var(--icon-md);height:var(--icon-md);stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}

/* --- L22 · .pn-searchbar — barre de recherche 3 champs, Projets neufs (planche
   01/09, amendée 01/09 soir — design/reference/Barre-recherche-projets-neufs.html).
   Dérivée de .searchbar/.sb-main (archive-cogestim_property.php, page-local,
   pas encore extrait en LIBRARY) réduite à 3 champs, TOUS .field-select §L20
   uniforme (.fr-trigger + .fr-panel/.fs-opt-list) — Ville a rejoint Transaction/
   Statut sur cette même anatomie (amendement : choix fermé ~22 villes, remplace
   .field-suggest §L19, cf. arbitrage 3 révisé de la planche). Carte flottante
   posée sur le hero .search-entry (identité --paper-warm inchangée, exception
   31/07 non rouverte). Bouton .sb-go toujours présent (desktop), .sb-apply
   toujours présent (mobile) — même si les champs filtrent/naviguent déjà en
   direct (constat réel sur la barre Acheter, arbitrage 1 de la planche). */
.pn-searchbar .mobile-filter-btn{display:none}
.pn-searchbar{
  margin-top:clamp(18px,2vw,26px);background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--radius-sm);
  padding:clamp(18px,2vw,24px) clamp(20px,2.4vw,30px) clamp(14px,1.6vw,18px);
  box-shadow:var(--shadow-float);
}
.pn-searchbar .sb-close,.pn-searchbar .sb-title{display:none}
.pn-searchbar .sb-apply{display:none}
.pn-main{display:grid;grid-template-columns:1fr 1fr 1.3fr auto;gap:clamp(20px,2.6vw,36px);align-items:end}
@media (max-width:900px){.pn-main{grid-template-columns:1fr 1fr;row-gap:22px}.pn-main .field-select:last-of-type{grid-column:1/-1}}

.mobile-filter-btn{display:none}
@media (max-width:720px){
  .mobile-filter-btn{
    display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;margin-top:24px;
    background:var(--paper);border:1px solid var(--rule);border-radius:var(--radius-pill);padding:15px 22px;
    font-family:var(--sans);font-weight:600;font-size:var(--cog-fs-field);color:var(--ink);
    box-shadow:0 16px 40px -34px rgba(26,26,31,.4);
  }
  .mobile-filter-btn .mfb-l{display:inline-flex;align-items:center;gap:11px}
  .mobile-filter-btn svg{width:var(--icon-md);height:var(--icon-md);stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
  .pn-searchbar{
    position:fixed;inset:0;z-index:1200;margin:0;border:0;border-radius:0;box-shadow:none;
    padding:0;display:none;flex-direction:column;background:var(--paper);overflow-y:auto;
  }
  .pn-searchbar.open{display:flex}
  .pn-searchbar .sb-close{display:inline-flex;position:absolute;right:18px;top:18px;width:var(--cog-control-md);height:var(--cog-control-md);border-radius:var(--radius-full);border:1px solid var(--rule);align-items:center;justify-content:center}
  .pn-searchbar .sb-close svg{width:var(--icon-md);height:var(--icon-md);stroke:var(--icon-strong);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
  .pn-searchbar .sb-title{display:block;padding:24px 24px 0;font-family:var(--sans);font-weight:300;font-size:26px;letter-spacing:-.01em}
  .pn-main{display:flex;flex-direction:column;gap:8px;padding:20px 24px 24px}
  .pn-main .sf{padding:14px 0}
  .pn-main .sb-go{display:none}
  .pn-searchbar .sb-apply{
    /* M2a F5 (15/10) : padding-bas 96px, voir archive-cogestim_property.php (.sb-apply) — flottants dégagés. */
    display:flex;position:sticky;bottom:0;margin-top:auto;gap:12px;padding:16px 24px calc(96px + env(safe-area-inset-bottom));
    background:var(--paper);border-top:1px solid var(--rule);
  }
  .pn-searchbar .sb-apply .btn{flex:1}
  .pn-searchbar .sb-reset{flex-shrink:0;font-family:var(--sans);font-weight:600;font-size:var(--cog-fs-cta);color:var(--ink-soft);padding:0 18px}
  .pn-searchbar .sf .fr-trigger,.pn-searchbar .sf .fs-input{font-size:var(--cog-fs-sf-value-mobile)}
}

/* --- L22b · .pn-searchbar.pn-sheet — panneau mobile des PILIERS Projets neufs (passe 3 phase B, 29/10).
   PORTAGE de la planche design/reference/Recherche-mobile-panneau.html, tel que porté sur /acheter/
   (9b6c968, bloc @media ≤720px d'archive-cogestim_property.php) : règles reprises verbatim, seuls les
   sélecteurs changent (.searchbar → .pn-searchbar.pn-sheet, .sb-main → .pn-main). Écarts d'origine de
   .pn-searchbar corrigés par ce portage : titre + croix non collants, champs en flex colonne avec
   align-items:end hérité du desktop (donc décalés à droite et dimensionnés sur leur contenu), rangée
   ouverte sans réserve --sb-push (panneau recouvrant « Voir les projets »). Réalisations et pages ville
   gardent l'ancien bloc ci-dessus (pas de .pn-sheet). Desktop : seul .sb-head est ajouté (masqué). — */
.pn-searchbar .sb-head{display:none}
@media (max-width:720px){
  .pn-searchbar.pn-sheet{z-index:var(--z-panel);overscroll-behavior:contain}
  .pn-searchbar.pn-sheet.open{transition:opacity var(--dur-fast) var(--ease-out)}
  @starting-style{.pn-searchbar.pn-sheet.open{opacity:0}}
  .pn-searchbar.pn-sheet .sb-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);position:sticky;top:0;z-index:calc(var(--z-popover) + 2);flex-shrink:0;padding:var(--space-2) var(--space-2) var(--space-2) 24px;background:var(--paper);border-bottom:1px solid var(--rule)}
  .pn-searchbar.pn-sheet .sb-title{display:block;margin:0;padding:0;font-family:var(--sans);font-weight:300;font-size:26px;line-height:1.15;letter-spacing:-.01em;color:var(--ink)}
  .pn-searchbar.pn-sheet .sb-title:focus{outline:none}
  .pn-searchbar.pn-sheet .sb-close{display:inline-flex;position:static;flex-shrink:0;background:transparent;cursor:pointer;transition:border-color var(--dur-fast) ease}
  .pn-searchbar.pn-sheet .sb-close:hover{border-color:var(--ink)}
  .pn-searchbar.pn-sheet .sb-close:focus-visible{outline:none;box-shadow:var(--cog-focus-ring)}
  /* Corps : une colonne pleine largeur alignée à gauche, ordre = ordre desktop (R3). */
  .pn-searchbar.pn-sheet .pn-main{display:grid;grid-template-columns:minmax(0,1fr);gap:0;align-items:start;padding:0 24px}
  .pn-searchbar.pn-sheet .pn-main > .sf{grid-column:1/-1;padding:var(--space-4) 0 var(--space-2);border-bottom:1px solid var(--rule-soft)}
  /* Zone de toucher = rangée entière (R6). */
  .pn-searchbar.pn-sheet .sf > .fr-trigger::before{content:"";position:absolute;inset:0}
  /* Rangée ouverte : réserve sous elle la hauteur de son panneau (--sb-push, posé par
     cogestim-recherche-mobile-panneau.js) — rien n'est recouvert (R4). */
  .pn-searchbar.pn-sheet .sf[data-open="true"]{margin-bottom:calc(var(--sb-push,0px) + var(--space-4))}
  /* Barre d'action (H5 30/07 → 15/10, R8/R9) : pleine largeur, bouton sur une ligne, réserve basse 96px. */
  .pn-searchbar.pn-sheet .sb-apply{align-items:stretch;z-index:calc(var(--z-popover) + 2);flex-shrink:0}
  .pn-searchbar.pn-sheet .sb-apply .btn{flex:1;white-space:nowrap}
  .pn-searchbar.pn-sheet .sb-reset{display:inline-flex;align-items:center;min-height:var(--cog-control-md);padding:0;border:0;background:transparent;cursor:pointer;transition:color var(--dur-fast) ease}
  .pn-searchbar.pn-sheet .sb-reset:hover{color:var(--ink)}
  .pn-searchbar.pn-sheet .sb-reset:focus-visible{outline:none;box-shadow:var(--cog-focus-ring)}
}
@media (max-width:720px) and (prefers-reduced-motion:reduce){.pn-searchbar.pn-sheet.open{transition:none}}

/* .start-secondary — bandeau de déviation (source : Agence-Lausanne, verbatim identique dans
   Courtage / Estimation / Projets-neufs, hors périmètre de cette passe) */
.start-secondary{display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap;border:1px solid var(--rule);padding:clamp(22px,2.4vw,30px) clamp(24px,3vw,40px)}
.start-secondary .txt{display:flex;align-items:center;gap:18px;min-width:0}
.start-secondary .ic{width:44px;height:44px;border-radius:var(--radius-full);border:1px solid var(--rule);display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}
.start-secondary .ic svg{width:18px;height:18px;stroke:var(--icon-strong);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.start-secondary .txt b{font-family:var(--sans);font-weight:500;font-size:16px;color:var(--ink);display:block}
.start-secondary .txt span{font-family:var(--sans);font-size:14px;color:var(--ink-soft);line-height:1.5}
@media (max-width:768px){.start-secondary{flex-direction:column;align-items:flex-start;gap:18px}}

/* --- L21 · .cog-video-overlay — lecteur vidéo plein écran partagé ---------
   Composant transverse (markup unique dans footer.php, comme .cw-scrim) :
   un seul overlay par page, peuplé par cogestim-video.js (mode overlay) au
   clic sur un déclencheur [data-video] hors .pilot-top (cartes carousel
   réalisations, futurs usages ; .pilot-top aussi sous 700px depuis le 15/10, lot M2a). Fond : --cog-ink assombri (pas de token de
   voile plein écran existant dans la bibliothèque au 17/08 — dérivé de
   --cog-ink via color-mix plutôt qu'une valeur rgba() inventée). Cadre
   vidéo : --shadow-modal (seule ombre nommée "modale/lightbox" des tokens).
   Croix de fermeture : .circle-cta.invert, cohérent avec les flèches du
   carousel réalisations sur le même fond sombre. */
.cog-video-overlay{
  position:fixed; inset:0; z-index:var(--z-modal);
  display:flex; align-items:center; justify-content:center; padding:clamp(16px,4vw,48px);
  background:color-mix(in srgb, var(--cog-ink) 85%, transparent);
}
.cog-video-overlay[hidden]{ display:none; }
.cog-video-overlay__close{ position:absolute; top:20px; right:20px; }
.cog-video-overlay__stage{ width:100%; max-width:1100px; aspect-ratio:16/9; box-shadow:var(--shadow-modal); }
/* :is(video,iframe) — correctif 24/09 : seule la <video> était dimensionnée ;
   l'<iframe> YouTube injectée gardait sa taille intrinsèque (300×150, en haut
   à gauche du stage). Le ratio 16/9 est porté par le stage. */
.cog-video-overlay__stage :is(video,iframe){ width:100%; height:100%; display:block; border:0; background:var(--cog-ink); }
/* État 9:16 (atelier 12/10, planche Adv-card-video-verticale) : posé par
   cogestim-video.js si le déclencheur porte data-video-ratio="9/16", retiré à
   la fermeture. Aucune règle 16:9 ci-dessus modifiée. Largeur = min(100 %,
   90vh en 9:16, (100vh − 136px) en 9:16) ; 136 = 2 × (20px + 48px de croix) :
   la croix ne recouvre jamais l'image. */
.cog-video-overlay[data-video-ratio="9/16"] .cog-video-overlay__stage{
  max-width:none; aspect-ratio:9/16;
  width:min(100%, calc(90vh * 9 / 16), calc((100vh - 136px) * 9 / 16));
  width:min(100%, calc(90svh * 9 / 16), calc((100svh - 136px) * 9 / 16));
}
/* Amendement géométrie 15/10 (lot M2a F2, hors atelier — précédent 25/09) :
   téléphone en portrait (≤700px), le cadre 16:9 rendait 343×193 à 375px
   (marge 16px = 91,5vw) et laissait ~600px de fond sombre. Marge latérale
   ramenée à 2,5vw → cadre ≈95vw, ratio 16:9 inchangé. Le 9:16 (min(100%,…))
   suit la nouvelle largeur utile sans règle propre et reste borné par la
   hauteur. Paysage et ≥701px : aucune règle ne s'applique, rendu strictement
   inchangé (la croix, à top/right:20px, recouvrirait un cadre 95vw en paysage). */
@media (max-width:700px) and (orientation:portrait){
  .cog-video-overlay{ padding-inline:2.5vw; }
}
body.cog-video-overlay-open{ overflow:hidden; }
/* --- L21b · .adv-card--vertical — slide vidéo verticale 9:16 d'avantage-carrousel (atelier 12/10) ---
   Logé ici et non dans blocks/avantage-carrousel/style.css : le CSS du bloc est inliné par WordPress
   dans un budget partagé ; l'alourdir basculait hero-courtage en <style>/avantage-carrousel en <link>
   sur Courtage et Gérance. Sélecteurs préfixés comme le reste du bloc. Planche :
   design/reference/Adv-card-video-verticale.html */
.wp-block-cogestim-avantage-carrousel .adv-card--vertical{grid-template-columns:minmax(0,1fr) calc(460px * 9 / 16)}
/* Le visuel entier est le déclencheur (<button>, précédent poster .vid 24/09) :
   reset bouton, aucune autre propriété de .visual touchée. */
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .visual{display:block;width:100%;padding:0;margin:0;border:0;font:inherit;color:inherit;text-align:left;cursor:pointer;-webkit-appearance:none;appearance:none}
/* Poster : 3:4 aujourd'hui (média 51009), recadré en cover. `top` garde la tête
   du sujet quand le recadrage est vertical (mobile/tablette). */
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .visual img{object-position:center top;transition:transform 1.3s ease}
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .visual:hover img{transform:scale(1.04)}
/* Pastille : registre .play-ic §2.34 (50px, --icon-sm, pastille claire,
   hover blanc + scale 1.08), centrée comme §2.34bis. */
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .play-ic{position:absolute;left:50%;top:50%;z-index:2;transform:translate(-50%,-50%);width:50px;height:50px;border-radius:var(--radius-full);background:rgba(255,255,255,.92);display:inline-flex;align-items:center;justify-content:center;color:var(--cog-ink);transition:background .3s ease,transform .3s ease}
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .play-ic svg{width:var(--icon-sm);height:var(--icon-sm);color:var(--icon-strong);margin-left:2px}
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .visual:hover .play-ic{background:var(--cog-white);transform:translate(-50%,-50%) scale(1.08)}
/* Focus clavier : porté par la pastille (un anneau sur le cadre serait rogné par
   l'overflow:hidden de .adv-card). Fond média = registre dark. */
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .visual:focus-visible{outline:none}
.wp-block-cogestim-avantage-carrousel .adv-card--vertical .visual:focus-visible .play-ic{background:var(--cog-white);box-shadow:var(--cog-focus-ring-dark)}

/* Mobile : colonne unique comme les autres slides, visuel pleine largeur en tête.
   Le 9:16 est plafonné à 460px (= hauteur desktop de la carte, aucune valeur
   nouvelle) ; au-delà le poster est recadré, jamais rétréci en colonne étroite
   (= letterbox rejeté). */
@media (max-width:920px){
	.wp-block-cogestim-avantage-carrousel .adv-card--vertical{grid-template-columns:1fr}
	.wp-block-cogestim-avantage-carrousel .adv-card--vertical .visual{height:auto;aspect-ratio:9/16;max-height:460px}
}

/* Lot M2a F3 (15/10) — .adv-chips mobile. Logé ici (budget CSS de bloc, voir L21b).
   ≤920px la pastille passait en flux DANS .visual (img en absolute) : pleine largeur,
   elle recouvrait 35 à 90 % de la photo (bande bleue FONCIER, cartes marché Courtage).
   Correctif : la photo reprend sa place seule (260px, img en flux) et les pastilles
   se rangent SOUS elle, côte à côte, dans le même .visual. Les slides sans pastille
   rendent exactement comme avant (.visual = 260px = hauteur de l'img). Hors
   .adv-card--vertical (poster 9:16, sans pastille, règles propres ci-dessus). */
@media (max-width:920px){
	.wp-block-cogestim-avantage-carrousel .adv-card:not(.adv-card--vertical) .visual{display:flex;flex-direction:column;height:auto;min-height:0;overflow:visible}
	.wp-block-cogestim-avantage-carrousel .adv-card:not(.adv-card--vertical) .visual img{position:static;flex:0 0 auto;height:260px}
	.wp-block-cogestim-avantage-carrousel .adv-card:not(.adv-card--vertical) .adv-chips{flex-direction:row;gap:8px;margin-top:8px}
	.wp-block-cogestim-avantage-carrousel .adv-card:not(.adv-card--vertical) .adv-chip{flex:1 1 0;min-width:0}
	/* M2a correctif C2 (15/10) : le fond de la pastille (`background:var(--paper)`, style.css ≤920, pensé
	   pour une pastille posée sur la photo) formait, une fois sous la photo, une bande pâle pleine largeur
	   « dépassant » sous l'image. Sous la photo la pastille devient une légende sans fond, alignée sur la
	   carte (les gouttières de .txt, elles, restent propres au bloc texte). Aucun fond n'est peint derrière
	   l'image elle-même (vérifié : .visual et img transparents sur les 6 pages). */
	/* M2a correctif C3 (15/10) : la légende était à 0 de padding alors que .txt (kicker, titre, paragraphe,
	   preuve) est à clamp(30px,4vw,56px) de chaque côté : deux alignements gauches dans la même slide
	   (texte à 24px / 54px à 393). Même gouttière que .txt, des deux côtés (symétrique). */
	.wp-block-cogestim-avantage-carrousel .adv-card:not(.adv-card--vertical) .adv-chip{background:transparent;backdrop-filter:none;padding:14px 0 0;border-radius:0}
	.wp-block-cogestim-avantage-carrousel .adv-card:not(.adv-card--vertical) .adv-chips{gap:16px;margin-top:0;padding-inline:clamp(30px,4vw,56px)}
	/* M2a correctif C1 (15/10) : la carte « preuve » (.garantie--carte, Carrière) héritait du
	   `.garantie{flex:0 0 calc(50% - 12px)}` (≤920) puis `flex:0 0 100%` (≤560) pensés pour la rangée
	   .garantie-row. Dans .txt (colonne, hauteur 100 % cyclique) la base en % ne se résolvait pas sur le
	   contenu : la ligne de grille restait trop courte de ~78px et le texte, centré, débordait VERS LE HAUT
	   sous l'image (« convivial », « formatrice » coupés) et du bas de la carte. Base ramenée au contenu,
	   comme déjà fait pour les .garantie classiques (style.css l. 23). Antérieur à F3 (mesuré à l'identique
	   avec l'ancien CSS) ; touche les 3 slides de Carrière, dont la verticale. */
	.wp-block-cogestim-avantage-carrousel .adv-card .garantie--carte{flex:0 0 auto}
}

/* --- L22 · home-pilotage (bloc réutilisé : Home, Pilotage, MEV) -----------
   Déplacé depuis cogestim-home.css (18/08) : cogestim-home.css n'est enqueuée
   que sur is_front_page()||has_block('cogestim/home-hero'), or ce bloc est
   aussi rendu sur des pages sans hero (ex. /pilotage-de-projets/) — le
   composant doit vivre dans la feuille chargée globalement. */
.pilot-top{
  display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(40px,6vw,96px);align-items:center;
}
.pilot-top .visual{position:relative;aspect-ratio:5/4;background:var(--cog-bg-scene-dark);overflow:hidden}
.pilot-top .visual img{width:100%;height:100%;object-fit:cover}
/* Variante logo/document (opt-in, champ ACF image_logo) : image entière sur fond blanc, sans rognage. Défaut = cover inchangé. */
.pilot-top .visual--logo{background:var(--cog-white)}
.pilot-top .visual--logo img{object-fit:contain;padding:clamp(16px,3vw,40px);box-sizing:border-box}
.pilot-top .visual.ph-fill{
  background:
    repeating-linear-gradient(135deg, transparent 0 12px, rgba(255,255,255,.03) 12px 13px),
    var(--night-2);
}
.pilot-top .visual .play{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:50px;height:50px;border-radius:var(--radius-full);
  background:rgba(255,255,255,.92);display:flex;align-items:center;justify-content:center;
  transition:background .3s ease,transform .3s ease;z-index:2;
}
.pilot-top .visual .play svg{width:var(--icon-sm);height:var(--icon-sm);margin-left:2px;color:var(--icon-strong)}
.pilot-top .visual .play:hover{background:var(--cog-white);transform:translate(-50%,-50%) scale(1.08)}
.pilot-top .visual video{width:100%;height:100%;object-fit:cover}
.pilot-top .visual.is-playing{aspect-ratio:16/9}
.pilot-top .visual .corner{
  position:absolute;left:18px;bottom:18px;
  font-family:var(--sans);font-size:var(--cog-fs-2xs);letter-spacing:var(--cog-ls-display);text-transform:uppercase;color:var(--cog-on-dark-a90);
  background:var(--cog-ink-a35);padding:7px 11px;backdrop-filter:blur(6px);
}
.pilot-top h2{max-width:18ch;margin-top:24px}
.pilot-top .body{margin-top:28px;max-width:48ch}
.pilot-top .cta{margin-top:32px;display:flex;align-items:center;gap:16px}
/* Lot M2a F1 (15/10) : aucun breakpoint n'existait — à 375px les deux colonnes
   rendaient 140/147px (titre 220px de haut). Sous 700px : 1 colonne, visuel au-dessus.
   Seuil mesuré : à 701px les colonnes font ~290px, lisibles. Vidéo : sous ce seuil le clic
   ouvre l'overlay partagé (cogestim-video.js, même seuil), au-dessus lecture en place. */
@media (max-width:700px){
  .pilot-top{grid-template-columns:minmax(0,1fr);gap:32px}
  .pilot-top h2{max-width:none;margin-top:0}
}

/* --- L23 · .frise — frise horizontale des 7 étapes (18/08, lot 550) -------
   Bandeau .frz-band (chevrons + libellé) au centre, 7 jalons .frz-step
   alternés haut/bas (grid-row 1/3 desktop) reliés par .frz-line/.frz-dot.
   Mobile (≤920px) : bascule en liste verticale, ligne continue via
   ::before/:last-of-type. */
.frise{--frz-band-h:76px;--frz-dot:var(--cog-control-sm);position:relative}
.frz-track{display:grid;grid-template-columns:repeat(7,1fr);grid-template-rows:1fr auto 1fr}
.frz-band{grid-column:1/-1;grid-row:2;position:relative;z-index:1;min-height:var(--frz-band-h);display:flex;align-items:center;padding:0 clamp(14px,1.8vw,26px);overflow:hidden}
.frz-chev{position:relative;z-index:1;flex:1;min-width:0;display:flex;align-items:center;justify-content:center}
.frz-chev svg{flex:0 0 auto;box-sizing:content-box;width:var(--icon-md);height:var(--icon-md);stroke:var(--icon-muted);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.frz-label{position:relative;z-index:1;margin:0;padding:0 clamp(12px,1.6vw,26px);font-family:var(--font-sans);font-weight:400;font-size:clamp(17px,1.5vw,22px);line-height:1.2;letter-spacing:var(--ls-h4);color:var(--ink);white-space:nowrap}
.frz-band{background:var(--paper-warm)}
.frz-step{position:relative;z-index:2;display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-3);padding:0 clamp(6px,.8vw,14px)}
.frz-step.is-up{grid-row:1;justify-content:flex-end}
.frz-step.is-down{grid-row:3;flex-direction:column-reverse;justify-content:flex-end}
@media (min-width:921px){
  .frz-track>.frz-step:nth-child(2){grid-column:1}
  .frz-track>.frz-step:nth-child(3){grid-column:2}
  .frz-track>.frz-step:nth-child(4){grid-column:3}
  .frz-track>.frz-step:nth-child(5){grid-column:4}
  .frz-track>.frz-step:nth-child(6){grid-column:5}
  .frz-track>.frz-step:nth-child(7){grid-column:6}
  .frz-track>.frz-step:nth-child(8){grid-column:7}
}
.frz-ic{display:inline-flex;align-items:center;justify-content:center}
.frz-ic svg{width:var(--icon-lg);height:var(--icon-lg);stroke:var(--icon-muted);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.frz-ic svg.ic-accent{stroke:var(--icon-accent)}
.frz-txt{margin:0;font-family:var(--font-sans);font-weight:500;font-size:var(--cog-fs-sm);line-height:1.45;color:var(--ink);max-width:19ch;text-wrap:pretty}
.frz-line{width:1px;background:var(--rule);height:clamp(16px,1.8vw,26px)}
.frz-dot{flex:0 0 auto;width:var(--frz-dot);height:var(--frz-dot);border-radius:var(--radius-full);background:var(--cog-white);border:1px solid var(--rule);display:inline-flex;align-items:center;justify-content:center;font-family:var(--font-sans);font-weight:600;font-size:var(--cog-fs-sm);color:var(--ink)}
.frz-step.is-up .frz-dot{margin-bottom:calc(var(--frz-dot) / -2)}
.frz-step.is-down .frz-dot{margin-top:calc(var(--frz-dot) / -2)}
@media (max-width:920px){
  .frise .frz-track{grid-template-columns:1fr;grid-template-rows:auto}
  .frise .frz-band{grid-row:1;grid-column:1;min-height:64px;margin-bottom:var(--space-7)}
  .frise .frz-step{grid-row:auto;grid-column:1;display:grid;grid-template-columns:var(--frz-dot) var(--icon-lg) 1fr;gap:0 var(--space-5);align-items:start;text-align:left;padding:0 0 var(--space-7)}
  .frise .frz-ic{grid-column:2;grid-row:1;padding-top:6px}
  .frise .frz-band + .frz-step{padding-top:0}
  .frise .frz-txt{grid-column:3;grid-row:1;max-width:34ch;font-size:var(--cog-fs-cap);padding-top:7px}
  .frise .frz-step.is-up .frz-dot,.frise .frz-step.is-down .frz-dot{grid-column:1;grid-row:1;margin:0}
  .frise .frz-line{grid-column:1;grid-row:1;position:absolute;left:calc(var(--frz-dot) / 2 - .5px);top:var(--frz-dot);height:auto;bottom:0}
  .frise .frz-band + .frz-step .frz-line{top:var(--frz-dot)}
  .frise .frz-step:last-of-type{padding-bottom:0}
  .frise .frz-step:last-of-type .frz-line{display:none}
}
@media (max-width:560px){
  .frise .frz-chev{flex:0 0 auto}
  .frise .frz-label{flex:1;text-align:center;white-space:normal;font-size:16px;padding:0 var(--space-4)}
}

/* --- L24 · .tools / .tool- — grille outils de communication (18/08, lot 550)
   4 familles en colonnes, tuiles .tool-tile (icône + libellé) empilées par
   famille. Réutilisable hors mise-en-valeur (pas de scope de page). */
.tools{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(22px,2.6vw,40px)}
.tools-fam{display:flex;flex-direction:column;gap:var(--space-6)}
.tools-fam-head{margin:0;padding-bottom:var(--space-4);border-bottom:1px solid var(--rule);font-family:var(--font-sans);font-weight:500;font-size:var(--cog-fs-lab);letter-spacing:var(--cog-ls-lab-lg);text-transform:uppercase;color:var(--ink-mute)}
.tools-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.tools--icons .tools-list{gap:var(--space-3)}
.tools--icons .tool-tile{display:flex;align-items:center;gap:var(--space-5);padding:var(--space-5) var(--space-6);border:1px solid var(--rule);background:var(--cog-white)}
.tools--icons .tool-tile svg{flex:0 0 auto;width:var(--icon-lg);height:var(--icon-lg);stroke:var(--icon-strong);fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.tools--icons .tool-tile b{font-family:var(--font-sans);font-weight:600;font-size:var(--cog-fs-cap);line-height:1.35;color:var(--ink)}
@media (max-width:920px){.tools{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.tools{grid-template-columns:1fr;gap:var(--space-10)}}
.pilot-top .cta .o-circle{border-color:var(--paper-warm);color:var(--paper-warm)}

/* --- L25 · .card--projet — dérivation de .card (§L7 ci-dessus) pour les projets
   neufs (extraction 21/08, lot Projets neufs passe 1 : vivait en copie dans
   Projets-neufs.html ET Projet-neuf-detail.html, source verbatim = Projets-neufs.html,
   les 3 déclarations communes étaient bit-identiques entre les deux pages — voir
   BIBLIOTHEQUE-COGESTIM-v1.md §2.12bis, déjà consigné, jamais encore fiché ici).
   Écarts, tous scopés à .card--projet (jamais .card/.card-ph/.card-badge) :
   (a) .card-title en tête de corps = nom du projet (le titre de bien descriptif
   n'existe pas sur un projet) ; (b) .card-price en pied de corps, au-dessus du
   courtier : « Dès CHF X » qualifie le projet entier, pas un lot ; (c) .price-free
   (prix absent, « Prochainement ») + .card-ph.is-empty (gap:12px, écart de 2px vs
   .ph-empty §L17 ci-dessus — divergence actée, non fusionnée silencieusement).

   Amendement daté 21/08 : DEUX flavors de markup pour .card--projet, variante
   assumée (même logique que la variante statique de .mosaic, 28/07) — consignation
   formelle en BIBLIOTHEQUE-COGESTIM-v1.md différée à une prochaine passe atelier :
   · carte PLEINE (Projets-neufs.html, grilles actifs/prochainement) : galerie
     interactive complète — data-id sur .card, .card-ph[data-idx], nav prev/next,
     .card-video, .card-count — anatomie .card standard intégrale (favori retiré 07/10) ;
   · carte STATIQUE (Projet-neuf-detail.html, section « Autres projets ») : teaser
     sans état — .card sans data-id, .card-ph sans data-idx/nav/vidéo/compteur.
     N'utilise ni .price-free ni .card-ph.is-empty (aucun
     projet suggéré sans visuel dans ce contexte). */
.card--projet .card-title{font-size:var(--cog-fs-body-lg);font-weight:500;line-height:1.25;margin:0}
.card--projet .card-price{margin-top:auto;padding-top:14px}
.card--projet .card-price .price-free{font-family:var(--sans);font-weight:500;font-size:var(--cog-fs-body-lg);letter-spacing:0;color:var(--ink-mute)}
.card--projet .card-broker{margin-top:0;padding-top:14px}
.card--projet .card-ph.is-empty{gap:12px}

/* .grid-p/.grid-p3 — grilles de la page Projets neufs (« .grid--wide » §2.12bis,
   extraction 21/08). .grid-p = 2 colonnes (grilles « actifs »/« prochainement »),
   .grid-p3 = 3 colonnes (grille « réalisations »). */
.grid-p{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(24px,2.6vw,36px)}
.grid-p3{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(24px,2.6vw,36px)}
@media (max-width:760px){.grid-p{grid-template-columns:1fr}}
@media (max-width:980px){.grid-p3{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.grid-p3{grid-template-columns:1fr}}

/* --- L26 · .pager — Pagination §2.30 (extraction 21/08, lot Projets neufs
   passe 4, page Réalisations) : documenté en bibliothèque mais jamais encore
   implémenté nulle part sur le site (aucun autre listing ne dépasse le seuil
   « Voir plus » — voir BIBLIOTHEQUE-COGESTIM-v1.md ligne 534, qui documente le
   choix « Voir plus » pour les LISTINGS actifs/prochainement, pas pour une
   archive dédiée comme Réalisations). Spec verbatim : « Boutons ronds +
   flèches, actif = fond --ink. [disabled] opacité .32 en bout de liste. »
   Liens `<a>` (jamais de bouton disabled réel : la page correspondante existe
   ou non, un lien mort n'est ici tout simplement pas rendu — cf. .is-edge). */
.pager{display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap}
.pager a,.pager span{width:var(--cog-control-md);height:var(--cog-control-md);border-radius:var(--radius-full);border:1px solid var(--rule);display:inline-flex;align-items:center;justify-content:center;font-family:var(--sans);font-size:14px;font-weight:500;color:var(--ink);transition:border-color .3s ease,background .3s ease,color .3s ease}
.pager a:hover{border-color:var(--ink)}
.pager .current{background:var(--ink);border-color:var(--ink);color:var(--cog-white)}
.pager span.is-edge{opacity:.32;border-color:var(--rule);pointer-events:none}
.pager .pg-arrow svg{width:var(--icon-sm);height:var(--icon-sm);stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}

/* --- L27 · carrousel « Autres services » (bloc réutilisé : Home, pages
   agences) — Déplacé depuis cogestim-home.css (25/08, lot pages agences) :
   cogestim-home.css n'est enqueuée que sur is_front_page()||has_block('cogestim/home-hero'),
   or cogestim/home-services est aussi rendu sur les pages agences (hero-courtage,
   pas home-hero) — le composant doit vivre dans la feuille chargée globalement.
   Même remède que §L22 home-pilotage (18/08), 4e occurrence du pattern. */
.services-head{
  display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:48px;gap:32px;flex-wrap:wrap;
}
.services-head h2{max-width:18ch;margin:20px 0 0} /* ex-inline margin-top */
.services-head .arrows{display:flex;gap:10px}
.svc-foot{
  margin-top:36px;display:flex;justify-content:flex-start;
}

.svc-scroll{
  margin:0 calc(var(--gut)*-1) 0 0;
  padding:48px var(--gut) 0 0;
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x proximity;scroll-behavior:smooth;
  scrollbar-width:none;
  border-top:1px solid var(--rule);
  position:relative;
}
.svc-scroll::-webkit-scrollbar{display:none}
.svc-scroll::before{display:none}
.svc-track{
  display:grid;grid-auto-flow:column;
  grid-auto-columns:calc((100% - 2 * 28px) / 3);
  gap:clamp(20px,2.6vw,32px);
}
.svc-track > .svc{scroll-snap-align:start;display:flex;flex-direction:column;gap:18px}
.svc-track > .svc .ph{aspect-ratio:4/5;overflow:hidden;background:var(--paper-deep);position:relative}
.svc-track > .svc .ph .play-ic{
  position:absolute;top:18px;left:18px;z-index:2;
  width:50px;height:50px;border-radius:var(--radius-full);
  background:rgba(255,255,255,.92);
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--cog-ink);
  transition:background .3s ease, transform .3s ease;
}
.svc-track > .svc .ph .play-ic svg{width:var(--icon-sm);height:var(--icon-sm);color:var(--icon-strong);margin-left:2px}
.svc-track > .svc:hover .ph .play-ic{background:var(--cog-white);transform:scale(1.08)}
.svc-track > .svc .ph .play{
  position:absolute;top:18px;left:18px;z-index:2;
  width:50px;height:50px;border-radius:var(--radius-full);
  background:rgba(255,255,255,.92);
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--cog-ink);
  appearance:none;border:0;padding:0;cursor:pointer;
  transition:background .3s ease, transform .3s ease;
}
.svc-track > .svc .ph .play svg{width:var(--icon-sm);height:var(--icon-sm);color:var(--icon-strong);margin-left:2px}
.svc-track > .svc:hover .ph .play{background:var(--cog-white);transform:scale(1.08)}
.svc-track > .svc .ph .play-tag{display:none}
.svc-track > .svc .ph img{width:100%;height:100%;object-fit:cover;transition:transform 1.3s ease}
.svc-track > .svc:hover .ph img{transform:scale(1.04)}
.svc-track > .svc .ph.ph-fill{
  background:
    repeating-linear-gradient(135deg, transparent 0 11px, var(--cog-ink-a05) 11px 12px),
    var(--paper-deep);
}
.svc-track > .svc .ph.ph-fill::after{
  content:attr(data-label);position:absolute;left:14px;bottom:14px;
  font-family:ui-monospace,monospace;font-size:var(--cog-fs-2xs);letter-spacing:var(--cog-ls-lab-lg);text-transform:uppercase;
  color:var(--ink-soft);background:var(--paper);padding:5px 9px;border:1px solid var(--rule);
}
@media (max-width:1024px){.svc-track{grid-auto-columns:calc((100% - 24px) / 2)}}
@media (max-width:560px){.svc-track{grid-auto-columns:88%}}
.svc h4{
  margin:6px 0 0;
  display:flex;align-items:baseline;justify-content:space-between;gap:8px;
}
.svc h4 .nm{
  font-family:var(--sans);font-size:var(--cog-fs-xs);color:var(--ink-mute);letter-spacing:var(--cog-ls-lab);font-weight:500;
}
.svc p{margin:0;color:var(--ink-soft);font-size:var(--cog-fs-sm);line-height:1.55}
.svc .arrow-row{margin-top:auto;padding-top:6px;display:flex;align-items:center;justify-content:space-between}
.svc .arrow{
  font-family:var(--sans);font-size:var(--cog-fs-sm);letter-spacing:.005em;font-weight:500;
  display:inline-flex;align-items:center;gap:9px;color:var(--ink);
  position:relative;padding-bottom:6px;
  transition:gap .3s ease,color .3s ease;
}
.svc .arrow::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:currentColor;opacity:.28;transform-origin:left;
  transition:opacity .3s ease;
}
.svc:hover .arrow{gap:16px;color:var(--red)}
.svc:hover .arrow::after{opacity:1}
.svc .arrow svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:var(--icon-stroke)}
@media (max-width:1024px){.svc-grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:768px){.svc-grid{grid-template-columns:1fr 1fr}}

/* --- L28 · réseau agences — carte + accordéon (bloc réutilisé : Home, pages
   agences) — Déplacé depuis cogestim-home.css (25/08, même passe que §L27) :
   cogestim/home-agences est aussi rendu sur les pages agences, hors du
   contexte is_front_page()||has_block('cogestim/home-hero') qui charge
   cogestim-home.css. */
.net{display:grid;grid-template-columns:1.25fr 1fr;gap:clamp(40px,5vw,80px);align-items:start}
.map-wrap{
  position:relative;background:transparent;
  aspect-ratio:1/1;padding:clamp(4px,1vw,12px);overflow:hidden;
}
.map-wrap svg{width:100%;height:100%;display:block}
.map-wrap .vaudmap-img{width:100%;height:100%;object-fit:contain;display:block}
.map-corner{
  position:absolute;left:clamp(28px,3vw,44px);top:clamp(28px,3vw,44px);
  font-family:var(--sans);font-size:var(--cog-fs-xs);letter-spacing:var(--cog-ls-lab-lg);text-transform:uppercase;color:var(--ink-mute);
  display:flex;flex-direction:column;gap:8px;
}
.map-corner b{font-family:var(--sans);font-weight:500;color:var(--ink);font-size:20px;letter-spacing:.005em;text-transform:none}
.map-corner i{font-family:var(--sans);font-style:italic;font-weight:400;color:var(--ink-soft);font-size:var(--cog-fs-sm);letter-spacing:.005em;text-transform:none}

.agencies{display:flex;flex-direction:column}
.ag{
  border-bottom:1px solid var(--rule);padding:22px 0;
}
.ag:first-child{border-top:1px solid var(--rule)}
.ag-head{
  display:flex;justify-content:space-between;align-items:center;gap:20px;cursor:pointer;
}
.ag-head .city{font-family:var(--sans);font-weight:500;font-size:24px;letter-spacing:-.002em;color:var(--ink);display:inline-flex;align-items:baseline;gap:14px}
.ag-head .role{font-family:var(--sans);font-weight:400;font-size:var(--cog-fs-xs);letter-spacing:var(--cog-ls-lab-lg);text-transform:uppercase;color:var(--ink-mute)}
/* ⭑ Passe 8 (03/07) : taille locale (--cog-control-md) supprimée — déjà la
   taille par défaut du composant LIBRARY, redondant. */
.ag-body{
  display:grid;grid-template-columns:1fr 1fr;gap:32px;
  max-height:0;overflow:hidden;transition:max-height .5s ease, padding .35s ease;
}
.ag.open .ag-body{max-height:460px;padding-top:24px}
.ag-info{display:flex;flex-direction:column;font-family:var(--sans);font-size:var(--cog-fs-cap);color:var(--ink-soft);line-height:1.75}
.ag-info b{color:var(--ink);font-weight:500}
.ag-info a.tel{color:var(--ink);font-weight:500;letter-spacing:.02em;transition:color .3s ease}
.ag-info a.tel:hover{color:var(--red)}
.ag-info .lks{display:flex;flex-direction:column;align-items:flex-start;gap:10px;margin-top:auto;padding-top:22px}
.ag-info .lks .link{align-self:flex-start}
.ag-hours{display:flex;flex-direction:column;font-family:var(--sans);font-size:var(--cog-fs-sm);color:var(--ink-soft);line-height:1.9}
.ag-hours .hrs b{color:var(--ink);font-weight:500}
.ag-hours .hl{font-family:var(--sans);font-size:var(--cog-fs-xs);letter-spacing:var(--cog-ls-lab-lg);text-transform:uppercase;color:var(--ink-mute);margin-bottom:8px}
.ag-hours .discover{margin-top:auto;padding-top:22px;align-self:flex-end}
@media (max-width:920px){.net{grid-template-columns:1fr}.ag-body{grid-template-columns:1fr}}

/* .net-list/.ag-mini — variante COMPACTE du réseau agences (amendement 25/08,
   pages agences uniquement). Remplace carte+accordéon (.agencies/.ag/…) : sur
   une page agence, l'enjeu est de renvoyer vers les 7 AUTRES agences, pas de
   réexposer coordonnées et horaires (déjà donnés §3 pour l'agence courante).
   La variante complète .ag reste certifiée pour la Home et le hub /agences/ —
   non touchée ici (bloc cogestim/home-agences, attribut ACF `variante`). */
.net-list{display:flex;flex-direction:column;justify-content:center}
.ag-mini{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:20px 0;border-bottom:1px solid var(--rule)}
.ag-mini:first-child{border-top:1px solid var(--rule)}
.ag-mini .city{font-family:var(--sans);font-weight:500;font-size:20px;letter-spacing:-.002em;color:var(--ink)}
@media (max-width:480px){.ag-mini{flex-wrap:wrap;gap:10px}}
/* Amendement 02/11 (retours Ludovic, HORS atelier maquette — à reporter dans la planche
   Agence-Lausanne) : la ligne entière est un seul <a>. « Découvrir l'agence » est retiré de
   l'affichage par défaut et révélé au survol (@media (hover:hover)) ou au focus clavier ; la
   flèche reste toujours visible (mobile compris). :focus-visible porté par la ligne. */
a.ag-mini{color:inherit;text-decoration:none;cursor:pointer}
.ag-mini .role{font-family:var(--sans);font-weight:400;font-size:var(--cog-fs-xs);letter-spacing:var(--cog-ls-lab-lg);text-transform:uppercase;color:var(--ink-mute);margin-left:6px}
.ag-mini .ag-go{gap:0;padding-bottom:0}
.ag-mini .ag-go::after{transform:scaleX(0)}
.ag-mini .ag-go .lbl{display:none;margin-right:var(--space-5)}
a.ag-mini:focus-visible{outline:none;box-shadow:var(--cog-focus-ring);border-radius:2px}
a.ag-mini:focus-visible .ag-go .lbl{display:block}
a.ag-mini:focus-visible .ag-go::after{transform:scaleX(1)}
@media (hover:hover){
  a.ag-mini:hover .ag-go .lbl{display:block}
  a.ag-mini:hover .ag-go::after{transform:scaleX(1)}
}
/* display:none et non une réduction de largeur : le dégradé background-clip:text de .link peint les
   glyphes d'un descendant même rogné par overflow:hidden. */
/* Carte des agences en SVG EN LIGNE (06/11, remplace l'<img> PNG et les liens transparents .map-pin).
   Règles du SVG marketing (spécification fournie, variables --cm-* mappées sur les tokens du thème) ;
   .cm-lien omis (groupe cm-connexions vide). Les états sont portés par .cm-agence : :hover, :focus-visible
   et .is-active (posé par cogestim-home.js : survol/focus de la liste, entrée ouverte). Seuls les points
   interactifs (attribut role, posé côté serveur) ont curseur et état actif ; le point de l'agence
   courante / sans page reste inerte. */
.map-wrap--svg{display:flex;align-items:center}
.map-wrap .cogestim-map{height:auto}
.cogestim-map{
  --cm-fond:var(--cog-paper-warm,#F0EBE3);
  --cm-contour:var(--cog-ink,#1A1A1F);
  --cm-contour-opacity:.55;
  --cm-lake:var(--cog-ink,#1A1A1F);
  --cm-lake-opacity:.10;
  --cm-label:var(--cog-ink,#1A1A1F);
  --cm-halo:var(--cog-paper-warm,#F0EBE3);
  --cm-region:var(--cog-ink-mute,#6E6E76);
  width:100%;height:auto;
}
.cogestim-map .cm-fond{fill:var(--cm-fond)}
.cogestim-map .cm-lac{fill:var(--cm-lake);fill-opacity:var(--cm-lake-opacity)}
.cogestim-map .cm-contour{stroke:var(--cm-contour);stroke-opacity:var(--cm-contour-opacity)}
.cogestim-map .cm-region{fill:var(--cm-region)}
.cogestim-map .cm-label{fill:var(--cm-label)}
.cogestim-map .cm-label-halo{fill:var(--cm-halo);stroke:var(--cm-halo)}
.cogestim-map .cm-agence[role]{cursor:pointer}
.cogestim-map .cm-agence:focus{outline:none}
.cogestim-map .cm-agence:focus-visible .cm-hit{stroke:var(--red);stroke-width:2}
.cogestim-map .cm-dot{transition:transform var(--dur-base,.4s) var(--ease-out,ease-out);transform-box:fill-box;transform-origin:center}
/* Halo : le disque de zone (.cm-hit) se teinte et grandit sous le point ; le libellé de la ville passe en rouge. */
.cogestim-map .cm-hit{fill:var(--red);fill-opacity:0;transform-box:fill-box;transform-origin:center;transform:scale(.4);transition:fill-opacity var(--dur-base,.4s) var(--ease-out,ease-out),transform var(--dur-base,.4s) var(--ease-out,ease-out)}
.cogestim-map .cm-label{transition:fill var(--dur-fast,.3s) var(--ease-out,ease-out)}
.cogestim-map .cm-agence[role]:hover .cm-dot,
.cogestim-map .cm-agence[role]:focus-visible .cm-dot,
.cogestim-map .cm-agence.is-active .cm-dot{transform:scale(1.8)}
.cogestim-map .cm-agence[role]:hover .cm-hit,
.cogestim-map .cm-agence[role]:focus-visible .cm-hit,
.cogestim-map .cm-agence.is-active .cm-hit{fill-opacity:.2;transform:scale(1.5)}
.cogestim-map .cm-ville:has(.cm-agence[role]:hover) .cm-label,
.cogestim-map .cm-ville:has(.cm-agence[role]:focus-visible) .cm-label,
.cogestim-map .cm-ville:has(.cm-agence.is-active) .cm-label{fill:var(--red)}
@media (prefers-reduced-motion:reduce){.cogestim-map .cm-dot,.cogestim-map .cm-hit,.cogestim-map .cm-label{transition:none}}
/* Variante compacte : sous ce seuil de conteneur les points (Yverdon/Orbe) se chevauchent au doigt ; la liste
   .ag-mini reste la navigation (arbitrage 02/11 conservé : seuil sur le conteneur, non sur le viewport). */
.map-wrap--compact{container-type:inline-size}
@container (max-width:540px){.map-wrap--compact .cm-agence{pointer-events:none}}
/* Entrée de liste mise en évidence au survol/focus de son point : mêmes affordances que le survol direct. */
.ag.is-hl .circle-cta--toggle{border-color:var(--color-text);color:var(--color-text)}
.ag.is-hl .circle-cta--toggle::before{transform:scale(1)}
.ag.is-hl .circle-cta--toggle .bar,
.ag.is-hl .circle-cta--toggle .bar::after{background:currentColor}
.ag-mini.is-hl .ag-go .lbl{display:block}
.ag-mini.is-hl .ag-go::after{transform:scaleX(1)}

/* --- L29 · .doc-list/.doc-row — liste de documents téléchargeables (lot
   doc-list, 31/08, certifié 6b8b6d1 — BIBLIOTHEQUE-COGESTIM-v1 §2.39).
   Rangée-lien plein cadre à séparateurs fins, dérivée de .ag-mini/.facts.
   Portage verbatim de la planche design/reference/Documents utiles -
   Composant doc-row.html — aucune valeur ajoutée ici. */
.doc-group{margin-top:var(--space-16)}
.doc-group:first-child{margin-top:0}
.doc-group-title{font-family:var(--sans);font-size:var(--cog-fs-xs);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);font-weight:600;margin:0 0 var(--space-4)}
.doc-list{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}
.doc-row{display:flex;align-items:center;flex-wrap:wrap;gap:10px var(--space-6);padding:18px 0;border-bottom:1px solid var(--rule);text-decoration:none;color:var(--ink)}
.doc-list li:first-child>.doc-row{border-top:1px solid var(--rule)}
.doc-title{flex:1 1 auto;min-width:0;font-family:var(--sans);font-weight:500;font-size:var(--cog-fs-cap);letter-spacing:-.002em;color:var(--ink);transition:color var(--dur-fast) ease}
.doc-meta{display:flex;align-items:center;gap:var(--space-3);margin-left:auto}
.doc-tag{display:inline-flex;align-items:center;font-family:var(--sans);font-size:var(--cog-fs-2xs);font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-soft);border:1px solid var(--rule);background:var(--paper);border-radius:0;padding:3px 9px}
.doc-tag.lang{color:var(--ink-mute)}
.doc-act{display:inline-flex;color:var(--icon-strong)}
.doc-act svg{width:var(--icon-md);height:var(--icon-md);stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
.doc-act svg.fill{fill:currentColor;stroke:none}
.doc-row:hover .doc-title{color:var(--red)}
.doc-row:hover .doc-act{color:var(--red)}
.doc-row:focus-visible{outline:none;box-shadow:var(--cog-focus-ring);border-radius:2px}
@media (max-width:560px){
  .doc-row{padding:16px 0}
  .doc-title{flex-basis:100%}
  .doc-meta{margin-left:0}
  .doc-act{margin-left:auto}
}

/* Amendement 31/08 (filtre langue + sommaire, planche « Documents utiles -
   Filtre langue et sommaire.html », BIBLIOTHEQUE §2.39/§9septies) : AUCUN
   CSS propre pour le filtre — .team-filter/.tf-chip §L8 verbatim (précédent
   #teamFilter, cogestim/courtiers). Seule règle nouvelle : masquage, patron
   .tc.tf-hide (Courtage §10) porté sur .doc-row ET .doc-group. */
.doc-row.tf-hide{display:none}
.doc-group.tf-hide{display:none}
/* Correctif fidélité spec 4 (planche « Documents utiles - Filtre langue et
   sommaire.html ») : `.tools` est déjà un composant certifié §2.32 (« 4
   cartes d'actions », grid 4 colonnes) — collision de nom involontaire avec
   la planche, où `.tools` n'est que le conteneur de démonstration
   (sommaire + filtre EMPILÉS, jamais une grille). Réutiliser cette classe
   ici aurait mis les deux rangées côte à côte au lieu de les empiler.
   Conteneur renommé `.doc-tools` (bloc-scopé, aucun composant certifié
   existant ne porte ce nom) : empilement simple, sommaire pleine largeur
   puis filtre dessous — markup/espacements verbatim spec 4
   (villes-row margin-top:0 en première position, filtre margin-top:18px). */
.wp-block-cogestim-doc-list .doc-tools{display:flex;flex-direction:column;margin-bottom:var(--space-16)}
.wp-block-cogestim-doc-list .villes-row{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}
.wp-block-cogestim-doc-list .doc-filter{margin-top:18px}

/* Atterrissage sommaire d'ancres : `header.site` est `position:sticky;top:0`
   (cogestim-base.css) et recouvre tout ancrage direct (`#id` scrollIntoView)
   sans compensation — AUCUN token/règle `scroll-margin`/`scroll-padding`
   n'existe dans le système à ce jour (vérifié : grep vide sur les 4 fichiers
   CSS thème) ; le header n'a pas non plus de hauteur figée en token (intrinsèque
   au logo 44px + padding vertical de `.wrap.nav`, jamais mesurée/fixée). Gap
   confirmé PAGE-LARGE, pas propre à ce bloc : les ancres `#s-marche`/
   `#s-contact-form` des 8 pages agences (agence-page-factory.php) ont le même
   défaut — signalé, hors périmètre de ce lot (aucune correction transverse
   apportée ici). Valeur locale approximative (logo+padding ≈ 76px de chrome
   visible + `--space-10` de respiration, aucun token dédié n'existant) — à
   remplacer par un token `--header-h` réel si/quand une passe transverse
   scroll-margin est décidée. */
.wp-block-cogestim-doc-list .doc-group{scroll-margin-top:calc(76px + var(--space-10))}

/* .hero--editorial — hero réduit, hero portant seulement l'identité de la
   page (pas d'outil ni de CTA de conquête) : §2.8, tranché session 31/08
   (planche « Hero réduit — Hauteurs et règle », écart daté planche Direction
   28/08). Ne redéfinit que hauteur + padding bas ; anatomie/ancrage haut du
   hero plein restent inchangés. Règle de spécificité identique à celle du
   bloc hero-courtage (blocks/hero-courtage/style.css) qui la redéclare pour
   primer sur `.wp-block-cogestim-hero-courtage.hero` — gardées synchronisées. */
.hero.hero--editorial{min-height:var(--cog-hero-h-editorial);padding-bottom:clamp(48px,5vw,72px)}
/* Sans image de fond : fond --cog-grad-scene (token A4, précédent hero Home),
   scrim §2.8 conservé tel quel. */
.hero--noimg{background:var(--cog-grad-scene)}

/* --- L20b · .field-select--multi — variante multi-sélection de .field-select (§L20)
   Champ « Type de bien » des listings /acheter/ /louer/ seul. Planche
   design/reference/Field-select-multi.html (13/10/2026, commit 3aab1a7) ; portage listing 14/10.
   Composant DÉRIVÉ : consomme sans les restyler .sf/.has-chev, .fr-trigger, .fr-panel
   (--fr-panel-w, --z-popover), .fs-native (§L18–L20), .consent (§L5), .fr-clear.link (§L18),
   + modificateur .consent--filter (amendement §L5, cases cochées en --ink). Aucun littéral
   nouveau : --space-*, --radius-sm, --rule, --rule-soft, --ink-mute (opacité .5 = valeur §L20).
   Mobile : une seule règle propre, voir « Modale mobile » ci-dessous. */

/* — Déclencheur : .fr-trigger §L18 inchangé (label CAPS, valeur, chevron
     .has-chev). Libellé L-B « Appartement +N » = seul consommateur des 3
     règles ci-dessous ; L-A « N types » n'en demande aucune. — */
.field-select--multi .fr-trigger.fsm-split{display:flex;align-items:baseline;gap:var(--space-2)}
.field-select--multi .fsm-first{min-width:0;overflow:hidden;text-overflow:ellipsis}
.field-select--multi .fsm-more{flex-shrink:0}

/* — Registre cases (retenu 13/10, Luis ; registre chips écarté, états désactivés non produits par le listing, règles retirées 14/10) : .consent §L5 consommé en rangée
     d'option. Positionnement seul (marge, padding, alignement) ; survol =
     traitement .fs-opt §L20 (--rule-soft, --radius-sm). — */
.field-select--multi .fsm-checks{display:flex;flex-direction:column;margin-top:var(--space-2)}
.field-select--multi .fsm-checks .consent{margin:0;align-items:center;padding:var(--space-3) var(--space-4);border-radius:var(--radius-sm)}
.field-select--multi .fsm-checks .consent:hover{background:var(--rule-soft)}
.field-select--multi .fsm-checks .consent label{flex:1;cursor:pointer}
/* — .consent--filter : modificateur PROPOSÉ (13/10, retour Luis) — AMENDEMENT
     BIBLIOTHÈQUE §L5 à consigner avant portage. Case cochée en --ink (famille
     Filtrer, §4.5.8 inversé noir) au lieu de --grad-45 (registre consentement
     nLPD). Coche blanche ::after, bordure repos, focus : §L5 inchangés. — */
.consent.consent--filter input:checked{background-image:none;background-color:var(--ink);border-color:var(--ink)}

/* — Modale mobile (constat portage 14/10) : dans #searchbar.open le .sf est ajusté à son
     contenu et aligné à droite (≈ 97px pour « Terrain »), donc width:100% (règle certifiée)
     écrase « Local commercial » / « Place de parc ». Le panneau multi prend la largeur de ses
     libellés (plancher = champ), ancré au bord droit du champ, borné à l'écran. — */
@media (max-width:720px){
  .field-select--multi .fr-panel{width:max-content;min-width:100%;max-width:calc(100vw - var(--space-6) * 2);left:auto;right:0}
}

/* — Pied : .fr-clear.link §L18 verbatim (piste T-β). Aucune règle. — */

/* --- L20c · .sel-row / .sel-chip — étiquettes de localités du champ Localité (§L19), listings /acheter/ /louer/
   Planche design/reference/Localites-chips.html (27/10/2026, v2) ; portage 29/10. Section reprise telle quelle de design/assets/localites-chips.css. --- */
/* ============================================================
   Localités multiples — étiquettes de sélection dans le champ
   Planche : design/reference/Localites-chips.html (27/10/2026, v2)
   Listings /acheter/ /louer/ (.searchbar, champ Localité .field-suggest §L19)
   et variantes Projets neufs (.pn-searchbar §L22, champ Ville).

   v2 (retour Luis 27/10, référence immoscout24.ch) : plus de rangée de
   pastilles rondes sous la barre. Au repos, le champ affiche une synthèse
   (« Morges +2 ») et garde sa hauteur. Au clic, il s'agrandit : le
   panneau ancré §L18 porte les étiquettes posées, puis les suggestions.

   COMPOSANT NOUVEAU : .sel-row / .sel-chip (étiquette compacte).
   Registre badge (§1.4 : rectangle à angles vifs), pas pastille :
   ni .tf-chip (Filtrer, bascule), ni .ville-chip (Nav, lien).
   Fond --paper-deep, texte --ink 13px/500, hauteur ≈ 25px.
   Glyphe : x (catalogue design/reference/cogestim-icons.html, Lucide).
   Aucun littéral nouveau : tokens seuls.
   ============================================================ */

/* — Zone des étiquettes, en tête du panneau ancré. Absente à 0 étiquette
     ([hidden]) : le panneau est alors celui du §L19, inchangé. — */
.sel-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);min-width:0;padding:var(--space-4) 0;margin-bottom:var(--space-2);border-bottom:1px solid var(--rule-soft)}
.sel-row[hidden]{display:none}
/* Effacer dans la rangée des étiquettes (29/10) : à droite sur la même ligne (le margin-top de .fr-clear tombe). */
#pan-ville .sel-row .fr-clear{margin:0 0 0 auto}

/* — Étiquette — */
.sel-chip{
  display:inline-flex;align-items:center;max-width:100%;box-sizing:border-box;
  min-height:calc(var(--icon-sm) + var(--space-3));padding:0 0 0 var(--space-3);
  border-radius:0;background:var(--paper-deep);
  font-family:var(--font-sans);font-weight:500;font-size:var(--cog-fs-cta-caps);letter-spacing:.02em;line-height:1.2;color:var(--ink);
}
.sel-lab{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* — Croix : seul contrôle de l'étiquette (<button>). Carrée comme elle ;
     survol --rule, focus --cog-focus-ring. Zone de toucher portée à 44px
     (--cog-control-md) par ::after, modèle R6 du panneau mobile (15/10). — */
.sel-x{
  position:relative;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;
  width:calc(var(--icon-sm) + var(--space-3));height:calc(var(--icon-sm) + var(--space-3));
  padding:0;border:0;border-radius:0;background:transparent;color:var(--ink-soft);cursor:pointer;
  transition:background var(--dur-fast) ease,color var(--dur-fast) ease;
}
.sel-x::after{content:"";position:absolute;inset:calc((var(--cog-control-md) - var(--icon-sm) - var(--space-3)) / -2)}
.sel-x:hover{background:var(--rule);color:var(--ink)}
.sel-x:focus-visible{outline:none;box-shadow:var(--cog-focus-ring);color:var(--ink)}
.sel-x svg{width:var(--icon-sm);height:var(--icon-sm);stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round;pointer-events:none}

/* — Légende du rayon (≥ 2 étiquettes, rayon > 0), pleine ligne sous les
     étiquettes : « Rayon : à 10 km de Morges ». Registre .fs-npa. — */
.sel-cap{flex-basis:100%;font-family:var(--font-sans);font-size:var(--cog-fs-xs);color:var(--ink-mute)}

/* Ancre {ancre}-form du formulaire cta-final (ex. #s-cta-form) : header.site sticky recouvre l'atterrissage sans compensation — même valeur locale que .doc-group (voir note ci-dessus), pas de token --header-h. */
.wp-block-cogestim-cta-final .msg[id],.wp-block-cogestim-cta-rappel .msg[id]{scroll-margin-top:calc(76px + var(--space-10))}
