/* =============================================================================
   SEO by Belentia — v3.3, correction après critique (reprise du 23/09/2026)
   Chargée en dernier (après seo-v32.css ; seule feuille de l'outil sur
   article.html). Rien ici ne touche au kit partagé (device.css, motion.css,
   scroll.css, base.css) : ce sont des réglages propres à SEO by Belentia.
   ========================================================================== */

/* ---------------------------------------------------------------- texte */
/* Titres équilibrés, pas de mot seul en fin de paragraphe (toutes les pages). */
h1, h2, h3, .h1, .h2, .h3 { text-wrap: balance; }
p, li, figcaption, .tool__d, .guide-card__excerpt, .check__why, .fact__d { text-wrap: pretty; }
.nw { white-space: nowrap; }

/* Panneaux de travail (emplacements, captures, prompts) : jamais en
   production. Visibles seulement avec ?dev=1 (voir seo-v33.js). */
.slots { display: none; }
html.is-dev .slots { display: block; }

/* ------------------------------------------------------------ téléphones */
/* Zone de sécurité basse de l'app (34 px CSS, celle d'un iPhone) : la barre
   d'accueil se pose sur le fond de l'app, jamais sur une ligne de texte. La
   hauteur visible de chaque capture est réglée pour finir dans un blanc :
   .seo-safe-44 = vue d'ensemble (fin de la carte du score) ; la Checklist a
   son propre réglage (.seo-checklist, plus bas). 0,23256cqi est
   la hauteur d'un pixel de l'app dans l'écran (90,7cqi / 390 px). */
