/* ============================================================
   COGESTIM PROJETS — gabarit « landing promotion »
   PORTAGE de design/pages/Landing-promo-projets-direction.html +
   design/assets/landing-promo-projets.css (planche de DIRECTION du
   04/09/2026). Cette planche REMPLACE la référence v2 certifiée 69f3d72
   pour ce gabarit — écart de gouvernance daté et assumé : planche de
   direction, spécification différée post-validation.

   La photographie fait le design : rythme photo → respiration →
   information. Typographie calme : Manrope (UI, texte, table) +
   Source Serif 4 (grands titres seuls), SELF-HOSTED (cf. @font-face
   ci-dessous) — aucune requête vers fonts.googleapis.com /
   fonts.gstatic.com, la CSP du site ne l'autorise pas et une landing
   ne fait pas d'exception.

   SCOPE — la planche scope sous `.pj`, ce portage sous `.lp-page`
   (classe déjà posée sur <body> ET sur le conteneur par
   cogestim_projet_landing_body_class(), functions.php). Substitution
   mécanique et exhaustive, aucune autre transformation des sélecteurs.

   ACCENT — la planche déclare --acc/--acc-deep/--acc-line/--acc-soft
   en dur sur .pj. Ici ces quatre valeurs sont publiées par
   cogestim_projet_landing_accent_css() depuis le champ ACF `accent_1`
   (mécanisme --lp-accent conservé) : les trois dérivés sont calculés
   en color-mix, ils ne sont donc PAS redéclarés ici. Les valeurs de la
   planche (#5B6347 et dérivés) restent en repli si l'inline manque.

   Tokens consommés : cogestim-design-tokens.css.
   ============================================================ */

/* ——— Fontes self-hosted ————————————————————————————————————————
   Sous-ensemble LATIN uniquement, woff2 seul (pas de ttf/woff : tous
   les navigateurs cibles gèrent woff2), poids strictement nécessaires
   — Manrope 400/500/600, Source Serif 4 400. font-display:swap : le
   texte est lisible immédiatement en fonte système, la fonte réelle
   remplace au chargement (aucun FOIT sur un hero photographique).
   Provenance — google-webfonts-helper (gwfh.mranftl.com), qui
   redistribue les binaires officiels de fonts.gstatic.com :
     · Manrope        v20  https://gwfh.mranftl.com/fonts/manrope?subsets=latin
     · Source Serif 4 v14  https://gwfh.mranftl.com/fonts/source-serif-4?subsets=latin
   ———————————————————————————————————————————————————————————— */
