/* ═══════════════════════════════════════════════════════════════════
   FACTORY LOCALE — DIRECTION ARTISTIQUE V3

   Rien ici n'invente une esthétique. Tout est relevé sur les pages Core
   servies en production le 10 septembre 2026, et transposé :

     typographie   H1 Syne 800, 99 px à 1440, interligne 0.92,
                   approche −0.042em          (relevé : /agence-referencement-naturel/)
     statements    H2 jusqu'à 86 px            (relevé : idem ; la V2 plafonnait à 54)
     hero          exactement 100 vh           (relevé : Core 900 px ; la V2 faisait 682)
     matière       grayscale(1) contrast(1.35) brightness(.62), object-fit cover,
                   boîte débordante 104–141 % de la largeur du viewport
     lisibilité    dégradé LOCALISÉ, jamais de voile noir uniforme
     fond          #06060A continu, aucune gouttière

   Le champ SVG déterministe reste, mais descend d'un rang : il n'est
   plus le sujet du hero, il est la couche signal posée sur la matière.
   ═══════════════════════════════════════════════════════════════════ */

.v3 {
  --ink: #06060A;
  --ink-2: #0B0B11;
  --ink-3: #13131E;
  --text: #E8E8F0;
  --text-2: #B8B8C4;
  --text-3: #9A9AB4;
  --line: rgba(232, 232, 240, .12);
  --line-2: rgba(232, 232, 240, .26);
  --blue: #1A6FFF;
  --blue-lift: #4A8CFF;

  --ff-d: 'Syne', system-ui, sans-serif;
  --ff-b: 'DM Sans', system-ui, sans-serif;
  --e: cubic-bezier(.16, 1, .3, 1);

  --gut: 1.5rem;
  --maxw: 1360px;

  /* Le filtre de matière du site, à la lettre. */
  --mat: grayscale(1) contrast(1.35) brightness(.62);

  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--ff-b);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

@media (min-width: 768px)  { .v3 { --gut: 2.5rem } }
@media (min-width: 1200px) { .v3 { --gut: 4rem } }

.v3 *, .v3 *::before, .v3 *::after { box-sizing: border-box }
.v3 img, .v3 video { display: block; max-width: 100% }
.v3 a { color: inherit }
.v3 em { font-style: normal; color: var(--blue-lift) }
.v3 ::selection { background: var(--blue); color: var(--ink) }
.v3 :focus-visible { outline: 2px solid var(--blue-lift); outline-offset: 4px; border-radius: 2px }

.v3 .wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut) }

/* Le fond du document appartient à la page. Sans cette règle, le rebond
   de défilement de macOS découvre le blanc du thème sous une page à
   l'encre — mesuré en production sur sept des huit villes. */
/* Deux classes pour un seul contrat : abcdt-bleed est celle que l'entrée
   de registre réclame en production, v3-bleed celle des aperçus. */
body.v3-bleed, body.abcdt-bleed { background: #06060A; margin: 0; padding-block: 0; overflow-x: clip; color-scheme: dark }
html body.v3-bleed .site-main,
html body.v3-bleed .page-content,
html body.v3-bleed .site-main > .page-content,
html body.abcdt-bleed .site-main,
html body.abcdt-bleed .page-content,
html body.abcdt-bleed .site-main > .page-content {
  max-width: none; width: 100%; margin-inline: 0; padding-inline: 0;
}

/* ── LIENS TYPOGRAPHIQUES — grammaire Core ─────────────────────────── */
.v3 .tl {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .35rem 0; font-family: var(--ff-b); font-size: 1rem; font-weight: 500;
  color: var(--text); text-decoration: none; border-bottom: 1px solid var(--line-2);
  transition: color .25s var(--e), border-color .25s var(--e);
}
.v3 .tl::after { content: '→'; transition: transform .3s var(--e) }
.v3 .tl:hover { color: var(--blue-lift); border-bottom-color: var(--blue) }
.v3 .tl:hover::after { transform: translateX(5px) }
.v3 .tl--lg { font-family: var(--ff-d); font-weight: 600; font-size: clamp(1.05rem, 2.2vw, 1.35rem); letter-spacing: -.01em }
.v3 .tl--min { border-bottom: 0; padding: 0; font-size: .92rem; color: var(--text-3) }
.v3 .tl--min:hover { color: var(--text) }

.v3 .eyebrow {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  margin: 0 0 1.5rem; font-size: .7rem; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase; color: var(--text-3);
}
/* Le filet de l'eyebrow Core : EXPERTISE ——— NOM */
.v3 .eyebrow__r { flex: 0 0 3.5rem; height: 1px; background: var(--line-2) }
.v3 .eyebrow__n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem; border: 1px solid var(--line-2); border-radius: 50%;
  font-size: .66rem; letter-spacing: .04em; color: var(--blue-lift);
  font-variant-numeric: tabular-nums;
}