.dv--phone .dv__screen { background: var(--dv-status-bg, #F4F3F8); }
.dv--phone { --seo-safe: 34; }
.dv--phone.seo-safe-44 { --seo-safe: 44; }
.dv--phone .dv__view { height: calc(100% - 11.5cqi - var(--seo-safe) * .23256cqi); }
/* Boucle 2 : la zone basse ci-dessus tient déjà la dernière carte au-dessus
   de la barre d'accueil en fin de défilement ; la marge du kit
   (--dv-scroll-end, 6cqi) s'y ajouterait (double bande vide). */
.dv--phone { --dv-scroll-end: 0px; }

/* Checklist (« Le rapport, en vrai », téléphone) : aucune coupe propre n'existe
   entre deux cartes dans la hauteur de l'écran (cartes de 476 et 409 px de
   l'app). L'écran va donc jusqu'en bas, comme un vrai téléphone : 10 px de fond
   de l'app en plus au-dessus de « Méta » font tomber le bas de l'écran juste
   sous le filet de « H2 manquant », dans le blanc de la ligne suivante ; la
   barre d'accueil se pose sur ce blanc, sans texte dessous. En fin de
   défilement, la marge du kit (--dv-scroll-end) vaut ici 45 px de l'app :
   la carte « Technique » s'arrête 61 px au-dessus du bas de l'écran, et le
   haut de l'écran tombe pile sur le filet au-dessus de « Données
   structurées » (aucune ligne coupée sous la barre d'état). */
.dv--phone.seo-checklist { --seo-safe: 0; --dv-scroll-end: 10.4cqi; }
.dv--phone.seo-checklist .dv__scroller { padding-top: 2.3256cqi; }

/* Correction 3 — Checklist au repos (mouvement réduit, et pause haute du
   cycle) : la barre d'accueil (779,7-785 px d'une vue de 794,5 à 390 px ;
   777,2-782,5 sur 791,9 à 360) coinçait « Structure du contenu » contre le
   filet de « H2 manquant ». Aucune position ne met l'espace Méta / Contenu
   sous la barre (il faudrait descendre l'écran de 280 px) ; les marges
   basses des lignes (16 px) ne laissent pas 7 px de part et d'autre. Le
   repos est donc décalé de 161 px de l'app : le haut de l'écran tombe sur le
   filet au-dessus de « Title trop court/long », la barre dans l'espace de
   18 px entre les cartes « Contenu » et « Technique ».
   Boucle 4 : réglage en px d'app du kit, data-dv-top="161" sur le téléphone
   (A.html), identique en mouvement normal et réduit ; les deux fractions
   (.114 / .1177) et la position d'avant le premier cycle, désormais posée
   par le kit, sont retirées d'ici. */

/* Correction 3 — téléphones « Vue d'ensemble » en mouvement : la zone basse
   (--seo-safe 44) ne sert plus qu'à l'image fixe (mouvement réduit). Pendant
   le cycle, la vue va jusqu'au bas de l'écran et le contenu file sous la
   barre d'accueil, comme sur un iPhone (plus de coupe nette au-dessus d'une
   bande vide). Pause haute : 33 px de fond de l'app ajoutés au-dessus de
   l'en-tête (7,674cqi) font tomber la barre dans l'espace entre la carte du
   score et « Travail effectué » (738,7-757,3 px de l'app). Pause basse : la
   marge de fin du kit, ramenée à 5,5cqi (23,6 px), fait tomber le haut de
   l'écran dans l'espace entre les pastilles « 17 Important » et
   « llms.txt présent » ; la barre est 30 px sous « Pages analysées ». */
@media (prefers-reduced-motion: no-preference) {
  .dv--phone.seo-safe-44 { --seo-safe: 0; --dv-scroll-end: 5.5cqi; }
  .dv--phone.seo-safe-44 .dv__scroller { padding-top: 7.674cqi; }
}

/* ------------------------------------------------------------------ hero */
/* L'indice GEO est montré à part des catégories, comme dans l'app. */
.demo__geo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 15px;
  color: var(--text);
}
.demo__geo > span:first-child { min-width: 0; }

/* Curseur guidé : une seule séquence (frappe, clic, résultats), puis il
   s'efface. En mouvement réduit, il n'apparaît pas du tout (le champ reste
   rempli par le kit, rien ne recouvre son bord). */
.demo-zone .tour__cursor { transition: transform 600ms var(--motion-ease), opacity .45s ease; }
/* Boucle 4 : la bulle ne glisse plus d'une cible à l'autre (kit : elle se
   pose puis apparaît) ; la page ne lui rend plus de transition de position,
   seulement son fondu de fin de parcours. */
.demo-zone .tour__label { transition: opacity .3s ease; }
.demo-zone.is-tour-done .tour__cursor,
.demo-zone.is-tour-done .tour__label { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .demo-zone .tour__layer { display: none; }
  /* Rien à rejouer : le panneau est déjà complet, comme le parcours du kit
     (ni curseur, ni bulle, ni boutons en mouvement réduit). */
  #demo-replay { display: none; }
}

/* Boucle 2 — démonstration : le panneau part vide dès le premier calcul de
   style (html.demo-armed, posé dans <head> si le mouvement est permis), puis
   reset() prend le relais en ligne, transitions coupées (.is-resetting).
   Plus rien ne se vide à l'envers au chargement. */
.demo-armed #demo [data-demo-fill] { transform: scaleX(0); transition: none; }
.demo-armed #demo .demo-ring__bar { stroke-dashoffset: 326.73; transition: none; }
.demo-armed #demo [data-demo-count] { visibility: hidden; }
/* Boucle 3 — écran tactile : le kit remplace la flèche par un point de
   toucher, posé à 96 px dans le champ pendant la frappe, donc sur les
   lettres de « belentia ». Ici le point n'apparaît qu'au toucher du bouton
   (le temps de l'ondulation) : l'adresse s'écrit seule, comme au clavier. */
@media (hover: none) {
  .demo-zone .tour__cursor { opacity: 0; }
  .demo-zone:has(#hero-submit.is-tour-active) .tour__cursor { opacity: 1; }
}

#demo.is-resetting .track__fill,
#demo.is-resetting .cbar__fill,
#demo.is-resetting .demo-ring__bar { transition: none !important; }

/* Correction 3 : constats du héros. À 320-360 px, « Ko » passait seul à la
   ligne. Dans la page : nombre et unité soudés (espace insécable), libellé
   « Page très lourde » d'un seul tenant (.nw) ; la seule coupe possible
   tombe donc avant la parenthèse. Titres équilibrés. */
.demo-find__t { text-wrap: balance; }

/* Carte de démonstration : anneau à gauche et barres sur toute la largeur
   dès 600 px ; en dessous, anneau centré puis barres pleine largeur. */
@media (min-width: 600px) and (max-width: 900px) {
  .demo__grid { grid-template-columns: 168px minmax(0, 1fr); gap: var(--space-4); justify-items: stretch; align-items: center; }
}
@media (max-width: 599px) {
  .demo__grid { justify-items: stretch; }
  .demo__score { justify-items: center; }
}

/* Les trois faits du hero, sur téléphone : trois colonnes égales, coche
   au-dessus, plus de mot seul sur une deuxième ligne. */
@media (max-width: 520px) {
  .hero .ticks-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    max-width: 360px;
    margin-inline: auto;
  }
  .hero .ticks-row li {
    flex-direction: column;
    gap: 4px;
    text-align: center;
    line-height: 1.3;
    text-wrap: balance;
  }
}
/* Boucle 4 : sous 375 px, chaque colonne n'a que ≈ 104 px ; « Jusqu'à
   10 pages » passait sur deux lignes, seul des trois. En 13 px, les trois
   faits tiennent chacun sur une ligne (320 à 374 px). */
@media (max-width: 374px) {
  .hero .ticks-row li { font-size: 13px; }
}

/* ------------------------------------------------------ titres de section */
/* Une seule règle : titres de section à gauche, sauf le hero et la vitrine
   « Ce que vous obtenez », centrée autour des appareils. */

/* ---------------------------------------------------- comment ça marche */
/* Trois colonnes reliées dès 640 px (la tablette ne garde plus une colonne
   étroite collée à gauche). */
@media (min-width: 640px) and (max-width: 900px) {
  .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
  .steps__line { display: block; width: calc(66.667% + var(--space-3) * 2 / 3); }
  .step__t { font-size: 18px; }
}

/* ------------------------------------------------ explorateur (catalogue) */
/* « À part du score » : l'indice GEO sous un séparateur, pas parmi les
   sept catégories. */
.exp-sep {
  display: block;
  margin: 10px 16px 2px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
@media (max-width: 900px) {
  /* Rail horizontal : le fondu à droite dit qu'il reste des onglets. */
  .explorer .explorer__tabs {
    padding-right: 48px;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 56px), transparent);
            mask-image: linear-gradient(90deg, #000 calc(100% - 56px), transparent);
  }
  .explorer .exp-tab { justify-content: flex-start; gap: 8px; }
  .explorer .exp-tab__label { flex: 0 0 auto; }
  .explorer .exp-tab__end { gap: 6px; }
  .explorer .exp-tab:not([aria-selected="true"]) .exp-tab__on { display: none; }
  .exp-sep {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    margin: 8px 6px;
    padding: 0 0 0 14px;
    border-top: 0;
    border-left: 1px solid var(--line);
    white-space: nowrap;
  }
}
/* Boucle 3 : « Voir les N vérifications » ne mène plus à la FAQ (qui n'en
   liste aucune) ; il déplie dans le panneau la liste réelle de la catégorie
   (_assets/data/seo-checks.md, intitulés du produit sans leurs variables).
   Même respiration sous le 3ᵉ constat qu'entre deux constats. */
.explorer__all {
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}
.explorer__all > summary {
  display: inline;
  list-style: none;
  cursor: pointer;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--accent);
  border-radius: 4px;
}
.explorer__all > summary::-webkit-details-marker { display: none; }
.explorer__all > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.explorer__chev { display: inline; vertical-align: -3px; margin-left: 4px; transition: transform var(--t) var(--ease); }
.explorer__all[open] .explorer__chev { transform: rotate(180deg); }
.explorer__all-hide,
.explorer__all[open] .explorer__all-show { display: none; }
.explorer__all[open] .explorer__all-hide { display: inline; }
.explorer__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-4);
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
}
.explorer__list li {
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  font-size: 15px;
  line-height: 1.45;
  color: var(--text);
}
@media (max-width: 720px) {
  .explorer__list { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  /* Deux lignes de description, pas une ligne coupée par des points. */
  .vcheck .check__why { -webkit-line-clamp: 2; }
}

/* ------------------------------------------------- le rapport, en vrai */
/* Ordinateur : capture (onglet Checklist) et page 1 du PDF côte à côte, de
   même hauteur (colonnes 1,14 / 1 : fenêtre de navigateur barre comprise, et
   page avec sa légende, finissent sur la même ligne), les trois atouts en
   rangée dessous. Tablette : la capture en pleine largeur, puis la page du
   PDF et les atouts côte à côte. Téléphone : tout en colonne. */
.exemples__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.14fr) minmax(0, 1fr);
  grid-template-areas: "screen paper" "perks perks";
  gap: var(--space-4);
  align-items: start;
}
.exemples__screen { grid-area: screen; min-width: 0; }
#exemples .paper { grid-area: paper; margin: 0; }
.exemples__perks { grid-area: perks; }
#exemples .browser__bar { gap: 12px; }
#exemples .browser__stamp { flex: 0 0 auto; }
/* 24/09 (retour Kylian : « on n'arrive pas à lire ») : plus l'appli entière
   réduite, mais un gros plan de la carte Méta, capturé à 1024 px de large
   (zone de 700 x 424 px CSS, rendu x3). À 1440 px, le texte courant de
   l'interface s'affiche à 11,9 px au lieu de 5,8 px. Même proportion de
   fenêtre qu'avant, donc même hauteur que la page du PDF à côté. */