@font-face{
  font-family:'Manrope';font-style:normal;font-weight:400;font-display:swap;
  src:url('../fonts/manrope-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Manrope';font-style:normal;font-weight:500;font-display:swap;
  src:url('../fonts/manrope-500.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Manrope';font-style:normal;font-weight:600;font-display:swap;
  src:url('../fonts/manrope-600.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Source Serif 4';font-style:normal;font-weight:400;font-display:swap;
  src:url('../fonts/source-serif-4-400.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* accent projet — REPLI. Les 4 valeurs réelles sont publiées en CSS inline
   par cogestim_projet_landing_accent_css() depuis `accent_1`/`accent_2`, sur
   `body.lp-page`. Ce repli sert si l'inline manque.
   CORRECTIF 24/09 : le repli était déclaré sur `.lp-page`, classe posée AUSSI
   sur le <div class="lp-page"> enfant de <body> — la redéclaration sur
   l'enfant masquait l'héritage de l'inline pour tout le contenu (CTA restés
   au kaki de la planche quel que soit l'accent saisi). Déclaré ici sur
   `body.lp-page`, même spécificité que l'inline, qui est émis APRÈS cette
   feuille (wp_add_inline_style) et gagne donc. Ne jamais redescendre ces
   quatre variables sur `.lp-page` seul. */
body.lp-page{--acc:#5B6347; --acc-deep:#474E36; --acc-line:#CDD0BE; --acc-soft:#EFF0E8}
.lp-page{
  --disp:'Source Serif 4',Georgia,'Times New Roman',serif;
  --ui:'Manrope','Helvetica Neue',Arial,sans-serif;
  background:var(--cog-white);color:var(--ink);font-family:var(--ui);
  font-size:var(--cog-fs-body);line-height:1.7;-webkit-font-smoothing:antialiased;
}
.lp-page *{box-sizing:border-box}
html{scroll-behavior:smooth}
/* 25/09 (logos 50px, 44px ≤720px) : scroll-margin = hauteur du header
   défilé + 16px de respiration, MESURÉE en computed :
   - > 900px (landing et fiche lot) : 14+50+14 + filet 1 = 79px → 96px ;
   - landing ≤ 900px : la nav passe sur sa propre ligne (rail d'ancres),
     header 132px (≤720px : 126px) → 148px / 142px — l'ancienne valeur
     unique (104/92px) laissait les titres sous le header sous 900px ;
   - fiche lot ≤ 720px (pas de rail, nav masquée) : 73px → 90px.
   SPY_AT (cogestim-landing-promo.js) LIT cette valeur (+52px) : une seule
   source, rien à resynchroniser à la main. */
.lp-page section[id]{scroll-margin-top:96px}
@media (max-width:900px){div.lp-page section[id]{scroll-margin-top:148px}}
@media (max-width:720px){.lp-page section[id]{scroll-margin-top:90px}div.lp-page section[id]{scroll-margin-top:142px}}
.lp-page a{color:var(--ink);text-decoration:none;transition:color var(--dur-fast) var(--ease-out)}
.lp-page a:hover{color:var(--acc)}
.lp-page img{display:block;max-width:100%}
.wrap{width:100%;max-width:1320px;margin:0 auto;padding:0 clamp(32px,4.4vw,72px)}
.s{padding:clamp(96px,10vw,152px) 0}
.s.paper{background:var(--paper)}
.s.white{background:var(--cog-white)}
/* .s.warm retiré (planche v3.1, 25/09) : plus aucun --paper-warm sur le
   gabarit ; seul consommateur (section contact landing + fiche lot) passé
   en .s.paper. */
.s.flush{padding-bottom:0}

/* ——— typographie : peu de niveaux, aucun effet ——— */
.kick{font-family:var(--ui);font-size:var(--cog-fs-2xs);font-weight:500;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-mute);margin:0 0 26px}
.kick.on-dark{color:rgba(245,240,232,.7)}
h1.disp{font-family:var(--disp);font-weight:400;font-size:clamp(58px,6.4vw,104px);line-height:.98;letter-spacing:-.02em;margin:0}
h2.disp{font-family:var(--disp);font-weight:400;font-size:clamp(33px,3.2vw,48px);line-height:1.1;letter-spacing:-.01em;margin:0;max-width:22ch;text-wrap:balance}
h3.disp{font-family:var(--disp);font-weight:400;font-size:clamp(23px,2vw,29px);line-height:1.18;letter-spacing:-.006em;margin:0}
.body{font-family:var(--ui);font-size:var(--cog-fs-body);line-height:1.75;color:var(--ink-soft);max-width:46ch;margin:0}
.cap{font-family:var(--ui);font-size:var(--cog-fs-legal);letter-spacing:.02em;color:var(--ink-mute);margin:0}

/* ——— boutons — pill plein / pill outline, sobres ——— */
.b{display:inline-flex;align-items:center;justify-content:center;font-family:var(--ui);font-size:14px;font-weight:500;letter-spacing:var(--ls-cta);padding:15px 30px;border-radius:var(--radius-pill);border:1px solid transparent;cursor:pointer;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out);gap:10px}
.b svg{width:17px;height:17px;flex:0 0 auto;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.lp-page .b--fill,.lp-page a.b--fill{background:var(--acc);color:#fff}
.lp-page .b--fill:hover,.lp-page a.b--fill:hover{background:var(--acc-deep);color:#fff}
.lp-page .b--out,.lp-page a.b--out{border-color:var(--ink);color:var(--ink);background:transparent}
.lp-page .b--out:hover,.lp-page a.b--out:hover{background:var(--ink);border-color:var(--ink);color:var(--cog-white)}
.lp-page .b--out.on-dark,.lp-page a.b--out.on-dark{border-color:rgba(245,240,232,.55);color:var(--cog-on-dark);background:transparent}
.lp-page .b--out.on-dark:hover,.lp-page a.b--out.on-dark:hover{background:rgba(245,240,232,.14);border-color:#fff;color:#fff}
.b:focus-visible{outline:none;box-shadow:var(--cog-focus-ring)}
/* Audit CTA 25/09 — l'anneau `--cog-focus-ring` est l'ENCRE à 5 %
   (rgba(26,26,31,.05)) : quasi invisible, et à l'encre. Surcharge scopée :
   anneau à l'accent du projet (35 %), landing ET fiche lot (body.lp-page) ;
   registre sombre (.on-dark, hero photo) : anneau clair du système. Même
   règle pour le lien-CTA `.link` (« Découvrir le projet »). */
.lp-page .b:focus-visible,.lp-page .link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--acc) 35%,transparent)}
.lp-page .b.on-dark:focus-visible{box-shadow:var(--cog-focus-ring-dark)}
.acts{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
/* lien secondaire discret — soulignement Cogestim, sans flèche */
.lnk{display:inline-flex;align-items:center;font-size:15px;color:var(--ink);border-bottom:1px solid var(--acc-line);padding-bottom:3px}
.lnk:hover{border-color:var(--acc)}

/* ——— ACCENT PROJET sur la landing (écart 15, décision Luis 24/09) ———
   La planche de direction tient outline, kickers et liens à l'encre ; ils
   passent à l'accent du projet. Scope `div.lp-page` et JAMAIS `.lp-page`
   seul : `body.lp-page` est aussi posé sur la fiche lot (certifiée 41ff013),
   que ce correctif ne touche pas. Le registre sombre (.on-dark, hero photo),
   le chrome .pjh et le footer .pjf (rattachement Cogestim) restent inchangés. */
div.lp-page .b--out:not(.on-dark){border-color:var(--acc);color:var(--acc)}
div.lp-page .b--out:not(.on-dark):hover{background:var(--acc);border-color:var(--acc);color:#fff}
div.lp-page .kick:not(.on-dark){color:var(--acc)}
div.lp-page .lnk{color:var(--acc)}
div.lp-page .lnk:hover{border-color:var(--acc-deep);color:var(--acc-deep)}
div.lp-page .lots td.lot a,
div.lp-page .lots .plan,
div.lp-page .optin a{color:var(--acc)}
div.lp-page .lots td.lot a:hover,
div.lp-page .lots .plan:hover,
div.lp-page .optin a:hover{color:var(--acc-deep)}

/* ——— placeholders photo (visuels fournis par le marketing) ——— */
.ph{position:relative;background:var(--paper-deep) repeating-linear-gradient(135deg,transparent 0 15px,rgba(26,26,31,.03) 15px 16px);overflow:hidden}
.ph > span{position:absolute;left:16px;bottom:14px;font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11.5px;letter-spacing:.05em;color:var(--ink-mute)}
.ph.dark{background:#2A2A28 repeating-linear-gradient(135deg,transparent 0 16px,rgba(255,255,255,.04) 16px 17px)}
.ph.dark > span{color:rgba(245,240,232,.58)}
/* Correctif post-validation navigateur (post 1038) : règle générique pour
   toute image réelle posée dans un conteneur .ph dimensionné (aspect-ratio
   ou hauteur), 3e occurrence après .hero-video et .duo .ph — cover pleine
   tuile, jamais de taille intrinsèque sous une bande de fond visible. */
.ph > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* ============================================================
   HEADER — .pjh, chrome PARTAGÉ landing + fiche lot (correctif 11/09)

   FACTORISATION — template-parts/projet-pjh.php rend le MÊME markup sur les
   deux gabarits (2ᵉ divergence constatée avait invalidé l'arbitrage
   « duplication assumée » de l'écart 1 initial de la fiche lot : tailles de
   logo décorrélées, alignements qui dérivaient). Ce bloc porte donc le
   registre SOMBRE (repos landing) ; le registre CLAIR (bascule .scrolled
   landing / état permanent .pjh--lot) est un bloc unique juste après —
   partagé par construction, jamais deux copies qui peuvent diverger à
   nouveau.
   ============================================================ */
.pjh{position:absolute;left:0;right:0;top:0;z-index:20;transition:background-color 220ms ease,border-color 220ms ease}
/* Passe 12/09 (Luis) : GRID -> FLEX. La grille `auto 1fr auto` forçait
   `.pjh-nav` dans une colonne de largeur variable centrée dans l'espace
   restant — structurellement incompatible avec une nav ancrée à gauche et
   détachée du logo par un retrait FIXE (pas une répartition d'espace).
   En flex, chaque enfant garde sa largeur intrinsèque ; `.pjh-nav` reçoit
   son propre `margin-left` (retrait après le logo) et `.pjh-right` un
   `margin-left:auto` (seul à droite) — la même logique que `justify-self:end`
   d'une grille, mais sans dépendre d'une colonne `1fr` qui n'a plus de rôle. */
.pjh-in{display:flex;align-items:center;padding-top:28px;padding-bottom:28px}
.pjh-mark{display:flex;flex-direction:column;gap:5px;color:var(--cog-on-dark)}
/* Logo projet (repli croisé blanc/couleur) — jamais rendu à taille native :
   même gabarit que la marque texte (.nm) qu'il remplace. HISTORIQUE : 34px
   dans tous les états jusqu'au 24/09 — désormais 60px, cf. règle ci-dessous.

   BOÎTE NORMALISÉE (correctif 12/09, passe 5) — CAUSE RACINE des 4 passes
   précédentes : elles mesuraient la BOÎTE `<img>` (34px partout, exact) alors
   que l'œil voit l'ENCRE. Mesure des pixels non transparents des assets réels :
     - logo_projet_blanc   1615x799, encre 1615x799  → encre rendue 68.7 x 34.0
     - logo_projet_couleur  842x595, encre  608x301  → encre rendue 34.7 x 17.2
   soit un facteur 1.97x d'encre perçue à hauteur CSS ÉGALE, parce que l'asset
   couleur porte ~50% de marge transparente (ink_h/canvas_h = 0.506). Aucune
   contrainte de hauteur ne peut corriger ça : c'est un défaut d'ASSET, signalé
   pour ré-export (🔵 Luis). Ce que la CSS doit garantir, c'est que le chrome
   reste robuste à tout asset FUTUR : hauteur fixe, largeur PLAFONNÉE (jamais
   fixe — un `width` fixe romprait les logos de ratio inhabituel, cf. rapport
   12/09), encre calée à gauche pour que le départ de la nav ne dérive pas avec
   le ratio de l'asset. */
/* Sélecteur préfixé `.pjh` — spécificité (0,2,0). MÊME CAUSE RACINE que le
   défaut du 11/09 : `.lp-page img{display:block;max-width:100%}` (l.78) porte
   (0,1,1) et battait `.pjh-logo` à (0,1,0) — le `max-width:140px` était donc
   INERTE (computed max-width:100%, prouvé par inspection de la cascade réelle
   le 11/09 : boîte rendue 159.8px au lieu de 140px plafonnés). Le plafond ne
   protégeait rien. Corrigé par le préfixe, comme les règles de bascule
   blanc/couleur plus bas — ne jamais redescendre ce sélecteur à une seule
   classe, il serait à nouveau battu sans erreur visible. */
/* LOGO 60px (décision Luis 24/09, ANNULE le « 34px dans tous les états »
   ci-dessus et son plafond 140px) — 48px ≤720px. Les 3 états (repos sombre,
   .scrolled clair, .pjh--lot) partagent la même hauteur ; l'alignement
   vertical avec la nav et le logo Cogestim (34px, inchangé) est porté par
   `.pjh-in{align-items:center}`, sans décalage manuel.
   `max-width:none` EXPLICITE : sans lui, retirer les 140px laissait en
   computed le `max-width:100%` de `.lp-page img` (0,1,1) — le logo
   redevenait compressible dans la rangée flex, sans erreur visible (même
   leçon que le 12/09). `display` n'est plus déclaré ici : il reste fourni
   par `.lp-page img` et par les règles de bascule (0,2,0) ci-dessous. */
/* 25/09 (compléments) : 50px, 44px ≤720px — même hauteur pour les trois
   logos (projet, Cogestim du chrome, footer). */
.pjh .pjh-logo{height:var(--pjh-logo-h,50px);width:auto;max-width:var(--pjh-logo-mw,none);object-fit:contain;object-position:left center}
@media (max-width:720px){.pjh .pjh-logo{height:calc(var(--pjh-logo-h,50px) - 6px)}}
.pjh-mark .nm{font-family:var(--disp);font-size:22px;letter-spacing:.16em;text-transform:uppercase;line-height:1;color:#fff}
/* NAV GAUCHE DÉTACHÉE (arbitrage Luis 12/09, ANNULE le retour-planche du
   12/09 précédent — la décision `justify-content:center` de cette même
   journée est elle-même abandonnée quelques heures plus tard : ce n'est
   PAS un retour à la position `flex-start` du 11/09, qui collait la nav
   contre le logo sans retrait. Ici la nav est ancrée à gauche ET détachée
   du logo par un ESPACEMENT FIXE assumé (`margin-left`), pas une colonne
   `1fr` qui centre ou une simple absence de justification). La planche
   (design/pages/Fiche-lot-projet.html) est amendée en miroir — note datée,
   le rendu code fait foi à partir de cette passe. */
/* Marge logo->nav augmentée (retour Luis 12/09, 2e passe) : 32-64px lu comme
   trop proche à l'œil. clamp(64px,7vw,120px) — le double environ à chaque
   borne (64px @1440, 87.5px @1000 contre 57.6/40px avant). */
.pjh-nav{display:flex;gap:clamp(14px,1.9vw,26px);margin-left:clamp(64px,7vw,120px)}
.pjh-nav a{font-size:14px;line-height:1;color:rgba(245,240,232,.84)}
.pjh-nav a:hover{color:#fff}
/* Recalage 12/09 (logo seul) : `.pjh-by` est désormais l'UNIQUE enfant de
   `.pjh-right` sur les deux gabarits (label retiré 12/09, CTA retiré 11/09).
   Le `gap:20px` ne séparait plus rien — retiré plutôt que laissé à une valeur
   qui décrit une structure inexistante. Si un second enfant revient un jour,
   le gap se redéclare à ce moment-là, en connaissance de cause.
   `justify-self:end` (grid) -> `margin-left:auto` (flex, passe 12/09 nav
   gauche) : pousse `.pjh-right` en bout de ligne flex, seul logo à droite. */
.pjh-right{margin-left:auto;display:flex;align-items:center}
/* .pjh-by — enveloppe du LOGO SEUL (amendement 12/09, décision Luis) : le
   label « Commercialisé par » a été retiré du chrome, le rattachement se fait
   par le logo seul (doctrine 07/09). Le wrapper est CONSERVÉ — il porte le
   logo, reste le point d'ancrage du markup partagé, et évite de re-câbler la
   structure des deux gabarits pour un seul enfant.
   Nettoyage associé : `.pjh-right .by` (font-size/letter-spacing/couleur,
   + ses deux surcharges de couleur au registre clair) et le `gap:9px` qui
   séparait le label du logo sont SUPPRIMÉS — règles devenues orphelines, plus
   aucun élément ne les consomme. L'attribution texte vit au footer.
   Historique : le `transform:translateY(4px)` de calage manuel du label avait
   déjà été retiré le 11/09 ; la question de son alignement optique devient
   sans objet, le label n'existant plus dans le chrome. */
.pjh-by{display:flex;align-items:center}
/* Logo Cogestim : 60px, 48px ≤720px (décision Luis 24/09, 2ᵉ passe) — MÊME
   hauteur que le logo projet dans les 3 états : un seul rang visuel. Préfixe
   `.pjh` → (0,2,1), qui bat `.lp-page img{max-width:100%}` (0,1,1) ;
   `max-width:none` explicite pour la même raison que le logo projet. La
   hauteur du header ne change pas (déjà portée par le logo projet 60px) :
   scroll-margin-top et SPY_AT restent valables. */
.pjh .pjh-right img{height:50px;width:auto;max-width:none}
@media (max-width:720px){.pjh .pjh-right img{height:44px}}

/* Deux versions de chaque logo dans le markup (partiel projet-pjh.php),
   bascule PUREMENT CSS (correctif 11/09 : jamais de logo blanc sur fond
   blanc). Registre sombre (repos landing, ce bloc) : blanc visible, couleur
   masquée — la fiche lot (.pjh--lot) ne rend que la version couleur, ces
   règles ne s'y appliquent donc à rien.

   CAUSE RACINE du défaut « 4 logos visibles » (correctif 11/09, passe
   corrective 2) — `.lp-page img{display:block;max-width:100%}` (rescopage
   des sélecteurs bare de la planche, plus haut dans cette même feuille)
   porte la spécificité (0,1,1) — une classe + un type — CONTRE (0,1,0) pour
   `.pjh-cog--light{display:none}` — une classe seule. La spécificité prime
   TOUJOURS sur l'ordre de déclaration : `.lp-page img` gagnait sur le
   `display:none`, quel que soit l'ordre des règles dans le fichier. Confirmé
   par inspection du panneau Styles (Playwright, cascade réelle du
   navigateur) — pas une hypothèse. Corrigé en portant les sélecteurs de
   bascule à (0,2,0) via le préfixe `.pjh`, qui bat (0,1,1) dans tous les
   cas, sans dépendre de l'ordre des fichiers. */
.pjh .pjh-logo--light,.pjh .pjh-cog--light{display:none}
.pjh .pjh-logo--dark,.pjh .pjh-cog--dark{display:block}

/* ============================================================
   HEADER — registre CLAIR partagé (correctif 11/09)

   S'applique à DEUX déclencheurs : `.pjh.scrolled` (landing, posé par
   cogestim-landing-promo.js au-delà de 60px de défilement) ET `.pjh--lot`
   (fiche lot, modificateur permanent posé par le partiel — jamais de
   bascule sur ce gabarit, qui n'a pas de hero photo). Valeurs COPIÉES
   BIT-À-BIT depuis la planche certifiée de la fiche lot
   (design/pages/Fiche-lot-projet.html, 41ff013), un seul bloc pour les deux
   états au lieu de deux copies qui peuvent diverger.

   `position:fixed` sur .scrolled — conservé comme au repos
   (`position:absolute`), SEUL le fond/la couleur/le blur transitionnent :
   `top:0` des deux côtés de la bascule, aucun changement de geste de
   positionnement qui déplacerait le contenu en dessous (le header reste
   superposé au hero, jamais dans le flux) → zéro saut de layout (CLS). Le
   hero est haut (min-height:90vh) : à 60px de défilement, l'overlay du
   header clair recouvre encore le haut de la photo, jamais du contenu de
   page. `.pjh--lot` reste `position:sticky` (comportement propre à ce
   gabarit, pas de hero à recouvrir : la fiche lot veut un header qui suit
   le flux normal puis se colle, jamais un overlay). */
.pjh.scrolled,
.pjh--lot{
  background:rgba(255,255,255,.94);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--rule);
}
.pjh.scrolled{position:fixed}
.pjh--lot{position:sticky;top:0}
.pjh.scrolled .pjh-in,
.pjh--lot .pjh-in{padding-top:14px;padding-bottom:14px}
.pjh.scrolled .pjh-mark,
.pjh--lot .pjh-mark{color:var(--ink)}
.pjh.scrolled .pjh-mark .nm,
.pjh--lot .pjh-mark .nm{
  font-family:var(--disp);font-size:17px;letter-spacing:.01em;
  text-transform:none;line-height:1;color:var(--ink);
}
.pjh.scrolled .pjh-nav a,
.pjh--lot .pjh-nav a{color:var(--ink-soft)}
.pjh.scrolled .pjh-nav a:hover,
.pjh--lot .pjh-nav a:hover{color:var(--acc)}
/*
 * Correctif 11/09 (passe finale, décision 1) : `height:34px` retiré ici —
 * redondant avec la base `.pjh-logo`/`.pjh-right img` ci-dessus.
 * 25/09 (compléments) : `opacity:.6` du logo Cogestim au registre clair
 * (.scrolled et .pjh--lot) RETIRÉ — il délavait le logo couleur. Le logo
 * Cogestim s'affiche en couleur pleine dans tous les états clairs ; au repos
 * sombre, la version blanche (bascule .pjh-cog--dark/--light) est inchangée.
 */
/* Nettoyage 12/09 (passe 5) : `.pjh--lot .pjh-right{gap:20px}` retiré — la base
   `.pjh-right` porte désormais 20px (valeur planche), la surcharge répétait la
   valeur héritée. `.pjh--lot .pjh-right .b{padding:11px 30px}` retiré aussi :
   le CTA a été sorti du chrome de la fiche lot (décision Luis 11/09), le partiel
   ne reçoit plus l'argument `cta` pour variant=lot — règle orpheline, comme la
   planche certifiée l'avait déjà fait de son côté. */

/* Bascule des deux logos en registre clair (correctif 11/09) — landing
   seule : .pjh--lot ne rend jamais la version blanche (rien à masquer). */
.pjh.scrolled .pjh-logo--dark,.pjh.scrolled .pjh-cog--dark{display:none}
.pjh.scrolled .pjh-logo--light,.pjh.scrolled .pjh-cog--light{display:block}

/* Offset admin bar (correctif 11/09) — un header fixed doit descendre sous
   la barre d'administration WP, sinon elle le recouvre. Seuil 783px =
   breakpoint natif WordPress où la hauteur de la barre passe de 46px
   (mobile) à 32px (desktop) ; .pjh--lot est sticky (déjà sous la barre au
   repos, seul .scrolled/fixed a besoin de l'offset). */
body.admin-bar .pjh.scrolled{top:32px}
@media (max-width:782px){
  body.admin-bar .pjh.scrolled{top:46px}
}

/* ============================================================
   HERO — photo pleine page, information au strict nécessaire
   ============================================================ */
/* Planche v3 §1 (24/09) : hauteur plafonnée à 900px, entièrement visible en
   1366×768 (100svh ≤ 900). */
.hero{position:relative;min-height:min(100svh,900px);display:flex;flex-direction:column;justify-content:flex-end;color:var(--cog-on-dark);overflow:hidden}
.hero .bg{position:absolute;inset:0}
.hero .bg > span{left:auto;right:clamp(32px,4.4vw,72px);bottom:auto;top:104px}
/* fond vidéo/photo — pattern certifié hero-courtage/home-hero : rempli et cadré dans .bg, jamais en taille intrinsèque */
.hero-video,.hero-poster,.hero-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.hero-video.is-fading{opacity:0}
.hero-video.is-playing{opacity:1;transition:opacity .4s ease}
@media (prefers-reduced-motion:reduce){
  .hero-video{display:none}
}
/* Correctif post-validation navigateur (post 1038, lot 2) : voile LATÉRAL
   (gauche→droite) superposé au voile vertical existant (bandeau bas) — le
   texte du hero vit à gauche (.hero-in, max-width:660px) et doit passer le
   contraste AA sur un visuel clair, sans éteindre la photo à droite. Le
   voile bas (dégradé vertical) reste pour le bandeau d'infos. */
.hero .bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(90deg,rgba(0,0,0,.62) 0%,rgba(0,0,0,.38) 42%,rgba(0,0,0,.10) 75%,rgba(0,0,0,0) 100%),
  linear-gradient(180deg,rgba(16,16,14,.5) 0%,rgba(16,16,14,.1) 32%,rgba(16,16,14,.34) 66%,rgba(16,16,14,.78) 100%)}
/* Amendement voile 02/10 (décision Luis, hors atelier) : dégradé DIRECTIONNEL
   desktop. Le voile existant (.bg::after, latéral + vertical) reste INCHANGÉ
   sur la zone des textes (0 → 45% de la largeur) ; un masque l'estompe de 45%
   à 100% jusqu'à 0 au bord droit → visuel lumineux côté droit, sans cassure.
   Ajustement 02/10 (diagnostic chiffré) : plancher 0 (au lieu de .4).
   NAV : le masque affaiblit aussi la tête du voile vertical qui protégeait la
   nav .pjh blanche (absolute sur le hero). ::before COMPENSE : tête du
   dégradé vertical d'origine (.5 → .35 à 105px, bas de nav → 0 à 220px,
   hauteur en px comme la nav) modulée en x par un masque = profil
   b(x)=A(1-m)/(1-mA) (A = voile d'origine, m = masque de ::after) → opacité
   composée du haut ≈ d'origine (≈.5 à y=0) sur toute la largeur, nulle dans la
   zone texte. Mobile (≤900px) : voile uniforme actuel conservé, ni masque ni
   bande. */
@media (min-width:901px){
  .hero .bg::after{
    -webkit-mask-image:linear-gradient(90deg,#000 0,#000 45%,transparent 100%);
    mask-image:linear-gradient(90deg,#000 0,#000 45%,transparent 100%)}
  .hero .bg::before{content:"";position:absolute;left:0;right:0;top:0;height:220px;z-index:1;pointer-events:none;
    background:linear-gradient(180deg,rgba(16,16,14,.5) 0%,rgba(16,16,14,.35) 48%,rgba(16,16,14,.12) 80%,rgba(16,16,14,0) 100%);
    -webkit-mask-image:linear-gradient(90deg,transparent 0,transparent 45%,rgba(0,0,0,.6) 60%,rgba(0,0,0,.714) 75%,rgba(0,0,0,.94) 90%,#000 100%);
    mask-image:linear-gradient(90deg,transparent 0,transparent 45%,rgba(0,0,0,.6) 60%,rgba(0,0,0,.714) 75%,rgba(0,0,0,.94) 90%,#000 100%)}
}
/* Voile mobile (≤900px) 10/11, retour Caroline : voile vertical plat .70 jusqu'à 70%
   (zone H1 + accroche) puis .78 en pied (bandeau d'infos). Garantit ≥4,5:1 sur le pixel
   le plus clair, mesuré texte à 82 % compris : H1 blanc ≥.58, accroche ≥.68 ; .66 donnait 4,28 → .70. Desktop inchangé. */
@media (max-width:900px){
  .hero .bg::after{background:linear-gradient(180deg,rgba(16,16,14,.70) 0%,rgba(16,16,14,.70) 70%,rgba(16,16,14,.78) 100%)}
}
.hero .wrap{position:relative;z-index:2;padding-bottom:0}
/* Correctif post-validation navigateur : le padding-top était piloté en vw
   (20vw, soit un axe LARGEUR) alors qu'il régit un espace VERTICAL — sur un
   titre de projet qui passe sur 2 lignes (cas courant, pas un edge case),
   la valeur figée à 180-280px ne se compressait jamais et poussait le CTA
   et le bandeau d'infos sous le pli. Piloté en vh (axe HAUTEUR) : se comprime
   avec la fenêtre au lieu de forcer le débordement. Rythme interne resserré
   en conséquence (promise/body/acts/bandeau) pour garder kicker→CTA visibles
   même à 800px de hauteur avec un titre sur 2 lignes. */
/* Planche v3 §1 (24/09) — hiérarchie C : kicker = nom du projet, H1
   « Nouveau projet à {ville} » sur UNE ligne dès 1100px, accroche en .body
   (ex-.promise serif). ÉCART ASSUMÉ : le padding-top reste en vh (leçon
   07/09, jamais de vw sur un axe vertical) au lieu du clamp en vw de la
   planche — le hero est en flex-end, sans effet visible en 1366/1440. */
.hero-in{padding:clamp(64px,10vh,150px) 0 clamp(28px,3vh,48px);max-width:760px}
.hero h1.disp{color:#fff;font-size:clamp(38px,4.6vw,66px);line-height:1.04}
@media (min-width:1100px){.hero h1.disp{white-space:nowrap}}
.hero .body{color:rgba(245,240,232,.82);margin-top:22px;max-width:58ch}
.hero .acts{margin-top:28px}
/* bandeau d'infos — une ligne, séparateurs fins */
.hero-band{position:relative;z-index:2}
.hero-band .wrap{display:flex;align-items:center;gap:clamp(24px,3vw,44px);padding-top:16px;padding-bottom:16px}
.hero-band .it{font-size:15px;color:rgba(245,240,232,.9);white-space:nowrap}
.hero-band .it b{font-weight:600;color:#fff}
.hero-band .sep{width:1px;height:15px;background:rgba(245,240,232,.28)}
.hero-band .down{margin-left:auto;color:rgba(245,240,232,.7)}
.hero-band .down svg{width:34px;height:34px;stroke:currentColor;fill:none;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}
.hero-band .down:hover{color:#fff}

/* ============================================================
   EN-TÊTES DE SECTION — planche v3 §2 (24/09), règle unique :
   .sh--col : kicker + H2 sur deux lignes max (20ch) + prose — colonne de
   texte face à un média (Le projet, La situation).
   .sh--row : kicker + H2 sur une ligne, pleine largeur, JAMAIS de prose ;
   slot droit (.aside) pour une donnée factuelle (Vidéo, Appartements,
   Galerie). Copie du bloc AMENDEMENTS v3, tokens existants seulement.
   ============================================================ */
.sh--row{display:flex;align-items:flex-end;justify-content:space-between;gap:22px 48px;flex-wrap:wrap;margin-bottom:clamp(30px,3.4vw,46px)}
.sh--row h2.disp{max-width:none;white-space:nowrap}
.sh--row .aside{font-size:var(--cog-fs-sm);color:var(--ink-mute);margin:0 0 6px;max-width:44ch;text-wrap:pretty}
.sh--col h2.disp{max-width:20ch}
.sh--col .body{margin-top:24px;max-width:56ch}
.sh--col .body + .body{margin-top:16px}
/* .sh--top (planche v3.1, 25/09) : en-tête de section posé AU-DESSUS d'une
   grille à deux colonnes (Contact) — marge basse de .sh--row, prose
   resserrée. Partial template-parts/projet-contact-head.php. */
.sh--top{margin-bottom:clamp(30px,3.4vw,46px)}
.sh--top .body{margin-top:16px}
/* La planche annule la marge haute des outils de filtre sous l'en-tête. */
.sh--row + .apt-tools{margin-top:0}

/* ============================================================
   LE PROJET — planche v3 §3 (24/09) : texte + cartes 2×2 à gauche, image
   droite au format 4/5 FIXE (ex-pleine hauteur de colonne, jugée
   exagérée), collée en défilement le long de la colonne texte. `top` =
   header défilé (79px depuis le 25/09, cf. scroll-margin-top) + 16px. Sous 1180px : une
   colonne, image statique en 4/3, ordre DOM de la planche (texte → cartes
   → image). Cartes = composant library .garantie--carte (cogestim-
   components.css L11bis) CONSOMMÉ, INCHANGÉ (écart 17 §2) : seules la
   grille, la typo UI du gabarit sur le h3 (Manrope, écart 1 — la library
   pose --font-sans sur un h4) sont locales.
   ============================================================ */
.proj{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(44px,5.5vw,96px);align-items:start}
.proj > .ph{aspect-ratio:4/5;position:sticky;top:96px}
.cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-5);margin-top:clamp(36px,3.6vw,52px)}
/* Nombre impair : la dernière carte couvre les deux colonnes — jamais de case vide. */
.cards > .garantie--carte:last-child:nth-child(odd){grid-column:1 / -1}
.cards .garantie--carte h3{margin:0;font-family:var(--ui);font-weight:600;font-size:var(--cog-fs-body);line-height:1.35;color:var(--ink)}
.cards .garantie--carte p{font-family:var(--ui)}
/* Planche v3.1 (25/09) : fond de carte --paper au lieu du --paper-warm de
   la library (écart 17 §2 bis) ; la pastille .hico reste blanche. Surcharge
   LOCALE — la library, consommée ailleurs (pilier Projets neufs), est
   intacte. */
.cards .garantie--carte{background:var(--paper)}
/* Survol UNIFORME (compléments 25/09, corrigé) : cartes projet et carte
   courtier/agence gardent l'animation de la carte du design system
   (`.card:hover` / `.garantie--carte:hover`, cogestim-components.css :
   translateY(-4px) + --shadow-card, transition .4s — identiques), SANS la
   bordure que la library ajoute au survol de .garantie--carte. Scopé
   .lp-page ; library et pilier Projets neufs intacts. */
.lp-page .garantie--carte:hover{border-color:transparent}
@media (max-width:1180px){
  .proj{grid-template-columns:1fr}
  /* 10/11 : relative (et non static) — `.ph > img` est en absolute inset:0 ; en static,
     l'image se calait sur le <body> et recouvrait le hero (retour Caroline). */
  .proj > .ph{position:relative;aspect-ratio:4/3}
}
@media (max-width:640px){.cards{grid-template-columns:1fr}}

/* ============================================================
   VIDÉO — grand format, légende dans l'image
   ============================================================ */
.vid{position:relative;width:100%;aspect-ratio:12/5;cursor:pointer;display:block;border:0;padding:0;background:none;overflow:hidden}
.vid .ph{position:absolute;inset:0}
.vid::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(16,16,14,.08),rgba(16,16,14,.28))}
.vid .mid{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;display:flex;flex-direction:column;align-items:center;gap:22px;color:#fff}
.vid .play{width:74px;height:74px;border-radius:var(--radius-full);background:rgba(255,255,255,.94);display:flex;align-items:center;justify-content:center;transition:transform var(--dur-base) var(--ease-pop),background var(--dur-fast) ease}
.vid:hover .play{background:#fff;transform:scale(1.05)}
.vid .play svg{width:24px;height:24px;fill:var(--ink);margin-left:4px}
/* SURVOL DES TUILES (compléments 25/09) — motif CERTIFIÉ de la galerie de
   la fiche lot (cogestim-lot-projet.css §galerie : `.gal > .ph > img`
   transition transform 300ms, zoom 1.04 dans le cadre), copié verbatim sur
   les vignettes de la galerie de la landing ET sur le poster du cadre vidéo
   (la pastille .play grandit déjà au survol, règle `.vid:hover .play`
   ci-dessus, inchangée). Recadrage par l'overflow:hidden de `.ph` / `.vid`.
   Scope `div.lp-page` : la fiche lot garde sa propre règle. Zoom posé
   seulement sans préférence de mouvement réduit. */
@media (prefers-reduced-motion:no-preference){
  div.lp-page .gal > .ph > img,div.lp-page .vid .ph > img{transition:transform 300ms}
  div.lp-page .gal > .ph:hover > img,div.lp-page .vid:hover .ph > img{transform:scale(1.04)}
}
/* Sous la pastille (25/09) : plus de libellé en dur (.lbl retiré) — seule
   la durée saisie, qui reprend le registre de l'ex-libellé, sans le
   rattrapage de marge qui la collait à lui. Scope `div.lp-page`. */
div.lp-page .vid .dur{font-size:15px;letter-spacing:.01em;color:rgba(255,255,255,.92)}

/* ============================================================
   APPARTEMENTS — information à gauche, photo à droite, puis table
   ============================================================ */
.duo{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);gap:clamp(44px,5.5vw,104px);align-items:center}
.duo.rev > :first-child{order:2}
.duo .ph{position:relative;aspect-ratio:4/3}
.duo .txt{display:flex;flex-direction:column;align-items:flex-start;gap:22px}
.duo .txt .acts,.duo .txt .lnk{margin-top:8px}

.apt-tools{display:flex;align-items:center;justify-content:space-between;gap:clamp(20px,3vw,40px);flex-wrap:wrap;margin:clamp(64px,7vw,104px) 0 26px}
.chips{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.chip{font-family:var(--ui);font-size:13.5px;padding:9px 19px;border:1px solid var(--rule);border-radius:var(--radius-pill);background:transparent;color:var(--ink-soft);cursor:pointer;transition:var(--transition-base)}
.chip:hover{border-color:var(--acc);color:var(--acc)}
/* CORRECTIF 30/09 (mandat #3, point 3) : l'état actif utilisait --ink (noir
   neutre du gabarit), pas l'accent du projet (--acc, alimenté par accent_1
   via cogestim_projet_landing_accent_css() dans functions.php) — corrigé
   pour que la chip active reflète la teinte du projet, comme les liens de
   la table (.lots td.lot a, déjà sur --acc, cf. plus haut l.148-153). */
.chip.on{background:var(--acc);border-color:var(--acc);color:var(--cog-white)}
.fld{display:flex;flex-direction:column;gap:7px}
.fld.inline{flex-direction:row;align-items:center;gap:12px}
.fld .lb{font-size:var(--cog-fs-2xs);font-weight:500;letter-spacing:var(--cog-ls-field-lab);text-transform:uppercase;color:var(--ink-mute);white-space:nowrap}
.fld .lb em{font-style:normal;color:var(--ink-mute);font-weight:400;letter-spacing:.04em;text-transform:none}
.fld .lb i{font-style:normal;color:#B4402F}
.fld select,.fld input,.fld textarea{font-family:var(--ui);font-size:var(--cog-fs-field);color:var(--ink);background:var(--cog-white);border:1px solid var(--rule);border-radius:var(--radius-sm);padding:13px 15px;width:100%;appearance:none}
.fld.inline select{width:auto;min-width:150px;padding-top:10px;padding-bottom:10px}
.fld textarea{resize:vertical;min-height:120px;line-height:1.6}
.fld select{background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236E6E76' stroke-width='1.6' stroke-linecap='round'><path d='m6 9 6 6 6-6'/></svg>");background-repeat:no-repeat;background-position:right 13px center;background-size:17px;padding-right:42px}
.fld :is(select,input,textarea):focus{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px color-mix(in srgb,var(--lp-accent) 18%,transparent)}
.fld ::placeholder{color:var(--ink-mute)}

/* --- .field-select — déclinaison du composant certifié §L20
   (cogestim-components.css, cousin cogestim-listing.js/fieldSelect())
   au gabarit Cogestim Projets (landing + fiche lot, mini-lot select natif→
   custom). Le <select> réel reste dans le DOM (.fs-native, masqué) : un
   bouton (.fld select devient .field-in) et un panneau ancré (.fr-panel)
   portent l'affichage. Rescopé avec les tokens ET la typographie
   (Manrope var(--ui)) DE CE GABARIT plutôt que ceux du certifié global —
   la structure/comportement de fieldSelect() est copiée verbatim, seules
   les valeurs de dessin sont celles du gabarit.
   SCOPE .lp-page, .lot-page (et non .lp-page seul) — vérifié sur le markup
   réel (18/09/2026) : <body> porte bien les deux classes sur la fiche lot
   (cogestim_projet_lot_body_class() les cumule), MAIS le conteneur
   <div id="top"> de single-cogestim_projet-lot.php ne porte QUE
   `lot-page` (pas lp-page, contrairement à celui de la landing). Un
   .lp-page seul aurait donc dépendu d'un match par ANCÊTRE éloigné
   (<body>) plutôt que du conteneur immédiat — fragile et trompeur pour
   la suite. Les deux classes ci-dessous rendent chaque règle valide
   quel que soit le conteneur qui la porte réellement. */
.lp-page .fld.field-select,.lot-page .fld.field-select{position:relative}
.lp-page .fs-native,.lot-page .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}
.lp-page button.field-in,.lot-page button.field-in{
  font-family:var(--ui);font-size:var(--cog-fs-field);color:var(--ink);background:var(--cog-white);
  border:1px solid var(--rule);border-radius:var(--radius-sm);padding:13px 42px 13px 15px;width:100%;
  text-align:left;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236E6E76' stroke-width='1.6' stroke-linecap='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat:no-repeat;background-position:right 13px center;background-size:17px;
}
.lp-page .fld.inline button.field-in,.lot-page .fld.inline button.field-in{width:auto;min-width:150px;padding-top:10px;padding-bottom:10px}
.lp-page button.field-in.is-empty,.lot-page button.field-in.is-empty{color:var(--ink-mute)}
.lp-page button.field-in:focus-visible,.lot-page button.field-in:focus-visible{outline:none;border-color:var(--ink);box-shadow:0 0 0 3px color-mix(in srgb,var(--lp-accent) 18%,transparent)}
.lp-page .field-select .fr-panel,.lot-page .field-select .fr-panel{
  display:none;position:absolute;z-index:20;top:calc(100% + 6px);left:0;right:0;
  background:var(--cog-white);border:1px solid var(--rule);border-radius:var(--radius-sm);
  box-shadow:0 12px 32px rgba(16,16,14,.12);padding:6px;
}
.lp-page .field-select[data-open="true"] .fr-panel,.lot-page .field-select[data-open="true"] .fr-panel{display:block}
.lp-page .fs-opt-list,.lot-page .fs-opt-list{list-style:none;margin:0;padding:0;max-height:260px;overflow-y:auto}
.lp-page .fs-opt,.lot-page .fs-opt{font-family:var(--ui);font-size:var(--cog-fs-field);color:var(--ink-soft);padding:11px 13px;border-radius:var(--radius-sm);cursor:pointer}
.lp-page .fs-opt[aria-selected="true"],.lot-page .fs-opt[aria-selected="true"]{color:var(--ink);font-weight:600}
.lp-page .fs-opt:hover:not([aria-disabled="true"]),.lp-page .fs-opt.is-active:not([aria-disabled="true"]),.lot-page .fs-opt:hover:not([aria-disabled="true"]),.lot-page .fs-opt.is-active:not([aria-disabled="true"]){background:var(--paper)}
.lp-page .fs-opt[aria-disabled="true"],.lot-page .fs-opt[aria-disabled="true"]{color:var(--ink-mute);cursor:not-allowed;opacity:.5}

.lots{width:100%;border-collapse:collapse;font-family:var(--ui)}
.lots thead th{font-size:var(--cog-fs-2xs);font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-mute);text-align:left;padding:0 22px 14px 0;border-bottom:1px solid var(--ink);white-space:nowrap}
.lots thead th.num{text-align:right}
/* Correctif post-validation navigateur (post 1038) : les cellules touchaient les
   bords du conteneur — padding horizontal sur la première et la dernière colonne,
   aligné sur la planche (~20-24px). */
.lots thead th:first-child{padding-left:22px}
.lots thead th:last-child{padding-right:22px;text-align:right}
.lots tbody td{font-size:15px;color:var(--ink);padding:18px 22px 18px 0;border-bottom:1px solid var(--rule-soft);vertical-align:middle;white-space:nowrap}
.lots tbody td.num{text-align:right;font-variant-numeric:tabular-nums}
.lots tbody td:first-child{padding-left:22px}
.lots tbody td:last-child{padding-right:22px;text-align:right}
.lots .lot{font-weight:600}
.lots .price{font-weight:600;font-variant-numeric:tabular-nums}
.lots .plan{display:inline-flex;align-items:center;gap:8px;font-size:14px;color:var(--ink-soft)}
.lots .plan svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.lots .plan:hover{color:var(--acc)}
.lots tbody tr:hover td{background:var(--paper)}
.lots tr.res td{color:var(--ink-mute)}
.lots tr.res .lot,.lots tr.res .price{font-weight:500;color:var(--ink-mute)}
.lots tr.res:hover td{background:transparent}
/* Rangées entières cliquables (correctif 11/09) — seules les rangées dont la
   cellule Lot porte un vrai lien (référence saisie) le sont : le curseur et
   le survol suivent le lien, jamais une rangée sans référence. Une rangée
   réservée référencée reste cliquable (variantes de statut sur la fiche) ;
   son survol est donc réarmé, contrairement à la règle "transparent" ci-
   dessus qui ne vaut plus que pour les rangées SANS lien. */
.lots tbody tr:has(td.lot a){cursor:pointer}
.lots tr.res:has(td.lot a):hover td{background:var(--paper)}
/* badges de statut — rectangles à angles vifs (§1.4) */
.bdg{display:inline-block;font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;padding:5px 9px}
.bdg.dispo{color:var(--acc);border:1px solid var(--acc-line);background:var(--acc-soft)}
/* 25/09 : Disponible = accent du projet (fond ~10 %, texte accent) ;
   Réservé = NEUTRE FIXE — il prenait --paper, donc couleur_fond_1 du projet
   depuis la palette de fonds. Même règle sur .lots (landing) et .otl (lot). */
.bdg.res{color:var(--ink-mute);border:1px solid var(--rule);background:var(--paper)}
/* Surcharge scopée (règle CSS du lot, 25/09) : body.lp-page couvre landing
   ET fiche lot. */
.lp-page .bdg.res{color:var(--ink-mute);border:1px solid #d7d5d0;background:#f4f4f2}
/* Rangées supplémentaires — la VISIBILITÉ EFFECTIVE est pilotée par le JS
   via l'attribut [hidden] : il combine les deux mécanismes (une rangée est
   visible si elle passe les filtres ET que la table est dépliée ou qu'elle
   n'est pas .xtra). Le CSS ne fait que deux choses :
     · l'état SANS JS — .xtra masquée, la table reste lisible et complète à
       10 rangées (le bouton de dépliage est alors inopérant, mais rien
       n'est cassé) ;
     · rendre display:table-row aux .xtra dès que le script a pris la main
       (.js-lots), UNIQUEMENT quand [hidden] est absent — [hidden] doit
       rester la SEULE autorité pour masquer. CORRECTIF 30/09 (mandat #3) :
       `.lots.js-lots tr.xtra{display:table-row}` (0,3,1) écrasait
       `.lots tr[hidden]{display:none}` (0,2,1) — une rangée .xtra filtrée
       ou repliée restait visible tant que le script avait posé .js-lots.
       Le sélecteur `:not([hidden])` ramène la spécificité SOUS [hidden]
       en pratique en rendant la règle inapplicable dès que [hidden] est
       présent, quelle que soit la spécificité brute. */
.lots tr.xtra{display:none}
.lots.js-lots tr.xtra:not([hidden]){display:table-row}
.lots tr[hidden]{display:none}
.lots-foot{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap;margin-top:clamp(30px,3.4vw,46px)}
.lots-foot .n{font-size:14px;color:var(--ink-mute)}
/* contrôle de dépliage — même composant secondaire que .b--out, donc à
   l'accent projet comme lui (30/09 : aucun CTA à l'encre sur ce gabarit) */
.disclose{display:inline-flex;align-items:center;gap:10px;font-family:var(--ui);font-size:14px;font-weight:500;letter-spacing:var(--ls-cta);color:var(--acc);background:transparent;border:1px solid var(--acc);border-radius:var(--radius-pill);padding:15px 30px;cursor:pointer;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out)}
/* CORRECTIF 30/09 (mandat #3, complement) : meme piege que tr.xtra --
   `.disclose{display:inline-flex}` (0,1,0) l'emportait sur le [hidden]
   natif du navigateur (poids UA plus faible qu'une regle auteur), donc
   toggle.hidden=true ne masquait pas reellement le bouton. */
.lots-foot .disclose[hidden]{display:none}
.disclose:hover{background:var(--acc);border-color:var(--acc);color:var(--cog-white)}
.disclose svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;transition:transform var(--dur-fast) var(--ease-out)}
.disclose[aria-expanded="true"] svg{transform:rotate(180deg)}
.disclose:focus-visible{outline:none;box-shadow:var(--cog-focus-ring)}

/* ============================================================
   BANDE PHOTO — respiration pleine largeur, aucun texte
   ============================================================ */
.band{position:relative}
.band .ph{aspect-ratio:24/9}

/* ============================================================
   SITUATION — distances + carte
   ============================================================ */
.situ{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);gap:clamp(44px,5.5vw,104px);align-items:start}
/* Planche v3 §4 (24/09) : proportions 5/7, la carte occupe toute la hauteur
   de la colonne texte (stretch). La prose de lieu_texte vit dans .sh--col. */
.situ{grid-template-columns:minmax(0,5fr) minmax(0,7fr);align-items:stretch}
.dist{margin:clamp(30px,3.4vw,44px) 0 0;border-top:1px solid var(--rule)}
/* CORRECTIF 24/09 (décision Luis) : flex space-between → GRILLE 2 colonnes.
   En flex, une valeur courte était poussée à droite et une valeur longue,
   qui passait à la ligne, s'étalait depuis la gauche : deux alignements dans
   la même liste. Désormais libellé en colonne fixe (130px), valeur toujours
   alignée À GAUCHE dans la colonne restante, retour à la ligne propre sous
   elle-même (jamais sous le libellé). */
.dist .r{display:grid;grid-template-columns:130px minmax(0,1fr);gap:20px;align-items:baseline;padding:13px 0;border-bottom:1px solid var(--rule-soft)}
.dist .r .k{font-size:15px;color:var(--ink-soft)}
.dist .r .v{font-size:15px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;text-align:left;overflow-wrap:break-word}
/* Planche v3 §4 : grille libellé/valeur proportionnelle (valeurs longues),
   libellé en --ink-mute, valeur en graisse normale. Icône Lucide 16px nue,
   couleur du libellé, devant chaque entrée qui en porte une (.dist--ico). */
.dist .r{grid-template-columns:minmax(120px,.8fr) minmax(0,1.6fr);align-items:start}
.dist .r .k{color:var(--ink-mute)}
.dist .r .v{font-weight:400;line-height:1.55}
.dist--ico .r .k{display:flex;align-items:flex-start;gap:10px}
.dist--ico .r .k svg{width:var(--icon-sm);height:var(--icon-sm);flex:0 0 auto;margin-top:4px;stroke:currentColor;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.map{position:relative;aspect-ratio:16/12;overflow:hidden;background:linear-gradient(0deg,rgba(26,26,31,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(26,26,31,.04) 1px,transparent 1px),var(--paper-deep);background-size:120px 120px,120px 120px,100% 100%}
/* Planche v3 §4 : carte pleine hauteur de la colonne (plus de ratio fixe). */
.situ .map{aspect-ratio:auto;min-height:560px}
@media (max-width:1180px){.situ .map{min-height:460px}}
@media (max-width:640px){.situ .map{min-height:380px}.dist .r{grid-template-columns:1fr;gap:2px}}
/* Le fond stylisé (fallback de la planche) ne se dessine que sans vraie
   carte : dès que la carte (Leaflet, tuiles OSM) est montée (.is-live, posée par
   cogestim-landing-promo.js §6), elle suffit. CORRECTIF 24/09 : la carte
   Google Static (.has-map/.map-img) est retirée de ce gabarit — Leaflet
   (Leaflet vendored) la remplace, cf. écart 11 du template. */
.map:not(.is-live)::before{content:"";position:absolute;left:-6%;top:64%;width:124%;height:42%;transform:rotate(-4deg);background:linear-gradient(180deg,rgba(95,107,113,.14),rgba(95,107,113,.04))}
/* Conteneur Leaflet : plein cadre, z-index:0 = contexte d'empilement propre
   (les panes Leaflet, z-index 200-1000, restent SOUS .addr). Invisible tant
   que la carte n'est pas montée. */
.map .map-canvas{position:absolute;inset:0;z-index:0;visibility:hidden;background:var(--paper-deep)}
.map.is-live .map-canvas{visibility:visible}
.map.is-live .pin{display:none}
/* Pin Leaflet (divIcon .cog-pin) — même garde que le funnel
   (cogestim-estimation.css, scopée funnel) : le SVG n'a aucune dimension
   intrinsèque, hors scope il retomberait sur 300×150. */
div.lp-page .map .cog-pin{display:flex}
/* Filtre tuiles OSM aligné sur la fiche bien et les agences (grayscale(.85) saturate(.6) — tuiles seules, jamais le pin ni
   l'attribution). Exclusion des gabarits projets du 14/10 ABROGÉE le 13/10 au soir (verdict Luis) : filtre global. */
div.lp-page .map .leaflet-tile-pane{filter:grayscale(.85) saturate(.6)}
div.lp-page .map .cog-pin svg{width:40px;height:40px;filter:drop-shadow(0 1px 2px color-mix(in srgb,var(--ink) 35%,transparent))}
/* Attribution « © OpenStreetMap contributors » (7ter, 24/09) : obligation
   de la licence ODbL des tuiles OSM, restylée
   aux tokens du gabarit mais JAMAIS masquée. */
div.lp-page .map .leaflet-control-attribution{font-family:var(--ui);font-size:10px;color:var(--ink-mute);background:color-mix(in srgb,var(--cog-white) 85%,transparent);padding:1px 6px}
div.lp-page .map .leaflet-control-attribution a{color:var(--ink-soft)}
/* Voile d'aide Ctrl + molette (Lot B 30/10) — copie VERBATIM de assets/css/cogestim-carte-resultats.css (3 règles .cmap-hint), scopée .map : cette feuille-là n'est chargée que sur le listing ; le voile est créé par cogestim-funnel-map.js avec opts.ctrlZoom (cartes projets). */
.map .cmap-hint{position:absolute;inset:0;z-index:calc(var(--z-popover) + 2);display:flex;align-items:center;justify-content:center;padding:0 24px;text-align:center;background:color-mix(in srgb,var(--ink) 45%,transparent);color:var(--cog-white);font-family:var(--font-sans);font-size:var(--cog-fs-body-lg);font-weight:500;pointer-events:none;opacity:0;transition:opacity var(--dur-fast) var(--ease-out)}
.map .cmap-hint.is-on{opacity:1}
@media (prefers-reduced-motion:reduce){.map .cmap-hint{transition:none}}
.map .pin,.map .addr{z-index:1}
.map .pin{position:absolute;left:47%;top:44%;transform:translate(-50%,-100%);display:flex;align-items:center;gap:10px}
.map .pin svg{width:30px;height:30px;fill:var(--acc);stroke:#fff;stroke-width:1.2}
.map .pin .t{font-size:14px;color:var(--ink);transform:translateY(-6px)}
.map .addr{position:absolute;left:16px;bottom:16px;font-size:13px;color:var(--ink-soft);background:var(--cog-white);padding:8px 13px}


/* ============================================================
   GALERIE — composition adaptable au nombre réel de visuels.
   1 : visuel unique · 2 : deux colonnes · 3 : une grande + deux
   secondaires · 4 à 6 : grille éditoriale · plus de 6 : sélection
   de 5–6 + lien vers la galerie complète. Aucun visuel inventé
   ni dupliqué pour remplir la grille.
   ============================================================ */
.gal-head{display:flex;justify-content:space-between;align-items:flex-end;gap:clamp(32px,4vw,72px);margin-bottom:clamp(30px,3.4vw,46px)}
.gal-head .cap{margin-top:14px}
.gal{display:grid;gap:14px;grid-template-columns:repeat(3,minmax(0,1fr))}
.gal > .ph{aspect-ratio:4/3}
/* 1 visuel */
.gal:has(> .ph:first-child:last-child){grid-template-columns:1fr}
.gal:has(> .ph:first-child:last-child) > .ph{aspect-ratio:21/9}
/* 2 visuels */
.gal:has(> .ph:nth-child(2):last-child){grid-template-columns:1fr 1fr}
/* 3 visuels : une grande à gauche, deux secondaires à droite */
.gal:has(> .ph:nth-child(3):last-child){grid-template-columns:minmax(0,1.66fr) minmax(0,1fr);grid-template-rows:1fr 1fr;aspect-ratio:16/9}
.gal:has(> .ph:nth-child(3):last-child) > .ph{aspect-ratio:auto}
.gal:has(> .ph:nth-child(3):last-child) > .ph:first-child{grid-row:span 2}
/* 4 visuels : grille 2 × 2 */
.gal:has(> .ph:nth-child(4):last-child){grid-template-columns:1fr 1fr}
/* plus de 6 visuels : 5 vignettes + compteur d'ouverture sur la 6ᵉ */
.gal .more{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;background:rgba(16,16,14,.5);color:#fff;font-family:var(--ui);border:0;cursor:pointer;transition:background var(--dur-fast) var(--ease-out)}
.gal .more:hover{background:rgba(16,16,14,.64)}
.gal .more .pl{font-family:var(--disp);font-size:32px;line-height:1}
.gal .more .t{font-size:13px;color:rgba(255,255,255,.86)}
.gal .more:focus-visible{outline:none;box-shadow:var(--cog-focus-ring)}

/* ============================================================
   LIGHTBOX — markup #lb rendu par le template HORS .lp-page (enfant direct
   de <body>, contrat de cogestim-projet.js) : pas de scope .lp-page ici.
   Correctif post-validation navigateur (post 1038, lot 2) : cette feuille
   ne portait AUCUNE règle .lb — perdues au remplacement de la feuille v2 au
   pivot du 04/09 — donc le clic sur une tuile bascule bien .open (JS déjà
   correct) mais rien ne rendait la superposition visible. Porté depuis
   cogestim-landing-promo.css (v2), mêmes tokens que le reste du gabarit. */
/* Correctif collision de nom (10/09) : le sélecteur était `.lb` bare, en
   collision avec `.fld .lb` (label de champ) — `.lb{display:none}`
   l'emportait sur les labels de formulaire faute de règle `display` dans
   `.fld .lb`, les faisant disparaître du rendu. Scopé sur #lb (id unique
   posé par le markup, cf. commentaire PHP juste avant la lightbox) : JS
   cible déjà l'élément par getElementById('lb') et ne lit que la classe
   .open, aucun changement requis côté JS/markup. */
#lb{position:fixed;inset:0;z-index:4000;display:none;background:rgba(16,15,18,.94);flex-direction:column}
#lb.open{display:flex}
#lb .lb-top{display:flex;align-items:center;justify-content:space-between;padding:20px clamp(16px,3vw,32px)}
.lb-count{font-family:var(--ui);font-size:14px;letter-spacing:.04em;color:rgba(255,255,255,.75)}
.lb-close{width:var(--cog-control-md);height:var(--cog-control-md);border-radius:var(--radius-full);border:1px solid rgba(255,255,255,.25);display:inline-flex;align-items:center;justify-content:center;transition:border-color var(--dur-fast) var(--ease-out),background var(--dur-fast) var(--ease-out);background:transparent;cursor:pointer}
.lb-close:hover{border-color:#fff;background:rgba(255,255,255,.08)}
.lb-close svg{width:var(--icon-md);height:var(--icon-md);stroke:#fff;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.lb-stage{flex:1;display:flex;align-items:center;justify-content:center;position:relative;padding:0 clamp(12px,4vw,60px) clamp(20px,3vw,40px);min-height:0}
.lb-stage img{max-width:100%;max-height:100%;object-fit:contain;box-shadow:var(--cog-shadow-modal)}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:var(--cog-control-md);height:var(--cog-control-md);border-radius:var(--radius-full);border:1px solid rgba(255,255,255,.25);background:transparent;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out)}
.lb-nav:hover{background:rgba(255,255,255,.15);border-color:#fff}
.lb-nav svg{width:var(--icon-lg);height:var(--icon-lg);stroke:#fff;fill:none;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.lb-nav.prev{left:clamp(10px,2vw,28px)}
.lb-nav.next{right:clamp(10px,2vw,28px)}
.lb-close:focus-visible,.lb-nav:focus-visible{outline:none;box-shadow:var(--cog-focus-ring-dark)}

/* ============================================================
   CONTACT — assemblage verbatim Fiche-lot-projet.html (amendement
   11/09/2026, passe assemblage) : disposition 2 colonnes ouverte sur
   le fond de section (.s.paper depuis la v3.1), PAS de carte blanche fermée. Colonne
   gauche « Votre interlocuteur » (vignette portrait 3/4, nom,
   fonction, téléphone en ligne avec glyphe) ; colonne droite
   formulaire large (h2.disp + p.intro + frow×3 + bouton svg + optin).
   ============================================================ */
.contact{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);gap:clamp(36px,5vw,88px);align-items:start}
/* Sans courtier saisi (`.broker` non rendu) : une seule colonne, le
   formulaire prend toute la largeur — jamais de colonne gauche vide. */
.contact:has(> .form:only-child){grid-template-columns:1fr;max-width:760px}
.broker .lb-top{font-family:var(--disp);font-size:19px;color:var(--ink);margin:0 0 20px}
/* Override du composant .card global (cogestim-components.css §L… —
   background/border pour les cartes de listing) : verbatim fiche lot, la
   carte courtier est PLATE sur le fond de section, jamais une carte
   fermée. Sans ce reset, le .card générique (background+border) fuit sous
   ce markup qui réutilise volontairement la classe .card de la fiche lot. */
.broker .card{display:grid;grid-template-columns:200px 1fr;gap:clamp(20px,2.4vw,32px);align-items:center;background:none;border:0;border-radius:0;overflow:visible}
.broker .ph{aspect-ratio:1/1}
/* Vignette courtier 200px (décision Luis 24/09, était 150px), landing ET
   fiche lot (feuille partagée). Ratio 3/4 inchangé. Recadrage vers le haut
   (50% 20%) pour garder le visage dans le cadre quand l'asset est plus haut
   que le ratio. (0,3,1) : bat `.ph > img` (0,1,1). Mobile : la colonne
   portrait suit la largeur de la carte (40 %, plafonnée à 200px), même ratio.
   La carte agence (.card + .card, une colonne) garde la largeur pleine de
   .broker, donc les mêmes bords que la carte courtier. */
/* COMPLÉMENTS 25/09 — cadrage serré : vignette CARRÉE 200×200 (124×124
   ≤720px), landing ET fiche lot (règle unique). Écart planche (planche :
   4/5). object-position mesuré sur le portrait Junod (2:3, visage centré
   à ~26 % de la hauteur) : en `cover` carré l'image n'est pas agrandie,
   seulement rognée en bas — 0 % est le réglage qui rapproche le plus le
   visage du centre (≈39 % de la hauteur du cadre ; 12 % le laissait à
   33 %). */
/* ZOOM ×2 (compléments 25/09, 2ᵉ passe) — le `cover` seul ne pouvait pas
   centrer le visage (image jamais agrandie). transform-origin mesuré en
   computed sur le portrait Junod (yeux à y≈73,5 / x≈97,5 dans le cadre de
   200px) : yeux au tiers supérieur du cadre (≈67px), visage centré. Les
   pourcentages valent aussi pour 124px. Recadrage par l'overflow:hidden de
   `.ph`. Source servie en medium_large (768px, functions.php
   cogestim_projet_courtier_photo_url()) pour limiter le flou. */
/* FIX 29/09 (mini-lot 2 correctifs, corrigé le même jour) — le cadrage
   centre-centre coupait le haut du visage sur les portraits Collaborateurs
   (format portrait, sujet cadré haut). object-position:center top remplace
   le 50% 0% équivalent pour lisibilité. Le transform-origin:47.5% 28% posé
   dans ce même fix était calé en literal proche-pixel sur une seule photo
   (Junod) et ne généralisait pas : sur d'autres portraits le zoom ×2
   repartait d'un point trop bas et coupait la tête. L'ancrage générique
   haut-centre (50% 0%) qui a suivi cassait encore un cas (Berchier).
   Amendement 2026-09-29 : suppression pure et simple du zoom — simple
   crop cover, ancrage 20% depuis le haut. Spécificité (0,3,1) — bat
   `.lp-page img` (0,1,1), cf. commentaire §L. */
.broker .card .ph > img{object-fit:cover;object-position:center 20%}
@media (max-width:720px){.broker .card{grid-template-columns:124px minmax(0,1fr)}}
/* Survol uniforme des cartes (décision 24/09, rétablie 25/09) : courtier et
   agence gardent le `.card:hover` du design system (soulèvement -4px +
   --shadow-card, sans bordure : .broker .card est en border:0), comme les
   cartes projet. Non cliquables : curseur normal. */
.lp-page .broker .card{cursor:default}
.broker .nm{font-family:var(--disp);font-size:24px;line-height:1.2;color:var(--ink);margin:0}
.broker .role{font-size:14px;color:#5d5d63;margin:4px 0 0}
.broker .rows{display:flex;flex-direction:column;gap:9px;margin-top:18px}
.broker .rows .r{display:flex;align-items:center;gap:11px;font-size:14.5px;color:var(--ink)}
.broker .rows svg{width:17px;height:17px;flex:0 0 auto;stroke:#5d5d63;fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
/* Carte AGENCE (écart 16, décision Luis 24/09) — 2ᵉ .card du même registre
   .broker, SANS portrait : une colonne, séparée de la carte courtier par un
   filet. Sélecteur de fratrie, aucune classe nouvelle. Les horaires
   (Cogestim_Agences_Render::horaires_html, format 'span') posent une ligne
   par <span>. */
/* 2 courtiers (02/10) : 2ᵉ carte courtier empilée sous la 1ʳᵉ, même registre ;
   courtier SANS portrait : pas de .ph rendu → une colonne, jamais de cadre vide.
   Le sélecteur agence est désormais `.card.agc` (la fratrie `.card + .card`
   aurait pris la 2ᵉ carte courtier pour la carte agence). */
.broker .card:not(.agc) + .card:not(.agc){margin-top:28px}
.broker .card:not(:has(.ph)){grid-template-columns:1fr}
.broker .card.agc{grid-template-columns:1fr;margin-top:28px;padding-top:24px;border-top:1px solid var(--rule)}
.broker .card.agc .nm{font-size:19px}
.broker .card.agc .rows{margin-top:14px}
.broker .card.agc .rows .r{align-items:flex-start;line-height:1.55}
.broker .card.agc .rows svg{margin-top:3px}
.broker .rows .hrs span{display:block}
.broker .rows .hrs b{font-weight:600}
/* Planche v3 §5 (24/09) — horaires sur DEUX colonnes (jours | plages),
   `.hours` de la planche porté sur le markup existant de horaires_html()
   (format 'span' : <span><b>jours</b> &nbsp; plage</span>) sans toucher au
   mu-plugin : chaque ligne passe en display:contents, <b> et le texte
   deviennent les deux cellules de la grille. Le &nbsp; + espace en tête de
   la plage (~7px, non collapsible) est absorbé par un column-gap réduit
   (9px → ~16px visuels, gap de la planche). Ligne sans jours (« Sur
   rendez-vous ») : pleine largeur. Jours en --ink-soft, graisse normale
   (dt de la planche). Pin de l'adresse (ligne sans .hrs) en --icon-strong,
   PAS en accent : exception « pin toujours accent » non appliquée sur
   l'expression Cogestim Projets (note d'arbitrage v3). Carte partagée
   landing + fiche lot (décision 24/09 « aucune divergence »). */
.broker .rows .hrs{display:grid;grid-template-columns:auto 1fr;gap:4px 9px}
.broker .rows .hrs > span{display:contents}
.broker .rows .hrs > span:not(:has(b)){display:block;grid-column:1 / -1}
.broker .rows .hrs b{font-weight:400;color:var(--ink-soft)}
.broker .card.agc .rows .r:not(:has(.hrs)) > svg{stroke:var(--icon-strong)}
.form h2.disp{margin-bottom:8px}
.form .intro{font-size:14.5px;color:#5d5d63;margin:0 0 26px}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.frow + .frow{margin-top:14px}
.frow.one{grid-template-columns:1fr}
.form .b{margin-top:20px}
.optin{display:flex;align-items:flex-start;gap:12px;margin-top:22px;padding-top:20px;border-top:1px solid #ececea}
.optin input{appearance:none;width:19px;height:19px;flex:0 0 auto;margin-top:2px;border:1px solid #d7d5d0;border-radius:2px;background:var(--cog-white);cursor:pointer}
.optin input:checked{background:var(--acc);border-color:var(--acc)}
.optin label{font-size:13.5px;line-height:1.6;color:#5d5d63}
.optin .sub{display:block;font-size:11.5px;color:#8c8c94;margin-top:5px}

/* ── Formulaires câblés (lot routing 4/7, 02/10) — scopé .lp-page (landing + fiche lot) ──
   cogestim-components.css n'est pas chargé sur ce gabarit : honeypot, erreur d'envoi,
   état succès et marquage des champs en erreur sont donc redéfinis ici, aux tokens.
   Case de consentement transactionnel = 2e .optin consécutif : une seule ligne de
   séparation (celle du premier), composition d'existants. */
.lp-page .field-hp{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}
.lp-page .form .form-error{font-size:var(--cog-fs-legal);color:var(--color-error,#b3261e);margin:14px 0 0}
.lp-page .form .optin + .optin{margin-top:14px;padding-top:0;border-top:0}
.lp-page .form .msg-done{display:none;align-items:center;gap:12px;font-weight:500;color:var(--ink)}
.lp-page .form .msg-done svg{width:24px;height:24px;flex:0 0 auto;stroke:var(--acc);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.lp-page .form.sent > :not(.msg-done){display:none}
.lp-page .form.sent .msg-done{display:flex}
.lp-page .form .fld.err input,.lp-page .form .fld.err textarea{border-color:var(--color-error,#b3261e)}
.lp-page .form .optin.err input{border-color:var(--color-error,#b3261e)}
/* État coché lisible (correctif 02/10) : coche du composant .consent certifié
   (cogestim-components.css L5, non chargé ici) reprise à l'identique — blanche sur le
   fond d'accent déjà posé par .optin input:checked. */
.lp-page .form .optin input{position:relative}
.lp-page .form .optin 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)}
.lp-page .form .optin input:focus-visible{outline:none;box-shadow:var(--cog-focus-ring)}
/* Astérisque de la case requise : même teinte que .fld .lb i. */
.lp-page .form .optin label i{font-style:normal;color:#B4402F}
/* Bouton inerte tant que les requis manquent (gating JS §7) : valeurs de .btn[disabled]. */
.lp-page .form .b[disabled]{opacity:.32;pointer-events:none}
/* Lien politique près du CTA (registre formulaires 02/10), hors de la case de consentement. */
.lp-page .form .form-privacy{margin:18px 0 0;font-size:var(--cog-fs-legal);color:#5d5d63}
.lp-page .form .form-privacy a{text-decoration:underline;text-underline-offset:2px}

/* ============================================================
   FOOTER Cogestim léger
   ============================================================ */
.pjf{background:var(--cog-white);border-top:1px solid var(--rule);padding:clamp(34px,3.4vw,48px) 0}
.pjf-top{display:flex;justify-content:space-between;align-items:center;gap:36px;flex-wrap:wrap}
.pjf-top img{height:50px;width:auto;max-width:none}
@media (max-width:720px){.pjf-top img{height:44px}}
.pjf-nav{display:flex;gap:26px;flex-wrap:wrap}
.pjf-nav a{font-size:14px;color:var(--ink-soft)}
.pjf-by{font-size:14px;color:var(--ink-mute)}
.pjf-sep{height:1px;background:var(--rule-soft);margin:clamp(24px,2.6vw,34px) 0 18px}
.pjf-bot{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;font-size:var(--cog-fs-legal);color:var(--ink-mute)}
.pjf-bot .lgl{display:flex;gap:20px;flex-wrap:wrap}
.pjf-bot a{color:var(--ink-mute)}
.pjf-bot a:hover{color:var(--ink)}
/* 25/09 (partial template-parts/projet-pjf.php) — ≤ 900 : padding-bas
   dégageant la bulle CMP HubSpot fixe (#hs_show_banner_button : 20px du bord
   + 56px = 76px, + 20px d'air). ≤ 720 : logo / nav / légende empilés. */
@media (max-width:900px){.pjf{padding-bottom:96px}}
@media (max-width:720px){.pjf-top{flex-direction:column;align-items:flex-start;gap:20px}}

/* ============================================================
   MOBILE — planche v3 §6 (24/09). Table : conteneur de défilement
   horizontal, la table .lots elle-même est intacte. Rail d'ancres : sous
   900px la nav passe sur sa propre ligne sous le logo et DÉFILE en
   interne (jamais masquée, jamais de burger), gouttières de .wrap
   débordées pour que le défilement aille jusqu'au bord. Scope `div.lp-page`
   : la fiche lot garde sa propre règle (.lot-page .pjh-nav). Mobile des
   en-têtes et du bandeau : H2 .sh--row sur plusieurs lignes, bandeau du
   hero sans filets et replié.
   ============================================================ */
.lots-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
@media (max-width:900px){
  div.lp-page .pjh-in{flex-wrap:wrap;row-gap:14px;padding-bottom:0}
  div.lp-page .pjh-nav{order:3;flex:1 0 100%;justify-content:flex-start;overflow-x:auto;scrollbar-width:none;margin:0 calc(-1 * clamp(32px,4.4vw,72px));padding:12px clamp(32px,4.4vw,72px);border-top:1px solid rgba(245,240,232,.18);gap:26px}
  div.lp-page .pjh.scrolled .pjh-nav{border-top-color:var(--rule)}
  div.lp-page .pjh-nav::-webkit-scrollbar{display:none}
  div.lp-page .pjh-nav a{white-space:nowrap}
  .sh--row h2.disp{white-space:normal}
}
@media (max-width:640px){
  .hero-band .sep{display:none}
  .hero-band .wrap{flex-wrap:wrap;gap:10px 20px}
}

@media (max-width:1180px){
  .duo,.situ,.contact{grid-template-columns:1fr}
  .duo.rev > :first-child{order:0}
}

/* ============================================================
   MODULE « PORTES OUVERTES » — bandeau CTA (.po-band)
   Portage de design/reference/Portes-ouvertes-bandeau-landing.html +
   portes-ouvertes-landing.css (planche atelier 18/09/2026), scope déjà
   `.lp-page` (feuille chargée sur ce seul gabarit) — substitution
   mécanique de `.pj` en rien (pas de collision de sélecteur), même
   discipline que le reste de ce fichier (cf. docblock SCOPE en tête).
   Anatomie : ligne d'information à séparateurs (= .hero-band .it/.sep),
   transposée sur fond clair. Emplacement A seul (§6.1bis), jamais sticky.
   Rendu uniquement si ≥ 1 date à venir (PHP, single-cogestim_projet-
   landing.php) — aucune règle CSS ne gère l'état vide, il n'existe pas.
   ============================================================ */
.po-band{border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);background:var(--cog-white)}
.po-band .wrap{display:flex;align-items:center;justify-content:space-between;gap:clamp(24px,3vw,48px);padding-top:clamp(26px,2.8vw,36px);padding-bottom:clamp(26px,2.8vw,36px)}
.po-band .kick{margin:0 0 10px}
.po-band-dates{display:flex;align-items:center;gap:clamp(16px,1.8vw,26px);flex-wrap:wrap;margin:0;padding:0;list-style:none}
.po-band-dates .d{font-family:var(--disp);font-weight:400;font-size:clamp(23px,2vw,29px);line-height:1.18;letter-spacing:-.006em;color:var(--ink)}
.po-band-dates .d .h{font-family:var(--ui);font-size:15px;color:var(--ink-soft);margin-left:12px;white-space:nowrap}
.po-band .cap{margin-top:10px}
.po-band .b{flex:0 0 auto}
@media (max-width:900px){.po-band .wrap{flex-direction:column;align-items:flex-start}.po-band-dates .d .h{display:block;margin:2px 0 0}}

/* Champ conditionnel « Date de visite » (module Portes ouvertes), piloté
   par cogestim-landing-promo.js. Registre .fld verbatim, aucun style propre. */
.fld[data-when][hidden]{display:none}
