/* ---------------------------------------------------------------------------
 * Deltas d'intégration VefaConnect — chargé APRÈS les 5 feuilles du prototype.
 *
 * Les fichiers 01→05 sont des COPIES VERBATIM des sources du handoff : ils ne
 * doivent jamais être édités, sinon la comparaison A/B contre le bundle
 * compilé de référence perd sa valeur. Tout écart assumé vit ici, documenté.
 * ------------------------------------------------------------------------ */

/* La navigation hybride a été greffée de la variante E1 sur la variante D.
 * Côté E1, le CTA du header est masqué sous 560 px par une règle scopée
 * `.e-page-editorial` — que D n'hérite pas (sa racine est `.d-page` seule).
 * Sans elle, marque + CTA + burger ne tiennent pas sur la ligne : mesuré à
 * 390 px, le burger sortait du header de 28 px et était rogné par le bord de
 * l'écran, donc INATTEIGNABLE. On reproduit la règle, scopée à `.d-page` pour
 * ne toucher aucune autre page du site. */
@media (max-width: 560px) {
  .d-page .d-header .d-button-small {
    display: none;
  }

  .d-page .e-mobile-menu > summary {
    width: 44px;
    height: 44px;
  }

  .d-page .e-mobile-menu > nav {
    top: calc(100% + 10px);
    right: -1px;
  }
}

/* EN-TÊTE PLEINE LARGEUR, COLLÉ EN HAUT (retour utilisateur 2026-08-17 : « sur
 * mobile la navbar doit être tout en haut, on cherche à optimiser l'espace »).
 *
 * Le prototype pose une carte flottante : 10 px de marge haute et 10 px de
 * gouttière de chaque côté. Sur 375 px de large, cette bordure décorative
 * coûte de la hauteur au-dessus de la ligne de flottaison sans rien apporter.
 * L'en-tête devient une barre d'application : bord haut et bords latéraux
 * retirés, bord bas gardé, coins bas arrondis pour conserver le langage de la
 * carte.
 *
 * Le MÊME écart est posé dans `site_header.css` pour les 209 autres gabarits —
 * l'en-tête est un composant unique, il ne peut pas être collé en haut ici et
 * flottant ailleurs. Deux fichiers parce que `/` ne charge pas la transposition
 * (cf. `partials/site_header.html`), pas parce que la règle diverge. */
@media (max-width: 560px) {
  .d-page .d-header {
    width: 100%;
    margin-top: 0;
    padding: 0 14px 0 16px;
    border-width: 0 0 1px;
    border-radius: 0 0 12px 12px;
  }
}

/* ---------------------------------------------------------------------------
 * MOTEUR COLLANT MOBILE (`.d-mobile-search`) — remplace le `.e-mobile-sticky-cta`
 * du prototype, retiré le 2026-08-17.
 *
 * Trois différences avec la barre livrée, chacune sur un défaut constaté :
 *   1. c'est un CHAMP, pas un lien vers `#d-search` : la barre livrée faisait
 *      remonter la page jusqu'au moteur, où il fallait ensuite taper ;
 *   2. elle est masquée par défaut et révélée par la seule classe `is-visible`
 *      (`home_mobile_search.js`) — la barre livrée était visible dès le
 *      chargement, par-dessus le champ du hero qu'elle dupliquait ;
 *   3. surface claire et non pastille orange pleine : elle doit se lire comme
 *      un champ de saisie, l'orange restant sur l'action.
 *
 * ⚠️ Les tokens `--d-*` sont déclarés sur `.d-page` (04-version-d.css), pas sur
 * `:root` : la barre DOIT rester dans `.d-page`. `position: fixed` y survit,
 * cet ancêtre ne posant ni `transform` ni `filter` (qui en feraient un bloc
 * conteneur et transformeraient le `fixed` en `absolute` silencieusement).
 *
 * ⚠️ Le bandeau cookies (`#tarteaucitronAlertBig`, `z-index` 2147483645) passe
 * devant et le recouvre entièrement tant qu'il n'a pas été traité. Assumé : la
 * barre est alors invisible, jamais tronquée, et retrouve sa place au premier
 * choix de l'utilisateur.
 * ------------------------------------------------------------------------ */
.d-page .d-mobile-search {
  position: fixed;
  z-index: 120;
  left: 10px;
  right: 10px;
  /* `--d-kb-inset` est posée par le JS = hauteur masquée par le clavier
   * virtuel. Repli `0px` : sans `visualViewport`, la barre garde sa place. */
  bottom: calc(var(--d-kb-inset, 0px) + max(10px, env(safe-area-inset-bottom)));
  display: none;
  align-items: center;
  gap: 8px;
  min-height: 58px;
  padding: 0 8px 0 14px;
  border: 1px solid var(--d-border);
  border-radius: 16px;
  background: rgba(255, 255, 255, .98);
  box-shadow: 0 18px 45px rgba(15, 23, 42, .24), 0 10px 28px rgba(255, 64, 0, .14);
  backdrop-filter: blur(14px);
  font-family: var(--ui);
}

.d-page .d-mobile-search-icon {
  flex: 0 0 auto;
  color: var(--d-blue-deep);
  font-size: 19px;
}

.d-page .d-mobile-search input {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  border: 0;
  background: transparent;
  color: var(--d-slate);
  font-family: var(--ui);
  /* 16 px est un SEUIL, pas un goût : en dessous, iOS Safari zoome à la prise
   * de focus et ne revient jamais en arrière. */
  font-size: 16px;
  outline: none;
}

.d-page .d-mobile-search input::placeholder {
  color: var(--d-subtle);
}

.d-page .d-mobile-search button {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--d-orange), #ff7a45); /* hex-ok — 2e stop du dégradé accent, pas de token autonome */
  color: var(--vefa-text-on-primary);
  font-family: var(--ui);
  font-size: 14px;
  font-weight: 800;
}