#exemples .browser__view { max-height: none; aspect-ratio: 700 / 424; }
#exemples .browser__view img { height: 100%; object-fit: cover; object-position: top; }
#exemples .paper__view { aspect-ratio: auto; }
#exemples .paper__view img { height: auto; }
.exemples__perks {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.exemples__perks .h3 { margin-top: var(--space-2); }
.exemples__perks p { margin-top: 6px; color: var(--text); }
@media (min-width: 721px) and (max-width: 1024px) {
  .exemples__grid {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    grid-template-areas: "screen screen" "paper perks";
    column-gap: var(--space-4);
  }
  .exemples__perks { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); margin-top: 0; }
  .exemples__perks .h3 { font-size: 18px; }
}
@media (max-width: 720px) {
  /* 24/09 : plus de capture ici sur téléphone (redite du parcours de « Ce que vous obtenez ») */
  .exemples__grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "paper" "perks"; }
  .exemples__perks { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); margin-top: var(--space-2); }
  #exemples .paper { margin-top: var(--space-2); }
}
/* 24/09, passe 2 : la page 1 entière du PDF restait illisible (7,5 px à
   1440, 5,1 px à 390). Elle est remplacée par un extrait réel, recadré dans
   le PDF rendu à 300 dpi : le bloc score + synthèse (2284 x 531). Trop large
   pour la colonne de droite, il passe sous la fenêtre, en bandeau de 880 px
   au plus (phrase de synthèse à 13,3 px), et les atouts montent à côté de la
   fenêtre. Téléphone : la seule colonne Synthèse (1355 x 290), à 9,1 px. */
.exemples__grid:has(.paper--extrait) { grid-template-areas: "screen perks" "paper paper"; align-items: center; }
.exemples__grid:has(.paper--extrait) .exemples__perks { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); margin-top: 0; }
#exemples .paper--extrait { justify-self: center; width: min(100%, 880px); margin-top: var(--space-2); }
@media (min-width: 721px) and (max-width: 1024px) {
  .exemples__grid:has(.paper--extrait) { grid-template-columns: minmax(0, 1fr); grid-template-areas: "screen" "paper" "perks"; }
  .exemples__grid:has(.paper--extrait) .exemples__perks { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .exemples__grid:has(.paper--extrait) { grid-template-areas: "paper" "perks"; }
  .exemples__grid:has(.paper--extrait) .exemples__perks { margin-top: var(--space-2); }
}

/* ------------------------------------------------------------- pour qui */
/* Atelier (boucle 4) : nouvelle photo usage-artisan-etabli.webp (établi de
   tourneur, mains sans visage, chiffon violet ; 1 800 × 1 200, 3:2) à la
   place de la vitrine (deuxième devanture de la page, intérieur beige).
   Cadrage simple en object-fit: cover, plus aucun positionnement en % : les
   anciennes règles width / left / top (ici, dans A.html et, pour la carte
   large, dans seo-v32.css) sont neutralisées. Ordinateur et tablette, 8:5 :
   la photo entière en largeur (552 × 345 à 1 440, 720 × 450 à 768, soit
   3,3 et 2,5 px de la source par px CSS). Téléphone, 4:5 : le bol, les deux
   mains et le papier de verre (279 × 349 à 390, 3,4 px de la source par px
   CSS) ; le chiffon violet reste hors cadre plutôt que tranché au bord.
   Indépendant (boucle 2) : usage-independant-carnet.webp, rendu 4:5 natif,
   affiché sans recadrage. */
#pour-qui .shot--wide .shot__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: 50% 45%;
  transform-origin: 50% 50%;
}
@media (max-width: 720px) {
  #pour-qui .shot--wide .shot__media img { object-position: 52% 50%; }
}