/* ── MATIÈRE ───────────────────────────────────────────────────────── */
.v3 .mat { position: absolute; inset: 0; overflow: hidden; z-index: 0 }
.v3 .mat > video, .v3 .mat > img {
  position: absolute; inset: 50% auto auto 50%; transform: translate(-50%, -50%);
  width: 104%; height: 104%; object-fit: cover; filter: var(--mat);
}
/* Un plan qui n'a pas encore chargé montre son poster : la matière est
   là dès la première image, elle n'attend pas la vidéo. */
.v3 .mat > video { background: var(--ink) }

/* Lisibilité : un dégradé LOCALISÉ du côté du texte, pas un voile. Le
   reste de l'image garde sa densité — c'est ce qui distingue une page
   Core d'une bannière avec un calque noir à 70 %. */
.v3 .mat__veil { position: absolute; inset: 0; z-index: 1; pointer-events: none }
.v3 .mat__veil--gauche {
  background:
    linear-gradient(100deg, rgba(6,6,10,.94) 0%, rgba(6,6,10,.86) 26%, rgba(6,6,10,.42) 52%, rgba(6,6,10,.06) 74%, rgba(6,6,10,0) 100%),
    linear-gradient(to top, rgba(6,6,10,.72) 0%, rgba(6,6,10,0) 34%);
}
.v3 .mat__veil--bas {
  background:
    linear-gradient(to top, rgba(6,6,10,.96) 0%, rgba(6,6,10,.72) 22%, rgba(6,6,10,.12) 58%, rgba(6,6,10,0) 100%),
    radial-gradient(120% 80% at 20% 100%, rgba(6,6,10,.7) 0%, rgba(6,6,10,0) 60%);
}
.v3 .mat__veil--bord {
  background:
    linear-gradient(to right, rgba(6,6,10,.9) 0%, rgba(6,6,10,0) 24%),
    linear-gradient(to left, rgba(6,6,10,.9) 0%, rgba(6,6,10,0) 18%),
    linear-gradient(to top, rgba(6,6,10,.86) 0%, rgba(6,6,10,0) 40%);
}
/* Le signal bleu du site, posé une seule fois par écran. */
.v3 .mat__signal {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(46% 52% at var(--sx, 72%) var(--sy, 44%), rgba(26,111,255,.30) 0%, rgba(26,111,255,.10) 34%, rgba(26,111,255,0) 68%);
  mix-blend-mode: screen;
}