@media (max-width: 860px) {
  /* `visibility` plutôt qu'une bascule `display` : une transition ne s'exécute
   * pas depuis `display: none`. La barre est donc posée mais hors de l'arbre
   * d'accessibilité et intactile tant que `is-visible` n'est pas là. */
  .d-page .d-mobile-search {
    display: flex;
    visibility: hidden;
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 180ms ease, transform 180ms ease, visibility 0s linear 180ms;
  }

  .d-page .d-mobile-search.is-visible {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition: opacity 180ms ease, transform 180ms ease, visibility 0s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .d-page .d-mobile-search {
    transition: none;
    transform: none;
  }
}

/* ---------------------------------------------------------------------------
 * Neutralisation de la fuite de cascade Bootstrap (étape 2 — base.html)
 *
 * base.html charge Bootstrap 5.3 depuis un CDN, HORS du bundle compress. Ses
 * sélecteurs d'ÉLÉMENT (`h2 {font-weight:500}`, `p {margin-bottom:1rem}`,
 * `label {…}`) ne sont dans aucune couche CSS, alors que le préflight du
 * prototype vit dans `@layer base` — la couche la MOINS prioritaire. Bootstrap
 * gagnait donc systématiquement.
 *
 * Mesuré avant correctif sur /home-d/ : 19 éléments sur 385 divergeaient
 * (titres passés en 700, H3 à 28 px, marges de paragraphe réintroduites).
 *
 * `:where()` porte une spécificité NULLE : ces règles pèsent donc exactement
 * (0,1,0) — assez pour battre un sélecteur d'élément nu, jamais assez pour
 * passer devant une règle du prototype (qui descend toujours d'une classe).
 * C'est ce qui rend le correctif sûr : il restaure la ligne de base du
 * préflight sans pouvoir écraser une intention de la maquette.
 * ------------------------------------------------------------------------ */
.d-page :where(h1, h2, h3, h4, h5, h6) {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}

.d-page :where(p, ul, ol, figure, blockquote, dl, dd) {
  margin: 0;
}

.d-page :where(label) {
  margin: 0;
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}

/* ---------------------------------------------------------------------------
 * FAQ reprise de E1 sur la variante D — raffinements mobiles
 *
 * Les 8 règles `@media (max-width:560px)` qui règlent la FAQ côté E1 sont
 * scopées `.e-page-editorial` : D ne les hérite pas et garderait les tailles
 * desktop sur mobile, avec des `summary` sous la cible tactile de 44 px.
 * Reproduites ici à l'identique, scopées `.d-page`.
 * ------------------------------------------------------------------------ */
@media (max-width: 560px) {
  .d-page .e-faq {
    width: calc(100% - 28px);
    padding: 4px 0 72px;
    gap: 30px;
  }

  .d-page .e-faq-head > span {
    font-size: 11px;
  }

  .d-page .e-faq-head h2 {
    font-size: 38px;
  }

  .d-page .e-faq-head p {
    margin-top: 18px;
    font-size: 16px;
  }

  .d-page .e-faq-head > a {
    min-height: 44px;
    margin-top: 16px;
    font-size: 14px;
  }

  .d-page .e-faq-list summary {
    min-height: 80px;
    padding: 18px 0;
    grid-template-columns: 28px 1fr 32px;
    gap: 10px;
    font-size: 19px;
  }

  .d-page .e-faq-list summary > span {
    font-size: 10px;
  }

  .d-page .e-faq-list details > p {
    margin: -2px 0 0 38px;
    padding: 0 38px 22px 0;
    font-size: 16px;
  }
}

/* ---------------------------------------------------------------------------
 * Schéma de parcours repris de E1 sur la variante D
 *
 * Le markup est identique à E1, mais deux familles de règles ne s'appliquent
 * pas ici :
 *   1. celles qui exigent l'ancêtre `.e-reality` (le cadre blanc du bloc) —
 *      la section de D s'appelle `.d-reality` ;
 *   2. les 33 règles scopées `.e-page-editorial` (typographie, 860 px, 560 px)
 *      qui portent TOUTE la mise en page mobile : sans elles le rail reste
 *      horizontal sur 6 colonnes et déborde de l'écran.
 * Reproduites à l'identique, scopées `.d-page`.
 * ------------------------------------------------------------------------ */
.d-page .d-reality .e-journey {
  margin-top: 24px;
  padding: 30px 30px 27px;
  border-color: rgba(203, 213, 225, .86);
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 24px 60px rgba(15, 23, 42, .08);

  /* `.d-reality` est une GRILLE côté D (un bloc côté E1) : le schéma y est donc
   * un élément de grille, dont le `min-width`/`min-height` implicite vaut
   * `auto` = min-content, et non 0. Aucun effet visible aujourd'hui, mais c'est
   * le débordement horizontal classique dès qu'un contenu refuse de rétrécir.
   * Les remettre à 0 aligne D sur les valeurs calculées d'E1. */
  min-width: 0;
  min-height: 0;
}

.d-page .e-journey-head span,
.d-page .e-simple-phases,
.d-page .e-simple-track b,
.d-page .e-simple-lanes span b {
  font-size: 12px;
}

.d-page .e-simple-track small,
.d-page .e-simple-lanes span small,
.d-page .e-simple-lane-vefa > i > b {
  font-size: 11px;
}

@media (max-width: 860px) {
  .d-page .d-reality .e-journey {
    overflow: visible;
  }

  .d-page .e-simple-journey {
    min-width: 0;
  }
}

@media (max-width: 560px) {
  .d-page .d-reality .e-journey {
    margin-top: 18px;
    padding: 22px 18px;
    overflow: visible;
  }

  .d-page .e-journey-head {
    margin-bottom: 26px;
  }

  .d-page .e-journey-head span {
    font-size: 11px;
  }

  .d-page .e-journey-head h3 {
    font-size: 26px;
    line-height: 1.05;
  }

  .d-page .e-journey-head > p {
    font-size: 15px;
  }

  .d-page .e-simple-phases {
    display: none;
  }

  .d-page .e-simple-track {
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
  }

  .d-page .e-simple-track::before {
    width: 4px;
    height: auto;
    left: 25px;
    right: auto;
    top: 27px;
    bottom: 27px;
    background: linear-gradient(180deg, #93c5fd 0%, #3498db 38%, #ff7a45 58%, #ff4000 100%);
  }

  .d-page .e-simple-track > span {
    min-height: 82px;
    display: grid;
    grid-template-columns: 54px 1fr;
    grid-template-rows: auto auto;
    justify-items: start;
    align-content: center;
    column-gap: 14px;
    text-align: left;
  }

  .d-page .e-simple-track i {
    grid-column: 1;
    grid-row: 1 / 3;
    width: 52px;
    height: 52px;
    border-radius: 16px;
  }

  .d-page .e-simple-track b {
    grid-column: 2;
    margin-top: 7px;
    font-size: 14px;
  }

  .d-page .e-simple-track small {
    grid-column: 2;
    margin-top: 2px;
    font-size: 12px;
  }

  .d-page .e-simple-lanes {
    margin-top: 20px;
    padding: 14px;
  }

  .d-page .e-simple-lanes > div {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .d-page .e-simple-lanes span b {
    font-size: 13px;
  }

  .d-page .e-simple-lanes span small {
    font-size: 12px;
  }

  .d-page .e-simple-lanes > div > i {
    height: 22px;
  }

  .d-page .e-simple-lane-vefa > i > b {
    overflow: hidden;
    font-size: 10px;
    white-space: nowrap;
  }

  .d-page .e-journey-warning {
    margin-top: 20px;
    padding: 17px;
    grid-template-columns: 40px 1fr;
    align-items: start;
    gap: 12px;
    border-radius: 12px;
  }

  .d-page .e-journey-warning > span {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    font-size: 18px;
  }

  .d-page .e-journey-warning small {
    font-size: 10px;
    line-height: 1.35;
  }

  .d-page .e-journey-warning strong {
    margin-top: 7px;
    font-size: 19px;
  }

  .d-page .e-journey-warning p {
    grid-column: 1 / -1;
    font-size: 15px;
  }
}

/* ---------------------------------------------------------------------------
 * FAQ — contenu riche venu de l'admin
 *
 * Le prototype livrait des réponses en dur : un paragraphe, jamais autre chose.
 * Elles viennent maintenant de `FAQItem.answer` (CKEditor), donc un éditeur
 * peut légitimement poser une liste, un lien ou du gras — que le CSS d'origine
 * ne prévoit pas et qui sortirait sans style. On aligne ces cas sur la mise en
 * forme du paragraphe existant (`.e-faq-list details > p`) plutôt que d'ouvrir
 * un nouveau langage visuel.
 * ------------------------------------------------------------------------ */
.d-page .e-faq-list details > ul,
.d-page .e-faq-list details > ol {
  max-width: 650px;
  margin: -6px 54px 0;
  padding: 0 0 26px 20px;
  color: var(--d-muted);
  font-size: 17px;
  line-height: 1.58;
}

.d-page .e-faq-list details > ul > li,
.d-page .e-faq-list details > ol > li {
  margin-bottom: 6px;
}

/* Deux paragraphes de suite : la marge négative du premier (qui le recolle au
 * summary) creuserait un chevauchement sur les suivants. */
.d-page .e-faq-list details > p ~ p {
  margin-top: 0;
  padding-top: 0;
}

.d-page .e-faq-list details a {
  color: var(--d-blue);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/*---------------------------------------------------------------------------
 * Visuel de tête « photo cadrée » — transposition de scope
 *
 * La composition livrée (source/page.tsx, route /version-e1) est stylée
 * sous `.e-page-editorial`, la racine du prototype E1. Notre page a pour
 * racine `.d-page` : sans ces copies, le hero sortirait NON STYLÉ.
 * C'est le même piège que pour le CTA du header, le burger, la FAQ et le
 * schéma de parcours — cinquième occurrence.
 *
 * Copies conformes des règles d'origine, seul le scope change. Ne pas les
 * modifier ici : corriger la source puis retransposer.
 ---------------------------------------------------------------------------*/
.d-page .e-hero {
  background:
    radial-gradient(circle at 78% 55%, rgba(255, 64, 0, .09), transparent 23%),
    linear-gradient(90deg, rgba(52, 152, 219, .07) 0%, rgba(52, 152, 219, .025) 47%, transparent 47%),
    linear-gradient(135deg, #eff6ff 0%, #fff 55%, #fff7ed 100%);
}
.d-page .e-hero-copy, .d-page .e-editorial-media {
  transform: translateY(clamp(-72px, -7vh, -42px));
}

@media (max-width: 860px) {
  .d-page .e-hero-copy, .d-page .e-editorial-media {
    transform: none;
  }
  .d-page .e-hero, .d-page .d-hero {
    height: auto;
    min-height: 0;
  }
  .d-page .e-editorial-inner {
    height: auto;
    min-height: 0;
    padding-bottom: 48px;
    gap: 30px;
  }
}

@media (max-width: 560px) {
  .d-page .e-editorial-inner {
    width: calc(100% - 28px);
    padding: 44px 0 32px;
    gap: 22px;
  }
  .d-page .e-hero h1 {
    margin: 20px 0 18px;
    font-size: 42px;
    line-height: .98;
  }
  .d-page .e-hero-copy > p {
    margin-bottom: 22px;
    font-size: 17px;
    line-height: 1.5;
  }
  .d-page .e-editorial-media {
    width: 100%;
    height: 300px;
    min-height: 0;
  }
  .d-page .e-photo-frame {
    width: 92%;
    padding: 7px;
    border-radius: 9px 20px 9px 20px;
    box-shadow: 0 20px 48px rgba(15, 23, 42, .14);
  }
  .d-page .e-photo-frame img {
    aspect-ratio: 4 / 3;
    border-radius: 5px 15px 5px 15px;
  }
  .d-page .e-conversation-card {
    width: 84%;
    left: 1%;
    bottom: -2px;
    padding: 12px;
    transform: rotate(-1deg);
  }
  .d-page .e-conversation-card > small, .d-page .e-neighbor-summary span, .d-page .e-message-preview p > span, .d-page .e-message-preview > a {
    font-size: 11px;
  }
  .d-page .e-neighbor-summary strong, .d-page .e-message-preview strong {
    font-size: 13px;
  }
  .d-page .e-editorial-inner {
    padding-bottom: 42px;
  }
  .d-page .e-editorial-media {
    height: auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    overflow: hidden;
    border: 1px solid rgba(203, 213, 225, .92);
    border-radius: 18px;
    background: #fff;
    box-shadow: 0 22px 52px rgba(15, 23, 42, .14);
  }
  .d-page .e-photo-frame {
    width: 100%;
    margin: 0;
    padding: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    transform: none;
  }
  .d-page .e-photo-frame img {
    width: 100%;
    height: 218px;
    aspect-ratio: auto;
    border-radius: 0;
    object-position: 68% 42%;
  }
  .d-page .e-conversation-card {
    position: relative;
    width: 100%;
    left: auto;
    bottom: auto;
    padding: 16px;
    border: 0;
    border-top: 1px solid var(--d-border);
    border-radius: 0;
    box-shadow: none;
    transform: none;
  }
  .d-page .e-neighbor-summary {
    padding-block: 12px;
  }
}

/* ---------------------------------------------------------------------------
 * « Qui est derrière VefaConnect » — section ajoutée hors livrable
 *
 * Le prototype n'a pas de bloc « à propos ». Ces classes sont donc PROPRES au
 * site (elles n'existent dans aucune feuille du handoff) et vivent ici, jamais
 * dans 04/05 dont le contenu est comparé octet à octet avec la livraison.
 *
 * Aucun langage visuel nouveau : mêmes tokens, même serif éditoriale pour le
 * titre, même ombre teintée slate que les cartes de la page (jamais de noir
 * pur, cf. les règles de marque du message de livraison).
 * ------------------------------------------------------------------------ */
.d-page .d-about {
  width: min(1200px, calc(100% - 48px));
  margin: 0 auto;
  padding: 78px 0 4px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 54px;
}

.d-page .d-about-copy h2 {
  margin: 14px 0 18px;
  font-family: Charter, "Bitstream Charter", "PT Serif", Georgia, serif;
  font-size: 38px;
  line-height: 1.12;
  letter-spacing: -.04em;
  color: var(--d-slate);
}

.d-page .d-about-copy h2 em {
  font-style: italic;
  color: var(--d-blue-deep);
}

.d-page .d-about-copy p {
  max-width: 620px;
  margin: 0 0 12px;
  color: var(--d-muted);
  font-size: 17px;
  line-height: 1.62;
}

.d-page .d-about-copy strong {
  color: var(--d-slate);
  font-weight: 750;
}

/* Carte auteur : le visage est le signal de confiance, il porte donc la carte. */
.d-page .d-about-card {
  width: 300px;
  padding: 26px;
  display: grid;
  justify-items: center;
  gap: 16px;
  border: 1px solid var(--d-border);
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 24px 60px rgba(15, 23, 42, .08);
  text-align: center;
}

.d-page .d-about-card img {
  width: 116px;
  height: 116px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
}

.d-page .d-about-card strong {
  display: block;
  font-family: var(--ui);
  font-size: 17px;
  font-weight: 850;
  letter-spacing: -.02em;
  color: var(--d-slate);
}

.d-page .d-about-card small {
  display: block;
  margin-top: 5px;
  color: var(--d-muted);
  font-family: var(--ui);
  font-size: 12px;
  line-height: 1.45;
}

.d-page .d-about-card a {
  margin-top: 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--d-orange);
  font-family: var(--ui);
  font-size: 13px;
  font-weight: 800;
  text-decoration: none;
}

.d-page .d-about-card a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 860px) {
  .d-page .d-about {
    padding-top: 58px;
    grid-template-columns: 1fr;
    justify-items: start;
    gap: 32px;
  }

  .d-page .d-about-copy h2 { font-size: 32px; }
}

@media (max-width: 560px) {
  .d-page .d-about {
    width: calc(100% - 28px);
    padding-top: 44px;
    gap: 26px;
  }

  .d-page .d-about-copy h2 { font-size: 27px; }
  .d-page .d-about-copy p { font-size: 15px; }

  /* La carte prend toute la largeur : à 300 px fixes elle laissait une
   * gouttière asymétrique une fois la grille passée en colonne. */
  .d-page .d-about-card {
    width: 100%;
    padding: 22px;
  }
}

/* Cible tactile du lien de la carte auteur : 21 px de haut en texte inline,
 * sous le minimum de 44 px. On élargit la zone cliquable au doigt sans toucher
 * au rendu à la souris — inutile de reproduire dans du code neuf le défaut
 * relevé sur la navbar mobile du site. */
@media (pointer: coarse) {
  .d-page .d-about-card a {
    min-height: 44px;
    padding: 0 8px;
  }
}

/* ---------------------------------------------------------------------------
 * LOT 2 — allègement homepage + mise en avant de la carte 3D (2026-08-18)
 *
 * Quatre chantiers, documentés chacun sous son propre en-tête ci-dessous :
 *   A. Duo de cartes phares dans `d-tools` (Studio 3D + Carte 3D)
 *   B. `.d-mini-tools` en grille 2×2 compacte sous 700 px
 *   C. `.d-promoter` en bannière compacte (une colonne)
 *   D. `.d-audiences` allégée (un item + un mockup retirés par carte)
 * ------------------------------------------------------------------------ */

/* ---------------------------------------------------------------------------
 * A. Duo de cartes phares — Studio 3D / Carte 3D (`#d-tools`)
 *
 * Le prototype livré n'a qu'UNE carte phare (`.d-studio-card`) à côté des
 * `.d-mini-tools` : `.d-product-grid` est une grille à 2 colonnes inégales
 * (1.15fr / .85fr) taillée pour CE couple précis. Elle n'a pas de place pour
 * un 3ᵉ bloc du même gabarit que le studio sans se réduire — on la bascule
 * donc en UNE colonne : les deux cartes phares en pleine largeur, l'une sous
 * l'autre, `.d-mini-tools` restant après (dernier enfant du DOM). Sous
 * 1120 px, `.d-product-grid` était déjà en 1 colonne (règle livrée,
 * `04-version-d.css`) : la bascule y est transparente, rien à faire.
 *
 * Conséquence à corriger : en pleine largeur, `.d-mini-tools` (qui vivait
 * dans la colonne étroite .85fr, ~480 px) passerait à 591 px par outil avec
 * son `grid-template-columns: 1fr 1fr` livré. On la repasse à 4 colonnes au
 * même point de rupture que la maquette (`repeat(4, 1fr)`, déjà le
 * comportement livré sous 1120 px) pour que les 4 outils tiennent sur une
 * ligne au lieu de s'étaler.
 *
 * `.d-carte-card` est une classe PROPRE au site (aucune feuille livrée ne la
 * connaît, comme `.d-about*`) : même anatomie que `.d-studio-card`
 * (copy + visuel), mêmes valeurs de structure, tokens `--d-*`/`--vefa-*` à la
 * place des hex dupliqués du livrable.
 * ------------------------------------------------------------------------ */
.d-page .d-product-grid {
  grid-template-columns: 1fr;
  gap: 22px;
}

@media (min-width: 1121px) {
  .d-page .d-mini-tools {
    grid-template-columns: repeat(4, 1fr);
  }
}

.d-page .d-carte-card {
  min-height: 650px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .26);
  border-radius: 24px;
  background: var(--vefa-bg);
  color: var(--d-slate) !important;
  box-shadow: var(--vefa-shadow-lg);
  transition: transform 350ms var(--vefa-ease);
}

.d-page .d-carte-card:hover {
  transform: translateY(-7px);
}

.d-page .d-carte-copy {
  padding: 32px;
}

.d-page .d-carte-copy > span {
  color: var(--d-orange-dark);
  font-family: var(--ui);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .1em;
}

.d-page .d-carte-copy h3 {
  max-width: 620px;
  margin: 12px 0 14px;
  font-family: var(--serif-heading);
  font-size: 39px;
  letter-spacing: -.04em;
  line-height: 1;
}

.d-page .d-carte-copy p {
  max-width: 580px;
  margin: 0;
  color: var(--d-muted);
  font-size: 16px;
  line-height: 1.52;
}

.d-page .d-carte-copy > b {
  margin-top: 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--ui);
  font-size: 11px;
}

.d-page .d-carte-copy > b i {
  color: var(--d-orange);
  font-size: 17px;
  font-style: normal;
}

/* Visuel : capture réelle du produit (website/images/home_e1/carte3d-quartier.webp),
 * même anatomie que `.d-studio-image` juste au-dessus dans le DOM (conteneur
 * relatif + `<img>` en `object-fit: cover`). Pas de badge « 3D » en
 * surimpression : la capture montre déjà le bouton 3D actif dans son UI, un
 * badge dupliquerait l'information. `alt` descriptif car l'image porte
 * l'information (plus d'`aria-hidden`, contrairement à l'ancien mockup CSS). */
.d-page .d-carte-visual {
  position: relative;
  /* Ratio ALIGNÉ sur celui de la capture (1440×998) : `object-fit: cover` ne
   * rogne alors rien — la fiche programme et la barre d'ensoleillement, qui
   * portent tout le message de la carte, restent entières à toute largeur. */
  aspect-ratio: 1440 / 998;
  min-height: 315px;
  margin-top: auto;
  overflow: hidden;
  border-top: 1px solid var(--d-border);
  background: var(--vefa-gradient-hero);
}

.d-page .d-carte-visual img {
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0;
  display: block;
  object-fit: cover;
  object-position: center;
}

@media (max-width: 560px) {
  .d-page .d-carte-card {
    min-height: 0;
  }

  .d-page .d-carte-copy {
    padding: 24px;
  }

  .d-page .d-carte-copy h3 {
    font-size: 32px;
  }

  .d-page .d-carte-visual {
    min-height: 220px;
  }
}

/* ---------------------------------------------------------------------------
 * B. `.d-mini-tools` en grille 2×2 compacte sur mobile
 *
 * Sous 560 px, la règle livrée passe `.d-mini-tools` à 1 seule colonne
 * (`04-version-d.css`) : les 4 outils s'empilent verticalement sur ~4 écrans
 * de hauteur. On force 2 colonnes dès 700 px, avec un padding resserré et le
 * `p` descriptif masqué — chaque tuile reste un LIEN ≥ 44 px de haut, avec
 * son icône et son titre lisibles, ce qui suffit à l'identifier et l'atteindre
 * au doigt.
 * ------------------------------------------------------------------------ */
@media (max-width: 700px) {
  .d-page .d-mini-tools {
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }

  .d-page .d-mini-tools > a {
    min-height: 44px;
    padding: 16px 14px;
  }

  .d-page .d-mini-icon {
    width: 34px;
    height: 34px;
    font-size: 13px;
  }

  .d-page .d-mini-tools small {
    margin-top: 12px;
    font-size: 9px;
  }

  .d-page .d-mini-tools h3 {
    margin: 6px 0 0;
    font-size: 16px;
  }

  .d-page .d-mini-tools p {
    display: none;
  }

  .d-page .d-mini-tools b {
    margin-top: 12px;
    padding-top: 10px;
    font-size: 10px;
  }
}

/* ---------------------------------------------------------------------------
 * C. `.d-promoter` en bannière compacte
 *
 * Le markup a perdu ses deux blocs décoratifs (`.d-pro-visual`, 3 panneaux ;
 * `.d-pro-features`, 4 items) — l'id `#d-promoter` (ancre du menu du site),
 * le kicker, le h2, le paragraphe et les DEUX liens restent seuls dans
 * `.d-pro-copy`. La grille 2 colonnes livrée (`.9fr 1.1fr`) et son
 * `min-height: 620px` visaient le visuel disparu : sans ce delta, `.d-pro-copy`
 * resterait coincée dans la colonne étroite avec une bande vide en dessous.
 * On repasse la section en UNE colonne, padding réduit à chaque palier déjà
 * découpé par le livrable (défaut, 1120, 860, 560).
 * ------------------------------------------------------------------------ */
.d-page .d-promoter {
  grid-template-columns: 1fr;
  min-height: 0;
  padding: 56px 64px;
}

.d-page .d-pro-copy {
  max-width: 760px;
}

@media (max-width: 1120px) {
  .d-page .d-promoter {
    padding: 46px 40px;
  }
}

@media (max-width: 860px) {
  .d-page .d-promoter {
    padding: 40px 28px;
  }
}

@media (max-width: 560px) {
  .d-page .d-promoter {
    padding: 34px 20px;
  }
}

/* ---------------------------------------------------------------------------
 * D. `.d-audiences` allégée
 *
 * Un `<li>` et son mockup (`.d-lead-card` / `.d-neighbor-card`) retirés par
 * carte côté markup ; les deux CTA restent. Le `min-height` livré (620 px en
 * base, 590 puis 660 px sous 860/560) réservait la place du mockup en
 * position absolue — sans lui, le contenu restant (3 puces + bouton) laisse
 * un vide en bas de carte. On repasse à `min-height: 0` à TOUS les paliers en
 * une seule règle non conditionnelle (spécificité `.d-page .d-audience-grid
 * article` > chacune des 3 déclarations livrées) : la grille étire alors les
 * deux cartes à la hauteur du contenu le plus long, sans les figer sur une
 * valeur pensée pour un mockup qui n'existe plus.
 * ------------------------------------------------------------------------ */
.d-page .d-audience-grid article {
  min-height: 0;
}

/* ---------------------------------------------------------------------------
 * LOT 3 — `d-workflow` en bande numérotée compacte (2026-08-18)
 *
 * Les 3 mockups `.d-step-visual` (`d-program-visual`, `d-neighbor-visual`,
 * `d-tools-visual`) sont retirés du markup : à 375 px, ils portaient à eux
 * seuls la quasi-totalité des ~2391 px de la section, en répétant en CSS ce
 * que `h3` + `p` disent déjà en texte. Chaque `<article>` ne garde plus que
 * `.d-step-meta` (numéro + label), `h3`, `p`.
 *
 * Les cartes livrées réservaient la hauteur du visuel retiré
 * (`min-height: 590 / 570 / 550 px` selon le palier) : sans neutralisation,
 * la grille garderait des cartes hautes et vides. `h3`/`p` n'avaient par
 * ailleurs aucune taille propre — ils héritaient du reset `:where()` plus
 * haut dans ce fichier (`font-size: inherit`) et rendaient à la même taille
 * que le corps de texte, invisible sous les visuels. Les tailles ci-dessous
 * leur donnent la hiérarchie qui manquait, plus nécessaire maintenant que le
 * texte est tout ce que porte la carte.
 *
 * Le numéro agrandi (`.d-step-meta span`) et le bandeau couleur par étape
 * (`::before`, déjà livré, une couleur par colonne) suffisent comme repère de
 * progression — aucun mockup réintroduit.
 * ------------------------------------------------------------------------ */
.d-page .d-workflow-grid article {
  min-height: 0;
  padding: 30px 26px;
}

.d-page .d-workflow-grid article:nth-child(2) {
  transform: none;
}

.d-page .d-step-meta {
  margin-bottom: 16px;
}

.d-page .d-step-meta span {
  font-size: 20px;
}

.d-page .d-workflow-grid article h3 {
  margin: 0 0 10px;
  font-family: var(--serif-heading);
  font-size: 23px;
  line-height: 1.22;
  letter-spacing: -.02em;
  color: var(--d-slate);
}

.d-page .d-workflow-grid article p {
  margin: 0;
  color: var(--d-muted);
  font-size: 15px;
  line-height: 1.52;
}

/* Sous 700 px : la grille 3 colonnes livrée passe déjà à 1 colonne sous
 * 860 px (`04-version-d.css`) — on va plus loin ici et abandonne le langage
 * « carte » (bordure, radius, ombre, fond teinté par étape) pour une liste :
 * chaque étape garde juste son numéro/label au-dessus du texte, séparée de la
 * suivante par un simple filet. Le bandeau couleur du haut devient un filet
 * vertical à gauche (même élément `::before`, seul son positionnement change)
 * — la même info de progression, sans réserver de largeur de carte pour elle. */
@media (max-width: 700px) {
  /* Réduit le vide au-dessus/en dessous de la section elle-même (livré :
   * 95 px de chaque côté, hérité de la règle `.d-workflow, .d-product` à
   * 860 px) — le contenu de `.d-section-head` ne bouge pas, seule la marge
   * qui l'entoure se resserre. */
  .d-page .d-workflow {
    padding: 64px 18px;
  }

  .d-page .d-workflow-grid {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .d-page .d-workflow-grid article {
    min-height: 0;
    padding: 20px 4px 20px 16px;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    /* Neutralise le fond pastel par étape (`.d-step-program` etc., posé en
     * `!important` dans 04-version-d.css) : sans `!important` ici, un
     * `!important` livré gagne toujours face à une déclaration normale, quelle
     * que soit la spécificité. */
    background: var(--vefa-bg) !important;
  }

  .d-page .d-workflow-grid article + article {
    border-top: 1px solid var(--d-border);
  }

  .d-page .d-workflow-grid article:nth-child(2) {
    transform: none;
  }

  .d-page .d-workflow-grid article::before {
    inset: 6px auto 6px 0;
    width: 3px;
    height: auto;
    border-radius: 3px;
  }

  .d-page .d-step-meta {
    margin-bottom: 8px;
  }

  .d-page .d-step-meta span {
    font-size: 16px;
  }

  .d-page .d-step-meta small {
    padding: 4px 8px;
    font-size: 9px;
  }

  .d-page .d-workflow-grid article h3 {
    font-size: 19px;
    line-height: 1.24;
  }

  .d-page .d-workflow-grid article p {
    margin-top: 6px;
    font-size: 14px;
    line-height: 1.48;
  }

  .d-page .d-workflow > .d-button {
    margin-top: 32px;
  }
}

/* ============================================================
   Démonstration « Explorateur du quartier » : section #d-quartier
   ------------------------------------------------------------
   Le « film » n'est ni une vidéo ni de la 3D dans la page : c'est une
   PILE de cinq captures réelles de `/search/?view=map` (Villa Galliéni,
   Asnières-sur-Seine), fondues l'une sur l'autre par `home_quartier.js`.

   Pourquoi une pile empilée plutôt qu'un fondu croisé classique : deux
   images qui se croisent en opacité laissent le fond transparaître au
   milieu du fondu (0,5 × A + 0,5 × B ≠ une image opaque). Ici chaque
   vue se pose PAR-DESSUS la précédente, qui reste opaque en dessous :
   le fondu ne montre jamais le fond. La 6e couche répète la 1re : au
   bouclage, le retrait instantané des couches 1→5 découvre une image
   IDENTIQUE à celle affichée, donc invisible. Sans elle, la boucle
   ferait une coupe franche.

   Les couleurs viennent des variables de la page (`--d-blue` = #3498db
   pour la structure, `--d-orange` = #ff4000 réservé aux actions).
   ============================================================ */

.d-page .q-demo {
  padding: 110px max(24px, calc((100vw - 1200px) / 2));
  background:
    radial-gradient(circle at 12% 12%, rgba(52, 152, 219, .10), transparent 26%),
    linear-gradient(180deg, #fff, #f8fafc);
}

.d-page .q-head { max-width: 900px; }

.d-page .q-head > span {
  color: var(--d-blue-deep);
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.d-page .q-head h2 {
  margin: 15px 0 0;
  color: var(--d-ink);
  font-family: Charter, "Bitstream Charter", "PT Serif", Georgia, serif;
  font-size: clamp(38px, 4.4vw, 60px);
  font-weight: 750;
  letter-spacing: -.04em;
  line-height: 1;
}

.d-page .q-head h2 em { color: var(--d-blue-dark); font-weight: 400; }

.d-page .q-intro {
  max-width: 680px;
  margin: 22px 0 0;
  color: var(--d-muted);
  font-size: 18px;
  line-height: 1.55;
}

.d-page .q-stage {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(300px, 1fr);
  gap: 40px;
  align-items: start;
  margin-top: 48px;
}

/* ---------- Le lecteur ---------- */

.d-page .q-player { margin: 0; }

/* `aspect-ratio` + `width`/`height` sur les images : la boîte occupe sa
   place définitive avant le moindre octet d'image : aucun décalage de
   mise en page pendant le chargement. */
.d-page .q-screen {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--d-border);
  border-radius: 20px;
  background: #f1f5f9;
  box-shadow: 0 24px 60px -28px rgba(15, 23, 42, .35), 0 2px 8px rgba(15, 23, 42, .05);
}

.d-page .q-screen img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Vue statique : seule image chargée sans JavaScript, sur mobile et en
   `prefers-reduced-motion`. Elle s'efface quand la pile prend le relais. */
.d-page .q-static {
  z-index: 8;
  opacity: 1;
  transition: opacity 600ms ease;
}

.d-page .q-player.is-live .q-static { opacity: 0; }

.d-page .q-frames { position: absolute; inset: 0; opacity: 0; }
.d-page .q-player.is-live .q-frames { opacity: 1; }

.d-page .q-frame {
  opacity: 0;
  transition: opacity 900ms ease-in-out;
}

.d-page .q-frame.is-on { opacity: 1; }

/* Deux moments où la bascule doit être INSTANTANÉE, sans fondu :
   le bouclage (cf. en-tête) et le retour forcé à la vue statique (fenêtre
   réduite sous 900 px, `prefers-reduced-motion` activé en cours de route).
   Sans cela, la pile et la vue statique se croiseraient en semi-transparence
   et laisseraient voir le fond de la boîte. */
.d-page .q-player.q-instant .q-frame,
.d-page .q-player.q-instant .q-static { transition: none; }

/* ---------- Le curseur de démonstration ---------- */

.d-page .q-cursor {
  position: absolute;
  left: var(--q-cx, 50%);
  top: var(--q-cy, 50%);
  z-index: 9;
  width: 22px;
  height: 22px;
  margin: -2px 0 0 -2px;
  opacity: 0;
  pointer-events: none;
  background: no-repeat center/contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 2.5 19 12.2l-6.1.9 3.2 6.6-2.6 1.3-3.2-6.6-4.3 4z' fill='%23fff' stroke='%230f172a' stroke-width='1.4' stroke-linejoin='round'/%3E%3C/svg%3E");
  filter: drop-shadow(0 3px 6px rgba(15, 23, 42, .45));
  transition: left 1100ms cubic-bezier(.4, 0, .2, 1), top 1100ms cubic-bezier(.4, 0, .2, 1), opacity 400ms ease;
}

.d-page .q-player.is-live .q-cursor { opacity: 1; }

/* Halo bleu au moment où le curseur « agit » (les deux réglages
   d'éclairage). L'orange reste réservé aux actions de l'utilisateur. */
.d-page .q-cursor::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 42px;
  height: 42px;
  margin: -21px 0 0 -21px;
  border-radius: 50%;
  background: rgba(52, 152, 219, .28);
  opacity: 0;
  transform: scale(.4);
}

.d-page .q-cursor.is-click::before { animation: q-cursor-pulse 1200ms ease-out; }

@keyframes q-cursor-pulse {
  0% { opacity: .9; transform: scale(.35); }
  100% { opacity: 0; transform: scale(1.15); }
}

.d-page .q-legend {
  margin: 14px 2px 0;
  color: var(--d-subtle);
  font-family: var(--ui);
  font-size: 12px;
  line-height: 1.5;
}

/* ---------- Les questions des futurs voisins ---------- */

.d-page .q-steps-title {
  margin: 0 0 16px;
  color: var(--d-slate);
  font-family: var(--ui);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .02em;
}

.d-page .q-steps {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: q-step;
}

.d-page .q-step {
  position: relative;
  margin: 0 0 10px;
  padding: 14px 16px 14px 46px;
  border: 1px solid var(--d-border);
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
  counter-increment: q-step;
  transition: border-color 300ms ease, box-shadow 300ms ease, background 300ms ease;
}

.d-page .q-step::before {
  content: counter(q-step);
  position: absolute;
  left: 14px;
  top: 14px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #eef2f7;
  color: var(--d-muted);
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 800;
  transition: background 300ms ease, color 300ms ease;
}

.d-page .q-step.is-current {
  border-color: rgba(52, 152, 219, .55);
  background: rgba(52, 152, 219, .05);
  box-shadow: 0 10px 24px -16px rgba(52, 152, 219, .9);
}

.d-page .q-step.is-current::before { background: var(--d-blue); color: #fff; }

.d-page .q-step p { margin: 0; }

.d-page .q-step-q {
  color: var(--d-slate);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
}

.d-page .q-step-a {
  margin-top: 5px !important;
  color: var(--d-muted);
  font-family: var(--ui);
  font-size: 13.5px;
  line-height: 1.5;
}

/* ---------- Chute + actions ---------- */

.d-page .q-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  margin-top: 22px;
}

.d-page .q-cta-note {
  flex: 1 1 100%;
  margin: 0 0 4px;
  color: var(--d-muted);
  font-size: 16px;
  line-height: 1.5;
}

.d-page .q-cta-main {
  display: inline-flex;
  gap: 10px;
  align-items: center;
  padding: 15px 24px;
  border-radius: 999px;
  background: var(--d-orange);
  color: #fff;
  font-family: var(--ui);
  font-size: 15px;
  font-weight: 700;
  transition: background 200ms ease, transform 200ms ease;
}

.d-page .q-cta-main:hover { background: var(--d-orange-dark); transform: translateY(-1px); }

.d-page .q-cta-alt {
  display: inline-flex;
  gap: 8px;
  align-items: center;
  padding: 15px 22px;
  border: 1px solid var(--d-blue);
  border-radius: 999px;
  color: var(--d-blue-deep);
  font-family: var(--ui);
  font-size: 15px;
  font-weight: 700;
  transition: background 200ms ease;
}

.d-page .q-cta-alt:hover { background: rgba(52, 152, 219, .08); }

/* ---------- Sous 900 px : la section ne s'affiche pas ----------
   Décision produit (2026-08-19) : la démonstration repose sur la lecture
   d'une capture d'écran d'application. Réduite à la largeur d'un téléphone,
   la carte devient illisible, et il ne reste qu'une vignette floue au-dessus
   d'une liste de cinq questions.

   `display: none` sur la section entière, et non un simple masquage du
   lecteur : c'est aussi ce qui garantit qu'aucune des images n'est
   téléchargée (une image `loading="lazy"` sous un ancêtre non rendu n'est
   jamais demandée). Le mobile ne paie donc rien pour cette section, ni en
   octets ni en pixels.

   ⚠️ Le texte de la section reste dans le HTML : Google indexant en
   mobile-first, il le lira sans le compter comme contenu visible. C'est
   assumé pour de la copie promotionnelle, ce ne le serait pas pour du
   contenu SEO. */

@media (max-width: 899px) {
  .d-page .q-demo { display: none; }
}

/* Mouvement réduit : la pile et le curseur restent en retrait, la vue
   statique tient la place. `home_quartier.js` applique la même règle en
   amont (il ne passe jamais en lecture), celle-ci est le filet CSS. */
@media (prefers-reduced-motion: reduce) {
  .d-page .q-player.is-live .q-static { opacity: 1; }
  .d-page .q-player.is-live .q-frames { opacity: 0; }
  .d-page .q-cursor { display: none; }
  .d-page .q-frame,
  .d-page .q-step { transition: none; }
}