/* ---------------------------------------------------------------- offres */
/* La pastille « Pour un usage régulier » se pose sur le bord de la carte :
   titres, prix, listes, boutons et notes alignés d'une carte à l'autre
   (sous-grille). Même libellés sur l'accueil et sur tarifs.html. */
.plan--featured { position: relative; }
.plan .ticks { align-content: start; }
.plan--featured .plan__flag {
  position: absolute;
  top: 0;
  left: var(--space-4);
  translate: 0 -50%;
  margin: 0;
  background: var(--canvas);
  border: 1px solid var(--accent);
  color: var(--accent);
}
@media (min-width: 721px) {
  #tarifs .grid-2 > .plan,
  .grid-3.plans > .plan {
    display: grid;
    grid-row: span 5;
    grid-template-rows: subgrid;
    row-gap: var(--space-2);
    align-content: start;
  }
  #tarifs .grid-2 > .plan .btn,
  .grid-3.plans > .plan .btn { margin-top: var(--space-1); align-self: end; }
  /* Boucle 2 : les montants n'ont pas la même taille (36, 44 et 26 px) ; la
     ligne de prix s'aligne sur la ligne de base partagée de la sous-grille :
     « sans carte bancaire », « paiement unique » et « selon vos besoins »
     tombent sur la même ligne. */
  #tarifs .grid-2 > .plan > .plan__price,
  .grid-3.plans > .plan > .plan__price { align-self: baseline; }
}
@media (max-width: 720px) {
  #tarifs .grid-2 > .plan--featured { order: 0; }
  /* Même construction que le Pass Pro : nom, puis prix (plus de nom coupé
     sur deux lignes à côté du prix). */
  #tarifs .plan:not(.plan--featured) { display: flex; flex-direction: column; align-items: stretch; gap: 12px; padding: 20px; }
  #tarifs .plan:not(.plan--featured) .plan__foot { display: block; }
  #tarifs .small:has(a[href*="contact"]) { display: block; }
  .plan--featured .plan__flag { left: 20px; }
  #tarifs .plan--featured,
  .plans .plan--featured { margin-top: 10px; }
}

/* ---------------------------------------------------------- bandeau final */
/* Le réseau a un fond blanc pur : « multiply » le fond dans la carte
   lavande, sans halo ovale ni masque. */
.vis--blend { background: transparent; border-radius: 0; }
.vis--blend > img { mix-blend-mode: multiply; object-fit: contain; }