/* ── HERO — trois compositions ─────────────────────────────────────── */
.v3 .hero { position: relative; min-height: 100vh; min-height: 100svh; display: flex; align-items: flex-end; overflow: hidden }
.v3 .hero__in { position: relative; z-index: 2; width: 100%; padding-block: clamp(3rem, 9vh, 6rem) }
.v3 .hero h1 {
  margin: 0 0 1.6rem; font-family: var(--ff-d); font-weight: 800; color: #fff;
  font-size: clamp(2.9rem, 6.9vw, 6.2rem); line-height: .92; letter-spacing: -.042em;
  text-wrap: balance;
}
.v3 .hero h1 em { font-style: normal; color: var(--blue-lift) }
.v3 .hero__lede { margin: 0 0 2.4rem; max-width: 46ch; color: var(--text-2); font-size: 1.0625rem; line-height: 1.6 }
.v3 .hero__lede b { color: #fff; font-weight: 500 }
.v3 .hero__acts { display: flex; flex-wrap: wrap; align-items: baseline; gap: 1.2rem 2.2rem }
.v3 .hero__meta {
  display: flex; flex-wrap: wrap; gap: .5rem 2rem; margin: 2.8rem 0 0;
  padding-top: 1.4rem; border-top: 1px solid var(--line);
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.v3 .hero__meta b { color: var(--text-2); font-weight: 500 }

/* A — CINEMATIC : la matière occupe tout le cadre, la typo est dessus. */
.v3 .hero--a .hero__in { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut) }
.v3 .hero--a h1 { max-width: 15ch }

/* B — EDITORIAL SPLIT — LE SYSTÈME RETENU
   ────────────────────────────────────────────────────────────────────
   Colonne de texte à l'encre, fenêtre de matière pleine hauteur à
   droite. Grammaire relevée sur le hero d'accueil : hero__win mesure
   662 px sur 1440, soit 46 %.

   Ce n'est pas un choix de goût. Sur une matière plein cadre, le pire
   cas est une image blanche : il faut alors un voile à α ≥ 0,97 pour
   que les petites capitales #9A9AB4 tiennent 4,5:1 — c'est-à-dire un
   rectangle noir, exactement ce que le §14 interdit. Ici le texte est
   sur l'encre : 16,6:1 pour le texte courant, 7,4:1 pour les petites
   capitales, 6,2:1 pour l'accent bleu. Garanti par construction, quelle
   que soit l'image, sur soixante-dix pages comme sur trois.
   ──────────────────────────────────────────────────────────────────── */
.v3 .hero--b { display: grid; grid-template-columns: 1fr; align-items: stretch; min-height: 100vh; min-height: 100svh }
.v3 .hero--b .hero__col {
  position: relative; z-index: 2; display: flex; flex-direction: column; justify-content: center;
  padding: clamp(7rem, 16vh, 10rem) var(--gut) clamp(3rem, 8vh, 5rem);
  max-width: var(--maxw); margin-inline: auto; width: 100%;
}
/* Au téléphone, la matière passe DEVANT le texte : sinon le premier
   viewport ne montre qu'une colonne de mots, et il faut défiler pour
   voir une image. Mesuré à 430 × 932 : la fenêtre occupe 40 % de la
   hauteur, le titre commence juste dessous et tient dans le pli. */
.v3 .hero--b .hero__win { position: relative; overflow: hidden; min-height: 40vh; order: -1 }
.v3 .hero--b .hero__col { order: 0 }
.v3 .hero--b .hero__win .mat > video, .v3 .hero--b .hero__win .mat > img { width: 100%; height: 100% }
@media (min-width: 1024px) {
  .v3 .hero--b { grid-template-columns: 54fr 46fr }
  .v3 .hero--b .hero__col {
    padding-inline: max(var(--gut), calc((100vw - var(--maxw)) / 2 + var(--gut)));
    padding-right: clamp(2.5rem, 5vw, 5rem); max-width: none; margin: 0;
    padding-block: clamp(8rem, 18vh, 11rem) clamp(3.5rem, 9vh, 6rem);
  }
  .v3 .hero--b .hero__win { min-height: 100vh; min-height: 100svh; order: 0 }
  /* L'autorité typographique des pages Core : 82 px dans une colonne de
     823 px à l'accueil ; ici 5.6vw plafonné à 5.2rem, soit 83 px dans
     une colonne de 778 px. Même densité, même présence. */
  .v3 .hero--b h1 { font-size: clamp(2.9rem, 5.6vw, 5.2rem); max-width: 13ch }
  .v3 .hero--b .hero__lede { max-width: 40ch }
}
/* La fenêtre ne coupe pas net : elle se fond dans l'encre sur son bord
   gauche et son bord haut. Un rectangle net ferait « bloc média », ce
   que le §12 refuse. */
.v3 .hero--b .hero__win::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(to top, var(--ink) 0%, rgba(6,6,10,.6) 14%, rgba(6,6,10,0) 42%);
}
@media (min-width: 1024px) {
  .v3 .hero--b .hero__win::after {
    background:
      linear-gradient(to bottom, var(--ink) 0%, rgba(6,6,10,.55) 9%, rgba(6,6,10,0) 26%),
      linear-gradient(to right, var(--ink) 0%, rgba(6,6,10,.5) 5%, rgba(6,6,10,0) 20%);
  }
}
/* La couche signal appartient à la matière, pas au texte : c'est là que
   le champ SVG déterministe trouve sa place (§28). */
