/* ==========================================================================
   correctifs.css — Premiere.Page
   --------------------------------------------------------------------------
   Correctifs responsive issus du « Rapport responsive Premiere.Page »
   (27 août 2026 — 37 URLs, 571 captures en 390x844, contre-vérifié iPhone 15),
   après vérification de chaque constat dans le DOM réel et dans la cascade.

   Chargé EN DERNIER, après common.css et après la feuille de template :
   à spécificité égale il l'emporte par l'ordre source, sans !important.
   Chaque !important présent ne sert qu'à battre un !important existant,
   et il est justifié en commentaire.

   RÈGLE : sauf les trois blocs marqués « GLOBAL », tout est enfermé dans une
   media query max-width et ne peut donc pas toucher le rendu desktop.

   --------------------------------------------------------------------------
   CONSTATS DU RAPPORT ÉCARTÉS APRÈS VÉRIFICATION (ne rien écrire pour eux) :

   - « 13 tableaux plus larges que l'écran, dont 9 sans moyen d'y accéder »
     FAUX. common.css:3850 applique déjà, à <=1024px :
       table { display:block; overflow-x:auto; -webkit-overflow-scrolling:touch }
     complété par common.css:3875 (td,th{min-width:300px}). Les 9 tableaux dits
     inaccessibles ont été mesurés en live : tous en display:block, overflow-x
     auto|scroll, scrollLeft effectif > 0. Le rapport cherchait un PARENT
     défilant ; c'est le <table> lui-même qui l'est.
     Rajouter la règle ici la ferait fuiter sur desktop et casserait px-compare.

   - « Effondrement vertical du tableau px-compare (360x2690) »
     FAUX. C'est un empilement volontaire en cartes sticky,
     cms-fille.css:1426-1521, avec main:has(.acf-table.px-compare){overflow:clip}
     posé exprès pour préserver le sticky. Toute règle table le casserait.

   - « Grilles multi-colonnes : paragraphes de 45px » sur /agence-seo-camping/
     et /agence-seo-shopify/
     FAUX sur ces deux pages. common.css:4682 (.container.cards .card
     {max-width:none}, 0,3,0) gagne déjà. Mesuré à 375px : 6 cartes de 301px
     empilées, aucun chevauchement. Seul /ressources/ est réellement touché
     (voir bloc J) — plus /author/*, que le rapport n'avait pas vu.

   - « Cartes de carrousel de 475px » causées par width:1135px !important
     FAUX quant à la cause. common.css:3891 pose
       .carrousel-texte-image div.carrousel-item { width:auto !important }
     (0,2,1) qui bat le 1135px (0,2,0). Les vraies causes sont les marges
     et le slick-list en overflow:visible (voir bloc H).

   - expertise.css:42/:95 « width:770px » et prestations.css:34/:85
     FAUX : sélecteurs morts. ACF insère un div.acf-innerblocks-container
     entre .expertise-first et ses enfants, le combinateur « > » ne matche rien.

   - expertise.css:153 « min-width:450px »
     FAUX : neutralisé par common.css:3882 (min-width:300px !important à <=1024).
   ========================================================================== */


/* ==========================================================================
   A · P0 — EN-TÊTE : bouton de menu invisible, logo perdu au défilement
   --------------------------------------------------------------------------
   « button.burger-menu mesure 40x40 et ses trois barres prennent une couleur
   fixe selon la page. Sur /audit-seo/gratuit/ et /blog/ elles sont en #1B1B1B,
   posées sur un en-tête qui devient noir au défilement : contraste 1:1. »

   Cause racine vérifiée :
   - le burger est injecté en JS dans .header-first
     (assets/js/scripts-animations.js:588-597)
   - au défilement vers le haut au-delà de 600px, .header-first reçoit la
     classe "sticky" et passe en background #1b1b1b (common.css:1378-1384)
   - common.css:1386 fait bien `.header-first.sticky * { color: white }`
     MAIS les barres sont peintes en `background`, pas en `color` : la règle
     ne les atteint pas.
   - trois feuilles de template posent #1B1B1B sans contrepartie sticky :
     contact.css:264, pre-audit.css:897, single.css:590.
     categorie.css:860 est la seule à prévoir `.sticky .burger-menu span`.
   ========================================================================== */

@media (max-width: 1024px) {

  /* L'en-tête réduit a un fond #1b1b1b : barres claires, tous templates.
     !important : bat contact.css / pre-audit.css / single.css, de même
     spécificité mais chargés avant. */
  .header-first.sticky .burger-menu span {
    background: #FCFAF4 !important;
  }

  /* /notre-agence/ : agence.css ne pose aucune couleur, le défaut
     common.css:3344 (#fff) s'applique sur un héros anis clair.
     Mesuré : barres rgb(255,255,255) sur fond anis = invisibles. */
  body.page-template-page-agence .header-first:not(.sticky) .burger-menu span {
    background: #1B1B1B !important;
  }

  /* Aucun état visible au clavier auparavant. */
  .burger-menu:focus-visible {
    outline: 2px solid #8F86FA;
    outline-offset: 3px;
  }

  /* Le logo mobile est un FRÈRE de .header-first (templates/header.twig:58),
     en position:absolute (common.css:2977). Quand .header-first passe en
     position:fixed, le logo reste dans le flux et disparaît vers le haut :
     plus de logo, plus de burger lisible, plus aucune navigation.
     On le fixe avec l'en-tête réduit. */
  .header-first.sticky ~ .logo-mobile {
    position: fixed;
    top: 6px;
    left: 20px;
    z-index: 10001;
  }

  .header-first.sticky ~ .logo-mobile img {
    width: 44px;
    height: auto;
  }
}

/* NON TRAITÉ ICI — « le logo desktop a.logo n'est pas masqué mais déplacé à
   left:-844px, il reste dans l'ordre de tabulation » (aside du constat 01).
   Vérification faite, ce n'est PAS un défaut mobile : sous 1024px, nav.menu est
   un panneau plein écran sorti de l'écran par transform (common.css:3152-3170)
   et `nav.menu .logo` y est le logo LÉGITIME du menu ouvert, à top:20px/left:30px
   (common.css:3182). Le left:-844px relève du rendu desktop, où toute
   intervention sortirait du cadre « ne pas modifier le desktop ».
   À traiter à la source, dans common.css. Voir la note de livraison. */


/* ==========================================================================
   B · P0 — AUDIT FLASH RANXPLORER : le résultat s'affiche hors de l'écran
   --------------------------------------------------------------------------
   « La colonne de gauche est écrasée à 0px, la colonne de droite mesure 400px
   et va de x=32 à x=432 dans un écran qui s'arrête à 390. Le bouton
   "Demander un devis SEO gratuit" finit à x=411. »

   Cause racine confirmée : ranxplorer-tool.css (plugin) ne contient QUE les
   media queries mobiles ; le thème duplique ensuite les règles DESKTOP du même
   composant, à spécificité identique (0,1,0) mais plus loin dans l'ordre
   source. Une media query n'ajoutant pas de spécificité, toute la couche
   mobile du plugin est battue.

   Déclaré dans QUATRE feuilles, pas une :
     pre-audit.css:526        /audit-seo/gratuit/
     agence-seo.css:549       /agence-seo/
     agence-seo-ville.css:836 pages ville (/agence-seo/bordeaux/…)
     cms-fille.css:755        /cms-seo/agence-seo-shopify/
   Ce fichier étant chargé après les quatre, un seul bloc les couvre toutes.

   Mesures live à 375px, arbre de résultats injecté dans le vrai conteneur :
     .ranxplorer-results-grid   -> grid-template-columns: 0px 400px
     .ranxplorer-right-column   -> width 400px, rect L=56 R=456 (81px hors écran)
     .ranxplorer-table-container-> overflow-x:hidden, width 2px (!) : le tableau
                                   de mots-clés est totalement masqué
     .ranxplorer-table-row      -> grid 0px 120px 100px : les mots-clés
                                   disparaissent, Volume/Position sont clippés
   Le champ URL et le bouton « Tester votre site » sont sains : ils sont sauvés
   par un <style> inline du bloc ACF. Ce <style> ne couvre rien de la zone
   résultats.

   Aucun !important : la victoire vient de l'ordre source. Le desktop est
   protégé par le @media (min-width:901px) du plugin.
   ========================================================================== */