/* =============================================================== tarifs.html */
.head-vis--tarifs { grid-template-columns: minmax(0, 1fr) minmax(0, 660px); align-items: center; }
.head-vis--tarifs .head-vis__device .dv--laptop { --dv-w: clamp(600px, 46vw, 680px); }
@media (max-width: 1024px) {
  .head-vis--tarifs { grid-template-columns: minmax(0, 1fr); margin-bottom: 0; }
  /* Sous 1 024 px : deux offres côte à côte, l'accompagnement dessous. */
  .grid-3.plans { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3.plans > .plan:last-child { grid-column: 1 / -1; }
}
@media (min-width: 721px) and (max-width: 1024px) {
  /* Carte « sur devis » en pleine largeur : nom et prix à gauche, liste à
     droite, bouton et note dessous — plus de moitié droite vide. */
  .grid-3.plans > .plan:last-child {
    grid-row: auto;
    grid-template-rows: none;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    column-gap: var(--space-4);
  }
  .grid-3.plans > .plan:last-child > .h3 { grid-column: 1; grid-row: 1; }
  .grid-3.plans > .plan:last-child > .plan__price { grid-column: 1; grid-row: 2; }
  .grid-3.plans > .plan:last-child > .ticks { grid-column: 2; grid-row: 1 / span 3; margin: 0; }
  .grid-3.plans > .plan:last-child > .btn { grid-column: 1; grid-row: 3; align-self: start; justify-self: start; }
  .grid-3.plans > .plan:last-child > .plan__foot { grid-column: 1 / -1; grid-row: 4; }
}
@media (max-width: 639px) {
  .grid-3.plans { grid-template-columns: minmax(0, 1fr); }
}
/* Téléphone du rapport : après les mentions de facturation, juste avant la
   FAQ (il ne coupe plus la lecture des prix). */
.plans-device { margin-top: var(--space-6); text-align: center; }
.plans-device .dv--phone { --dv-w: 290px; }

/* ================================================================ blog.html */
.head-vis--phone { grid-template-columns: minmax(0, 1fr) minmax(0, 420px); align-items: center; margin-bottom: var(--space-6); }
.head-vis--phone .head-vis__device { display: flex; justify-content: center; }
.head-vis--phone .dv--phone { --dv-w: 250px; }
@media (max-width: 1024px) {
  .head-vis--phone { grid-template-columns: minmax(0, 1fr); margin-bottom: var(--space-5); }
}
/* Guide à la une : la même carte bordée que les deux autres guides. */
.guide-card--featured { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
.guide-card--featured .guide-card__cover { height: 100%; aspect-ratio: 3 / 2; border-bottom: 0; border-right: 1px solid var(--line); }
.guide-card--featured .guide-card__body { justify-content: center; gap: var(--space-2); padding: var(--space-5); }
.guide-card--featured .guide-card__title { font-size: 28px; line-height: 1.2; -webkit-line-clamp: 3; }
.guide-card--featured .guide-card__excerpt { -webkit-line-clamp: 3; font-size: 17px; color: var(--text); }
@media (max-width: 900px) {
  .guide-card--featured { grid-template-columns: minmax(0, 1fr); }
  .guide-card--featured .guide-card__cover { height: auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .guide-card--featured .guide-card__body { padding: var(--space-3); }
  .guide-card--featured .guide-card__title { font-size: 22px; }
}
/* Couvertures : une carte réelle de l'app, entière, sur son propre fond.
   Correction 3 : fond violet teinté franc #DCCAFB (violet de l'outil
   #7C3AED à 28 % sur blanc) au lieu du lavande à 3 % #F4F3F8, qui se lisait
   comme du gris ; la carte (pixels inchangés) garde son bord blanc net. Le
   filet gris entre la couverture et le texte de la carte prend la couleur
   du fond (bordure transparente sur le fond de l'image). */
.guide-card__cover[src*="couverture-"],
.article__cover[src*="couverture-"] { aspect-ratio: 3 / 2; object-fit: cover; background: #DCCAFB; border-color: transparent; }
#guides .guide-card__cover[src*="couverture-"] { border-color: transparent; }

/* Métadonnées d'article (boucle 2) : un seul séparateur sur les trois pages.
   Le point appartient à l'élément qui le suit et se pose dans l'espace entre
   deux éléments ; un élément qui ouvre une ligne a son point hors de la boîte,
   masqué. Ni point seul en fin de ligne, ni point en début de ligne. */
.post-meta {
  display: flex;
  flex-wrap: wrap;
  column-gap: 20px;
  row-gap: 2px;
  overflow: hidden;
}
.post-meta span { position: relative; white-space: nowrap; }
.post-meta span + span::before {
  content: "·";
  position: absolute;
  left: -10px;
  translate: -50% 0;
  color: var(--muted);
}
.post-meta span:not(:last-child)::after { content: none; }

/* En-tête des tarifs, tablette : les trois assurances en colonne (plus de
   « Paiement unique, sans abonnement » seule sur une deuxième ligne). */
@media (min-width: 721px) and (max-width: 1024px) {
  .head-vis--tarifs .ticks-row { flex-direction: column; align-items: flex-start; gap: 8px; }
}

/* Guides de l'accueil, tablette : trois cartes horizontales empilées (plus
   de troisième carte seule sur sa ligne). */
@media (min-width: 721px) and (max-width: 1024px) {
  #guides .grid-3 { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
  #guides .guide-card { display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr); }
  #guides .guide-card__cover { height: 100%; border-bottom: 0; border-right: 1px solid var(--line); }
  #guides .guide-card__body { justify-content: center; }
}

/* « Ce que l'audit ne mesure pas », ordinateur : chaque point sur une ligne. */
@media (min-width: 1025px) {
  .scope__grid { grid-template-columns: repeat(4, auto); justify-content: space-between; }
}

/* =============================================================================
   Boucle 3 (23/09) — section ambiance de l'accueil (kit _assets/ambiance.css)
   Remplace la vidéo blanc sur blanc de la loupe. Réglages relevés sur
   l'affiche : fond uni #3B188F à gauche, violet vif de l'outil pour le texte
   du bouton. Une marge blanche de section au-dessus (le gris de « Comment ça
   marche » ne touche jamais le panneau), les chiffres réels dessous.
   ========================================================================== */
.seo-amb {
  --amb-bg: #3B198F;
  --amb-ink: #7C3AED;
  --amb-pos: 64% 50%;
  --amb-pos-m: 78% 50%;
  --amb-y: var(--section-y);
}
.seo-amb .bignums { margin-top: var(--space-8); padding-top: 0; border-top: 0; }
/* Correction 3 : le titre d'ambiance ne dépasse jamais le H1 du héros
   (54 px) : 52 px au plus, et « au bon moment. » finit ≈ 75 px avant la
   devanture à 1 440. Boucle 4 : réservé à l'ordinateur (≥ 901 px, texte posé
   sur l'aplat) ; en dessous, le kit empile texte et vidéo et règle le titre
   lui-même (41,5 px à 768, 33,5 à 390, toujours sous le H1). */
@media (min-width: 901px) {
  .seo-amb .amb__title { font-size: clamp(34px, 3.7vw, 52px); }
}
/* La phrase se coupe toujours après « en premier, » (sur une seule ligne à
   1 280 px, elle frôlait la vitrine). */
.seo-amb .amb__lead { max-width: 21em; }
.seo-amb .bignum__l { text-wrap: balance; }
/* Ordinateur : le texte reste sur l'aplat uni de l'affiche, qui s'arrête à
   43,5 % de la largeur de la vidéo (calée en largeur de 901 à 1 440 px) ;
   entre 901 et 1 279 px, zone de texte à 46 % pour que la plus longue ligne
   finisse avant le bord de la vitrine. Boucle 4 : l'ancien réglage tablette
   (721-900 px, vidéo collée à gauche, colonne de 340 px) est retiré, le kit
   empile désormais texte et vidéo jusqu'à 900 px. */
@media (min-width: 901px) and (max-width: 1279px) {
  .seo-amb { --amb-text-w: 46%; }
}

/* Boucle 4 — limite de l'aplat de la vidéo. Dans la boucle, des passants
   sortent de l'aplat uni (mur violet, 42,7 à 44,2 % de la largeur de la
   vidéo selon la hauteur) : ils y étaient tranchés par une verticale nette
   (1,6-1,8 s et 2,8-3,4 s). Le voile amb--scrim du kit est posé, mais son
   profil (opacité a au bord, 0,62 a à 55 % de la fin, 0 à la fin) ne peut
   pas être opaque sur la limite sans voiler toute la vitrine éclairée :
   ici, même voile, profil propre. Couleur de l'aplat pleine jusqu'à 42 % de
   la vidéo (--amb-scrim-a), puis fondu adouci jusqu'à 48,5 %
   (--amb-scrim-end) : le passant apparaît en fondu sur ≈ 80 px de la vidéo,
   le fondu s'arrête sur le pilier et le cadre de la devanture, avant la
   vitre éclairée (50,2 %). Rien au-delà : la scène n'est ni voilée ni
   assombrie. Les positions sont exprimées en % de la zone vidéo :
   ordinateur (vidéo calée en largeur) = % de la vidéo ; tablette (16:10) et
   téléphone (4:3), vidéo calée en hauteur et cadrée à 78 % :
   x = (1 − k) × 0,78 + e × k, k = 1,105 (16:10) ou 1,326 (4:3). */
.seo-amb {
  --amb-scrim-a: 100%;
  --amb-scrim-from: 42%;
  --amb-scrim-end: 48.5%;
}
.seo-amb.amb--scrim .amb__media::after {
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--amb-bg) var(--amb-scrim-a), transparent) 0,
    color-mix(in srgb, var(--amb-bg) var(--amb-scrim-a), transparent) var(--amb-scrim-from),
    color-mix(in srgb, var(--amb-bg) calc(var(--amb-scrim-a) * .82), transparent) calc(var(--amb-scrim-from) + (var(--amb-scrim-end) - var(--amb-scrim-from)) * .25),
    color-mix(in srgb, var(--amb-bg) calc(var(--amb-scrim-a) * .5), transparent) calc(var(--amb-scrim-from) + (var(--amb-scrim-end) - var(--amb-scrim-from)) * .5),
    color-mix(in srgb, var(--amb-bg) calc(var(--amb-scrim-a) * .18), transparent) calc(var(--amb-scrim-from) + (var(--amb-scrim-end) - var(--amb-scrim-from)) * .75),
    transparent var(--amb-scrim-end));
}
@media (max-width: 900px) {
  /* le kit masque le voile une fois empilé : ici il reste, calé sur la limite */
  .seo-amb.amb--scrim .amb__media::after { display: block; }
  .seo-amb { --amb-scrim-from: 38.2%; --amb-scrim-end: 45.4%; }
}
@media (max-width: 480px) {
  .seo-amb { --amb-scrim-from: 30.3%; --amb-scrim-end: 38.9%; }
}

/* Bande de constats figée (mouvement réduit) : boucle 4, le kit ne décale
   plus une bande posée dans un .container ; l'ancien correctif de la page
   (padding-inline-start: 0) est retiré. */

/* ================================================================ blog.html */
/* Boucle 3 : en-tête avec l'affiche de l'ambiance (sans vidéo).
   Correction 3 : l'affiche entière est composée pour recevoir le texte de
   l'accueil sur son aplat violet (43,5 % de la largeur) ; seule, elle
   montrait un grand rectangle vide. Le blog prend sa découpe « scène »
   (ambiance-scene.webp, 1 220 × 1 086, x = 700 à 1 920 de l'affiche, sans
   agrandissement) : devanture, rue et passants, une bande violette de 11 %
   au bord gauche. L'image est plus étroite que son cadre à toutes les
   largeurs (1,12:1) : seul le cadrage vertical compte (object-position).
   Ordinateur : 4:3 à droite du titre (560 px, 2,2 px de la source par px
   CSS). 821-1 024 px : même disposition, image à 44 % (un bandeau pleine
   largeur n'aurait plus que 1,25 px de la source par px CSS à 1 024).
   721-820 px : bandeau 5:2 sous l'introduction (720 × 288 à 768 : vitrine
   et porte entières, il ne domine plus l'en-tête). Téléphone : 16:9 (358 ×
   201 à 390) ; en 5:2, le bandeau n'avait plus que 143 px et coupait la
   devanture au-dessus des jardinières. */
.head-vis--amb { grid-template-columns: minmax(0, 1fr) minmax(0, 560px); }
.head-vis__amb {
  margin: 0;
  overflow: hidden;
  border-radius: 28px;
  background: #3B198F;
  aspect-ratio: 4 / 3;
}
.head-vis__amb img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% var(--amb-head-y, 38%); }
@media (min-width: 821px) and (max-width: 1024px) {
  .head-vis--amb { grid-template-columns: minmax(0, 1fr) minmax(0, 44%); gap: var(--space-5); }
}
@media (max-width: 820px) {
  .head-vis--amb { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); margin-bottom: var(--space-5); }
  .head-vis__amb { aspect-ratio: 5 / 2; }
}
@media (max-width: 720px) {
  .head-vis__amb { border-radius: 24px; aspect-ratio: 16 / 9; }
}