.v3 .hero--b .hero__field { opacity: .34 }

/* C — IMMERSIVE SIGNAL : matière plein cadre + champ SVG en surimpression. */
.v3 .hero--c .hero__in { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut) }
.v3 .hero--c h1 { max-width: 13ch }
.v3 .hero__field {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  mix-blend-mode: screen; opacity: .3;
  /* Le champ s'efface là où le texte se lit : il n'est jamais un motif
     posé sur une phrase. */
  -webkit-mask-image: linear-gradient(100deg, transparent 0%, transparent 34%, #000 62%, #000 100%);
          mask-image: linear-gradient(100deg, transparent 0%, transparent 34%, #000 62%, #000 100%);
}
.v3 .hero__field svg { width: 100%; height: 100% }

/* Le champ, quel que soit son emploi. */
.v3 .loc-field { display: block; width: 100%; height: 100% }
.v3 .loc-field__grid line { stroke: rgba(232,232,240,.05); stroke-width: 1 }
.v3 .loc-field__web line { stroke: var(--blue-lift); stroke-width: .8 }
.v3 .loc-field__nodes circle { fill: rgba(232,232,240,.42) }
.v3 .loc-field__pulse circle { fill: none; stroke: rgba(26,111,255,.20); stroke-width: 1 }
.v3 .loc-field__focal circle { fill: var(--blue) }
.v3 .loc-field__focal .loc-field__halo { fill: rgba(26,111,255,.22) }

/* ── STATEMENT — le grand message pleine largeur ───────────────────── */
.v3 .st { position: relative; padding-block: clamp(6rem, 16vh, 11rem); overflow: hidden }
.v3 .st__in { position: relative; z-index: 2; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut) }
.v3 .st h2 {
  margin: 0; font-family: var(--ff-d); font-weight: 800; color: #fff;
  font-size: clamp(2rem, 5.9vw, 5.4rem); line-height: .96; letter-spacing: -.038em;
  max-width: 17ch; text-wrap: balance;
}
.v3 .st h2 em { font-style: normal; color: var(--blue-lift) }
.v3 .st__p { margin: 2.2rem 0 0; max-width: 58ch; color: var(--text-2); font-size: 1.0625rem }
.v3 .st__p + .st__p { margin-top: 1.1rem }
.v3 .st--mat { min-height: 78vh; display: flex; align-items: center }

/* ── SÉQUENCE — l'expertise en lignes, jamais en grille de cartes ──── */
.v3 .sq { padding-block: clamp(4.5rem, 11vh, 8rem) }
.v3 .sq__head { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut); margin-bottom: clamp(2.5rem, 6vh, 4rem) }
.v3 .sq__head h2 {
  margin: 0; font-family: var(--ff-d); font-weight: 700; color: #fff;
  font-size: clamp(1.6rem, 3.4vw, 2.9rem); line-height: 1.04; letter-spacing: -.03em; max-width: 22ch;
}
.v3 .sq__l { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut); list-style: none; margin-block: 0 }
.v3 .sq__i { display: grid; gap: .4rem 2.5rem; padding-block: clamp(1.6rem, 3.4vh, 2.4rem); border-top: 1px solid var(--line) }
.v3 .sq__i:last-child { border-bottom: 1px solid var(--line) }
@media (min-width: 900px) { .v3 .sq__i { grid-template-columns: 5rem minmax(0, 26ch) minmax(0, 1fr) } }
.v3 .sq__n { margin: 0; font-family: var(--ff-d); font-weight: 600; font-size: .78rem; letter-spacing: .12em; color: var(--blue-lift); font-variant-numeric: tabular-nums }
.v3 .sq__t { margin: 0; font-family: var(--ff-d); font-weight: 600; font-size: clamp(1.05rem, 1.9vw, 1.3rem); line-height: 1.2; letter-spacing: -.018em; color: #fff }
.v3 .sq__d { margin: 0; color: var(--text-2); font-size: .97rem; max-width: 62ch }
/* Le survol allume la ligne entière : une seule micro-interaction,
   la même que les listes Core. */
.v3 .sq__i { transition: background .35s var(--e) }
@media (hover: hover) { .v3 .sq__i:hover { background: linear-gradient(to right, rgba(26,111,255,.06), rgba(26,111,255,0) 60%) } }

/* ── BANDE — le deuxième moment visuel ─────────────────────────────── */
.v3 .bd { position: relative; min-height: 92vh; display: flex; align-items: flex-end; overflow: hidden }
.v3 .bd__in { position: relative; z-index: 2; width: 100%; max-width: var(--maxw); margin-inline: auto; padding: 0 var(--gut) clamp(3.5rem, 10vh, 6rem) }
.v3 .bd h2 {
  margin: 0 0 1.4rem; font-family: var(--ff-d); font-weight: 800; color: #fff;
  font-size: clamp(2.1rem, 6.4vw, 5.8rem); line-height: .94; letter-spacing: -.04em; max-width: 16ch;
}
/* Sans cette règle, Syne n'ayant pas d'italique dessinée, le navigateur
   en synthétise une : l'accent bleu devenait un faux oblique. */
.v3 .bd h2 em { font-style: normal; color: var(--blue-lift) }
.v3 .bd__p { margin: 0; max-width: 52ch; color: var(--text-2) }
.v3 .bd__k { display: flex; flex-wrap: wrap; gap: .6rem 2.4rem; margin: 2.4rem 0 0; padding-top: 1.3rem; border-top: 1px solid var(--line);
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-3) }