@media (max-width: 900px) {
  .ranxplorer-results-grid {
    grid-template-columns: 1fr;
    gap: 24px;
  }

  .ranxplorer-right-column { width: 100%; }
  .ranxplorer-left-column  { min-width: 0; }

  .ranxplorer-chart-container {
    max-width: 100%;
    margin: 0 auto;
  }
}

@media (max-width: 768px) {
  /* width:2px + overflow hidden -> le tableau était invisible ET inatteignable */
  .ranxplorer-table-container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .ranxplorer-table-header,
  .ranxplorer-table-row {
    grid-template-columns: minmax(120px, 1fr) 70px 55px;
    gap: 8px;
    padding: 10px 8px;
    min-width: 280px;
  }

  .ranxplorer-keyword {
    font-size: 13px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .ranxplorer-traffic-table {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .ranxplorer-traffic-table-header,
  .ranxplorer-traffic-row {
    grid-template-columns: minmax(140px, 1fr) 80px;
    gap: 8px;
    padding: 8px 10px;
    min-width: 240px;
  }

  .ranxplorer-site-cell {
    max-width: none;
    min-width: 0;
  }

  .ranxplorer-chart-container {
    max-width: 280px;
    height: 200px;
  }

  /* Le bouton de devis débordait de 21px. */
  .ranxplorer-cta,
  .ranxplorer-cta-right {
    width: 100%;
    max-width: 100%;
  }

  .ranxplorer-cta-button {
    width: 100%;
    box-sizing: border-box;
    white-space: normal;
    text-align: center;
  }
}

@media (max-width: 480px) {
  .ranxplorer-table-header,
  .ranxplorer-table-row {
    grid-template-columns: 1fr 60px 45px;
    gap: 6px;
    padding: 8px 6px;
    min-width: 260px;
  }

  .ranxplorer-traffic-table-header,
  .ranxplorer-traffic-row {
    grid-template-columns: minmax(120px, 1fr) 70px;
    gap: 6px;
    padding: 6px 8px;
    min-width: 220px;
  }

  .ranxplorer-chart-container {
    max-width: 260px;
    height: 180px;
  }
}


/* ==========================================================================
   C · P0 — PIED DE PAGE : les liens « Nos expertises » en display:none
   --------------------------------------------------------------------------
   « Le <ul> est en display:none et ses liens mesurent 0px de haut. Sur les
   37 pages, le visiteur mobile perd l'accès aux pages d'expertise et le
   maillage interne ne se transmet pas. »

   Sélecteur réel relevé dans le DOM : div.menu-expertises > ul.menu-footer
   (le rapport proposait .footer-col--expertises, qui n'existe pas).
   Vérifié : 7 items, display:none, hauteur 0. Après correctif : hauteur 212px.
   ========================================================================== */

@media (max-width: 768px) {
  .menu-expertises ul.menu-footer {
    display: block;
  }
}


/* ==========================================================================
   D · P0 — /ressources/ et /author/* : la grille de listing hors cadre
   --------------------------------------------------------------------------
   « Sur la page ressources, la colonne de gauche sort de l'écran et les titres
   de la colonne de droite débordent de leurs cartes. »

   Seul vrai cas de « grille multi-colonnes non repliée » du rapport.
   Règles fautives :
     categorie.css:180-190  .ressource-item{display:flex;width:calc(33% - 11px);
                            height:390px}  -> largeur calculée 104.83px à 375px
     categorie.css:202-206  .ressource-content{position:absolute;top:105px;
                            left:65px}     -> 40px utiles dans une carte de 105
     categorie.css:208-216  .ressource-title{max-width:300px}
                                           -> titre 63 à 77px hors carte
   categorie.css n'a qu'UNE @media (ligne 856) qui ne concerne que le burger.
   La largeur étant en %, aucune règle générique de common.css ne la neutralise.

   PORTÉE ÉLARGIE : author.css:116-126 porte la règle à l'identique et n'a
   AUCUNE @media -> toutes les pages /author/* sont touchées aussi. Absent du
   rapport, confirmé sur 6 .ressource-item.
   /videos/ n'est PAS touché : archive-videos.twig sort des .video-card sans
   .ressource-item (les règles de video.css sont du code mort).

   Mesuré après correctif : cartes 351px, x=12, débordement vertical 0,
   titre à -24px du bord, scrollWidth 375. Aucun !important nécessaire.
   ========================================================================== */

@media (max-width: 768px) {
  .ressources-list {
    padding-left: 20px;
    padding-right: 20px;
    gap: 16px;
  }

  .ressources-list .ressource-item {
    width: 100%;
    height: auto;
    min-height: 0;
  }

  .ressources-list .ressource-content {
    position: static;
    padding: 28px 24px 76px;
  }

  .ressources-list .ressource-title {
    max-width: none;
    font-size: 20px;
  }

  .ressources-list .video-card.ressource-item { height: 200px; }

  .ressources-list .ressource-item:not(.video-card)::after {
    bottom: 24px;
    right: 24px;
  }
}


/* ==========================================================================
   E · P1 — PASTILLES ANIS par-dessus le fil d'Ariane
   --------------------------------------------------------------------------
   « Les pastilles se chevauchent entre elles et recouvrent intégralement le
   fil d'Ariane. »

   Mesuré sur /notre-agence/ à 390px, avant correctif :
     fil d'Ariane (p#breadcrumbs)  x 39->351   y 141->175
     .etiquette "Humain"           x 142->242  y 108->153   recouvrement 114x23
     .etiquette "Excellence"       x 19->153   y 119->164   recouvrement 111x22
     .etiquette "Expertise"        x 240->357  y 153->200   recouvrement 100x12
     « Humain » recouvre aussi « Excellence » sur 11x33.

   Les .etiquette sont dispersées par des top/left en dur et pivotées par
   transform, valeurs posées par template. On neutralise dispersion et rotation
   sous 768px et on les repasse en flux, en ligne qui se replie.
   Le fil d'Ariane réel est p#breadcrumbs (et non .fil-ariane).
   ========================================================================== */

@media (max-width: 768px) {
  .etiquettes {
    position: static !important;   /* bat les règles de template en 0,1,0 */
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    height: auto !important;
    margin: 14px 0 6px;
  }

  .etiquettes .etiquette {
    position: static !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    transform: none !important;    /* supprime la rotation décorative */
  }

  /* NE PAS toucher au positionnement de p#breadcrumbs.
     Une version antérieure de ce fichier posait ici
       header p#breadcrumbs { position: relative; z-index: 2; }
     pour « faire repasser le fil d'Ariane devant ». C'était une RÉGRESSION :
     p#breadcrumbs est en position:absolute par conception dans le héros, et le
     repasser en relative le réinjecte dans le flux, où il atterrit par-dessus
     le h1. Mesuré : 312 x 34px de recouvrement sur /blog/ et /cms-seo/, là où
     il n'y en avait aucun avant. Règle supprimée.

     Le z-index était de toute façon inutile : une fois les .etiquette repassées
     en static juste au-dessus, elles ne recouvrent plus rien. Vérifié après
     suppression : les trois chevauchements avec le fil d'Ariane tombent à zéro
     sur /notre-agence/, ce qui était l'objectif du constat. */

  /* « L'en-tête noir fixe recouvre la dernière ligne du bloc précédent quand
     le défilement s'arrête » (section 06, propre à Safari). */
  :target,
  h2, h3 {
    scroll-margin-top: 90px;
  }
}


/* ==========================================================================
   F · P1 — CIBLES TACTILES sous 40px
   --------------------------------------------------------------------------
   « 1 269 cibles tactiles sous 40px. Le numéro de téléphone de l'en-tête à
   22x15px, "Nous contacter" à 108x16px. »

   Mesuré à 390px : .header-tel 21x15 ; .header-contact 105.5x16.
   Seuil retenu 44x44. On agrandit la zone tactile sans changer le rendu
   visuel : ni police, ni couleur, ni position apparente.

   Le fil d'Ariane est traité par padding négatif compensé, et non par
   min-height : p#breadcrumbs est en position:absolute, un min-height le
   faisait passer de 34 à 64px de haut et décalait tout le bloc.
   ========================================================================== */

@media (max-width: 768px) {
  .header-tel,
  .header-contact {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-inline: 12px;
  }

  /* Zone tactile élargie sans effet sur la mise en page. */
  p#breadcrumbs a {
    display: inline-block;
    padding: 12px 6px;
    margin: -12px -6px;
  }

  input[type="checkbox"] {
    width: 24px;
    height: 24px;
  }

  input[type="checkbox"] + label {
    padding: 10px 0;
  }

  /* Sous 16px, Safari iOS ZOOME automatiquement la page à la mise au point du
     champ, et n'en ressort pas. Relevé en vérification : le champ newsletter du
     pied de page est à 14px. Les champs HubSpot, eux, sont déjà à 16px.
     Le sélecteur DOIT porter l'ID : common.css cible `input#EMAIL` (1,0,1), qui
     bat `input[name="EMAIL"]` (0,1,1) quel que soit l'ordre de chargement.
     À spécificité désormais égale, c'est l'ordre source qui tranche. */
  input#EMAIL,
  input[type="email"] {
    font-size: 16px;
  }
}


/* ==========================================================================
   G · P1 — ONGLETS : la barre est coupée des deux côtés, sans signal
   --------------------------------------------------------------------------
   « ul.onglets-nav est en overflow-x:scroll donc le contenu existe, mais aucune
   flèche, pastille ni dégradé ne signale le glissement. Sur /blog/ la barre est
   coupée des deux côtés : le premier onglet s'affiche "les articles" au lieu de
   "Tous les articles". »

   Cause racine de la coupure GAUCHE, trouvée :
   1. sur /blog/ le markup est div.container > ul.onglets-nav.container
      (sur /videos/ le parent est div.section : c'est pourquoi /videos/ n'est
      pas coupé à gauche)
   2. common.css:3009 `.container .container{padding:0}` (0,2,0) bat
      categorie.css:793 `.onglets-nav{padding:16px 43px}` (0,1,0)
   3. common.css:882 met overflow-x:scroll ; un conteneur en overflow != visible
      fait CLIPPER son contenu par le border-radius:60px (categorie.css:797).
      Padding 0 + rayon 60px => le coin arrondi mange le début du 1er libellé.
   Côté DROIT : le contenu déborde simplement sans que rien ne le signale.
   (Une hypothèse « order:-1 déplace la marge de sécurité de :last-of-type »
   avait été avancée ; contre-vérification faite sur /blog/, `order` vaut 0 sur
   tous les items et `margin-right` vaut 0 : cette explication est fausse. Les
   deux règles :first-of-type/:last-of-type ci-dessous sont donc des no-ops
   inoffensifs, conservés comme garde-fou si un template pose ces marges.)

   Résultat mesuré sur /blog/ : le premier item passe de x=15 — soit le bord
   exact du <ul>, mangé par le border-radius — à x=37. « Tous les articles »
   redevient lisible en entier.

   Barre de navigation, pas bloc de preuve -> on garde le défilement et on
   ajoute le signal qui manque. Le masque est color-agnostique : il ne
   présuppose pas la couleur de fond de la barre, qui varie selon le gabarit.
   ========================================================================== */

@media (max-width: 768px) {
  .onglets-nav,
  .onglets-nav.container,
  div.bloc-onglets .onglets-nav {
    padding-left: 22px;            /* rétablit l'espace mangé par le rayon */
    padding-right: 22px;
    gap: 16px;
    scroll-padding-inline: 22px;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* le dégradé de bord droit : le signal absent partout */
    -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent);
            mask-image: linear-gradient(90deg, #000 88%, transparent);
  }

  .onglets-nav::-webkit-scrollbar { display: none; }

  .onglets-nav .onglets-nav-item { scroll-snap-align: center; }

  /* La butée de fin doit suivre l'item réellement affiché en dernier, pas
     :last-of-type que order:-1 déplace. Un pseudo flex-item est fiable. */
  .onglets-nav .onglets-nav-item:last-of-type { margin-right: 0; }
  .onglets-nav .onglets-nav-item:first-of-type { margin-left: 0; }

  .onglets-nav::after {
    content: "";
    flex: 0 0 26px;
    align-self: stretch;
  }

  .onglets-nav .onglets-nav-item div,
  .onglets-nav .onglets-nav-item button {
    font-size: 13px;
    white-space: nowrap;
  }
}


/* ==========================================================================
   H · P1 — BLOCS DE PREUVE qui défilent sans signal
   --------------------------------------------------------------------------
   « Logos clients, avis, études de cas, fiches équipe, témoignages : partout le
   même comportement. Pour le visiteur, ce n'est pas un carrousel, c'est un bug
   d'affichage. »
   « On ne fait pas glisser une preuve, on la montre » : pour ces blocs on
   empile, on ne signale pas.
   ========================================================================== */

@media (max-width: 768px) {

  /* --- Compteur de chiffres clés (/notre-agence/) : 1230px pour 390 ---------
     Cause : common.css:827 overflow-x:scroll + common.css:831
     .chiffre-bloc{min-width:100%} => 4 blocs de 100% = 4 écrans pour 4 chiffres.
     « Deux chiffres par ligne plutôt qu'un seul centré donneraient déjà un bloc
     lisible » (rapport). */
  .compteur,
  .compteur.container {
    overflow-x: visible;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 28px 16px;
    padding: 34px 20px;
    align-items: start;
  }

  .compteur .chiffre-bloc {
    min-width: 0;
    width: auto;
    display: block;
    text-align: center;
  }

  .compteur .chiffre { font-size: 46px; line-height: 100%; margin-bottom: 8px; }
  .compteur .chiffre-texte { max-width: none; font-size: 14px; line-height: 125%; }

  /* --- Portraits d'équipe (/notre-agence/) : 1002px de contenu pour 360 ------
     Le rapport parlait d'une « gouttière mesurée à zéro » : contre-vérification
     faite, c'est INEXACT — l'écart entre deux .equipe-membre voisins vaut 22px
     avant correctif. Le vrai défaut est le débordement horizontal, mesuré
     jusqu'à 3306px de contenu pour 360 visibles, d'où « deuxième carte
     tranchée » : les portraits partent hors écran, ils ne sont pas collés.
     common.css:841 met `div.equipe-role__membres{display:-webkit-inline-box}`
     (flexbox legacy 2009) : le !important ci-dessous neutralise ce display pour
     passer en grille. Après correctif : scrollWidth 360, plus rien hors écran. */
  div.equipe-role__membres {
    display: grid !important;
    grid-template-columns: 1fr 1fr;
    gap: 18px 16px;
    flex-wrap: wrap;
    overflow-x: visible;
    max-width: 100%;
    width: 100%;
    justify-content: stretch;
  }

  div.equipe-membre { width: auto; min-width: 0; }

  img.equipe-membre__photo.equipe-membre__photo--rectangle {
    height: 190px;
    width: 100%;
    object-fit: cover;
    border-radius: 20px;
  }

  p.equipe-membre__prenom { font-size: 16px; line-height: 120%; }

  /* --- Cartes d'études de cas (single) : 1065px, coupées des DEUX côtés -----
     Cause : etude-de-cas-single.css:266 justify-content:center sans overflow —
     centrer un flex qui déborde le coupe des deux bords, sans rattrapage
     possible au doigt. etude-de-cas-single.css n'a aucune @media (763 lignes).

     L'EMPILEMENT EST IMPOSSIBLE ICI, contrairement aux autres blocs de preuve.
     common.css @1024 impose `.etudes-de-cas.container{flex-flow:row !important;
     overflow-x:auto !important}` et @480 `.etude-de-cas{flex:0 0 90% !important}`.
     Forcer `flex-direction:column !important` a été testé : le conteneur retombe
     à height:0, donc le bloc disparaît. On garde donc le défilement — ce que le
     rapport accepte explicitement comme seconde option — et on ajoute le signal
     qui manquait, plus l'alignement à gauche qui supprime la coupure côté gauche. */
  /* NB : le rapport attribuait la coupure à `justify-content:center`. Contrôle
     fait, le calculé vaut DÉJÀ `flex-start` et la première carte est à x=50,
     entièrement visible — cette partie du diagnostic est fausse et n'appelle
     aucune règle. Ce qui manquait réellement, c'est le signal de défilement et
     l'accroche ; c'est ce que fait le bloc ci-dessous, qui raccourcit au passage
     la course de 1065 à 953px en supprimant les marges latérales des cartes. */
  .fourth-single-etude-de-cas .etudes-de-cas.container {
    gap: 16px;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: 15px;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 90%, transparent);
            mask-image: linear-gradient(90deg, #000 90%, transparent);
  }

  .fourth-single-etude-de-cas .etudes-de-cas::-webkit-scrollbar { display: none; }

  .fourth-single-etude-de-cas .etude-de-cas {
    scroll-snap-align: start;
    margin: 0;
    max-width: none;
  }

  /* --- Chiffres clés de l'étude : 908px ------------------------------------
     « On lit +17, +2, +1 sans jamais savoir s'il s'agit de 17%, de 170% ou de
     17 points. » Cause : common.css:1205 overflow-x:scroll + :1210 flex 0 0 80%. */
  div.div-chiffres-cle {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    overflow-x: visible;
    max-width: 100%;
    margin-bottom: 32px;
  }

  div.div-chiffres-cle .chiffre-cle {
    flex: 0 0 auto;
    min-width: 0;
    width: auto;
    padding: 24px 14px;
    text-align: center;
  }

  .div-chiffres-cle .etude-de-cas-chiffre-cle { font-size: 38px; line-height: 100%; }
  .div-chiffres-cle .etude-de-cas-complement-chiffre-cle { font-size: 14px; line-height: 125%; }

  /* --- Tableaux de résultats de l'étude : 752px, parent overflow-x visible --
     Un <table> ne s'empile pas sans toucher au markup (les ::before de cellule
     en dépendent) : on dégraisse le padding, puis on rend le défilement
     découvrable. Cause : etude-de-cas-single.css:574 (padding 30px 50px, soit
     100px par colonne) et :746 (.container.table en position:relative seul). */
  /* NB : l'élément qui défile réellement est le <table> lui-même
     (display:block; overflow-x:auto hérité de common.css:3850), PAS
     .container.table dont scrollWidth == clientWidth == 360. Une première
     version posait ici quatre dégradés « signal de défilement » en
     background-attachment:local : mesure faite, ils étaient figés sur un
     élément qui ne défile jamais, donc purement décoratifs et trompeurs.
     Supprimés. Le gain réel de ce bloc est le dégraissage des cellules,
     mesuré à -74px de hauteur de tableau.
     Le défilement, lui, fonctionnait déjà : contenu 752px, boîte 360px. */
  .container.table {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* :not(.px-compare) par ceinture de sécurité : si un tableau px-compare était
     un jour placé dans un .container.table, une min-width casserait son
     empilement en cartes sticky. Et pas de min-width imposée : une fois le
     padding dégraissé, on laisse le tableau prendre sa largeur naturelle
     plutôt que de forcer un défilement dont il n'a pas forcément besoin. */
  .container.table table.acf-table:not(.px-compare) { border-spacing: 0 12px; }

  .container.table tr td:nth-child(2) div,
  .container.table tr td:nth-child(3) div { padding: 16px 12px; font-size: 14px; }

  .container.table th:nth-child(2)::before { width: 34px; height: 34px; margin: 18px auto 0; }

  /* --- Bloc de tête de l'étude : 422px « rognés de 32px pour de bon » -------
     Ce n'est pas du contenu mais le pseudo décoratif common.css:1155
     div.column.column-prix::after{width:120%;left:-25px}. 120% de 350 = 420px.
     On le cale exactement sur la largeur d'écran. */
  div.column.column-prix::after {
    width: calc(100% + 40px);
    left: -20px;
  }

  /* --- Bandeau « Quel que soit votre CMS » ---------------------------------
     « Les logos défilent tout seuls, le logo WordPress est tranché par le bord
     droit, et à certains moments un seul logo reste visible. »
     Structure vérifiée : 1 .cms > 2 .cms-block (duplicata du marquee) animés
     par common.css:2754. Preuve de couverture technique -> on arrête
     l'animation et on empile. */
  .cms {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 26px;
    overflow-x: visible;
  }

  .cms .cms-block {
    animation: none !important;     /* bat l'animation de common.css:2754 */
    transform: none !important;
    flex-wrap: wrap;
    justify-content: center;
    gap: 16px 18px;
    width: 100%;
  }

  .cms .cms-block + .cms-block { display: none; }   /* le duplicata du marquee */

  .cms .page-item { margin-right: 0; flex: 0 0 auto; }

  /* Calibré pour tenir 4 logos par rangée dans 350px utiles (4x78 + 3x18 = 366
     -> 4 par rangée dès 366px de large), ce qui limite la hauteur du bandeau.
     Arrêter le marquee rend forcément le bloc plus haut : c'est le prix à payer
     pour que la preuve de couverture technique soit lisible en entier. */
  .cms .page-item img {
    height: 24px !important;        /* bat prestation.css:437 height !important */
    width: auto;
    max-width: 78px;
    object-fit: contain;
  }
}


/* ==========================================================================
   I · P1 — BLOC « VOS EXPERTS » : 4 portraits, 4 formats, le 4e hors écran
   --------------------------------------------------------------------------
   « La grille .experts__grid mesure 441px de contenu dans 360 affichés : la
   quatrième fiche est tranchée, et rien ne permet de faire défiler. Les quatre
   portraits sont mesurés à 76x88, 122x152, 80x152 et 97x121px. »

   Cause : cms-fille.css:2044 normalise bien l'image, mais SCOPÉ à .page-id-548.
   Hors de cette page-là, aucune règle ne s'applique à l'image, qui sort à sa
   taille intrinsèque. Et common.css:5507 `.experts__grid{display:flex;gap:22px}`
   n'a ni flex-wrap ni overflow -> 4e fiche tranchée.
   « C'est au CSS de les cadrer, pas au fichier. »
   ========================================================================== */

@media (max-width: 768px) {
  .experts__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px 14px;
    overflow-x: visible;
    align-items: start;
  }

  .experts__grid .expert { min-width: 0; }

  .experts__grid .expert-card__photo img,
  .expert-card__photo img {
    display: block;
    width: 100%;
    height: 180px;
    max-height: none;
    object-fit: cover;
    object-position: top center;
    border: solid 1px #1B1B1B;
    border-radius: 20px;
  }

  .expert-card__body { text-align: center; }
  p.expert-card__name { font-size: 16px; line-height: 120%; margin: 6px 0 2px; }
  .team-member__role { font-size: 13px; line-height: 125%; }

  /* « la mention Langues parlées : se retrouve avec ses deux-points orphelins » */
  .team-member__langues {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 4px 6px;
    font-size: 13px;
    line-height: 125%;
    text-wrap: balance;
  }

  .team-member__langues img { flex: 0 0 auto; }

  a.expert-card__linkedin {
    top: 10px; right: 10px;
    width: 22px; height: 22px;
    line-height: 24px; font-size: 12px;
  }
}


/* ==========================================================================
   J · P1 — FILTRES D'ÉTUDES DE CAS : 386px de haut pour quatre libellés
   --------------------------------------------------------------------------
   « Le bloc div.filters occupe 386px de haut, soit 46% d'un écran d'iPhone,
   pour afficher quatre déclencheurs dont les libellés mesurent 24px chacun.
   96px de contenu utile et 290px de vide. »
   Objectif du rapport : 120px au lieu de 386.

   Causes : etude-de-cas-archive.css:93 `.filters{padding:100px 0}` hors media
   query (200px à lui seul) + :379 `.filtre-row` en flex SANS flex-wrap avec
   gap:50px + :386 `.filtre{margin-right:20px}` => 210px de gouttière sur
   ~320px utiles, d'où le repli extrême.
   ========================================================================== */

@media (max-width: 768px) {
  .filters { padding: 20px 0; }

  /* Le conteneur de référence des menus déroulants devient la RANGÉE, pas le
     filtre. Sans cela le menu est ancré sur un déclencheur étroit (76 à 125px)
     placé n'importe où dans la rangée, et un menu de 250px sort forcément de
     l'écran — par la droite s'il est ancré à gauche (mesuré : right=436 sur le
     filtre « Type de site »), par la gauche s'il est ancré à droite (mesuré :
     x=-46 sur le filtre « CMS »). Aucun ancrage relatif au déclencheur ne peut
     fonctionner ici : il faut un ancrage relatif à la rangée, qui elle occupe
     toute la largeur utile. */
  .filtre-row { position: relative; }
  .filtre { position: static; }

  /* flex-direction:row est INDISPENSABLE : la rangée est en column dans le
     thème, ce qui rendait `flex-wrap:wrap` totalement inerte. Sans cette
     ligne le bloc restait à 222px au lieu des ~120px visés. */
  .filtre-row {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 10px 12px;
  }

  .filtre {
    margin-right: 0;
    width: auto;
    flex: 0 0 auto;
    max-width: 100%;
  }

  .filtre-trigger {
    padding: 7px 30px 7px 14px;
    border: solid 1px #4D4D4D;
    border-radius: 40px;
    line-height: 1.2;
  }

  .filtre-placeholder,
  .filtre-selected { font-size: 14px; padding: 0; }

  /* Les options du menu : 44px de haut, pas 15. Une version antérieure de ce
     fichier leur posait `padding:0`, ce qui les ramenait à 15,4px de haut —
     une cible tactile deux fois trop petite, et créée par le correctif
     lui-même. Le constat « 1 269 cibles sous 40px » vaut aussi ici. */
  .filtre ul li {
    font-size: 14px;
    padding: 12px 14px;
    min-height: 44px;
    display: flex;
    align-items: center;
    /* INDISPENSABLE, ne pas retirer. etude-de-cas-archive.css pose
       `.filtre ul li{color:#fff}` parce que le fond du menu y est sombre
       (rgba(53,53,53,.3)). Opacifier ce fond en clair juste en dessous SANS
       repasser le texte en sombre donnait du blanc sur crème : contraste
       1,04:1, menu fonctionnellement illisible. Les deux règles vont ensemble. */
    color: #1B1B1B;
  }

  /* Le menu héritait d'un fond rgba(53,53,53,.3) — translucide et sombre — avec
     un texte #1B1B1B posé dessus. Illisible, et d'autant plus visible depuis
     que le menu se rapproche des visuels d'études de cas. On l'opacifie avec
     les couleurs de marque : #1B1B1B sur #FCFAF4 = 15,9:1. */
  .filtre ul {
    background: #FCFAF4;
    border: solid 1px #1B1B1B;
    border-radius: 16px;
    box-shadow: 0 8px 24px rgba(27, 27, 27, .18);
  }

  .filtre-placeholder,
  .filtre-selected { white-space: nowrap; }

  .filtre-placeholder::after,
  .filtre-selected::after { margin-left: 10px; }

  /* le menu déroulant ne doit jamais sortir de l'écran.
     ATTENTION : ne PAS ancrer à droite (`right:0`) les filtres 3 et 4. Les
     .filtre sont étroits (101px et 76px mesurés) et alignés à gauche : ancrer
     un menu de 250px sur leur bord droit projetait son bord gauche à x=-134 et
     x=-159, donc hors écran par la GAUCHE — alors qu'avant correctif les
     quatre menus étaient entièrement visibles. Régression détectée en
     vérification et supprimée : on garde l'ancrage à gauche pour tous. */
  .filtre ul {
    left: 0;                 /* = bord gauche de la rangée, donc dans l'écran */
    right: auto;
    top: auto;               /* position statique : juste sous son déclencheur */
    margin-top: 6px;
    width: min(250px, calc(100vw - 48px));
    max-width: calc(100vw - 40px);
    max-height: 52vh;
    overflow-y: auto;
  }
}


/* ==========================================================================
   K · P1 — CARROUSEL « comment ça marche »
   --------------------------------------------------------------------------
   « Chaque étape est une carte de 475px de large dans un écran de 390. La
   navigation est posée 90px sous la carte, deux cercles de 90px contenant les
   emojis 👈 et 👉. »

   Le width:1135px !important n'est PAS la cause : common.css:3891
   `.carrousel-texte-image div.carrousel-item{width:auto !important}` (0,2,1)
   le bat déjà. Les vraies causes, vérifiées :
     common.css:5447 / prestation.css:695  .columns{margin-right:85px}
     common.css:709                        div.slick-slide .columns{padding-right:25px}
     prestation.css:673                    .slick-list{overflow:visible}
     common.css:5453                       .custom-next-prev{margin-top:50px}
     common.css:5492                       cercles 90x90 (c'est CETTE règle
                                           qui s'applique, pas prestation.css:707)
   350 + 85 + 25 ≈ 460 : d'où la carte plus large que l'écran.

   ATTENTION SÉLECTEUR : les commandes réelles de ce carrousel sont
   .custom-prev-cti / .custom-next-cti, et non .custom-prev / .custom-next
   (qui servent un AUTRE carrousel). Les deux sont ciblées par sécurité.
   ========================================================================== */

@media (max-width: 768px) {
  .carrousel-texte-image .slick-list { overflow: hidden !important; }

  .carrousel-texte-image .carrousel-item {
    width: calc(100vw - 40px) !important;
    max-width: calc(100vw - 40px) !important;
  }

  .carrousel-texte-image .carrousel-item .columns,
  div.slick-slide .columns {
    margin-right: 0 !important;
    padding-right: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    box-sizing: border-box !important;
  }

  div.carrousel-item__col.column.carrousel-item__col--texte {
    padding: 66px 20px 30px !important;
    box-sizing: border-box !important;
  }

  /* div. en préfixe : common.css @768 déclare `div.carrousel-item__numero
     {font-size:40px}` en (0,1,1), qui battait un simple .carrousel-item__numero. */
  div.carrousel-item__numero { font-size: 34px; padding: 2px 18px; left: 18px; }
  .carrousel-item ul { padding-left: 26px; margin-top: 24px; }

  .carrousel-bloc .custom-next-prev,
  .custom-next-prev {
    margin-top: 18px;
    margin-left: auto;
    margin-right: auto;
    gap: 14px;
    justify-content: center;
  }

  .custom-prev-cti, .custom-next-cti,
  .custom-prev, .custom-next {
    width: 46px;
    height: 46px;
    line-height: 46px;
    font-size: 18px;
  }
}

@media (max-width: 480px) {
  .carrousel-texte-image .carrousel-item {
    width: calc(100vw - 30px) !important;
    max-width: calc(100vw - 30px) !important;
  }
}

@media (max-width: 375px) {
  .carrousel-texte-image .carrousel-item {
    width: calc(100vw - 24px) !important;
    max-width: calc(100vw - 24px) !important;
  }
}


/* ==========================================================================
   L · P1 — FORMULAIRE HUBSPOT DU PRÉ-AUDIT : deux colonnes à 375px
   --------------------------------------------------------------------------
   Non listé tel quel dans le rapport, mais il tombe sous « Ce qu'il reste à
   vérifier — les formulaires HubSpot », et il est bloquant pour la conversion.

   Cause : formulaire-contact.twig enveloppe le formulaire dans
   .onglets-contenus > .onglet-contenu, structure empruntée aux onglets, ce qui
   déclenche dans common.css un jeu de règles SANS repli mobile :
     common.css:5612  .onglet-contenu form label{flex:1 0 100px}
     common.css:5616  .onglet-contenu form .hs-form-field{display:flex}
     common.css:5622  .onglet-contenu form .hs-form-field .input{width:calc(100% - 100px)}
   Mesuré à 375px : champs Nom/Prénom/Site à 167px, consentement RGPD sur 12
   lignes dans 207px, bouton d'envoi 93x42, et le bloc reCAPTCHA réapparaît
   (common.css:2015 .hs_recaptcha{display:none} en 0,1,0 est battu par 0,3,0).

   Sur /prestations-seo/ le même formulaire est sain : il n'y a pas de
   .onglet-contenu autour. Le défaut est propre au pré-audit.
   ========================================================================== */

@media (max-width: 768px) {
  .onglet-contenu form .hs-form-field { display: block; }
  .onglet-contenu form label { flex: none; width: 100%; display: block; }
  .onglet-contenu form .hs-form-field .input { width: 100%; }
  .onglet-contenu form .hs-form-field.hs_recaptcha { display: none; }  /* 0,4,0 > 0,3,0 */
  .onglet-contenu form .hs_submit.hs-submit .hs-button { width: 100%; padding: 14px 20px; }
}


/* ==========================================================================
   M · P1 — PAGES PRESTATIONS : densité d'information
   --------------------------------------------------------------------------
   Relève de « gabarits pensés en 1400px et empilés tels quels en 390 »
   (section 03 du rapport). Trois pertes de surface mesurées.
   ========================================================================== */

@media (max-width: 768px) {
  /* prestations.css:582 — padding 50px 59px 80px conservé sur mobile :
     118px perdus sur 351 (34%), texte des puces réduit à 196px.
     common.css remet width:100% mais jamais le padding. */
  .bloc-onglets .onglets-contenus .onglet-contenu .colonne.droite {
    padding: 30px 22px 35px;
  }

  .bloc-onglets .onglets-contenus .onglet-contenu .droite li {
    padding-left: 28px;
    font-size: 16px;
  }

  /* prestations.css:664 — .faux-cta garde 232px de padding vertical :
     carte de 392px de haut dont 232 de vide, texte sur 227px.
     common.css:788 corrige la largeur mais pas le padding. */
  .faux-cta { padding: 40px 30px 40px 25px; }
  .faux-cta::after { bottom: 20px; right: 20px; }

  /* prestations.css:532 — le sticker « prix » sort de l'écran à gauche :
     mesuré left = -13px à 375px, rogné par body{overflow-x:hidden}. */
  .bloc-onglets .onglets-contenus .onglet-contenu .sticker {
    margin-left: 0;
    font-size: 15px;
    padding: 7px 14px;
    top: -30px;
    max-width: calc(100% - 20px);
  }
}

@media (max-width: 480px) {
  .bloc-onglets .onglets-contenus .onglet-contenu .colonne.droite {
    padding: 24px 16px 28px;
  }
}


/* ==========================================================================
   N · P1 — TABLEAU COMPARATIF : 931px à faire défiler dans 351
   --------------------------------------------------------------------------
   « C'est systématiquement l'information utile qui disparaît : ce qui est
   licite ou à proscrire, la comparaison SEO contre SEA. »

   Le défilement fonctionne (common.css:3850) mais la première colonne — le
   libellé de ligne — disparaît dès qu'on fait glisser : le contenu des
   colonnes 2 et 3 devient non identifiable. On la rend collante.
   common.css:3885 neutralise th:nth-child(2) p{padding-left:0} mais OUBLIE
   th:nth-child(3) : mesuré 75px de padding horizontal dans une cellule de 300.

   NB : exclut px-compare, dont les lignes sont en position:sticky par design.
   ========================================================================== */

@media (max-width: 768px) {
  table.acf-table:not(.px-compare) th:nth-child(3) p { padding-left: 22px; }

  table.acf-table:not(.px-compare) th p {
    font-size: 22px;
    padding-top: 40px;
    padding-bottom: 20px;
  }

  table.acf-table:not(.px-compare) tr td:first-of-type {
    position: sticky;
    left: 0;
    z-index: 3;
    background: #fff;
  }

  table.acf-table:not(.px-compare) tr td:first-of-type::before { background: #fff; }
}


/* ==========================================================================
   O · P1 — ARTICLES, DÉFINITIONS, OUTILS : rythme et densité
   --------------------------------------------------------------------------
   « Sur un article, il faut franchir 5,4 écrans avant le premier titre » et
   « 497 706px de défilement cumulés, 15 écrans par page en moyenne ».
   single.css, single-definitions.css et single-outil.css n'ont AUCUNE media
   query : tout leur responsive repose sur common.css, qui ne couvre pas ces
   calibrages.
   ========================================================================== */

@media (max-width: 768px) {
  /* single.css:105 — navigation d'articles : deux colonnes de 184 et 167px,
     titres coupés sur 5 lignes. Aucun repli dans common.css. */
  .post-navigation { flex-direction: column; align-items: stretch; gap: 24px; }
  .prev-post, .next-post { width: 100%; font-size: 16px; }
  .next-post { justify-content: space-between; }

  /* single.css:360 / single-definitions.css:329 — .essentiel garde
     padding:50px 42px : contenu réduit à 267px sur 375 (71% du viewport),
     avec .titre-intro à 36px dedans. */
  .second-single .essentiel,
  .second-single-definition .essentiel {
    padding: 32px 20px;
    margin-top: 45px;
    margin-bottom: 32px;
  }

  .second-single .titre-intro,
  .second-single-definition .titre-intro { font-size: 26px; letter-spacing: 0; }

  /* .citation — padding 15px 40px figé (contenu 271px) et guillemets
     décoratifs en 40px qui étranglent le bloc. */
  .second-single .citation,
  .second-single-definition .citation,
  .second-single-outil .citation { padding: 26px 20px; margin: 32px 0; }

  .second-single .citation::before, .second-single .citation::after,
  .second-single-definition .citation::before, .second-single-definition .citation::after,
  .second-single-outil .citation::before, .second-single-outil .citation::after {
    font-size: 26px;
  }

  /* .h3 figé à 36px dans la carte sommaire : common.css:185 ne réduit que
     l'ÉLÉMENT h3, or les titres de carte sont des <div class="h3">.
     Mesuré : « Pour aller plus loin » sur 2 lignes / 79px dans 279px. */
  .second-single .colonne-carte .h3, .second-single .newsletter .h3,
  .second-single-definition .colonne-carte .h3,
  .second-single-outil .colonne-carte .h3 { font-size: 24px; }

  /* padding:35px sur une carte de 351px -> 279px utiles, et en cascade le
     paragraphe du bloc contact tombe à 181px (single.css:328). */
  .second-single .colonne-carte > div,
  .second-single-definition .colonne-carte > div,
  .second-single-outil .colonne-carte > div { padding: 24px 20px; }

  .second-single-definition .colonne-carte .more,
  .second-single-outil .colonne-carte .more { padding-bottom: 24px; }

  .second-single .newsletter { padding: 24px 20px; }

  /* .card du bloc contact : common.css:914 ajoute div.card{margin:0 25px} qui
     s'additionne au padding du container -> 219px de contenu utile pour du
     texte en 24px, soit ~8 caractères par ligne. */
  .fourth-single .card .col-1 { padding: 28px 22px 24px; }
  .fourth-single .contenu p,
  .fourth-single .tel { font-size: 19px; line-height: 130%; }

  /* Rythme vertical : jusqu'à 250px de vide par section, jamais réduit.
     .third-single-definition mesuré à 250px de haut pour 27px de contenu. */
  .second-single { padding-top: 50px; padding-bottom: 60px; }
  .second-single-definition, .second-single-outil { padding-top: 50px; }
  .fourth-single { padding-top: 60px; }
  .third-single-outil { margin-top: 60px; margin-bottom: 60px; }
  main > .third-single-definition { padding-top: 60px; }   /* 0,1,2 > common.css:3024 */
  .first-single .intro { margin-bottom: 40px; }

  /* common.css:4014 impose gap:0 !important sur .columns : une fois empilées,
     la carte noire et le texte se touchent sans séparation. On n'écrase pas le
     gap (bataille de !important), on ajoute une marge sur l'élément voisin. */
  .second-single .colonne-first,
  .second-single-definition .colonne-first,
  .second-single-outil .colonne-first { margin-bottom: 40px; }
}

@media (max-width: 480px) {
  /* .h1 en flex avec vignette de largeur figée : 144px (définitions) ou 104px
     (outils) non réduits, laissant 157 à 187px à un h1 en 40px. */
  .first-single-definition .h1-image,
  .first-single-outil .h1-image { width: 76px; height: 76px; }
  .first-single-outil .h1-image { padding: 12px; }

  .first-single-definition .h1 h1,
  .first-single-outil .h1 h1 { font-size: 30px; }

  /* annule la double gouttière de common.css:914 */
  .fourth-single .card { margin: 0; }
}


/* ==========================================================================
   P · P2 — LA COQUILLE « 786px »
   --------------------------------------------------------------------------
   prestations.css:735, prestation.css:724, agence.css:287 et metier-mere.css
   déclarent @media (max-width: 786px). 786 est une coquille pour 768 : aucun
   autre point de bascule du thème n'utilise cette valeur (common.css ne connaît
   que 1150 / 1024 / 850 / 768 / 480 / 375).

   Ce n'est pas une zone morte mais une bande de 18px (769-786) où la règle
   mobile se déclenche 18px trop tôt, pendant que le reste de la page est encore
   en desktop. Mesuré à 780px sur /prestations-seo/consulting-seo/ :
   .section.fourth-prestation .columns passe en column-reverse (donc empilé ET
   en ordre inversé) alors que toutes les autres .columns restent en row.

   Ceci est un pansement. Le vrai correctif est de remplacer 786 par 768 dans
   les fichiers source — voir la note de livraison.
   ========================================================================== */

@media (min-width: 769px) and (max-width: 786px) {
  .section.fourth-prestation .columns { flex-direction: row; }
  .prestations-first { padding-bottom: 100px !important; }  /* la source use !important */
  .second-prestations { padding-top: 150px !important; }    /* idem */
}


/* ==========================================================================
   Q · GLOBAL — CONTRASTE
   --------------------------------------------------------------------------
   « Gris #999999 sur beige #FCFAF4 : rapport 2,73:1 pour un seuil requis de
   4,5:1. C'est la couleur des dates de publication, présente sur 29 pages et
   répétée sur chaque carte des listings. »

   APPLIQUÉ À TOUTES LES LARGEURS, desktop inclus : le défaut de contraste est
   identique sur grand écran, le restreindre au mobile laisserait une
   non-conformité WCAG AA sur desktop. Changement de couleur seul, aucun effet
   de mise en page. #6B6B6B sur #FCFAF4 = 5,9:1.

   Le rapport proposait une variable --gris-meta : le thème n'a AUCUN bloc
   :root. On corrige donc les règles réelles. Occurrences relevées :
     author.css:156, categorie.css:220, categorie.css:788,
     relation-presse.css:289, video.css:170     -> .ressource-date
     common.css:1709  -> .blog.container.columns .article time
   ========================================================================== */

.ressource-date,
.blog.container.columns .article time {
  color: #6B6B6B;
}


/* ==========================================================================
   R · GLOBAL — LISTES À DOUBLE MARQUEUR
   --------------------------------------------------------------------------
   « 95 items avec list-style-type: disc conservé et un ::before en police
   icones par-dessus. » Compté dans le DOM de /cms-seo/ : exactement 95.

   Cause : le thème neutralise le marqueur avec `::marker{content:none}`
   (cms-mere.css:334 et :397). Safari n'applique pas `content` sur ::marker :
   la puce native reste affichée sous l'icône. `list-style:none` fonctionne
   partout.

   APPLIQUÉ À TOUTES LES LARGEURS : le défaut n'est pas propre au mobile.
   Effet desktop : la puce parasite disparaît, l'icône reste.
   ========================================================================== */

.bloc-onglets .onglets-contenus .onglet-contenu .droite li,
.cms-mere-third li,
.cms-mere-fourth li,
.agence-fourth li {
  list-style: none;
}


/* ==========================================================================
   T · P1 — FICHE DE POSTE : galerie photo et carte d'offre
   --------------------------------------------------------------------------
   « La galerie affiche trois photos issues du même format source, rendues à
   trois tailles qui n'ont rien à voir. La troisième garde sa taille source et
   déborde de 225px. »

   CAUSE RACINE, qui n'est pas celle du rapport : WP Rocket insère un <noscript>
   après CHAQUE <img> lazy-loadée. Les images occupent donc les positions
   nth-child 1, 3, 5, 7, 9 — et non 1 à 5. Or toutes les règles du thème ciblent
   nth-child(1..5) : common.css:947-957, offre-demploi-single.css:421-444,
   recrutement.css:202-224.

   Conséquence mesurée à 390px — le rapport sous-estimait le défaut :
     img1 (nth-child 1) -> attrapée      -> 360x200   correct
     img2 (nth-child 3) -> règle du 2    -> 169x197
     img3 (nth-child 5) -> display:none  -> MASQUÉE
     img4 (nth-child 7) -> AUCUNE règle  -> 600x700, x 15->615 (225px hors écran)
     img5 (nth-child 9) -> AUCUNE règle  -> 600x700, x 15->615 (225px hors écran)

   `:nth-of-type` ne compte que les <img> et règle le problème à la racine.

   ATTENTION — CE BLOC EST VOLONTAIREMENT GLOBAL, il modifie aussi le desktop.
   Le défaut y est identique et bien visible : mesuré à 1440px, img4 sort à
   x=1191 et la mosaïque est détruite. Les valeurs reprises ci-dessous sont
   celles d'offre-demploi-single.css : on rétablit l'intention d'origine du
   thème, on n'invente pas une nouvelle maquette. Après correctif, les deux
   rangées retombent exactement sur 1300px.
   Effet collatéral voulu : /recrutement/ (archive) porte le même bug.
   ========================================================================== */

.galerie-recrutement > img:nth-of-type(1) { width: calc(55% - 11px); max-height: 400px; display: block; }
.galerie-recrutement > img:nth-of-type(2) { width: calc(45% - 11px); max-height: 400px; display: block; }
div.galerie-recrutement > img:nth-of-type(3) { width: calc(30% - 14px); max-height: 300px; display: block; }
.galerie-recrutement > img:nth-of-type(4) { width: calc(30% - 16px); max-height: 300px; display: block; }
.galerie-recrutement > img:nth-of-type(5) { width: calc(40% - 14px); max-height: 300px; display: block; }

@media (max-width: 768px) {
  /* !important obligatoire : common.css:948 et :953 déclarent déjà
     width et max-height en !important. */
  div.galerie-recrutement > img:nth-of-type(1) {
    width: 100% !important;
    max-height: 200px !important;
    display: block !important;
  }

  div.galerie-recrutement > img:nth-of-type(2),
  div.galerie-recrutement > img:nth-of-type(3),
  div.galerie-recrutement > img:nth-of-type(4),
  div.galerie-recrutement > img:nth-of-type(5) {
    width: calc(50% - 11px) !important;
    max-height: 200px !important;
    display: block !important;
  }

  /* « La carte blanche de l'offre se termine sans marge inférieure, le logo
     violet se retrouve à cheval sur la découpe de la carte. »
     Arithmétique du thème : common.css:1019 fait déborder .prix-div de 350px
     sous son parent (margin-bottom:-350px), mais l'espace réservé après
     .first-single-offre n'est que 150 (common.css:1024) + 150
     (offre-demploi-single.css:114) = 300px. Déficit de 50px, d'où le
     chevauchement mesuré : logo à y=1144 sous une carte finissant à y=1169.
     On porte la réserve à 250 + 150 = 400px, soit 50px de respiration. */
  div.first-single-offre { margin-bottom: 250px; }
}


/* ==========================================================================
   U · P2 — VIGNETTES VIDÉO : le bouton de lecture masque le texte
   --------------------------------------------------------------------------
   « Le bouton de lecture des vignettes vidéo est centré pile sur le texte
   incrusté et le masque, sur l'accueil, la page camping, /agence-ia/,
   /contact/ et l'intégralité de /videos/. »

   Deux faits qui déterminent la solution :
   - le bouton n'est pas un élément mais un pseudo, .video-card .placeholder
     ::after (common.css:2417), content:"▶", 64x64, centré par translate(-50%,-50%)
   - le texte n'est PAS dans le DOM : il est CUIT dans le fichier image de la
     vignette. Il est donc impossible de le déplacer. Seul le bouton peut bouger.

   Relevé des zones de texte sur les 4 gabarits de vignette : la seule zone
   libre commune est le coin HAUT-DROIT. Le coin bas-droit, qui était
   l'intention initiale (common.css:2328, écrasée depuis), est occupé par les
   bandeaux crème.
   La zone cliquable reste .placeholder (handler délégué,
   scripts-animations.js:313) : elle n'est pas touchée.

   Le survol doit être surchargé aussi, sinon common.css:2436 (scale sur le
   translate d'origine) ramènerait le bouton au centre au survol.

   NON APPLIQUÉ AU DESKTOP volontairement : le recouvrement y existe aussi
   (le texte étant cuit, il est proportionnel), mais le corriger déplacerait le
   bouton sur toutes les vignettes du site. C'est un choix de maquette, pas un
   correctif responsive. Voir la note de livraison.
   ========================================================================== */

@media (max-width: 768px) {
  .video-card .placeholder::after {
    top: 14px;
    right: 14px;
    left: auto;
    bottom: auto;
    transform: none;
    width: 52px;
    height: 52px;
    font-size: 20px;
  }

  .video-card:hover .placeholder::after { transform: scale(1.08); }
}


/* ==========================================================================
   V · P2 — BLOCS « .section.container » sans respiration entre 376 et 480px
   --------------------------------------------------------------------------
   « Le bloc noir de fin colle au bouton Voir plus qui le précède, et ses deux
   boutons touchent le bas du bloc, sans marge intérieure. Le même bloc est
   correctement espacé sur la page camping. »

   LE DIAGNOSTIC DU RAPPORT EST FAUX sur sa seconde moitié. Mesuré sur les deux
   pages : padding-top et padding-bottom valent 0 des DEUX côtés. Camping a
   exactement le même défaut interne ; la seule différence est le bloc qui
   précède (une .section SANS .container, qui garde donc ses 30px).
   Il n'y a donc pas de « modèle camping » à recopier : il faut corriger les deux.

   Vraie cause racine : common.css:4867, dans @media (max-width:480px),
   déclare `.container { padding: 0 15px }` — un RACCOURCI, qui remet donc le
   padding vertical à zéro. La règle arrive après `.section{padding:40px 0 30px}`
   à spécificité égale, et gagne par l'ordre source. Tout élément portant à la
   fois .section et .container perd son padding vertical.

   Fenêtre de casse mesurée : 376px -> 480px uniquement.
   (à <=375px le thème redonne 35/25 ; à >=481px les 50/40 s'appliquent)
   Une media query max-width:768px serait donc FAUSSE ici : elle écraserait un
   padding déjà correct sur la plage 481-768.
   ========================================================================== */

@media (min-width: 376px) and (max-width: 480px) {
  /* :not(.camping-tags) — EXCLUSION VÉRIFIÉE. Ce bloc-là n'est PAS cassé :
     agence-seo-ville.css lui donne `.page-id-56241 .camping-tags{padding:60px 0}`
     à spécificité (0,2,0), STRICTEMENT ÉGALE à `.section.container`. Le
     départage se ferait donc au seul ordre de chargement, et comme ce fichier
     est enfilé en dernier il écraserait 60/60 en 40/30, soit -50px, sans raison.
     Si un autre bloc à padding sur mesure apparaît dans cette bande, l'ajouter
     à cette exclusion.

     Rayon d'action mesuré sur 5 pages : 8 éléments seulement, tous réellement
     à 0/0 sauf celui-ci. /prestations-seo/ n'en compte aucun. */
  .section.container:not(.camping-tags) { padding-top: 40px; padding-bottom: 30px; }
  .section.camping-cta.container { padding-top: 40px; padding-bottom: 40px; }
}


/* ==========================================================================
   S · GLOBAL — BADGE reCAPTCHA
   --------------------------------------------------------------------------
   « reCAPTCHA v3 affiche un badge fixe en bas à droite, en permanence, sur
   chaque page où son script est présent, y compris /videos/ et les articles de
   blog, qui ne contiennent aucun formulaire. »
   Vérifié : .grecaptcha-badge présent sur /notre-agence/ (page sans
   formulaire), 256px de large, à cheval sur le bord droit.

   ATTENTION — Google autorise ce masquage À CONDITION que la mention légale
   soit affichée dans chaque formulaire :
   « Ce site est protégé par reCAPTCHA. La politique de confidentialité et les
     conditions d'utilisation de Google s'appliquent. »
   Cette mention relève du gabarit de formulaire, PAS du CSS : elle reste à
   ajouter. Voir la note de livraison.
   ========================================================================== */

.grecaptcha-badge {
  visibility: hidden;
}