/* =============================================================================
   Boucle 5 « vivant » (24/09/2026)
   ========================================================================== */

/* Parcours sur les appareils du rapport (accueil « Ce que vous obtenez »,
   tarifs) : le kit motion (.tour[data-tour]) clique les onglets du rapport,
   le kit bascule les écrans empilés (.tour-screens, [data-screen], fondu de
   260 ms). Les cibles sont des zones invisibles posées en % sur la capture :
   elles ne reçoivent ni contour ni décalage (seule l'onde du clic se voit,
   la capture n'est jamais recouverte). */
.seo-hit { position: absolute; display: block; }
.tour .seo-hit.is-tour-hover,
.tour .seo-hit.is-tour-active { outline: 0; box-shadow: none; transform: none; }
/* (Correction 6 : pas de .tour-hit du kit ici : il ferait viser le centre
   des onglets, le point de toucher couvrirait leur libellé ; la visée par le
   bas, vérifiée au contrôle 5, est gardée.) */
/* Pause / Rejouer sous l'appareil, dans le flux (rien n'est recouvert). */
.seo-tour__ctrls { margin-top: var(--space-5); }
.seo-tour__ctrls:empty { display: none; }
.head-vis__device .seo-tour { width: 100%; }
.head-vis__device .seo-tour .dv--laptop { margin-inline: auto; }
.head-vis__device .seo-tour__ctrls { margin-top: var(--space-4); }
/* 24/09, passe 2 (captures lisibles) : l'ordinateur du parcours montre des
   gros plans réels (zone de 600 x 375 px CSS de l'app à 920 px de large, rendu
   x3) : 17 px à l'accueil, 12,4 px dans l'en-tête de /app/upgrade.
   25/09 : le petit téléphone posé à côté de l'ordinateur est rétabli dans le
   duo (demande de Kylian). Il garde la taille du kit (21 % du duo) : son bord
   gauche tombe sur le cadre de l'ordinateur, jamais sur son écran (mesuré à
   1440 et 1024 px). Il montre les captures téléphone v3, prises dans l'app à
   390 px, et suit les onglets du parcours. Le parcours téléphone reste
   intact sous 721 px. */