/* ── MÉTHODE — colonne collante, pas de cartes ─────────────────────── */
.v3 .mt { padding-block: clamp(4.5rem, 11vh, 8rem) }
.v3 .mt__g { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut); display: grid; gap: 2.5rem }
@media (min-width: 1024px) { .v3 .mt__g { grid-template-columns: 38fr 62fr; gap: 4rem; align-items: start } }
.v3 .mt__aside { position: static }
@media (min-width: 1024px) { .v3 .mt__aside { position: sticky; top: 8rem } }
.v3 .mt__aside h2 {
  margin: 0; font-family: var(--ff-d); font-weight: 700; color: #fff;
  font-size: clamp(1.7rem, 3.6vw, 3rem); line-height: 1.02; letter-spacing: -.032em;
}
.v3 .mt__fig { margin: 2rem 0 0; position: relative; aspect-ratio: 4/3; overflow: hidden; border: 1px solid var(--line) }
.v3 .mt__p { margin: 0 0 1.6rem; color: var(--text-2); font-size: 1.0625rem; max-width: 64ch }
.v3 .mt__p:last-child { margin-bottom: 0 }
.v3 .mt__p b { color: #fff; font-weight: 500 }

/* ── PREUVE ────────────────────────────────────────────────────────── */
.v3 .pr { padding-block: clamp(4rem, 10vh, 7rem) }
.v3 .pr__g { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut) }
.v3 .pr__k { display: grid; gap: 0; margin: 0 0 2.6rem }
@media (min-width: 760px) { .v3 .pr__k { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 2.5rem } }
.v3 .pr__ki { padding-block: 1.3rem; border-top: 1px solid var(--line) }
.v3 .pr__kn { margin: 0; font-family: var(--ff-d); font-weight: 800; font-size: clamp(2.2rem, 5vw, 3.4rem); line-height: 1; letter-spacing: -.04em; color: #fff; font-variant-numeric: tabular-nums }
.v3 .pr__kl { margin: .5rem 0 0; font-size: .86rem; color: var(--text-3) }
.v3 .pr__q { margin: 0; max-width: 44ch }
.v3 .pr__q p { margin: 0; font-family: var(--ff-d); font-weight: 500; font-size: clamp(1.1rem, 2.2vw, 1.45rem); line-height: 1.36; letter-spacing: -.018em; color: #fff }
.v3 .pr__q footer { margin: 1.1rem 0 0; font-size: .84rem; color: var(--text-3) }

/* ── CONTACT — la brique validée du site, reprise telle quelle ─────── */
.v3 .end { position: relative; overflow: hidden; padding-block: clamp(5rem, 13vh, 9rem) }
.v3 .end__in { position: relative; z-index: 2; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut) }
.v3 .end h2 {
  margin: 0; font-family: var(--ff-d); font-weight: 700; color: #fff;
  font-size: clamp(1.9rem, 5vw, 3.4rem); line-height: 1.02; letter-spacing: -.034em; max-width: 18ch; text-wrap: balance;
}
.v3 .end__p { margin: 1.6rem 0 0; max-width: 56ch; color: var(--text-2) }
.v3 .end__acts { display: flex; flex-wrap: wrap; gap: 1.3rem 2.4rem; margin-top: 2.6rem }
.v3 .end__co { margin: 2.8rem 0 0; padding-top: 1.6rem; border-top: 1px solid var(--line); display: flex; flex-wrap: wrap; gap: .4rem 2rem; font-size: .86rem; color: var(--text-3) }
.v3 .end__co a { color: var(--text-2); text-decoration: none; border-bottom: 1px solid var(--line) }
.v3 .end__co a:hover { color: var(--blue-lift); border-bottom-color: var(--blue) }

/* ── RÉVÉLATION — contrat identique aux pages Core ─────────────────── */
.js-motion .v3 .v3-rv { opacity: 0; transform: translateY(20px); transition: opacity .8s var(--e), transform .8s var(--e) }
.js-motion .v3 .v3-rv.is-in { opacity: 1; transform: none }
@media (prefers-reduced-motion: reduce) {
  .js-motion .v3 .v3-rv { opacity: 1; transform: none; transition: none }
  .v3 * { animation: none !important }
}

/* ── HUB ───────────────────────────────────────────────────────────── */
.v3 .hb { padding-block: clamp(4.5rem, 11vh, 8rem) }
.v3 .hb__g { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut) }
.v3 .hb__fam { border-top: 1px solid var(--line) }
.v3 .hb__fam:last-of-type { border-bottom: 1px solid var(--line) }
.v3 .hb__s { display: grid; gap: .3rem 2rem; padding-block: clamp(1.8rem, 4vh, 2.6rem); align-items: baseline }
@media (min-width: 900px) { .v3 .hb__s { grid-template-columns: 5rem minmax(0, 30ch) minmax(0, 1fr) } }
.v3 .hb__n { margin: 0; font-family: var(--ff-d); font-weight: 600; font-size: .78rem; letter-spacing: .12em; color: var(--blue-lift); font-variant-numeric: tabular-nums }
.v3 .hb__t { margin: 0; font-family: var(--ff-d); font-weight: 700; font-size: clamp(1.3rem, 2.8vw, 2rem); line-height: 1.06; letter-spacing: -.028em; color: #fff }
.v3 .hb__d { margin: 0; color: var(--text-2); font-size: .97rem; max-width: 56ch }
.v3 .hb__l { list-style: none; margin: 1.4rem 0 0; padding: 0; display: grid; gap: 0 2rem; grid-template-columns: minmax(0, 1fr) }
@media (min-width: 620px) { .v3 .hb__l { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
@media (min-width: 1024px) { .v3 .hb__l { grid-template-columns: repeat(4, minmax(0, 1fr)) } }
.v3 .hb__li { border-top: 1px solid var(--line) }
.v3 .hb__li a { display: block; padding: .85rem 0; text-decoration: none; color: var(--text-2); transition: color .25s var(--e), padding-left .25s var(--e) }
.v3 .hb__li a:hover { color: #fff; padding-left: .4rem }
.v3 .hb__ville { display: block; font-family: var(--ff-d); font-weight: 600; font-size: 1.02rem; letter-spacing: -.012em; color: inherit }
.v3 .hb__angle { display: block; margin-top: .2rem; font-size: .82rem; color: var(--text-3); line-height: 1.4 }
.v3 .hb__li a:hover .hb__angle { color: var(--text-2) }
.v3 .hb__vide { margin: 1.2rem 0 0; font-size: .92rem; color: var(--text-3); max-width: 60ch }

.v3 .sp { max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut); display: grid; gap: 1.6rem 2.5rem }
@media (min-width: 760px) { .v3 .sp { grid-template-columns: repeat(3, minmax(0, 1fr)) } }
.v3 .sp__i { border-top: 1px solid var(--line); padding-top: 1.2rem }
.v3 .sp__e { margin: 0 0 .4rem; font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--text-3) }
.v3 .sp__t { margin: 0 0 .5rem; font-family: var(--ff-d); font-weight: 600; font-size: 1.05rem; letter-spacing: -.015em; color: #fff }
.v3 .sp__d { margin: 0; font-size: .94rem; color: var(--text-2) }

/* Sources — Lyon est la seule page du corpus à citer les siennes.
   Elles se lisent comme un appareil de note, pas comme du contenu. */
.v3 .st__src { list-style: none; margin: 2.6rem 0 0; padding: 1.3rem 0 0; border-top: 1px solid var(--line); display: grid; gap: .7rem }
@media (min-width: 760px) { .v3 .st__src { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .7rem 2.5rem } }
.v3 .st__src li { display: grid; gap: .15rem; font-size: .8rem }
.v3 .st__src b { color: var(--text-2); font-weight: 500 }
.v3 .st__src span { color: var(--text-3); font-size: .74rem; letter-spacing: .04em }

/* Une situation n'a pas de glose : elle occupe la colonne de texte. */
@media (min-width: 900px) { .v3 .sq__i--large { grid-template-columns: 5rem minmax(0, 1fr) } }

/* ═══════════════════════════════════════════════════════════════════
   EN-TÊTE FACTICE — APERÇUS SEULEMENT

   L'en-tête et le pied de page du site sont LOCKED : ils ne sont pas
   modifiés, et ils ne sont pas non plus reproduits en production. Mais
   une planche qui compare une page Core AVEC son en-tête à une page
   locale SANS le sien ne compare pas le même premier viewport. Cette
   pastille inerte occupe exactement la place de l'en-tête réel — 76 px
   de haut, encart flottant, 40 px de marge — pour que le jugement porte
   sur la composition et pas sur un manque.
   ═══════════════════════════════════════════════════════════════════ */
.v3-nav { position: fixed; inset: 0 0 auto 0; z-index: 50; padding: 20px; pointer-events: none }
.v3-nav__p {
  display: flex; align-items: center; gap: 1.4rem; height: 56px; padding: 0 8px 0 22px;
  max-width: 1310px; margin-inline: auto;
  background: rgba(11, 11, 17, .82); border: 1px solid rgba(232, 232, 240, .1);
  border-radius: 999px; backdrop-filter: blur(14px);
  font-family: 'DM Sans', system-ui, sans-serif;
}
.v3-nav__logo { display: grid; font-family: 'Syne', system-ui, sans-serif; font-weight: 800; font-size: 1.05rem; letter-spacing: -.02em; color: #fff; line-height: 1 }
.v3-nav__logo small { font-size: .38rem; letter-spacing: .12em; color: #9A9AB4; font-weight: 500 }
.v3-nav__i { font-size: .74rem; letter-spacing: .04em; color: #B8B8C4; white-space: nowrap }
.v3-nav__s { flex: 1 }
.v3-nav__cta {
  margin-left: auto; padding: .6rem 1.1rem; border-radius: 999px;
  background: #1A6FFF; color: #fff; font-size: .8rem; font-weight: 500; white-space: nowrap;
}
@media (max-width: 1023px) { .v3-nav__i { display: none } }

/* Le hub porte un titre plus long qu'une ville : « SEO à Paris » tient
   sur deux lignes, « Nos expertises, marché par marché » non. On lui
   donne un cran de moins pour qu'il tienne dans le premier viewport. */
@media (min-width: 1024px) {
  .v3 .hero--hub h1 { font-size: clamp(2.6rem, 4.4vw, 4.1rem); max-width: 15ch }
}