/* Téléphones du parcours : écrans fixes 390 × 792 (pris en cliquant dans
   l'app). La vue s'arrête à 767 px de l'app, dans un blanc commun aux cinq
   écrans (765-769 : sous la carte du score, entre deux lignes du constat,
   sous « Meta description longueur », entre deux pages) ; la barre
   d'accueil se pose sur la zone basse, au fond de l'app. */
.dv--phone.seo-tour-phone { --seo-safe: 27; }

/* Le téléphone accompagne le rapport sans recouvrir l'écran de l'ordinateur. */
@media (min-width: 721px) {
  #obtenir .dv-duo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) clamp(200px, 23%, 250px);
    align-items: end;
    gap: clamp(20px, 2.5vw, 36px);
  }
  #obtenir .dv-duo > .dv--laptop { width: 100%; }
  #obtenir .dv-duo > .dv--phone {
    position: relative;
    right: auto;
    bottom: auto;
    width: 100%;
    margin: 0;
  }
}

/* Point de toucher sur le téléphone, même affiché sur un ordinateur : classe
   .tour--touch du kit (correction 6, le point local de 26 px faisait écart
   avec le kit). Ici seulement : il se lève entre deux gestes. */
.seo-tour--touch .tour__cursor { transition: transform 600ms var(--motion-ease), opacity .2s ease; }
.seo-tour--touch:has(.seo-hit--p-rest0.is-tour-hover, .seo-hit--p-rest1.is-tour-hover, .seo-hit--p-rest2.is-tour-hover, .seo-hit--p-rest3.is-tour-hover) .tour__cursor { opacity: 0; }

/* Contre-critique 4, mineur 2 : pas de mot seul en fin de ligne dans les
   questions de FAQ, les libellés courts et les liens fléchés. base.css le
   fait déjà, mais la règle « pretty » de cette feuille (plus haut) passait
   devant pour .tool__d : on la rétablit ici pour tous. */
.faq summary, .check__title, .ticks li > span, .step__d, .tool__d, .link-arrow { text-wrap: balance; }

/* Contre-critique 4, mineur 1 : ambiance sur tablette (481-900 px). Vidéo en
   4:3 calée en hauteur (k = 1,326) et cadrée à droite : la limite du mur
   (42,7-44,2 % de la vidéo) tombe à 24,0-26,0 % de la zone, l'aplat passe de
   38 % à 24 % de la largeur ; devanture, rue et passants remplissent les
   trois quarts de la zone. Voile recalé : x = e × k − (k − 1). */
@media (min-width: 481px) and (max-width: 900px) {
  .seo-amb {
    --amb-ratio-t: 4 / 3;
    --amb-pos-t: 100% 50%;
    --amb-scrim-from: 23.1%;
    --amb-scrim-end: 31.7%;
  }
}

/* Contre-critique 4, mineur 3 : « Pour qui » de 901 à 1 024 px. Trois cartes
   sur une ligne, l'atelier en 4:5 comme sur téléphone (bol et mains) : la
   section passe de 1 699 à ≈ 800 px à 1 024, sans photo agrandie. */
@media (min-width: 901px) and (max-width: 1024px) {
  #pour-qui .gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4) var(--space-3); }
  #pour-qui .shot--wide { grid-column: auto; }
  #pour-qui .shot--wide .shot__media { aspect-ratio: 4 / 5; }
  #pour-qui .shot--wide .shot__media img { object-position: 52% 50%; }
}
/* (Correction 6 : « curseur invisible avant le premier geste » est
   désormais dans le kit, doublon retiré.) */

/* =============================================================================
   Correction 6 (24/09/2026)
   ========================================================================== */

/* Tarifs, héros : les trois coches se dessinent l'une après l'autre jusqu'à
   ≈ 2,6 s (le script des coches pose un délai de 120 ms en ligne ; ces
   valeurs le remplacent). Mouvement réduit : coches déjà dessinées (kit). */
/* Contre-vérification du 24/09 : cascade resserrée (0 / 80 / 160 ms), plus
   de liste sans puces au premier écran. */
.seo-ticks-cascade > li:nth-child(1) { --check-delay: 0ms !important; }
.seo-ticks-cascade > li:nth-child(2) { --check-delay: 80ms !important; }
.seo-ticks-cascade > li:nth-child(3) { --check-delay: 160ms !important; }

/* Blog (à la une) et article (couverture) : un cadre violet léger (filet
   complet teinté, fond 9 %) se pose sur la première correction de la vraie
   carte « Par quoi commencer », puis glisse vers la deuxième, en boucle de
   9 s : l'ordre de l'article, lu sur la capture, sans rien ajouter. Cadre
   calé en pixels de l'image (1 800 × 1 200) : --s suit l'échelle de
   object-fit: cover, même quand la carte recadre l'image (blog à 1 024). */
.seo-cover { position: relative; overflow: hidden; }
.seo-cover > img { display: block; width: 100%; }
.guide-card--featured .seo-cover > img { height: 100%; }
.article .seo-cover { border-radius: 14px; }
/* --s, --ox, --oy : échelle et décalage de l'image dans sa boîte, posés par
   seo-v33.js (ResizeObserver) ; sans script, le cadre reste masqué. */
.seo-cover__focus {
  --px: calc(var(--s, 0) * 1px);
  --t1: calc(var(--oy, 0) * 1px + 405 * var(--px)); --h1: calc(530 * var(--px));
  --t2: calc(var(--oy, 0) * 1px + 990 * var(--px)); --h2: calc(205 * var(--px));
  position: absolute;
  left: calc(var(--ox, 0) * 1px + 205 * var(--px));
  width: calc(1390 * var(--px));
  top: var(--t1);
  height: var(--h1);
  border: 2px solid rgba(124, 58, 237, .5);
  border-radius: calc(34 * var(--px));
  background: rgba(124, 58, 237, .09);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.seo-cover.is-sized .seo-cover__focus {
  visibility: visible;
  animation: seo-cover-focus 9s cubic-bezier(.45, 0, .25, 1) .8s infinite;
}
@keyframes seo-cover-focus {
  0%   { opacity: 0; top: var(--t1); height: var(--h1); }
  6%   { opacity: 1; top: var(--t1); height: var(--h1); }
  42%  { opacity: 1; top: var(--t1); height: var(--h1); }
  52%  { opacity: 1; top: var(--t2); height: var(--h2); }
  82%  { opacity: 1; top: var(--t2); height: var(--h2); }
  90%  { opacity: 0; top: var(--t2); height: var(--h2); }
  100% { opacity: 0; top: var(--t1); height: var(--h1); }
}
@media (prefers-reduced-motion: reduce) {
  .seo-cover__focus { display: none; }
}

/* Contre-vérification du 24/09 — h1 de l'accueil : le surtitre « Audit SEO
   en ligne, en français » entre dans le h1 (mot-clé principal), même rendu. */
.seo-h1-eyebrow { margin-bottom: var(--space-2); }
.seo-h1-main { display: block; }

/* Contre-vérification du 24/09 — démonstration du hero : état d'attente
   cohérent. Avant le clic : ni valeurs de catégories, ni pastille de niveau,
   ni compteurs, ni constats, ni « pages analysées ». Tout apparaît avec son
   remplissage. Sans JavaScript ou en mouvement réduit : panneau complet. */
#demo .cbar__v, #demo .cbars__rest, #demo .demo__geo, #demo .demo__score .chip,
#demo .demo__counts, #demo .demo__findings, #demo .demo__scan-row > span:last-child {
  transition: opacity .4s ease;
}
.demo-armed #demo .cbar__v, .demo-armed #demo .cbars__rest, .demo-armed #demo .demo__geo,
.demo-armed #demo .demo__score .chip, .demo-armed #demo .demo__counts,
.demo-armed #demo .demo__findings, .demo-armed #demo .demo__scan-row > span:last-child,
#demo.is-waiting .demo__scan-row > span:last-child,
#demo.is-unscored .cbar__v, #demo.is-unscored .cbars__rest, #demo.is-unscored .demo__geo,
#demo.is-uncounted .demo__score .chip, #demo.is-uncounted .demo__counts,
#demo.is-uncounted .demo__findings { opacity: 0; }
#demo.is-resetting .cbar__v, #demo.is-resetting .cbars__rest, #demo.is-resetting .demo__geo,
#demo.is-resetting .demo__score .chip, #demo.is-resetting .demo__counts,
#demo.is-resetting .demo__findings, #demo.is-resetting .demo__scan-row > span:last-child { transition: none; }

/* Dernière passe (24/09, 5 h 35) — démonstration du hero.
   1. Barre d'adresse à 390 : la puce « Pass Pro · 15 pages » tronquait
      l'adresse (« seo.belentia.fr/audit/1… »). Sur téléphone, la barre ne
      montre que le domaine, comme Safari sur iPhone ; le chemin revient
      au-delà de 480 px.
   2. Constats : tant que la démonstration n'a pas compté (html.demo-armed,
      #demo.is-uncounted), chaque constat est masqué, pas seulement leur liste.
      Plus aucun constat opaque au chargement, même sur un écran très haut ;
      quand la liste apparaît, ils entrent un à un (délai --j du kit). */
@media (max-width: 480px) {
  #demo .seo-url-path { display: none; }
}
.demo-armed #demo .demo-find,
#demo.is-uncounted .demo-find { opacity: 0; transform: translate3d(0, 10px, 0); }

/* Boucle 9,5 (24/09, 5 h 50) — parcours du téléphone seul (≤ 720 px).
   Les bulles ne couvrent plus rien : cibles des 4 gestes en visée centrale
   ("aim": "center", même point de toucher qu'avant), la règle du kit les pose
   au-dessus de l'onglet, dans le blanc de l'en-tête de l'app, à droite du
   titre. Libellés courts (Problèmes, Checklist, Faire glisser, Les 15 pages)
   pour tenir à côté du titre dès 360 px. La bulle annonce le geste, puis
   s'efface au toucher : elle ne double pas le titre du nouvel écran. */
.seo-tour--touch:has(.seo-hit--p-problemes.is-tour-active, .seo-hit--p-checklist.is-tour-active,
  .seo-hit--p-pages.is-tour-active, .seo-hit--p-rail.is-tour-hover) .tour__label { opacity: 0; }
