/* ============================================================
   Immigration Voyages — immigration-voyage.com
   Charte rouge & blanc, version épurée
   Polices : Sora (titres) + Inter (texte)
   Mobile-first, aucun framework

   v3 — 22/08/2026 : corrections de l'audit d'interface
   - #65 cibles tactiles ≥ 44 px sous 768 px (liens de cartes, pied de page,
     barre supérieure, FR/EN, bouton menu, réseaux, boutons, champs)
   - #66 aucun texte < 14 px sous 768 px (--fs-xs passe à .875rem ;
     accroche de marque 11 px, seule exception)
   - #67 contraste : tout texte rouge et tous les fonds de boutons rouges
     passent à --red-dark (6,16:1) ; --red reste aux gros titres et icônes
   - #18 plus de flou d'arrière-plan (backdrop) sur la barre collante (fond .97)
   - #19 plus de transition « all »
   - #36 plus de noir pur : --navy-darker
   - #37 verts WhatsApp → --teal / --teal-dark ; pêche FFD9A0 → --amber-light
   - #38 échelle typographique : 8 paliers --fs-* (aucune taille écrite en dur)
   - #39 rayons --r-sm / --r / --r-lg / --r-pill ; ombres --shadow / --shadow-sm / --ring
   - #40 couleurs de la charte toujours par leur variable
   - #43 .btn 12px 24px (gap 8), .btn-sm 8px 16px — grille de 4 px
   - #44 plus de police serif sur le guillemet des témoignages
   - #6  .footer-titre (remplaçant des <h4> du pied de page)
   - #25 .iv-bandeau-langue (bandeau de langue, préparation)
   ============================================================ */

:root {
  --red: #E8231A;         /* rouge logo — gros titres (≥ 24 px), icônes, bordures d'accent */
  --red-dark: #C21510;    /* TOUT texte rouge courant (6,16:1 sur blanc) */
  /* Le rouge qui sert de FOND sous du texte blanc. Distinct de --red-dark
     parce qu'il doit S'ASSOMBRIR en theme sombre, quand l'encre s'eclaircit :
     une seule variable ne peut pas faire les deux. Sans lui, chaque page qui
     porte un bouton rouge devait ecrire son propre bloc sombre. */
  --red-fond: #C21510;
  /* L'ENCRE QUI NE BASCULE JAMAIS. --white nomme une SURFACE : elle devient
     sombre en theme nuit. Sur un fond rouge ou noir — qui, lui, ne bascule
     pas — il faut une encre qui reste claire. Confondre les deux, c'est
     ecrire en bleu nuit sur du rouge : mesure 1,79:1 sur les titres de
     « Votre itineraire avec nous ». */
  --sur-couleur: #FFFFFF;
  /* L'ambre pâle qui s'écrit SUR un fond rouge : elle non plus ne
     bascule pas, puisque le fond sous elle ne bascule pas. */
  --sur-couleur-ambre: #FBF3DC;
  /* Le FOND sombre qui reste sombre dans les deux themes. --navy-dark, lui,
     bascule en clair la nuit (c'est une couleur de TITRE) : du blanc pose
     dessus tombait a 1,14:1 — le selecteur de devise de Prepa TCF. */
  --fond-sombre: #171314;
  --red-deep: #8F0E0B;    /* survol des boutons rouges, fin des dégradés */
  --red-ink: #8F0E0B;     /* l'ENCRE rouge sur fond rose ; en sombre, elle s'eclaircit */
  --navy: #B31410;        /* alias historiques conservés */
  --navy-dark: #171314;   /* quasi noir neutre — titres, blocs sombres */
  --navy-deep: #171314;
  --navy-darker: #0F0C0D; /* survol des blocs sombres — jamais de noir pur */
  --blue: #D31E14;        /* survols, focus */
  --teal: #128C4B;        /* vert succès (coches, WhatsApp) */
  --teal-dark: #0E7A40;   /* survol WhatsApp */
  --teal-light: #E9F8EF;
  /* L'ENCRE verte : ce qui s'ecrit SUR --teal-light. Elle doit s'eclaircir
     en theme sombre, comme --amber-ink et --red-ink — sinon le vert fonce
     se pose sur un fond vert fonce (1,96:1 mesure). */
  --teal-ink: #0A5C33;
  --amber: #C79A2A;       /* or discret */
  --amber-light: #FBF3DC;
  --amber-ink: #7A5A10;   /* l'encre des notes ambrees ; en sombre, elle s'eclaircit */
  --ink: #1F1B1A;
  --muted: #6B6462;
  --line: #ECE9E8;
  --bg: #FAFAF9;
  --blush: #FDF0EF;       /* rose très pâle — pastilles d'icônes */
  --white: #FFFFFF;
  --maxw: 1280px;

  /* Échelle d'espacement (v4, 30/08) — NEUF paliers, pas un de plus.
     Née de l'audit : les écarts entre blocs valaient 8, 10, 12, 13, 14, 16,
     18, 20, 22, 24, 26, 30, 34, 40, 44, 46, 50, 56, 64 px — vingt-et-une
     valeurs décidées une par une. Personne ne le remarque consciemment ;
     tout le monde le ressent. Toute nouvelle marge passe par un de ces neuf. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 40px;
  --sp-8: 48px;
  --sp-9: 64px;

  /* Rayons (v3) — quatre valeurs, pas une de plus */
  --r-sm: 8px;            /* petits éléments : champs, puces, barres */
  --r: 12px;              /* boutons, cartes, pastilles d'icônes */
  --r-lg: 20px;           /* grands blocs : hero-card, cta-band, why-visual */
  --r-pill: 999px;        /* pilules et traits */

  /* Ombres (v3, affinées le 10/09/2026) — deux ombres et un anneau de focus,
     rien d'autre. Chaque ombre a DEUX couches : un contact net d'un pixel et
     une portée douce. Une ombre d'une seule couche floue flotte sans se poser. */
  --shadow: 0 1px 2px rgba(23, 19, 20, .05), 0 12px 32px rgba(23, 19, 20, .09);
  --shadow-sm: 0 1px 2px rgba(23, 19, 20, .05), 0 4px 14px rgba(23, 19, 20, .05);
  --ring: 0 0 0 4px rgba(232, 35, 26, .12);
  /* Le trait des champs et des boutons clairs (10/09/2026) : il était écrit en
     dur, en trois gris voisins (#DDD8D7, #D8D3D2, #D9D3D1). */
  --line-strong: #DDD8D7;
  /* Le mouvement (10/09/2026) : une seule courbe, qui part vite et se pose. */
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  /* L'interlettrage des grands titres, en em : il suit la taille du titre. */
  --tracking-display: -0.028em;
  --tracking-title: -0.02em;
  /* La barre de défilement du navigateur, aux couleurs de la page. */
  --scroll-thumb: #CFC7C4;

  /* Échelle typographique (v3) — huit paliers, toute taille passe par l'un d'eux */
  --fs-xs: .75rem;        /* 12 px — mentions, badges (14 px sur téléphone, voir plus bas) */
  --fs-sm: .875rem;       /* 14 px — texte secondaire, liens de cartes, pied de page */
  --fs-base: .9375rem;    /* 15 px — texte courant des cartes, boutons, menu */
  --fs-md: 1rem;          /* 16 px — corps, champs de saisie, H3 */
  --fs-lg: 1.125rem;      /* 18 px — H3 fort, prix, sous-titres */
  --fs-xl: 1.5rem;        /* 24 px — H2 de carte, gros chiffres fixes */
  /* 10/09/2026 : plus d'assurance sur grand écran (h1 50 → 53 px, h2 34 → 38 px),
     les mêmes tailles qu'avant au téléphone. */
  --fs-h2: clamp(1.5rem, 1.1rem + 1.6vw, 2.375rem);
  --fs-h1: clamp(1.9rem, 1.2rem + 3.2vw, 3.3rem);
}
/* Téléphone : plancher de 14 px — le plus petit palier remonte, tout ce qui l'utilise suit */
@media (max-width: 768px) {
  :root { --fs-xs: .875rem; }
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* ⚠️ « hidden » DOIT CACHER. À poser AVANT tout le reste, et à ne jamais retirer.
   ------------------------------------------------------------------------
   Le navigateur cache un élément « hidden » avec une règle de priorité
   MINIMALE. La moindre règle de classe qui pose un display la bat — et cette
   feuille en compte une soixantaine. L'élément reste alors À L'ÉCRAN alors que
   le script le croit caché.

   Ce n'est pas une hypothèse : le défaut a mordu quatre fois.
   · 02/09 — les deux boutons « Partager / Enregistrer l'image » du score CRS
     restaient visibles (`.crs-emporter { display: flex }` battait le hidden)
     alors que le script était sorti AVANT de leur poser un gestionnaire :
     deux boutons bien visibles qui ne faisaient RIEN. C'est ce qu'Alex a vu.
   · paiement.html : « Version de l'IELTS » restait affiché sur un achat TCF.
   · en/evaluation.html : quatre rustines, une par classe.
   · gestion.css porte cette règle depuis toujours — d'où l'absence du défaut
     dans l'espace de gestion.

   On règle donc le problème À LA SOURCE, une fois, comme /gestion le fait
   déjà. Vérifié avant de poser : AUCUNE règle du site ne cherche à afficher
   un élément « hidden ». */
[hidden] { display: none !important; }

/* 10/09/2026 — ce que le navigateur dessine seul porte aussi la marque : la
   barre de défilement, le curseur de saisie, les cases et les boutons radio. */
html { color-scheme: light; scroll-behavior: smooth; scrollbar-color: var(--scroll-thumb) transparent; accent-color: var(--red-dark); }
input, textarea, select { caret-color: var(--red-dark); }
::placeholder { color: var(--muted); opacity: 1; }
body {
  font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
  color: var(--ink);
  background: var(--white);
  line-height: 1.62;
  font-size: var(--fs-md);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4, .footer-titre, .brand-name, .btn, .step-num, .stat b {
  font-family: 'Sora', 'Inter', 'Segoe UI', sans-serif;
}
img { max-width: 100%; display: block; }
a { color: var(--red-dark); text-decoration: none; }
ul { list-style: none; }

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }

/* ---------- Topbar ---------- */
.topbar {
  background: var(--navy-dark);
  color: #C9C2C0;
  font-size: var(--fs-xs);
  padding: 7px 0;
}
.topbar .container {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.topbar a { color: #EDE8E7; }
.topbar a:hover { color: var(--sur-couleur); }
.topbar-left { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.topbar-item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.topbar-item svg { width: 13px; height: 13px; stroke: var(--amber); flex: none; }
.topbar-item .wa-ico { fill: var(--teal); stroke: none; }
.topbar-right { display: flex; gap: 12px; align-items: center; }
.topbar-right .sep { opacity: .3; }
/* 24/10/2026 — Facebook, Instagram, WhatsApp faisaient moins de 24 px de haut
   au doigt (robot visiteurs, tablette) : zone agrandie, dessin inchangé. */
.topbar-right > a { display: inline-block; padding: 8px 0; margin: -8px 0; }
.topbar .hours { display: none; }
/* 12/09/2026 : dès 960 px (900 avant) — entre 900 et 959 px, les horaires ET le bouton
   lune/soleil ne tenaient pas sur une ligne (mesuré : il manquait jusqu'à 44 px). */
@media (min-width: 960px) { .topbar .hours { display: inline-flex; } }
/* Mobile : on retire les réseaux de la topbar (présents au footer + bouton flottant)
   pour éviter tout débordement horizontal */
@media (max-width: 680px) {
  .topbar-right { display: none; }
  .topbar .container { justify-content: center; }
  .topbar-left { justify-content: center; row-gap: 2px; }
}
/* 12/09/2026 — LE BOUTON LUNE / SOLEIL vit dans ce bandeau, à toutes les tailles
   (js/main.js). Dans la barre de navigation, ses 52 px la faisaient passer sur
   deux lignes à 420-480, 980-1040 et 1180-1220 px (mesuré largeur par largeur)
   et coupaient le nom de la marque à 375 px. Ici, la place ne manque jamais. */
.topbar-theme {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 30px; height: 26px; padding: 0; border: 0; border-radius: var(--r-sm);
  background: none; color: #EDE8E7; cursor: pointer;
  margin: -4px 0;   /* 26 px de cible, mais 18 px dans la ligne : le bandeau garde ses 33 px */
}
.topbar-theme:hover { color: var(--sur-couleur); }
.topbar-theme:focus-visible { outline: 2px solid var(--amber); outline-offset: 1px; }
.topbar-theme svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
@media (max-width: 680px) {
  /* Au téléphone, les réseaux quittent le bandeau : seul le bouton y reste, à côté du numéro. */
  .topbar-right { display: flex; }
  .topbar-right > :not(.topbar-theme) { display: none; }
  .topbar-theme { width: 44px; height: 44px; margin: 0; }   /* cible tactile */
}
/* 21/10/2026 — de 770 à 798 px, « Se déconnecter » (icône ; retiré le 24/10, la
   déconnexion vit dans la page Mon compte) faisait passer le bandeau sur
   deux lignes : à droite, onze éléments et dix écarts de 12 px ne laissaient pas
   la place au téléphone et à l'e-mail. Écarts de 8 px jusqu'à 899 px (mesuré au
   pas de 2 px, 33 px de 770 à 1500). À 768 px et moins, les deux lignes de 44 px
   sont voulues (cibles tactiles, plus bas dans cette feuille). */
@media (min-width: 769px) and (max-width: 899px) {
  .topbar-right { gap: 8px; }
}
@media (min-width: 768px) and (max-width: 979px) {
  .mobile-menu > .btn { order: 2; }
}

/* ---------- Navbar ---------- */
.navbar {
  position: sticky; top: 0; z-index: 100;
  /* v3 : plus de flou d'arrière-plan (coût à chaque image de défilement sur une barre collante) */
  background: rgba(255,255,255,.97);
  border-bottom: 1px solid var(--line);
}
.navbar .container {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 68px; gap: 16px;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand img { width: 40px; height: 40px; object-fit: contain; }
.brand-name { font-weight: 700; color: var(--navy-dark); font-size: var(--fs-md); line-height: 1.3; letter-spacing: -.2px; }
/* 10/09/2026 — l'accroche perd ses capitales espacées : un quart plus courte,
   elle tient sur une ligne à 1280 px (elle se cassait en deux). */
.brand-name small { display: block; font-weight: 600; color: var(--red-dark); font-size: var(--fs-xs); letter-spacing: .01em; margin-top: 4px; }

.nav-links { display: none; align-items: center; gap: 20px; }
.nav-links a { color: var(--ink); font-weight: 500; font-size: var(--fs-base); position: relative; padding: 6px 0; white-space: nowrap; }
.nav-links a:hover, .nav-links a.active { color: var(--red-dark); }
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 2px;
  border-radius: var(--r-pill); background: var(--red-dark);
  transform: scaleX(0); transform-origin: left; transition: transform .25s ease;
}
.nav-links a:hover::after, .nav-links a.active::after { transform: scaleX(1); }
.nav-cta { display: none; align-items: center; gap: 12px; }
.lang-switch {
  font-weight: 600; font-size: var(--fs-xs); color: var(--navy-dark);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 6px 11px;
}
.lang-switch:hover { border-color: var(--navy-dark); }
.burger {
  display: inline-flex; flex-direction: column; gap: 5px; background: none;
  border: none; cursor: pointer; padding: 0;
  width: 44px; height: 44px; justify-content: center; align-items: center; /* cible tactile 44×44 */
}
.burger span { width: 24px; height: 2px; background: var(--navy-dark); border-radius: var(--r-pill); transition: background-color .3s, border-color .3s, color .3s, box-shadow .3s, transform .3s, opacity .3s; }
.burger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger.open span:nth-child(2) { opacity: 0; }
.burger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Le menu complet n'apparaît qu'à partir de 980 px (940 jusqu'au 02/09/2026).
   Mesuré ce jour-là : entre 940 et 970 px, avec l'onglet « Prépa TCF & IELTS »,
   le nom de la marque se cassait sur deux lignes et la barre passait de 68 à
   87 px. En dessous de 980, le menu se replie derrière le bouton, comme au
   téléphone : un menu qui ne tient pas ne doit pas être montré. */
@media (min-width: 980px) {
  .nav-links, .nav-cta { display: flex; }
  .burger { display: none; }
}
@media (max-width: 979px) {
  /* Sur mobile : la pastille FR/EN reste accessible à côté du burger (le bouton devis vit dans le menu). */
  .nav-cta { display: flex; margin-left: auto; }
  .nav-cta .btn { display: none; }
}
@media (min-width: 980px) and (max-width: 1179px) {
  .nav-links { gap: 10px; }
  .nav-links a { font-size: var(--fs-xs); }
  .nav-cta { gap: 8px; }
  .nav-cta .btn { padding: 9px 12px; font-size: var(--fs-xs); }
}
/* Le bouton « Demander un devis » ne se casse JAMAIS sur deux lignes. Quand la
   barre manque de place, c'est l'accroche de marque qui se replie (elle sait le
   faire), pas un bouton. Constat du 02/09/2026 : l'onglet « Prépa TCF & IELTS »,
   plus long que « Préparations », pliait le bouton en deux dès 1280 px. */
.nav-cta .btn { white-space: nowrap; }
/* Sous 1320 px, l'accroche prend sa taille compacte — la même exception qu'au
   téléphone (11 px, voir plus bas). Mesuré : une ligne à 1280 px, deux à 1180,
   trois à 980, sans jamais faire grandir la barre. */
@media (min-width: 980px) and (max-width: 1319px) {
  .brand-name small { font-size: 11px; letter-spacing: 0; }
}
/* 24/10/2026 — 👤 LE ROND « MON COMPTE » (js/main.js, maquette validée par Alex) :
   dans .nav-cta, après « Évaluer mon profil » ; au téléphone, entre la loupe et
   le menu ☰ (44 px, bloc « LE SITE COMME UNE APPLICATION »). Connecté : rouge, à
   l'initiale du nom d'utilisateur ; sans session : gris, icône « personne ». */
.cpt-rond {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--red-fond); color: var(--sur-couleur);
  font-family: Sora, Inter, sans-serif; font-weight: 700; font-size: var(--fs-base); line-height: 1;
  box-shadow: 0 0 0 2px var(--white), 0 0 0 4px transparent;
  transition: box-shadow .2s ease, transform .15s ease;
  -webkit-tap-highlight-color: transparent;
}
.cpt-rond:hover, .cpt-rond[aria-current="page"] { box-shadow: 0 0 0 2px var(--white), 0 0 0 4px var(--red); }
.cpt-rond:focus-visible { border-radius: 50%; }
.cpt-rond:active { transform: scale(.96); }
.cpt-rond.cpt-visiteur { background: var(--line); color: var(--navy-dark); }
:root[data-theme="nuit"] .cpt-rond.cpt-visiteur { background: var(--line-strong); }
.cpt-rond svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* L'accroche de la marque reste sur une ligne à 1280 px avec le rond en plus. */
@media (min-width: 1220px) and (max-width: 1319px) { .nav-links { gap: 16px; } }
/* Mesuré le 24/10 (index, compte) : de 980 à 1050 px, avec le rond, la marque
   n'avait que 158-238 px — accroche sur 3 lignes, barre de 88,5 px au lieu de 68 ;
   idem de 1180 à 1210 px (liens à la taille normale). L'accroche s'efface dans
   la première plage ; la seconde garde la taille compacte des liens jusqu'à 1219. */
@media (min-width: 980px) and (max-width: 1059px) { .brand-name small { display: none; } }
@media (min-width: 1180px) and (max-width: 1219px) {
  .nav-links { gap: 10px; }
  .nav-links a, .nav-links .nav-groupe-btn { font-size: var(--fs-xs); }
  .nav-cta { gap: 8px; }
  .nav-cta .btn { padding: 9px 12px; font-size: var(--fs-xs); }
}

.mobile-menu {
  display: none; flex-direction: column; gap: 4px;
  padding: 12px 20px 22px; background: var(--white); border-top: 1px solid var(--line);
}
/* ⚠️ LE MENU DOIT DEFILER DANS LUI-MEME.
   La barre de navigation est collante : le menu reste donc fige en haut de
   l'ecran et ne suit pas le defilement de la page. Quand la liste depasse la
   hauteur du telephone, tout ce qui est en bas devient INATTEIGNABLE — mesure
   du 27/08/2026 : 1266 px de menu sur 812 px d'ecran, onze entrees perdues,
   dont « Combien ça coûte », « Contact » et « Demander un devis ».
   La hauteur maximale est posee par js/main.js a l'ouverture, parce qu'elle
   depend de la place qui reste SOUS la barre — et cette place change selon que
   le bandeau de contact est encore visible ou deja remonte. */
.mobile-menu.open {
  display: flex;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.mobile-menu a {
  padding: 11px 10px; border-radius: var(--r); color: var(--ink); font-weight: 500;
}
.mobile-menu a:hover, .mobile-menu a.active { background: var(--bg); color: var(--red-dark); }
.mobile-menu .btn { margin-top: 10px; text-align: center; }
/* 13/10/2026 — « .mobile-menu a » passait devant .btn-red : le bouton rouge du
   menu s'écrivait en noir sur rouge (2,9:1 mesuré à 375 px), et au survol il
   perdait son rouge. */
.mobile-menu a.btn-red, .mobile-menu a.btn-red:hover { color: var(--sur-couleur); }
.mobile-menu a.btn-red:hover { background: var(--red-deep); }
/* Les familles du menu telephone (29/08/2026) : de simples etiquettes, la
   liste reste une liste — un depliant au doigt ferait rater des pages. */
.mobile-menu .mobile-grp { display: block; padding: 12px 12px 2px; font-size: .75rem;
  font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
@media (min-width: 980px) { .mobile-menu { display: none !important; } }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 24px; border-radius: var(--r); font-weight: 600; font-size: var(--fs-base);
  border: none; cursor: pointer; transition: background-color .22s, border-color .22s, color .22s, box-shadow .22s, transform .22s, opacity .22s; line-height: 1.2;
}
.btn svg { width: 17px; height: 17px; flex: none; }
.btn-red { background: var(--red-fond); color: var(--sur-couleur); box-shadow: var(--shadow-sm); }
.btn-red:hover { background: var(--red-deep); }
.btn-navy { background: var(--navy-dark); color: var(--sur-couleur); }
.btn-navy:hover { background: var(--navy-darker); }
.btn-outline-light { background: transparent; color: var(--sur-couleur); border: 1px solid rgba(255,255,255,.5); }
.btn-outline-light:hover { background: rgba(255,255,255,.12); }
.btn-outline { background: transparent; color: var(--navy-dark); border: 1px solid var(--line-strong); }
.btn-outline:hover { border-color: var(--navy-dark); background: var(--bg); }
/* Blanc sur --teal = 4,30:1 (sous 4,5) : le fond du bouton est le vert foncé, le survol remonte au vert maison. */
.btn-whatsapp { background: var(--teal-dark); color: var(--sur-couleur); }
/* 10/09/2026 : le survol ÉCLAIRCISSAIT le vert (blanc à 4,3:1) ; il l'assombrit. */
.btn-whatsapp:hover { background: var(--teal-dark); box-shadow: inset 0 0 0 100vmax rgba(0, 0, 0, .14); }
.btn-sm { padding: 8px 16px; font-size: var(--fs-sm); }
/* 10/09/2026 — un bouton ne SAUTE plus au survol (deux pixels de saut à chaque
   passage de souris) : il fonce, et s'enfonce d'un rien au clic. */
.btn:active { transform: scale(.98); }
@media (prefers-reduced-motion: reduce) { .btn:active { transform: none; } }

/* ---------- Hero (clair, épuré) ---------- */
.hero {
  position: relative; overflow: hidden;
  background:
    radial-gradient(900px 420px at 88% -20%, rgba(232, 35, 26, .07), transparent 60%),
    linear-gradient(180deg, var(--white) 0%, var(--bg) 100%);
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.hero-inner {
  position: relative; z-index: 2;
  display: grid; gap: 44px; align-items: center;
  /* padding-top/bottom uniquement : le raccourci `padding: X 0 Y` écrasait le
     padding latéral 20px de .container (contenu collé aux bords sur mobile) */
  padding-top: 62px; padding-bottom: 78px;
}
@media (min-width: 940px) {
  .hero-inner { grid-template-columns: 1.15fr .85fr; padding-top: 84px; padding-bottom: 100px; }
}
.hero-badge {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--white); border: 1px solid var(--line);
  padding: 7px 14px; border-radius: var(--r-pill); font-size: var(--fs-xs); font-weight: 600;
  color: var(--muted); margin-bottom: 24px; box-shadow: var(--shadow-sm);
}
.hero-badge .dot { width: 16px; height: 16px; border-radius: 50%; background: var(--teal); border: 4px solid var(--teal-light); }
.hero h1 { font-size: var(--fs-h1); line-height: 1.06; font-weight: 700; letter-spacing: var(--tracking-display); color: var(--navy-dark); }
/* Le mot en rouge dans un titre : le code de l'accueil (« au Canada »),
   generalise le 30/08 a la demande d'Alex (« tous » des packs TCF). */
/* ⚠️ 09/09 — l'encre par defaut, pas le rouge du logo : hors d'un grand titre
   ce mot descend a 15 px (mesure sur « chaque » dans Prepa TCF), et #E8231A
   n'y donne que 4,29:1. Le grand titre du hero garde le rouge vif, lui : au
   dela de 24 px la norme n'exige que 3:1. */
.accent { color: var(--red-dark); }
.hero h1 .accent { color: var(--red); }
.hero-sub { margin: 22px 0 30px; color: var(--muted); font-size: var(--fs-md); max-width: 560px; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; }
.hero-trust { display: flex; gap: 22px; margin-top: 34px; flex-wrap: wrap; }
.hero-trust .item { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--ink); font-weight: 500; }
.hero-trust svg { width: 16px; height: 16px; stroke: var(--teal); flex: none; }
.links-cat svg { width: 22px; height: 22px; stroke: var(--red); fill: none; flex: none; }

/* Carte itinéraire — bloc rouge signature */
.hero-visual { position: relative; display: flex; justify-content: center; }
.hero-card {
  background: linear-gradient(160deg, var(--red-dark) 0%, var(--red-deep) 100%);
  border-radius: var(--r-lg); padding: 28px;
  width: 100%; max-width: 400px; color: var(--sur-couleur);
  box-shadow: var(--shadow);
}
.hero-card h3, .hero-card .h3-visuel { font-size: var(--fs-md); font-weight: 600; color: var(--sur-couleur); margin-bottom: 18px; display: flex; align-items: center; gap: 8px; }
.hero-card h3 svg, .hero-card .h3-visuel svg { width: 18px; height: 18px; stroke: var(--amber-light); }
.route { display: flex; flex-direction: column; }
.route-step { display: flex; gap: 14px; }
.route-marker { display: flex; flex-direction: column; align-items: center; }
.route-marker .pin {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.3);
  /* ⚠️ 09/09 — MÊME PIÈGE QUE --white : --amber-light nomme une SURFACE pale,
     elle devient sombre en theme nuit. Ces chiffres sont poses sur la carte
     rouge, qui ne bascule pas : leur ambre ne doit pas basculer non plus.
     Mesure avant : 1,1:1, des chiffres invisibles au premier ecran. */
  font-size: var(--fs-xs); font-weight: 700; color: var(--sur-couleur-ambre);
}
.route-marker .line { width: 2px; flex: 1; min-height: 20px; background: linear-gradient(180deg, rgba(251, 243, 220,.55), rgba(255,255,255,.12)); }
.route-step:last-child .line { display: none; }
.route-body { padding-bottom: 18px; }
.route-body strong { display: block; color: var(--sur-couleur); font-size: var(--fs-sm); font-weight: 600; }
.route-body span { font-size: var(--fs-xs); color: #F4C4C0; }

.hero-plane { display: none; }

/* ---------- Stats band ---------- */
.stats { background: transparent; position: relative; z-index: 3; }
/* 10/09/2026 — plus de carte flottante à cheval sur l'accueil (le gabarit
   « gros chiffres dans une boîte ») : une bande de preuves, posée, séparée par
   des filets. Les chiffres sont les mêmes ; ils respirent. */
.stats .container {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px;
  background: none; border-radius: 0; box-shadow: none;
  padding: var(--sp-6) 20px; margin-top: 0; border: 0; border-bottom: 1px solid var(--line);
}
@media (min-width: 800px) {
  .stats .container { grid-template-columns: repeat(4, 1fr); gap: 0; padding-top: var(--sp-7); padding-bottom: var(--sp-7); }
  .stat + .stat { border-left: 1px solid var(--line); }
}
/* Sous 360 px, la marge de 28 px de chaque cote faisait deborder le bandeau
   hors de l'ecran (mesure : 331 px de contenu pour 320 px d'ecran). */
@media (max-width: 360px) { .stats .container { padding: 22px 15px; gap: 12px; } }
/* min-width: 0 : sans lui, une case de grille refuse de descendre sous la
   largeur de son contenu et pousse tout le bandeau vers la droite. */
.stat { text-align: center; min-width: 0; }
.stat b { font-size: var(--fs-h2); color: var(--navy-dark); font-weight: 700; display: block; line-height: 1.1; letter-spacing: var(--tracking-title); }
.stat b .plus { color: var(--red-dark); }
.stat span { font-size: var(--fs-sm); color: var(--muted); font-weight: 500; }

/* ---------- Sections ---------- */
.section { padding: 78px 0; }
/* 10/09/2026 : sur grand écran, les sections respirent davantage. */
@media (min-width: 1100px) { .section { padding: 96px 0; } }
.section.alt { background: var(--bg); }
.section-head { max-width: 680px; margin: 0 auto 48px; text-align: center; }
/* 10/09/2026 — L'ÉTIQUETTE AU-DESSUS DU TITRE (« — NOS SERVICES — ») a quitté
   les pages de présentation : le titre parle seul. Ce qui reste de .eyebrow
   (la bande « Nos candidats », les outils de la check-list et de « Mes
   chances » où elle passe SOUS le titre) est une ligne simple, sans capitales
   espacées ni tirets. */
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--red-dark); font-weight: 600; font-size: var(--fs-sm);
  letter-spacing: 0; margin-bottom: 12px;
}
.section-head h2, .section-head-left h2 { font-size: var(--fs-h2); font-weight: 700; color: var(--navy-dark); letter-spacing: var(--tracking-title); line-height: 1.15; }
.section-head p { color: var(--muted); margin: 16px auto 0; font-size: var(--fs-md); max-width: 60ch; }

/* 20/09/2026 — SORTIR DU TOUT-CENTRÉ (demande d'Alex). Sur les pages à volets,
   titre centré, chapeau centré, bouton centré : d'une section à l'autre rien
   ne changeait de place, et l'œil n'avait plus de bord où revenir à chaque
   ligne. Le titre et son chapeau s'alignent à gauche dès que la fenêtre est
   large ; au téléphone, où la colonne est unique et le titre tient en trois
   lignes, le centre reste juste et ne bouge pas. */
@media (min-width: 900px) {
  .fus-volet .section-head { text-align: left; margin-left: 0; max-width: 64ch; }
  .fus-volet .section-head p { margin-left: 0; margin-right: 0; }
  /* ⚠️ Le titre ne part pas seul. La colonne de texte qui le suit — un div
     sans classe, centré par `margin: 0 auto` — serait restée à 240 px du bord
     pendant que son titre touchait la marge : deux bords gauches dans la même
     section, et la page paraît cassée avant de paraître aérée. Elle prend le
     bord de son titre. */
  .fus-volet .container > div:not([class]) { margin-left: 0 !important; }
  /* La ligne « Outil gratuit » passe SOUS le titre depuis le 10/09 : elle
     vivait dans une colonne centrée (check-list.css, admissibilite.css). Le
     titre parti à gauche, elle restait seule au milieu. */
  .fus-volet .section-head:has(> .eyebrow) { align-items: flex-start; }
}

/* 20/09 — LE MÊME BLANC COMPTÉ DEUX FOIS. Le premier titre d'un volet porte
   dans la page un `style="margin-top: var(--sp-9)"` (64 px) qui le décollait
   du titre PRÉCÉDENT, à l'époque où tout se suivait dans une seule colonne.
   Depuis, la section qui l'entoure a sa propre respiration : les deux
   s'additionnaient (48 + 64 = 112 px sous les onglets). Le premier titre n'a
   rien au-dessus de lui à repousser. `!important` est ici le seul niveau qui
   passe devant un style écrit dans la balise. */
.fus-volet .container > .section-head:first-child { margin-top: 0 !important; }

/* ---------- Services grid ---------- */
.services-grid { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 680px) { .services-grid { gap: 20px; } }
@media (min-width: 1000px) { .services-grid { grid-template-columns: repeat(3, 1fr); } }
/* 10/09/2026 — huit cartes sur trois colonnes laissaient un trou en bas à
   droite. La première (la consultation : la porte d'entrée, la seule tarifée)
   prend deux colonnes : la grille se remplit et la hiérarchie apparaît. */
@media (min-width: 1000px) {
  .services-grid:has(> :nth-child(8):last-child) > :first-child { grid-column: span 2; }
}
/* 10/09/2026 — sur ces huit cartes, l'icône se range À CÔTÉ du titre : la tuile
   d'icône posée SUR un titre est le gabarit de carte le plus répandu du web.
   Grille à quatre rangées (icône + titre, prix, texte, lien) : les liens
   « En savoir plus » restent alignés au pied des cartes d'une même rangée.
   Au téléphone (cartes de 160 px), l'icône reste au-dessus. */
/* 20/09 — la règle ne visait QUE la grille de huit : les trois cartes du
   cabinet et les six du livre gardaient la tuile d'icône posée SUR le titre,
   celle que tous les générateurs de pages produisent. Elle vaut pour toute
   carte qui porte une icône, quel que soit le nombre de cartes. Les packs de
   services.html, dont l'icône est DANS le titre, ne sont pas concernés :
   c'est ce que dit `:has(> .service-icon)`. */
@media (min-width: 680px) {
  .services-grid > .service-card:has(> .service-icon) {
    display: grid; grid-template-columns: 44px minmax(0, 1fr); grid-template-rows: auto auto 1fr auto; column-gap: 14px;
  }
  .services-grid > .service-card:has(> .service-icon) > * { grid-column: 1 / -1; }
  .services-grid > .service-card:has(> .service-icon) > .service-icon { grid-column: 1; grid-row: 1; width: 44px; height: 44px; margin: 0; }
  .services-grid > .service-card:has(> .service-icon) > h3 { grid-column: 2; grid-row: 1; align-self: center; margin: 0; }
  .services-grid > .service-card:has(> .service-icon) > .price-tag { grid-row: 2; justify-self: start; margin: 14px 0 0; }
  .services-grid > .service-card:has(> .service-icon) > p { grid-row: 3; margin-top: 12px; }
  .services-grid > .service-card:has(> .service-icon) > .service-link { grid-row: 4; }
}

/* 20/09/2026 — LA CARTE CONSEILLÉE SE VOIT. Les trois packs ne se
   distinguaient que par la couleur de leur trait : à deux mètres, trois
   rectangles blancs identiques. Celle qui porte l'étiquette « Conseillé »
   prend le fond ambré qui va avec son trait — une teinte qui dit un SENS,
   pas une décoration, et qui suit le thème sombre par son jeton. */
.service-card:has(> .pack-badge) { background: var(--amber-light); }
.service-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 30px 26px; transition: background-color .28s, border-color .28s, color .28s, box-shadow .28s, transform .28s, opacity .28s; display: flex; flex-direction: column;
}
.service-card:hover { box-shadow: var(--shadow); border-color: #F3D4D2; }
.service-icon {
  width: 52px; height: 52px; border-radius: var(--r); margin-bottom: 18px;
  display: flex; align-items: center; justify-content: center;
  background: var(--blush);
}
.service-icon svg { width: 25px; height: 25px; stroke: var(--red); }
.service-card h3 { font-size: var(--fs-lg); font-weight: 600; color: var(--navy-dark); margin-bottom: 10px; letter-spacing: -0.01em; }
.service-card p { font-size: var(--fs-sm); color: var(--muted); flex: 1; }
.service-link { margin-top: 16px; font-weight: 600; font-size: var(--fs-sm); color: var(--red-dark); display: inline-flex; align-items: center; gap: 6px; }
.service-link svg { width: 15px; height: 15px; transition: background-color .25s, border-color .25s, color .25s, box-shadow .25s, transform .25s, opacity .25s; }
.service-card:hover .service-link svg { transform: translateX(4px); }
.price-tag {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  background: var(--blush); color: var(--red-dark); font-size: var(--fs-xs); font-weight: 700;
  padding: 5px 12px; border-radius: var(--r-pill); margin-bottom: 12px;
}

/* ---------- Steps ---------- */
.steps { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 720px) { .steps { gap: 18px; } }
@media (min-width: 1040px) { .steps { grid-template-columns: repeat(5, 1fr); } }
.step {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 26px 22px;
}
.step-num {
  width: 38px; height: 38px; border-radius: 50%; font-weight: 700; font-size: var(--fs-sm);
  display: flex; align-items: center; justify-content: center; margin-bottom: 14px;
  background: var(--blush); color: var(--red-dark); border: 1px solid #F3D4D2;
}
.step:last-child .step-num { background: var(--red-fond); color: var(--sur-couleur); border-color: var(--red-dark); }
.step h3 { font-size: var(--fs-md); font-weight: 600; color: var(--navy-dark); margin-bottom: 8px; }
.step p { font-size: var(--fs-sm); color: var(--muted); }

/* ---------- Why us ---------- */
.why { display: grid; gap: 44px; align-items: center; }
@media (min-width: 940px) { .why { grid-template-columns: 1fr 1fr; } }
.why-visual {
  border-radius: var(--r-lg); overflow: hidden; position: relative; min-height: 380px;
  background:
    radial-gradient(480px 280px at 82% 18%, rgba(251, 243, 220, .18), transparent 60%),
    linear-gradient(160deg, var(--red-dark) 0%, var(--red-deep) 70%, #5C0705 100%);
  display: flex; align-items: center; justify-content: center;
}
/* 08/09 — LA VITRINE DU LIVRE (page A propos) a SON fond : blanc casse, parce
   que la couverture, rouge elle aussi, se noyait dans le degrade (07/09).
   ⚠️ Ce fond avait ete pose sur TOUT `.why-visual` : sur l'accueil, le logo —
   blanc par filtre — disparaissait sur blanc casse (capture d'Alex, 08/09).
   Le rouge d'origine est de retour partout, le blanc casse ne vaut qu'ici. */
.why-visual.vitrine-livre {
  background:
    radial-gradient(480px 280px at 82% 18%, rgba(232, 35, 26, .06), transparent 60%),
    var(--bg);
  border: 1px solid var(--line);
}
.why-visual img.logo-big { width: 44%; filter: brightness(0) invert(1) drop-shadow(0 18px 36px rgba(23, 19, 20, .3)); opacity: .95; }
.why-visual .badge-float {
  position: absolute; background: var(--white); border: 0; border-radius: var(--r); box-shadow: var(--shadow);
  padding: 12px 16px; display: flex; align-items: center; gap: 10px; font-size: var(--fs-xs); font-weight: 600; color: var(--navy-dark);
}
.why-visual .badge-float svg { width: 20px; height: 20px; stroke: var(--teal); flex: none; }
.badge-float.b1 { top: 22px; left: 18px; }
.badge-float.b2 { bottom: 22px; right: 18px; }
.why-list { display: flex; flex-direction: column; gap: 20px; margin-top: 28px; }
.why-item { display: flex; gap: 16px; }
.why-item .ico {
  width: 46px; height: 46px; border-radius: var(--r); flex: none;
  background: var(--blush); display: flex; align-items: center; justify-content: center;
}
.why-item .ico svg { width: 22px; height: 22px; stroke: var(--red); }
.why-item h3 { font-size: var(--fs-md); font-weight: 600; color: var(--navy-dark); }
.why-item p { font-size: var(--fs-sm); color: var(--muted); margin-top: 4px; }
.section-head-left .eyebrow::before { display: none; }

/* ---------- Testimonials ---------- */
.testi-track { display: grid; gap: 20px; grid-template-columns: 1fr; }
@media (min-width: 760px) { .testi-track { grid-template-columns: repeat(3, 1fr); } }
.testi {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 28px 26px; display: flex; flex-direction: column;
}
.testi .quote-mark { font-size: var(--fs-h2); line-height: 1; color: var(--red-dark); opacity: .5; }
.testi p { font-size: var(--fs-base); color: var(--ink); flex: 1; margin: 8px 0 18px; }
.testi-footer { display: flex; align-items: center; gap: 12px; border-top: 1px solid var(--line); padding-top: 16px; }
.avatar {
  width: 42px; height: 42px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: var(--fs-base);
  /* fond unique très contrasté + couleur forcée : .testi-footer span écrasait le blanc */
  /* 09/09 : --red-dark est une ENCRE, elle s'eclaircit la nuit — du blanc
     dessus tombait a 2,79:1 sur les pastilles d'initiales. */
  background: var(--red-fond) !important;
  color: var(--sur-couleur) !important;
}
.testi-footer strong { display: block; font-size: var(--fs-sm); color: var(--navy-dark); }
.testi-footer span { font-size: var(--fs-xs); color: var(--muted); font-weight: 500; }
.testi .result {
  display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
  background: var(--teal-light); color: var(--teal-ink); font-size: var(--fs-xs); font-weight: 700;
  padding: 5px 11px; border-radius: var(--r-pill); text-transform: uppercase; letter-spacing: .6px;
  margin-bottom: 10px; border: 1px solid #BFE5CE;
}
.testi .result svg { width: 13px; height: 13px; stroke: var(--teal-ink); }

/* ---------- CTA band ---------- */
.cta-band {
  background:
    radial-gradient(640px 280px at 12% 130%, rgba(251, 243, 220, .18), transparent 60%),
    linear-gradient(140deg, var(--red-dark), var(--red-deep));
  border-radius: var(--r-lg); color: var(--sur-couleur); padding: 56px 32px; text-align: center;
}
.cta-band h2 { font-size: var(--fs-h2); font-weight: 700; margin-bottom: 12px; letter-spacing: -.5px; }
.cta-band p { color: #F4C4C0; max-width: 540px; margin: 0 auto 28px; font-size: var(--fs-base); }
.cta-band .actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.cta-band .btn-red { background: var(--white); color: var(--red-dark); box-shadow: none; }
.cta-band .btn-red:hover { background: var(--blush); }

/* ---------- Community strip ---------- */
.community {
  display: flex; flex-wrap: wrap; gap: 20px; align-items: center; justify-content: space-between;
  background: var(--teal-light); border: 1px solid #CDEBDA; border-radius: var(--r);
  padding: 26px 30px;
}
.community h3 { color: #0C6B39; font-size: var(--fs-md); font-weight: 700; display: flex; gap: 10px; align-items: center; }
.community p { color: #34655A; font-size: var(--fs-sm); margin-top: 4px; }

/* ---------- Page hero (pages intérieures) ---------- */
.page-hero {
  background: linear-gradient(180deg, var(--white), var(--bg));
  border-bottom: 1px solid var(--line);
  color: var(--navy-dark); padding: 52px 0; text-align: center;
}
.page-hero h1 { font-size: clamp(1.75rem, 1.1rem + 2.6vw, 2.75rem); font-weight: 700; letter-spacing: var(--tracking-display); line-height: 1.12; }
/* Le titre du SECOND volet d'une page fusionnée (04/09/2026) : dessiné comme un h1,
   mais c'est un h2 — une page n'a qu'un seul h1, Google et les lecteurs d'écran y tiennent. */
.page-hero h2.titre-volet { font-size: clamp(1.75rem, 1.1rem + 2.6vw, 2.75rem); font-weight: 700; letter-spacing: var(--tracking-display); line-height: 1.12; }
.page-hero .crumbs { margin-top: 10px; font-size: var(--fs-sm); color: var(--muted); font-weight: 500; }
.page-hero .crumbs a { color: var(--red-dark); }
.page-hero .crumbs span { margin: 0 8px; opacity: .5; }

/* 23/09/2026 — « c'est décalé », suite. Le bandéau gris gardait son titre, son
   bouton et son fil d'Ariane AU CENTRE, alors que tout ce qui le suit part du
   bord gauche depuis le 20/09. Mesuré à 1456 px : titre centré à 728 px,
   contenu à 108 — le regard descend et doit repartir en arrière. Un seul bord
   gauche, du haut de la page au bas. Sous 900 px, la colonne est unique et le
   centre reste juste : même palier que les titres et la barre d'onglets. */
@media (min-width: 900px) {
  .page-hero { text-align: left; }
}

/* ---------- Service detail ---------- */
.service-detail { display: grid; gap: 34px; align-items: start; padding: 46px 0; border-bottom: 1px solid var(--line); }
.service-detail:last-child { border-bottom: none; }
@media (min-width: 900px) { .service-detail { grid-template-columns: 1fr 1.4fr; } }
.service-detail .head h2 { font-size: var(--fs-xl); font-weight: 700; color: var(--navy-dark); margin: 14px 0 10px; letter-spacing: -.4px; }
.service-detail .head p.lead { color: var(--muted); font-size: var(--fs-base); }
.service-detail .big-icon {
  width: 62px; height: 62px; border-radius: var(--r-lg);
  background: var(--blush);
  display: flex; align-items: center; justify-content: center;
}
.service-detail .big-icon svg { width: 29px; height: 29px; stroke: var(--red); }
.check-list { display: flex; flex-direction: column; gap: 12px; }
.check-list li { display: flex; gap: 11px; font-size: var(--fs-base); color: var(--ink); }
.check-list svg { width: 19px; height: 19px; stroke: var(--teal); flex: none; margin-top: 3px; }
/* 10/09/2026 — une note teintée, bordée d'un trait fin sur tout son tour : le
   trait épais sur le bord gauche est la marque la plus reconnaissable d'une
   page produite à la chaîne. */
.pill-note {
  margin-top: 20px; background: var(--amber-light); border: 1px solid color-mix(in srgb, var(--amber) 34%, transparent);
  border-radius: var(--r); padding: 13px 16px; font-size: var(--fs-sm); color: var(--amber-ink);
}

/* ---------- Contact ---------- */
.contact-grid { display: grid; gap: 34px; }
@media (min-width: 960px) { .contact-grid { grid-template-columns: .9fr 1.1fr; } }
.info-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 24px; display: flex; gap: 16px; align-items: flex-start;
}
.info-card + .info-card { margin-top: 14px; }
.info-card .ico {
  width: 46px; height: 46px; border-radius: var(--r); flex: none;
  background: var(--blush); display: flex; align-items: center; justify-content: center;
}
.info-card .ico svg { width: 21px; height: 21px; stroke: var(--red); }
.info-card h3, .info-card .h3-visuel { font-size: var(--fs-base); color: var(--navy-dark); font-weight: 700; }
.info-card p, .info-card a { font-size: var(--fs-sm); color: var(--muted); }
.info-card a:hover { color: var(--red-dark); }
.form-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 34px 30px;
}
.form-card h2 { font-size: var(--fs-lg); color: var(--navy-dark); font-weight: 700; margin-bottom: 6px; letter-spacing: -.3px; }
.form-card > p { color: var(--muted); font-size: var(--fs-sm); margin-bottom: 24px; }
.form-grid { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-grid .full { grid-column: 1 / -1; }
@media (min-width: 640px) { .form-grid { gap: 16px; } }
.field label { display: block; font-size: var(--fs-xs); font-weight: 600; color: var(--navy-dark); margin-bottom: 6px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 12px 14px; border: 1px solid var(--line-strong); border-radius: var(--r);
  font: inherit; font-size: var(--fs-md); color: var(--ink); background: var(--white); transition: background-color .2s, border-color .2s, color .2s, box-shadow .2s, transform .2s, opacity .2s; /* jamais <16px : iOS zoome au focus */
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--red-dark); box-shadow: var(--ring);
}
/* 10/09/2026 — un champ mal rempli le dit, mais seulement APRÈS qu'on l'a
   touché (:user-invalid) : jamais de rouge sur une page qu'on vient d'ouvrir. */
.field input:user-invalid, .field select:user-invalid, .field textarea:user-invalid { border-color: var(--red-dark); }
.map-frame { border: 0; width: 100%; height: 330px; border-radius: var(--r); box-shadow: var(--shadow-sm); }
.eval-banner {
  display: flex; flex-wrap: wrap; gap: 18px; align-items: center; justify-content: space-between;
  background: var(--blush); border: 1px solid #F3D4D2; border-radius: var(--r);
  padding: 22px 26px; margin-bottom: 28px;
}
.eval-banner h3, .eval-banner .h3-visuel { color: var(--red-dark); font-size: var(--fs-md); font-weight: 700; }
.eval-banner p { color: #8A4A45; font-size: var(--fs-sm); margin-top: 3px; }

/* ---------- Blog ---------- */
.blog-grid { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 700px) { .blog-grid { gap: 22px; } }
@media (min-width: 1020px) { .blog-grid { grid-template-columns: repeat(3, 1fr); } }
.post-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; display: flex; flex-direction: column; transition: background-color .28s, border-color .28s, color .28s, box-shadow .28s, transform .28s, opacity .28s;
}
.post-card:hover { box-shadow: var(--shadow); border-color: #F3D4D2; }
.post-cover {
  height: 150px; display: flex; align-items: center; justify-content: center;
  background: linear-gradient(150deg, var(--red-dark), var(--red-deep));
}
.post-cover svg { width: 42px; height: 42px; stroke: rgba(255,255,255,.85); }
.post-body { padding: 22px 24px 24px; display: flex; flex-direction: column; flex: 1; }
.post-meta { display: flex; gap: 10px; align-items: center; font-size: var(--fs-xs); color: var(--muted); font-weight: 500; margin-bottom: 10px; }
.post-meta .cat { background: var(--blush); color: var(--red-dark); font-weight: 700; padding: 3px 10px; border-radius: var(--r-pill); }
.post-body h3 { font-size: var(--fs-md); font-weight: 600; color: var(--navy-dark); margin-bottom: 8px; letter-spacing: -.2px; }
.post-body p { font-size: var(--fs-sm); color: var(--muted); flex: 1; }
.post-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.post-foot .service-link { margin-top: 0; }
.post-reactions { display: flex; gap: 14px; font-size: var(--fs-xs); color: var(--muted); font-weight: 500; }
.post-reactions svg { width: 15px; height: 15px; stroke: var(--muted); vertical-align: -2px; }

/* ---------- Footer ---------- */
footer { background: var(--navy-dark); color: #B5AEAC; margin-top: 78px; }
.footer-grid {
  display: grid; gap: 28px 20px; padding-top: 44px; padding-bottom: 32px; grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 720px) { .footer-grid { gap: 36px; padding-top: 60px; padding-bottom: 40px; } }
@media (min-width: 1040px) {
  /* Colonnes à leur largeur naturelle, espace restant réparti à parts égales :
     les écarts entre les 4 colonnes sont visuellement équilibrés */
  .footer-grid { grid-template-columns: minmax(260px, 320px) auto auto auto; justify-content: space-between; }
}
.footer-brand img { width: 44px; margin-bottom: 14px; filter: brightness(0) invert(1); opacity: .95; }
.footer-brand p { font-size: var(--fs-sm); max-width: 300px; }
.socials { display: flex; gap: 10px; margin-top: 18px; }
.socials a {
  width: 38px; height: 38px; border-radius: var(--r); display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.07); transition: background-color .25s, border-color .25s, color .25s, box-shadow .25s, transform .25s, opacity .25s;
}
.socials a:hover { background: var(--red); }
/* --sur-couleur et non --white : en thème nuit --white devient bleu nuit, et les icônes disparaissaient sur le pied de page (12/10/2026). */
.socials svg { width: 17px; height: 17px; stroke: var(--sur-couleur); }
/* .footer-titre : même dessin que footer h4 — remplaçant des <h4> du pied de page (#6) */
footer h4, .footer-titre { color: var(--sur-couleur); font-size: var(--fs-base); font-weight: 600; margin-bottom: 18px; }
.footer-links li { margin-bottom: 7px; }
.footer-links a { color: #B5AEAC; font-size: var(--fs-sm); }
.footer-links a:hover { color: var(--sur-couleur); }
.footer-contact li { display: flex; gap: 10px; margin-bottom: 12px; font-size: var(--fs-sm); }
.footer-contact svg { width: 16px; height: 16px; stroke: var(--amber); flex: none; margin-top: 4px; }
.footer-contact a { color: #EDE8E7; }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,.08); padding-top: 20px; padding-bottom: 20px; font-size: var(--fs-xs);
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: space-between;
}
/* ⚠️ 09/09 — Le pied de page est SOMBRE dans les deux themes : un lien y prend
   la couleur d'un lien ordinaire (le rouge fonce) et tombe a 2,99:1. Mesure
   faite sur « Confidentialite » au bas du formulaire IRCC. Deux pages avaient
   deja bricole leur propre correctif dans leur <style> ; cette regle-ci les
   rend inutiles et couvre celles qui viendront. */
.footer-bottom a { color: #EDE8E7; }

/* ---------- WhatsApp float ---------- */
.wa-float {
  position: fixed; right: 18px; bottom: 18px; z-index: 90;
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--teal); display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow); transition: background-color .25s, border-color .25s, color .25s, box-shadow .25s, transform .25s, opacity .25s;
}
/* ⚠️ Sur téléphone, la bulle se posait SUR le bouton « Demander un devis »
   de l'accueil (mesuré à 375 px, audit du 30/08) : on tapait WhatsApp en
   croyant demander un devis. Décaler la bulle ne règle rien — une bulle fixe
   recouvre toujours QUELQUE CHOSE. Le remède : sur téléphone elle n'apparaît
   qu'une fois la page défilée, donc jamais par-dessus les boutons d'accueil.
   Sur ordinateur, rien ne change : il y a de la place sur les côtés. */
@media (max-width: 767px) {
  .wa-float { right: 14px; bottom: 14px; width: 52px; height: 52px; }
  .js .wa-float {
    opacity: 0; visibility: hidden; transform: scale(.85);
    transition: opacity .2s ease, transform .2s ease, visibility .2s;
  }
  .js body.a-defile .wa-float { opacity: 1; visibility: visible; transform: none; }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .js .wa-float { transition: none; }
}
.wa-float:hover { transform: scale(1.08); }
.wa-float svg { width: 28px; height: 28px; fill: var(--white); }

/* ---------- Reveal ----------
   Masquage scopé sous html.js (classe posée par le script inline du <head>) :
   sans JavaScript, le contenu reste visible. */
/* 10/09/2026 — PLUS D'APPARITION AU DÉFILEMENT. Chaque section arrivait par le
   même fondu : un geste répété partout ne dit plus rien, et le contenu restait
   caché tant que le script ne l'avait pas vu passer. Le seul mouvement voulu
   est l'entrée de l'accueil (« Le moment de l'accueil », plus bas). La classe
   .reveal reste dans les pages : elle ne cache plus rien. */

/* ---------- Partage blog ---------- */
.share-bar { display: flex; gap: 8px; align-items: center; margin-top: 14px; flex-wrap: wrap; }
.share-bar .share-label { font-size: var(--fs-xs); color: var(--muted); font-weight: 600; margin-right: 2px; }
.share-btn {
  width: 34px; height: 34px; border-radius: var(--r); border: 1px solid var(--line);
  background: var(--white); cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center; transition: background-color .2s, border-color .2s, color .2s, box-shadow .2s, transform .2s, opacity .2s; padding: 0;
}
.share-btn:hover { box-shadow: var(--shadow-sm); border-color: var(--line-strong); }
.share-btn svg { width: 16px; height: 16px; }
.share-btn.wa svg { fill: var(--teal); }
/* Facebook et Telegram : couleurs de marques tierces, seule exception admise (CHARTE.md) */
.share-btn.fb svg { stroke: #1877F2; fill: none; }
.share-btn.tg svg { stroke: #29A9EB; fill: none; }
.share-btn.img svg { stroke: var(--red); fill: none; }
.share-btn.dl svg { stroke: var(--navy-dark); fill: none; }

/* ---------- Liens utiles ---------- */
.link-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 24px; display: flex; gap: 16px; align-items: flex-start; transition: background-color .25s, border-color .25s, color .25s, box-shadow .25s, transform .25s, opacity .25s;
}
.link-card:hover { box-shadow: var(--shadow); border-color: #F3D4D2; }
.link-card .ico {
  width: 44px; height: 44px; border-radius: var(--r); flex: none;
  background: var(--blush); display: flex; align-items: center; justify-content: center;
}
.link-card .ico svg { width: 20px; height: 20px; stroke: var(--red); }
.link-card h3 { font-size: var(--fs-base); color: var(--navy-dark); font-weight: 700; }
.link-card p { font-size: var(--fs-sm); color: var(--muted); margin: 4px 0 10px; }
.link-card .service-link { margin-top: 0; word-break: break-all; }
.links-grid { display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 700px) { .links-grid { gap: 18px; } }
.links-cat {
  font-size: var(--fs-lg); font-weight: 700; color: var(--navy-dark);
  margin: 44px 0 18px; padding-bottom: 10px; border-bottom: 2px solid var(--blush);
  display: flex; align-items: center; gap: 10px;
}
.links-cat:first-of-type { margin-top: 0; }

/* ---------- Surbrillances au survol ----------
   10/09/2026 — SEUL CE QUI SE CLIQUE réagit à la souris. Les témoignages, les
   étapes, les chiffres, les cartes d'adresse et les lignes de liste bougeaient
   au survol sans rien ouvrir : on croyait pouvoir cliquer. Les liens du pied
   de page changent de teinte sans glisser ; la marque ne grossit plus. */
.footer-links a { display: inline-block; transition: color .2s ease; }
.stat { padding: 6px; }
.check-list li { border-radius: var(--r-sm); padding: 4px 8px; margin: -4px -8px; }
.topbar a, .footer-contact a { transition: color .2s ease; }

/* ---------- Page du livre ---------- */
.livre-hero { display: grid; gap: 44px; align-items: center; grid-template-columns: 1fr; }
@media (min-width: 900px) { .livre-hero { grid-template-columns: .8fr 1.2fr; } }
.livre-cover-wrap { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.livre-cover {
  width: 300px; aspect-ratio: 3 / 4.3; border-radius: var(--r-sm) var(--r) var(--r) var(--r-sm);
  background:
    radial-gradient(340px 260px at 85% 8%, rgba(251, 243, 220, .25), transparent 60%),
    linear-gradient(160deg, var(--red-dark) 0%, var(--red-deep) 62%, #5C0705 100%);
  color: var(--sur-couleur); padding: 30px 26px; display: flex; flex-direction: column;
  box-shadow: var(--shadow);
  position: relative;
}
.livre-cover::before {
  content: ""; position: absolute; left: 10px; top: 0; bottom: 0; width: 2px;
  background: rgba(255,255,255,.25);
}
.lc-logo { width: 40px; filter: brightness(0) invert(1); margin-bottom: 10px; }
.lc-marque { font-size: var(--fs-xs); font-weight: 700; letter-spacing: 2.4px; color: #F4C4C0; }
.lc-titre {
  font-family: 'Sora'; font-weight: 700; font-size: var(--fs-h2); line-height: 1.05;
  letter-spacing: 1px; margin: auto 0 14px;
}
.lc-sub { font-size: var(--fs-sm); color: #FBE9E7; line-height: 1.5; margin-bottom: 18px; }
.lc-bas { font-size: var(--fs-xs); color: var(--amber-light); border-top: 1px solid rgba(255,255,255,.25); padding-top: 12px; }
.livre-badge {
  background: var(--blush); color: var(--red-dark); font-weight: 700; font-size: var(--fs-xs);
  padding: 7px 16px; border-radius: var(--r-pill); border: 1px solid #F3D4D2;
}
.livre-titre-page { font-size: var(--fs-h2); font-weight: 700; color: var(--navy-dark); letter-spacing: -.6px; line-height: 1.2; }
.livre-pitch { color: var(--muted); margin-top: 16px; font-size: var(--fs-md); }
.chap-num { font-family: 'Sora'; font-weight: 700; color: var(--red-dark); font-size: var(--fs-md); }

/* ---------- Formules de cours (prépa) ---------- */
.formules-grid { display: grid; gap: 8px; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 18px; }
@media (min-width: 720px) { .formules-grid { gap: 16px; } }
.formule {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 18px; text-align: center; position: relative; transition: background-color .25s, border-color .25s, color .25s, box-shadow .25s, transform .25s, opacity .25s;
}
.formule:hover { box-shadow: var(--shadow); }
.formule.star { border-color: var(--red); }
.formule .f-tag {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  background: var(--red-fond); color: var(--sur-couleur); font-size: var(--fs-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .8px; padding: 4px 12px; border-radius: var(--r-pill); white-space: nowrap;
}
.formule h4, .formule .h4-visuel { font-size: var(--fs-sm); color: var(--navy-dark); margin-bottom: 6px; }
.formule .f-prix { font-family: 'Sora'; font-weight: 700; font-size: var(--fs-lg); color: var(--red-dark); }
.formule .f-prix small { font-size: var(--fs-xs); color: var(--muted); font-weight: 500; }

/* ---------- Filtre de l'historique des tirages ---------- */
.tirage-filtre { display: flex; align-items: center; gap: 10px; margin: 14px 0 6px; flex-wrap: wrap; font-size: var(--fs-sm); color: var(--muted); font-weight: 600; }
.tirage-filtre select { padding: 8px 12px; border: 1px solid var(--line-strong); border-radius: var(--r-sm); font-family: inherit; font-size: var(--fs-sm); background: var(--white); color: var(--ink); }

/* ---------- Capture de prospect (panneaux des calculateurs) ---------- */
.ivc-lead { margin-top: 10px; }
.ivc-lead-toggle { width: 100%; padding: 10px 14px; border: 1.5px dashed var(--red-dark); background: var(--blush); color: var(--red-dark); border-radius: var(--r); font-family: Sora, sans-serif; font-weight: 700; font-size: var(--fs-sm); cursor: pointer; }
.ivc-lead-toggle:hover { background: #FBE3E1; }
.ivc-lead form { display: grid; gap: 8px; margin-top: 10px; }
.ivc-lead input { padding: 9px 11px; border: 1px solid var(--line-strong); border-radius: var(--r-sm); font-size: var(--fs-sm); font-family: inherit; }
.ivc-lead-envoi { padding: 10px 14px; border: none; border-radius: var(--r); background: var(--red-fond); color: var(--sur-couleur); font-family: Sora, sans-serif; font-weight: 700; font-size: var(--fs-sm); cursor: pointer; }
.ivc-lead-envoi:hover { background: var(--red-deep); }
.ivc-lead-note { font-size: var(--fs-xs); color: var(--muted); text-align: center; line-height: 1.45; margin: 0; }
.ivc-lead-ok { background: var(--teal-light); color: var(--teal-ink); font-size: var(--fs-sm); font-weight: 600; padding: 10px 12px; border-radius: var(--r); text-align: center; margin-top: 10px; }
.ivc-lead-err { background: #FBEAE8; color: var(--red-dark); font-size: var(--fs-xs); padding: 9px 12px; border-radius: var(--r); text-align: center; margin-top: 8px; }
.ivc-lead-err a { color: var(--red-dark); font-weight: 700; }

/* ---------- FAQ (accordéons) ---------- */
.faq { max-width: 820px; margin: 0 auto; display: grid; gap: 12px; }
.faq details { background: var(--white); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.faq summary { list-style: none; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 16px 18px; font-family: Sora, sans-serif; font-weight: 600; font-size: var(--fs-base); color: var(--navy-dark); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; font-size: var(--fs-lg); color: var(--red-dark); font-weight: 700; flex: none; transition: transform .2s; }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details[open] summary { border-bottom: 1px solid var(--line); }
.faq .faq-body { padding: 14px 18px 16px; font-size: var(--fs-sm); color: var(--muted); line-height: 1.65; }
.faq .faq-body a { color: var(--red-dark); font-weight: 600; }
.faq .faq-body b { color: var(--ink); }

/* ---------- Confort de lecture & accessibilité ---------- */
/* ⚠️ L'anneau de focus était translucide (.45) : mesuré à 2,08:1 sur blanc et
   1,68:1 sur les fonds sombres — soit INVISIBLE dans le pied de page et les
   bandeaux rouges, alors que la norme demande 3:1. Couleur pleine + un liseré
   blanc extérieur : l'anneau se voit désormais sur clair COMME sur sombre,
   quel que soit le fond (audit du 30/08). */
:focus-visible {
  outline: 3px solid var(--red-dark);
  outline-offset: 2px;
  box-shadow: var(--shadow-sm);
  border-radius: var(--r-sm);
}
/* Sur fond sombre, c'est le liseré qui porte le contraste : on l'inverse. */
footer :focus-visible,
.topbar :focus-visible,
.cta-band :focus-visible,
.hero-card :focus-visible {
  outline-color: #FFFFFF;
  box-shadow: var(--shadow-sm);
}
::selection { background: rgba(232, 35, 26, .16); }
p { text-wrap: pretty; }
h1, h2, h3 { text-wrap: balance; }
/* Audit #6 : titres de carte passés de h3 à h2 pour une hiérarchie sans saut, même dessin. */
.h3-visuel, .h4-visuel, .h5-visuel { letter-spacing: 0; }
@media (prefers-reduced-motion: reduce) {
  /* ⚠️ « .js .reveal » (deux classes) doit être nommé tel quel : la seule
     classe .reveal perdait le duel de spécificité et la garde était morte
     (défaut pré-existant, revue adverse du 30/08). */
  .reveal, .js .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}
@media (max-width: 480px) {
  body { font-size: var(--fs-base); }
  .section { padding: 58px 0; }
  .btn { width: 100%; }
  .hero-actions .btn, .cta-band .actions .btn { width: 100%; }
}

/* ============================================================
   MODERNISATION DU 10/09/2026 — skill impeccable, identité gardée
   ============================================================ */
/* Un lien dans un texte se reconnaît sans compter sur la couleur seule
   (WCAG 1.4.1) : un soulignement fin, qui s'affirme au survol. */
:where(main, article) :where(p, li) > a:not([class]) {
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .2em;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  transition: text-decoration-color .2s ease;
}
:where(main, article) :where(p, li) > a:not([class]):hover { text-decoration-color: currentColor; }
/* Les chiffres qui se comparent s'alignent (prix, compteurs, étapes, tableaux). */
.stat b, .formule .f-prix, .price-tag, .route-marker .pin, .step-num, table { font-variant-numeric: tabular-nums; }
/* La barre du haut prend un rien de relief dès qu'on défile — sans script,
   et seulement là où le navigateur sait le faire. */
@supports (animation-timeline: scroll()) {
  .navbar { animation: iv-barre linear both; animation-timeline: scroll(root); animation-range: 0 90px; }
}
@keyframes iv-barre { to { box-shadow: 0 8px 24px rgba(23, 19, 20, .07); } }
/* LE MOMENT DE L'ACCUEIL — le seul mouvement voulu du site : le titre, la
   phrase, les boutons puis la carte rouge se posent l'un après l'autre.
   `backwards` et pas `both` : l'animation lâche prise une fois jouée (une
   transformation retenue casse les éléments collants, 29/08). Qui a demandé
   moins d'animation voit tout, immobile. */
@media (prefers-reduced-motion: no-preference) {
  .hero-inner > div:first-child > *, .hero-visual { animation: iv-pose .8s var(--ease-out) backwards; }
  .hero-inner > div:first-child > :nth-child(2) { animation-delay: .06s; }
  .hero-inner > div:first-child > :nth-child(3) { animation-delay: .12s; }
  .hero-inner > div:first-child > :nth-child(n+4) { animation-delay: .18s; }
  .hero-visual { animation-delay: .24s; }
}
@keyframes iv-pose { from { opacity: 0; transform: translateY(12px); } }

/* ---------- Utilities ---------- */
.center { text-align: center; }
.mt-30 { margin-top: 30px; }

/* ============ Blog dynamique : compte, article, commentaires ============ */
.blog-auth { display: flex; justify-content: flex-end; align-items: center; gap: 12px; margin-bottom: 22px; flex-wrap: wrap; }
/* 24/10/2026 (prise en main au téléphone, lot 2) : « Se connecter » faisait 41 px
   de haut à 360 px et portait un emoji en guise d'icône — l'icône du rond compte,
   et 44 px au doigt. */
.blog-auth .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2); min-height: 44px; }
.blog-auth svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.auth-hello { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--muted); }
.auth-hello b { color: var(--navy-dark); }
.blog-vide { color: var(--muted); font-size: var(--fs-base); text-align: center; padding: 26px 0; }
.post-cover { text-decoration: none; }
.post-body h3 a { color: inherit; text-decoration: none; }
.post-body h3 a:hover { color: var(--red-dark); }

.blog-modal-overlay { position: fixed; inset: 0; background: rgba(23, 19, 20, .55); z-index: 300; display: flex; align-items: center; justify-content: center; padding: 20px; }
.blog-modal { position: relative; width: 100%; max-width: 420px; max-height: 90vh; overflow-y: auto; }
/* 24/10/2026 (lot 2) : la croix de 44 px (top/right 14 px) recouvrait l'onglet
   « Inscription » à 375 px (croix y 60→104, onglets dès y 80). Elle remonte dans
   l'angle et les onglets passent dessous : plus aucun empiètement. Dessin SVG
   (même trait que la loupe de l'en-tête), plus de « ✕ » typographique. */
.blog-modal-close { position: absolute; top: var(--sp-2); right: var(--sp-2); background: none; border: none;
  font-size: var(--fs-md); color: var(--muted); cursor: pointer; padding: 6px; border-radius: var(--r-sm);
  /* 30/08 : la largeur tombait a ~22 px — sous la norme des 24 px. */
  min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.blog-modal-close svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.blog-modal-close:hover { color: var(--red-dark); }
.blog-modal-tabs { display: flex; gap: 8px; margin-top: var(--sp-5); margin-bottom: 20px; }
.bm-tab { flex: 1; padding: 9px 0; border: 1px solid var(--line); background: var(--white); border-radius: var(--r); font-family: Sora, sans-serif; font-weight: 600; font-size: var(--fs-sm); color: var(--muted); cursor: pointer; transition: background .2s ease, color .2s ease, border-color .2s ease; }
.bm-tab.active { background: var(--navy-dark); border-color: var(--navy-dark); color: var(--sur-couleur); }
.bm-err { background: #FDECEB; color: var(--red-dark); font-size: var(--fs-sm); padding: 9px 12px; border-radius: var(--r-sm); margin-bottom: 12px; }
.bm-ok { background: var(--teal-light); color: var(--teal-ink); font-size: var(--fs-sm); padding: 9px 12px; border-radius: var(--r-sm); margin-bottom: 12px; }
/* 20/10/2026 — « Mot de passe oublié ? » sous le mot de passe (blog, questions), et
   son écran : une phrase, l'e-mail, le lien, le retour. */
.bm-oubli, .bm-retour { display: block; padding: 6px 0; min-height: 32px; background: none; border: 0;
  font: inherit; font-size: var(--fs-sm); font-weight: 600; color: var(--red-dark); cursor: pointer;
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px;
  transition: text-decoration-color .15s ease-out; }
.bm-oubli { margin: 6px 0 10px auto; }
.bm-retour { margin: 12px auto 0; }
.bm-form-oubli .field { margin-bottom: 16px; }
.bm-oubli:hover, .bm-retour:hover { text-decoration-color: currentColor; }
.bm-oubli:focus-visible, .bm-retour:focus-visible { outline: 2px solid var(--red-dark); outline-offset: 2px; border-radius: 4px; }
.bm-intro { font-size: var(--fs-sm); color: var(--muted); line-height: 1.55; margin-bottom: 14px; }

/* 07/09 — LARGEUR DE LECTURE. Mesure de l'etat des lieux : 93 caracteres par
   ligne, alors que l'oeil decroche au-dela de 75. 680 px avec un corps a
   18 px donnent environ 75 caracteres — et un texte plus grand se lit mieux
   sur telephone comme sur ecran. */
.article-container { max-width: 680px; }
.article-titre { font-size: var(--fs-h2); font-weight: 700; color: var(--navy-dark); letter-spacing: -.6px; line-height: 1.25; text-wrap: balance; }
.article-contenu { margin-top: 22px; }
.article-contenu p { margin-bottom: var(--sp-4); color: var(--ink); font-size: var(--fs-lg); line-height: 1.75; text-wrap: pretty; }
.article-actions { margin: 26px 0 6px; display: flex; align-items: center; gap: 14px; }
.like-btn { display: inline-flex; align-items: center; gap: 8px; padding: 9px 18px; border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--white); font-family: Sora, sans-serif; font-weight: 600; font-size: var(--fs-sm); color: var(--muted); cursor: pointer; transition: background .2s ease, color .2s ease, border-color .2s ease, transform .2s ease; }
.like-btn svg { width: 18px; height: 18px; stroke: currentColor; }
.like-btn:hover { border-color: var(--red-dark); color: var(--red-dark); transform: translateY(-2px); }
.like-btn.liked { background: var(--blush); border-color: #F3D4D2; color: var(--red-dark); }
.like-btn.liked svg { fill: var(--red-dark); }

/* Ponts de conversion en fin d'article (injectés par blog.js) */
.article-ponts { display: grid; gap: 10px; margin-top: 26px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.article-ponts .pont {
  display: block; padding: 15px 17px; border: 1px solid #F3D4D2; border-radius: var(--r);
  background: var(--blush); font-size: var(--fs-sm); line-height: 1.5; color: var(--ink); transition: background-color .2s, border-color .2s, color .2s, box-shadow .2s, transform .2s, opacity .2s;
}
.article-ponts .pont b { display: block; color: var(--red-dark); font-size: var(--fs-sm); margin-bottom: 2px; }
.article-ponts .pont span { color: var(--muted); }
.article-ponts .pont:hover { border-color: #F3D4D2; }

.article-comments { margin-top: 38px; border-top: 1px solid var(--line); padding-top: 28px; }
.comments-titre { font-size: var(--fs-lg); font-weight: 700; color: var(--navy-dark); margin-bottom: 18px; }
.comm { display: flex; gap: 12px; margin-bottom: 16px; }
.comm-avatar { flex: none; width: 38px; height: 38px; border-radius: 50%; background: var(--red-fond); color: var(--sur-couleur); display: flex; align-items: center; justify-content: center; font-family: Sora, sans-serif; font-weight: 700; font-size: var(--fs-sm); }
.comm-body { flex: 1; background: var(--bg); border: 1px solid var(--line); border-radius: var(--r); padding: 10px 14px; }
.comm-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.comm-head b { font-size: var(--fs-sm); color: var(--navy-dark); }
.comm-head small { font-size: var(--fs-xs); color: var(--muted); }
.comm-head .comm-del { margin-left: auto; background: none; border: none; color: var(--muted);
  cursor: pointer; font-size: var(--fs-xs); padding: 2px 6px;
  /* Idem : carre, pour que la cible existe vraiment. */
  min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.comm-head .comm-del:hover { color: var(--red-dark); }
.comm-body p { font-size: var(--fs-sm); color: var(--ink); line-height: 1.6; }
.comm-form { margin-top: 18px; }
.comm-form textarea { width: 100%; }

/* Puces à coche : le texte (avec ses gras) reste un seul bloc fluide */
.check-list li > span { flex: 1; min-width: 0; }

/* ============ Liens utiles : sections repliables ============ */
.links-acc { border: 1px solid var(--line); border-radius: var(--r); margin-bottom: 16px; background: var(--white); overflow: hidden; }
.links-acc summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 12px; padding: 4px 20px; transition: background .2s ease; }
.links-acc summary::-webkit-details-marker { display: none; }
.links-acc summary:hover { background: var(--bg); }
.links-acc summary .links-cat { flex: 1; margin: 14px 0; border-bottom: none; padding-bottom: 0; }
.acc-count { flex: none; font-size: var(--fs-xs); font-weight: 600; color: var(--red-dark); background: var(--blush); border-radius: var(--r-pill); padding: 3px 12px; }
.acc-chevron { flex: none; width: 20px; height: 20px; color: var(--muted); transition: transform .25s ease; }
.links-acc[open] .acc-chevron { transform: rotate(180deg); }
.links-acc .links-grid { padding: 0 20px 20px; }

/* ============ Page Tirages Entrée Express ============ */
.tirage-vedette {
  display: flex; align-items: center; justify-content: space-between; gap: 26px; flex-wrap: wrap;
  background: linear-gradient(120deg, var(--red-dark), var(--red-deep));
  border-radius: var(--r-lg); padding: 30px 34px; color: var(--sur-couleur); margin-bottom: 26px;
}
.tirage-vedette .eyebrow { color: #F4C4C0; }
.tirage-vedette h2 { font-size: clamp(1.2rem, 2.6vw, 1.7rem); font-weight: 700; letter-spacing: -.4px; margin-top: 6px; text-wrap: balance; }
.tv-stats { display: flex; gap: 34px; margin-top: 18px; }
.tv-stat b { display: block; font-family: Sora, sans-serif; font-size: var(--fs-h2); font-weight: 700; line-height: 1.1; }
.tv-stat span { font-size: var(--fs-xs); color: #F4C4C0; }
.tirage-vedette .btn-red { background: var(--white); color: var(--red-dark); box-shadow: none; }
.tirage-vedette .btn-red:hover { background: var(--blush); }

.chart-card { border: 1px solid var(--line); border-radius: var(--r); padding: 20px 22px; background: var(--white); }
.chart-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; }
.chart-titre { font-size: var(--fs-md); font-weight: 700; color: var(--navy-dark); }
.chart-select { font-size: var(--fs-sm); font-weight: 600; color: var(--muted); display: flex; align-items: center; gap: 8px; }
.chart-select select {
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 7px 10px; font-size: var(--fs-sm);
  font-family: Inter, sans-serif; color: var(--ink); background: var(--white); max-width: 300px;
}
#chartCrs svg { width: 100%; height: auto; display: block; }
/* 30/09 — un seul graphique, deux axes : invitations en barres (gauche),
   seuil CRS en courbe (droite). Couleurs en variables : le mode nuit suit. */
#chartCrs .ch-grille { stroke: var(--line); stroke-width: 1; }
#chartCrs .ch-mois { stroke: var(--line); stroke-width: 1; opacity: .6; }
#chartCrs .ch-txt { font-size: 11px; fill: var(--muted); }
#chartCrs .ch-crs { fill: var(--red-dark); font-weight: 600; }
#chartCrs .ch-barre { fill: var(--muted); opacity: .38; }
#chartCrs .ch-barre:hover { opacity: .6; }
#chartCrs .ch-ligne { fill: none; stroke: var(--red-dark); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
#chartCrs .ch-point { fill: var(--red-dark); }
.leg-barre { display: inline-block; width: 12px; height: 12px; border-radius: 2px; background: var(--muted); opacity: .38; }
.chart-legende { display: flex; gap: 20px; margin-top: 10px; flex-wrap: wrap; }
.leg-item { display: flex; align-items: center; gap: 7px; font-size: var(--fs-xs); color: var(--muted); }
.leg-trait { display: inline-block; width: 26px; height: 0; border-top: 3px solid var(--red-dark); border-radius: var(--r-pill); }
.leg-trait.tirets { border-top-style: dashed; border-top-color: var(--muted); }

.tirage-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); }
.tirage-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.tirage-table th { background: var(--bg); text-align: left; padding: 11px 16px; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 1px; color: var(--muted); border-bottom: 1px solid var(--line); }
.tirage-table th.num, .tirage-table td.num { text-align: center; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tirage-table th:nth-child(1) { width: 26%; }
.tirage-table th:nth-child(2) { width: 34%; }
.tirage-table th:nth-child(3) { width: 20%; }
.tirage-table th:nth-child(4) { width: 20%; }
.tirage-table td { padding: 11px 16px; border-bottom: 1px solid var(--line); }
.tirage-table tbody tr:last-child td { border-bottom: none; }
.tirage-table tbody tr:hover { background: var(--bg); }
.cat-badge { display: inline-block; font-size: var(--fs-xs); font-weight: 600; background: var(--blush); color: var(--red-dark); border-radius: var(--r-pill); padding: 3px 11px; white-space: nowrap; }

/* ============ Menu déroulant « Ressources » ============ */
.nav-groupe { position: relative; }
.nav-groupe-btn {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: none; cursor: pointer;
  font-family: Inter, sans-serif; color: var(--ink); font-weight: 500; font-size: var(--fs-base);
  padding: 6px 0; position: relative; white-space: nowrap;
}
.nav-groupe-btn svg { width: 13px; height: 13px; transition: transform .25s ease; }
.nav-groupe-btn:hover, .nav-groupe-btn.active,
.nav-groupe:hover .nav-groupe-btn, .nav-groupe.open .nav-groupe-btn { color: var(--red-dark); }
.nav-groupe-btn::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 2px;
  border-radius: var(--r-pill); background: var(--red-dark);
  transform: scaleX(0); transform-origin: left; transition: transform .25s ease;
}
.nav-groupe-btn.active::after, .nav-groupe:hover .nav-groupe-btn::after, .nav-groupe.open .nav-groupe-btn::after { transform: scaleX(1); }
.nav-groupe:hover .nav-groupe-btn svg, .nav-groupe.open .nav-groupe-btn svg { transform: rotate(180deg); }

.nav-sous {
  position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%) translateY(6px);
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); padding: 8px; min-width: 230px;
  opacity: 0; visibility: hidden; transition: opacity .2s ease, transform .2s ease, visibility .2s;
  z-index: 120;
}
/* pont invisible pour ne pas perdre le survol entre le bouton et le panneau */
.nav-sous::before { content: ""; position: absolute; top: -12px; left: 0; right: 0; height: 12px; }
.nav-groupe:hover .nav-sous, .nav-groupe:focus-within .nav-sous, .nav-groupe.open .nav-sous {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
}
.nav-sous a {
  display: block; padding: 10px 14px; border-radius: var(--r);
  color: var(--ink); font-weight: 500; font-size: var(--fs-sm); white-space: nowrap;
}
.nav-sous a:hover, .nav-sous a.active { background: var(--blush); color: var(--red-dark); }

/* Le panneau Ressources en deux familles (29/08/2026) : une colonne d'outils,
   une colonne de lecture, chacune coiffee d'une etiquette. */
.nav-sous-2col { display: grid; grid-template-columns: auto auto; gap: 0 6px; }
/* Trois colonnes depuis le 30/08 : huit outils gratuits sur onze étaient
   introuvables depuis la navigation — ni au menu, ni dans le plan du site.
   Ce sont pourtant les mots qu'on tape dans Google (« compresser un PDF »). */
.nav-sous-3col { display: grid; grid-template-columns: auto auto auto; gap: 0 6px; }
@media (max-width: 1100px) { .nav-sous-3col { grid-template-columns: auto auto; } }
.nav-sous-grp { display: block; padding: 8px 14px 4px; font-size: .75rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.nav-sous a::after { display: none; }

@media (min-width: 980px) and (max-width: 1179px) {
  .nav-groupe-btn { font-size: var(--fs-xs); }
}

/* ===== Diagnostic par tranche & carnet d'erreurs (11/08/2026) =====
   Le score brut ne dit pas OÙ l'élève perd ses points : ces barres, si.
   Le barème TCF va de 3 points (Q1-4) à 33 points (Q36-39) — une erreur
   tardive coûte onze fois plus cher qu'une erreur du début. */
.diag-bloc { margin-top: 18px; padding: 16px; background: #FAF7F6; border: 1px solid #EADFDC;
  border-radius: var(--r); text-align: left; }
.diag-titre { font-weight: 700; font-size: var(--fs-md); margin-bottom: 4px; }
.diag-intro { font-size: var(--fs-sm); color: var(--muted); margin-bottom: 14px; line-height: 1.5; }
.diag-ligne { display: grid; grid-template-columns: minmax(0, 1fr) 90px 74px; gap: 10px;
  align-items: center; padding: 7px 0; border-top: 1px solid #EFE7E5; }
.diag-ligne:first-of-type { border-top: 0; }
.diag-nom { font-size: var(--fs-sm); line-height: 1.35; min-width: 0; }
.diag-nom small { display: block; color: var(--muted); font-size: var(--fs-xs); }
.diag-barre { height: 9px; background: #E9E1DF; border-radius: var(--r-sm); overflow: hidden; }
.diag-barre span { display: block; height: 100%; border-radius: var(--r-sm); }
.diag-chiffres { text-align: right; font-size: var(--fs-sm); }
.diag-chiffres small { display: block; color: var(--muted); font-size: var(--fs-xs); }
.diag-conseil { margin-top: 14px; padding: 12px 14px; background: var(--blush); border: 1px solid color-mix(in srgb, var(--red-dark) 22%, transparent);
  border-radius: var(--r-sm); font-size: var(--fs-sm); line-height: 1.55; }

.carnet-section { margin-bottom: 14px; background: var(--white); border: 1px solid #EADFDC; border-radius: var(--r); }
.carnet-section > summary { cursor: pointer; padding: 13px 16px; font-size: var(--fs-base);
  display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.carnet-section > summary small { color: var(--muted); font-size: var(--fs-xs); font-weight: 600; }
.carnet-q { padding: 14px 16px; border-top: 1px solid #F0E8E6; }
.carnet-q h4 { font-size: var(--fs-sm); margin-bottom: 8px; display: flex; justify-content: space-between;
  align-items: center; gap: 10px; flex-wrap: wrap; }
.carnet-choix { list-style: none; margin: 8px 0; padding: 0; }
.carnet-choix li { padding: 7px 10px; border-radius: var(--r-sm); font-size: var(--fs-sm); margin-bottom: 4px;
  background: #FAF7F6; line-height: 1.45; }
.carnet-choix li.carnet-bonne { background: #E8F5EE; border: 1px solid #B9E0CA; }
.carnet-choix li.carnet-mienne { background: #FDEDEC; border: 1px solid #F3C9C6; }
.carnet-etiq { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  padding: 2px 7px; border-radius: var(--r-pill); white-space: nowrap; }
.carnet-etiq.ok { background: #1E8E5A; color: var(--sur-couleur); }
.carnet-etiq.ko { background: var(--red-fond); color: var(--sur-couleur); }

@media (max-width: 560px) {
  .diag-ligne { grid-template-columns: minmax(0, 1fr) 62px; row-gap: 6px; }
  .diag-barre { grid-column: 1 / -1; order: 3; }
}

/* ===== Plan d'entraînement (11/08/2026) =====
   126 sujets sans plan, c'est un mur : la date d'examen donne un rythme,
   le diagnostic donne une priorité. */
.plan-carte { background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
  padding: 16px 18px; margin-bottom: 18px; }
.plan-carte.plan-urgent { border-color: #F3C9C6; background: #FFFBFB; }
.plan-carte.plan-jour-j { border-color: #B9E0CA; background: #F6FCF9; }
.plan-tete b { display: block; font-size: var(--fs-md); color: var(--navy-dark); }
.plan-tete small { display: block; color: var(--muted); font-size: var(--fs-sm); margin-top: 3px; line-height: 1.5; }
.plan-form { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-top: 14px; }
.plan-form label { font-size: var(--fs-sm); font-weight: 600; color: var(--ink); display: flex;
  flex-direction: column; gap: 5px; }
.plan-form input, .plan-form select { padding: 9px 11px; border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); font-family: inherit; font-size: var(--fs-sm); font-weight: 400; }
.plan-chiffres { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 14px 0 10px; }
.plan-chiffres div { text-align: center; padding: 10px 6px; background: #FAF7F6; border-radius: var(--r); }
.plan-chiffres b { display: block; font-family: Sora, sans-serif; font-size: var(--fs-xl); color: var(--red-dark); }
.plan-chiffres small { display: block; color: var(--muted); font-size: var(--fs-xs); line-height: 1.35; margin-top: 3px; }
.plan-jauge { height: 8px; background: #EFE7E5; border-radius: var(--r-sm); overflow: hidden; margin-bottom: 12px; }
.plan-jauge span { display: block; height: 100%; background: var(--red-dark); border-radius: var(--r-sm); }
.plan-note { font-size: var(--fs-sm); line-height: 1.6; color: var(--ink); }
.plan-actions { margin: 12px 0 0; }
@media (max-width: 560px) {
  .plan-chiffres { gap: 6px; }
  .plan-chiffres div { padding: 8px 4px; }
  .plan-chiffres b { font-size: var(--fs-lg); }
  .plan-form { flex-direction: column; align-items: stretch; }
  .plan-form label { width: 100%; }
  .plan-form .btn { width: 100%; }
}

/* ============ v3 (22/08/2026) — bandeau de langue (#25, préparation) ============
   Barre fine en haut du document : « Cette page existe en français / This page is
   available in English ». Le chef de chantier pose le HTML ; ici, le dessin. */
.iv-bandeau-langue {
  position: relative; z-index: 101;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  background: var(--blush); color: var(--navy-dark);
  font-size: var(--fs-sm); text-align: center; padding: 8px 16px;
  border-bottom: 1px solid var(--line);
}
.iv-bandeau-langue a { color: var(--red-dark); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.iv-bandeau-langue .fermer {
  flex: none; width: 44px; height: 44px; margin: -8px 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; cursor: pointer; color: var(--muted);
  font-size: var(--fs-lg); line-height: 1; border-radius: var(--r-sm);
}
.iv-bandeau-langue .fermer:hover { background: var(--white); color: var(--navy-dark); }

/* ============ v3 (22/08/2026) — téléphone et tablette : cibles tactiles ≥ 44 px (#65),
   planchers de texte (#66), champs de saisie ≥ 16 px ============ */
@media (max-width: 768px) {
  /* Accroche de marque : 11 px, la seule taille hors paliers (elle nomme aussi l'espace
     candidat — on ne la masque pas) */
  .brand-name small { font-size: 11px; letter-spacing: 0; }
  .brand { min-height: 44px; min-width: 0; }
  /* Le bouton menu et la pastille FR/EN ne cèdent jamais leur largeur à la marque */
  .burger, .lang-switch { flex: none; }

  /* Barre supérieure : deux lignes de 44 px (téléphone + e-mail) */
  .topbar { padding: 0; }
  .topbar-left { row-gap: 0; }
  .topbar-item a { display: inline-flex; align-items: center; min-height: 44px; }

  .lang-switch { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; }

  .btn, .btn-sm { min-height: 44px; }

  /* Liens de cartes (services, blog, liens utiles) */
  .service-link { min-height: 44px; padding: 8px 0; margin-top: 8px; }
  .post-body h3 a { display: block; padding: 10px 0; margin: -10px 0; }
  .page-hero .crumbs a { display: inline-block; padding: 11px 0; margin: -11px 0; }
  /* 24/10/2026 (lot 2) : « Accueil » du fil des Prépa TCF / IELTS faisait 17 px
     de haut au doigt. Zone de 45 px, sans rien décaler (marges négatives). */
  .pp-hero .crumbs a { position: relative; z-index: 1; display: inline-block; padding: 14px 0; margin: -14px 0; }
  .info-card a { display: inline-block; padding: 11px 0; margin: -11px 0; }

  /* Pied de page */
  .footer-links li { margin-bottom: 0; }
  .footer-links a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
  .footer-contact a { display: inline-flex; align-items: center; min-height: 44px; }
  .socials a { width: 44px; height: 44px; }
  /* 24/10/2026 (lot 2) : « Assistance WhatsApp », seul sur sa ligne au bas des
     conditions Prépa, faisait 17 px de haut au doigt. */
  .footer-bottom a[href*="wa.me"] { display: inline-flex; align-items: center; min-height: 44px; }

  /* Blog, commentaires, calculateurs */
  .share-btn { width: 44px; height: 44px; }
  .like-btn, .bm-tab, .blog-modal-close, .comm-head .comm-del,
  .ivc-lead-toggle, .ivc-lead-envoi, .iv-bandeau-langue a { min-height: 44px; }
  .comm-head .comm-del, .iv-bandeau-langue a { display: inline-flex; align-items: center; }

  /* Champs de saisie : jamais sous 16 px (iOS zoome) et 44 px de haut */
  .field input, .field select, .field textarea,
  .ivc-lead input, .plan-form input, .plan-form select,
  .tirage-filtre select, .chart-select select { font-size: var(--fs-md); min-height: 44px; }
  /* 24/10/2026 (lot 2) : TOUT champ texte, liste ou zone de saisie à 16 px au
     moins — sous 16 px, l'iPhone zoome dès qu'on touche le champ. :where() ne
     pèse rien : un champ que sa feuille veut plus grand (la loupe, 18 px) le
     reste ; ceux qu'une règle précise met plus petit sont repris un à un
     (.ann-cherche ici, l'alerte tirage plus bas, après sa propre règle). */
  :where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"],
    [type="submit"], [type="button"], [type="reset"], [type="image"]), select, textarea) { font-size: var(--fs-md); }
  input.ann-cherche { font-size: var(--fs-md); }
}
/* Sous 420 px, l'accroche de marque (décorative) tiendrait sur trois lignes : on la masque */
@media (max-width: 419px) {
  .brand-name small { display: none; }
}
  /* ---------- La fusion check-list + coûts (29/08/2026) ---------- */
/* La rangée s'organise en GRILLE (demande d'Alex, 29/08 : « organise mieux
   les boutons ») : boutons de même largeur, lignes équilibrées. auto-fit +
   minmax fait le reste — une page à 2 volets reste deux boutons centrés,
   une page à 7 volets fait des lignes pleines de 4, sans orphelins flottants. */
.fus-barre { display: grid; grid-template-columns: repeat(auto-fit, minmax(225px, 250px));
  justify-content: center; gap: 10px 12px; padding: 16px 16px 0; max-width: 1100px;
  margin: 0 auto; }

/* 23/09/2026 — « c'est décalé » (Alex, capture à l'appui). Mesuré à 1280 px
   sur prepa-tcf.html : les onglets vivaient dans une colonne de 1100 px,
   CENTRÉS, quand le titre juste en dessous partait à 20 px du bord dans une
   colonne de 1280. Premier onglet à 98 px, titre à 20 : deux bords gauches à
   78 px l'un de l'autre, en haut de page, là où l'œil s'installe.
   C'est la suite directe du 20/09 : en sortant le contenu du tout-centré,
   j'avais laissé sa barre d'onglets au milieu. Elle prend le même bord.
   Sous 900 px, la colonne est unique et le centre reste juste : rien ne bouge
   — même palier que l'alignement des titres. */
@media (min-width: 900px) {
  .fus-barre { max-width: var(--maxw); padding-left: 20px; padding-right: 20px;
    justify-content: start; }
}

/* 20/09/2026 — LE VOLET APPARTIENT À SES ONGLETS. Mesure à 1280 px sur
   services.html : 26 px au-dessus de la rangée de boutons, 96 px en dessous.
   Le premier titre tombait à 147 px de l'onglet qui l'ouvre — la page
   paraissait vide plutôt qu'aérée, et rien ne disait que ce titre était la
   RÉPONSE au bouton. On resserre ce qui va ensemble ; deux sections voisines,
   elles, gardent leurs 96 px : c'est le contraste entre les deux qui fait le
   rythme, pas une valeur unique répétée partout. */
.fus-volet.section,
.fus-volet > section.section:first-of-type { padding-top: 40px; }
@media (min-width: 1100px) {
  .fus-volet.section,
  .fus-volet > section.section:first-of-type { padding-top: 48px; }
}

/* 20/09/2026 — LA PAGE RESPIRE PAR BANDES. La couleur ne vivait que dans les
   boutons : sur les pages à volets, une section sur deux prend le fond pâle,
   et le blanc continu redevient une alternance lisible. Les jetons suivent le
   thème sombre tout seuls. */
.fus-volet > section.section:nth-of-type(even):not(.alt) { background: var(--bg); }
.fus-onglet { min-height: 44px; padding: 10px 14px; border: 1px solid var(--line);
  border-radius: var(--r-pill); background: var(--white); color: var(--ink); font: inherit;
  font-size: 1rem; font-weight: 600; cursor: pointer; text-align: center; line-height: 1.25;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  box-shadow: var(--shadow-sm);
  transition: border-color .15s, color .15s, background-color .2s ease,
    box-shadow .2s ease, transform .15s ease; }
@media (max-width: 560px) {
  .fus-barre { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fus-onglet { font-size: .875rem; padding: 10px 8px; }
}
/* La pastille ronde blanche des icônes de volets (30/08/2026, demande
   d'Alex) : émoji ou drapeau dessiné, chaque icône entre dans un cercle
   blanc cerclé fin — lisible sur le bouton rouge comme sur le blanc. */
.onglet-ico { display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 24px; height: 24px; border-radius: 50%; background: var(--white);
  box-shadow: 0 0 0 1px var(--line); vertical-align: middle; margin-right: 7px;
  /* Windows dessine certains emojis AVEC la couleur du texte : sur un bouton
     rouge (texte blanc), l'icone devenait blanc sur pastille blanche. La
     pastille impose donc son encre, quel que soit l'etat du bouton. */
  color: var(--ink); font-size: .875rem; }
/* 30/08 : les emoji des outils sont devenus de VRAIES icônes dessinées, dans
   le même langage graphique que les cartes de service (trait de 2, bouts
   arrondis, grille de 24). Un emoji ne prend pas le rouge de la marque et
   s'affiche différemment sur chaque système ; une icône, si. */
.onglet-ico svg { width: 14px; height: 14px; display: block;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; }
.fus-onglet .onglet-ico { margin-right: 0; }
.btn .onglet-ico { margin-right: 0; }
.q-onglet .onglet-ico { margin-right: 0; }

/* La banniere de compte, etat SANS compte (30/08, Alex : « creer mon compte
   doit etre centre ») : phrase et bouton au centre. L'etat connecte garde
   sa ligne (temoin + Reinitialiser a droite). */
.fus-compte.sans-compte { flex-direction: column; align-items: center; text-align: center; }
.fus-compte.sans-compte .fus-compte-actions { justify-content: center; }
.onglet-ico .drapeau { width: 16px; height: 11px; border-radius: 2px; display: block; }
.fus-onglet:hover { border-color: var(--red);
  box-shadow: var(--shadow-sm); }
/* ⚠️ 09/09 — DEUX ÉTATS POUR UN MÊME REPÈRE VISUEL. Sur un grand écran ces
   boutons sont des ONGLETS (aria-selected) ; sur un téléphone ils deviennent
   un ACCORDÉON (aria-expanded), où rien n'est ouvert tant que le visiteur
   n'a pas choisi. Le rouge marque le volet ouvert dans les deux cas. */
.fus-onglet[aria-selected="true"],
.fus-onglet[aria-expanded="true"] { background: var(--red-fond); border-color: var(--red-fond); color: #fff;
  box-shadow: var(--shadow-sm); }

/* Les pastilles-filtres (Questions du public, entraîneur d'entrevue, et
   bientôt les révisions par module) : même langage que les volets — pilule
   blanche à icône en pastille, relief au survol, actif rouge. PARTAGÉ ici
   depuis le 30/08 : Alex a vu des boutons NUS sur « Préparer mon dossier »
   parce que la règle ne vivait que dans blog.html. */
.q-onglets { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.q-onglet { min-height: 44px; padding: 9px 16px; border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--white); color: var(--ink); font: inherit; font-size: .9375rem; font-weight: 600;
  cursor: pointer; display: inline-flex; align-items: center; gap: 8px; line-height: 1.25;
  box-shadow: var(--shadow-sm);
  transition: border-color .15s, color .15s, background-color .2s ease,
    box-shadow .2s ease, transform .15s ease; }
.q-onglet:hover { border-color: var(--red);
  box-shadow: var(--shadow-sm); }
.q-onglet[aria-selected="true"] { background: var(--red-fond); border-color: var(--red); color: #fff;
  box-shadow: var(--shadow-sm); }
.q-onglet .q-nb { font-weight: 400; opacity: .75; }
@media (prefers-reduced-motion: reduce) {
  .fus-onglet, .q-onglet { transition: none; }
  .fus-onglet:hover, .q-onglet:hover { transform: none; }
}
@keyframes fus-apparait { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* `backwards`, PAS `both` : avec `both`, l'animation retient une
   transformation residuelle sur le volet — et un ancetre transforme CASSE
   tout position:sticky a l'interieur (la jauge de la check-list, le total
   du calculateur de couts). Le fondu joue, puis lache prise. */
.fus-volet:not([hidden]) { animation: fus-apparait .3s ease backwards; }
@media (prefers-reduced-motion: reduce) { .fus-volet:not([hidden]) { animation: none; } }

  /* Le bandeau du compte (29/08/2026) : conservé/effacé, dit clairement. */
.fus-compte { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px 16px; margin-top: 16px; padding: 12px 16px; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--bg); font-size: .9375rem; }
.fus-compte-actions { display: inline-flex; align-items: center; gap: 12px; }
.fus-compte .btn-sm { min-height: 44px; }
.fus-compte small { color: var(--muted); }

/* ============================================================
   MOUVEMENTS DU SITE — passer d'une page, d'un outil, d'un bouton
   à l'autre avec de la matière (ordre d'Alex, 30/08/2026 :
   « des transitions et effets spéciaux […] pour rendre le site
   plus esthétique »). Les volets ont déjà fus-apparait, les cartes
   leurs survols : ce bloc ajoute ce qui manquait.
   ============================================================ */

/* ── 1. De PAGE en PAGE ─────────────────────────────────────────
   Navigateurs récents : vraie transition de document à document
   (l'ancienne page s'efface, la nouvelle se lève). Les autres
   ignorent la règle et reçoivent le fondu d'arrivée plus bas. */
@view-transition { navigation: auto; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: iv-page-sort .16s ease both; }
  ::view-transition-new(root) { animation: iv-page-entre .26s ease both; }
}
/* Mouvement réduit : on coupe AUSSI le fondu croisé que le navigateur
   jouerait par défaut (revue adverse du 30/08) — bascule instantanée. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
@keyframes iv-page-sort  { to   { opacity: 0; } }
@keyframes iv-page-entre { from { opacity: 0; transform: translateY(10px); } }

/* Le fondu d'arrivée, pour TOUS les navigateurs. Il joue AUSSI là où la
   transition de document existe : les deux fondus se superposent sur un
   quart de seconde, indiscernables — alors que la version conditionnée
   (@supports) laissait Firefox et Safari 18 SANS AUCUN effet, leur
   @supports connaissant view-transition-name sans avoir la transition de
   document (revue adverse du 30/08). Opacité pure : aucun script qui
   mesure la page au chargement (rebours, pont des Chances…) n'est décalé. */
@media (prefers-reduced-motion: no-preference) {
  body { animation: iv-arrivee .3s ease both; }
}
@keyframes iv-arrivee { from { opacity: 0; } }

/* ── 2. De BOUTON en BOUTON ─────────────────────────────────────
   Le survol soulève, la pression enfonce : la main sent le bouton.
   (.btn a déjà sa transition .22s ; on n'ajoute que le geste.)
   :where() = spécificité nulle : les boutons qui ont DÉJÀ leur propre
   soulèvement (-2px des rouges, marine, WhatsApp) le gardent — la revue
   adverse a montré que .btn:hover les écrasait à -1px. */
@media (prefers-reduced-motion: no-preference) {
  :where(.btn):hover { transform: translateY(-1px); }
  .btn:active { transform: translateY(0) scale(.97); }
  .fus-onglet:active, .q-onglet:active { transform: scale(.97); }
  /* Les grosses portes d'outils (familles de la barre) : même geste. */
  .fus-groupes-barre .fus-onglet:hover { transform: translateY(-1px); }
}
@media (prefers-reduced-motion: reduce) {
  .btn:hover, .btn:active { transform: none; }
}

/* Cases de consentement de la modale du blog (30/08 — ordre d'Alex :
   Alerte tirage en tête, charte en dernier et obligatoire). */
.bm-consent { display: flex; align-items: flex-start; gap: 8px; font-size: .875rem;
  line-height: 1.5; margin: 0 0 10px; cursor: pointer; color: var(--ink); }
.bm-consent input { width: 18px; height: 18px; margin-top: 2px; flex: 0 0 auto; accent-color: var(--red); }
.bm-consent a { color: var(--red-dark); }

/* ============================================================
   ACCESSIBILITÉ — lien d'évitement (audit du 30/08)
   ------------------------------------------------------------
   Chaque page fait retraverser une vingtaine de tabulations (barre du haut,
   menu de 9 liens, sous-menu, sélecteur de langue) avant d'atteindre le
   contenu. Ce lien, invisible à la souris, apparaît au premier appui sur
   Tab et saute directement au contenu.
   ============================================================ */
.saut-contenu {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--red-fond); color: #fff;
  padding: 12px 20px; border-radius: 0 0 var(--r) 0;
  font-weight: 600; font-size: var(--fs-base);
  min-height: 44px; display: inline-flex; align-items: center;
}
.saut-contenu:focus { left: 0; }

/* Classe de masquage accessible : lu par les lecteurs d'écran, invisible
   à l'œil. Le site n'en avait aucune — d'où les repères manquants. */
.lecture-seule {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Icône en tête d'un bouton ou d'un titre (30/08) — remplace les emoji qui
   servaient d'icônes. Elle prend la couleur du texte qui la suit, donc elle
   suit l'état du bouton (rouge, blanc sur fond rouge, gris désactivé) : un
   emoji, lui, gardait ses propres couleurs et changeait d'un appareil à
   l'autre. Alignée sur la ligne de base optique du texte. */
.ico-t { display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 1.15em; height: 1.15em; margin-right: .45em;
  vertical-align: -.16em; }
.ico-t svg { width: 100%; height: 100%; display: block;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; }
h2 .ico-t, h3 .ico-t { color: var(--red-dark); }

/* Accusé de réception du formulaire de devis (30/08) — il n'en avait aucun :
   le formulaire ouvrait WhatsApp et restait rempli à l'écran, sans un mot. */
.devis-merci {
  border: 1px solid var(--teal); background: var(--teal-light);
  border-radius: var(--r); padding: var(--sp-5) var(--sp-5);
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.devis-merci:focus { outline: none; }
.devis-merci-titre {
  font-family: Sora, sans-serif; font-weight: 700; font-size: var(--fs-lg, 1.25rem);
  color: var(--teal-ink); margin: 0;
}
.devis-merci p { margin: 0; color: var(--ink); font-size: var(--fs-base); }
.devis-merci-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.devis-merci-note { color: var(--muted); font-size: var(--fs-sm); }

/* « Gardez votre score » (30/08) — le calculateur ne produisait rien qu'on
   puisse emporter. Discret : c'est une commodité, pas l'action principale. */
.crs-emporter {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2);
  margin: var(--sp-4) 0; padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}
.crs-emporter-mot { font-size: var(--fs-sm); color: var(--muted); font-weight: 600; }

/* Bloc de confiance de la page de paiement (30/08) — elle n'avait rien :
   ni témoignage, ni rappel de ce qu'on achète, ni un mot sur le
   remboursement, alors que c'est l'instant où l'on hésite le plus. */
.pay-confiance { padding: var(--sp-6) 0 var(--sp-8); background: var(--bg); }
.pay-confiance .container { max-width: 720px; }
.pay-confiance h2 { margin: 0 0 var(--sp-4); }
.pay-confiance-liste { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--sp-3); }
.pay-confiance-liste li { padding-left: var(--sp-5); position: relative;
  font-size: var(--fs-base); line-height: 1.65; color: var(--ink); }
.pay-confiance-liste li::before { content: ""; position: absolute;
  left: 0; top: .62em; width: 8px; height: 8px; border-radius: 50%;
  background: var(--red); }
.pay-confiance-preuve { margin: var(--sp-4) 0 0; font-weight: 600; }

/* « Une information périmée ici ? » (30/08) — les annuaires et les tarifs
   vieillissent forcément ; les visiteurs sont les premiers à le voir et
   n'avaient aucun moyen de le dire. Discret par construction : c'est un
   service rendu, pas un appel à l'action. */
.signaler-pied { margin: var(--sp-6) 0 0; padding-top: var(--sp-4);
  border-top: 1px dashed var(--line); text-align: center; }
.signaler-lien { display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 var(--sp-3); font-size: var(--fs-sm); color: var(--muted);
  text-decoration: underline; text-underline-offset: .2em; }
.signaler-lien:hover { color: var(--red-dark); }

/* Invitation à l'alerte tirage (30/08) — elle n'était proposée nulle part,
   alors que tout le mécanisme existe. Posée là où on vient justement pour
   ne rien rater : la page des tirages. */
.alerte-invite {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-5);
  padding: var(--sp-5); border-radius: var(--r);
  background: var(--blush); border: 1px solid #F3D4D2;
}
.alerte-invite-texte { flex: 1 1 320px; min-width: 0; }
.alerte-invite h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); color: var(--navy-dark); }
.alerte-invite p { margin: 0; color: var(--ink); font-size: var(--fs-base); line-height: 1.6; }

/* ---------- Questions voisines (04/09/2026, maillage) ----------
   Posées par tools/generer-questions.py sous les réponses : trois questions
   proches et la porte vers l'évaluation gratuite. */
.q-voisines { margin: 30px 0 0; padding-top: 22px; border-top: 1px solid var(--line); }
.q-voisines h2 { font-size: var(--fs-md); margin-bottom: 10px; }
.q-voisines ul { list-style: none; padding: 0; margin: 0 0 16px; display: grid; gap: 8px; }
.q-voisines li a { display: block; padding: 10px 14px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--white); color: var(--ink); font-weight: 500; text-decoration: none; }
.q-voisines li a:hover { border-color: var(--red); color: var(--red-dark); }
.q-porte { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; }

/* ============================================================
   PREMIER ÉCRAN AU TÉLÉPHONE + ALERTE TIRAGE PARTOUT (04/09/2026, audit)
   Mesuré à 375 px avant : barre noire 88 px + menu 69 + titre 184 = 341 px
   d'habillage avant le premier contenu. Ici : la barre noire sur une ligne
   (l'e-mail vit au pied de page), le titre à taille mobile, le bouton d'action
   AVANT le fil d'Ariane, et un bandeau discret d'alerte tirage au-dessus du
   pied de page — le meilleur aimant à contacts du site.
   ============================================================ */
.page-hero .hero-cta { margin: 16px 0 0; }
.page-hero .hero-cta .btn { min-width: 250px; }
.acces-rapides { background: var(--white); border-bottom: 1px solid var(--line); }
.acces-rapides .container { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; padding-top: 14px; padding-bottom: 14px; }
.acces-rapides a { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r); background: var(--bg); color: var(--ink); text-decoration: none; transition: border-color .2s ease, transform .2s ease; }
.acces-rapides a:hover { border-color: var(--red); }
.acces-rapides .ar-ico { font-size: 1.5rem; line-height: 1; flex: none; }
/* 10/09/2026 — les quatre émojis (feuille, toque, billets, cible) sont devenus
   des icônes dessinées, du trait des cartes de service : un émoji ne prend pas
   le rouge de la marque et change de dessin d'un téléphone à l'autre. */
.acces-rapides .ar-ico svg { display: block; width: 24px; height: 24px; fill: none; stroke: var(--red); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.acces-rapides b { display: block; font-size: var(--fs-sm); color: var(--navy-dark); }
.acces-rapides small { display: block; color: var(--muted); font-size: var(--fs-xs); }
/* Dans le hero de l'accueil : quatre tuiles sous les gages de confiance, sans bande ni bordure. */
.hero .acces-rapides { background: transparent; border: 0; margin-top: 26px; }
.hero .acces-rapides .container { grid-template-columns: repeat(2, 1fr); gap: 10px; padding: 0; max-width: 560px; margin: 0; }
.hero .acces-rapides a { background: var(--white); }
.ev-badge { display: inline-block; margin-left: 8px; padding: 2px 9px; border-radius: var(--r-pill); background: var(--teal-light, #E3F4F1); color: var(--navy-dark); font-size: .75rem; font-weight: 600; white-space: nowrap; vertical-align: middle; }
.ev-case { display: flex; gap: 10px; align-items: flex-start; font-size: var(--fs-sm); }
.ev-case input { margin-top: 3px; flex: none; width: 18px; height: 18px; }
.reassurance { margin: 6px 0 14px; font-size: var(--fs-sm); color: var(--muted); }
.alerte-bandeau { background: var(--bg); border-top: 1px solid var(--line); }
.alerte-bandeau .container { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding-top: 18px; padding-bottom: 18px; flex-wrap: wrap; }
.alerte-bandeau .ab-texte { flex: 1 1 320px; }
.alerte-bandeau .ab-texte b { display: flex; align-items: flex-start; gap: var(--sp-2); color: var(--navy-dark); font-size: var(--fs-md); }
/* 24/10/2026 (lot 2) : l'enveloppe du pied de page remplace l'emoji boîte aux lettres. */
.alerte-bandeau .ab-texte b svg { width: 20px; height: 20px; flex: none; margin-top: 2px; fill: none; stroke: var(--red); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.alerte-bandeau .ab-texte small { color: var(--muted); font-size: var(--fs-xs); }
.alerte-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; flex: 1 1 340px; position: relative; }
/* 24/10/2026 (lot 2) : le champ n'avait qu'un texte d'exemple, qui s'efface à la
   première lettre — un libellé visible, au-dessus. */
.alerte-form .alerte-libelle { flex: 1 0 100%; margin: 0; font-size: var(--fs-sm); font-weight: 600; color: var(--ink); }
/* Toucher le libellé place le curseur dans le champ : 45 px de zone au doigt
   (13 au-dessus, 8 dessous jusqu'au champ), sans rien décaler. */
@media (max-width: 768px) { .alerte-form .alerte-libelle { padding: 13px 0 8px; margin: -13px 0 -8px; } }
.alerte-form input[type="email"] { flex: 1 1 200px; min-width: 0; padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--r-sm); font: inherit; font-size: var(--fs-sm); background: var(--white); color: var(--ink); }
.alerte-form input[type="email"]:focus { outline: 2px solid var(--red); outline-offset: 1px; border-color: var(--red); }
.alerte-form .btn { white-space: nowrap; }
.alerte-form .alerte-etat { flex: 1 0 100%; font-size: var(--fs-xs); color: var(--muted); margin: 0; min-height: 0; }
.alerte-form .alerte-etat:empty { display: none; }
.alerte-form .alerte-etat.ok { color: var(--teal-dark, #0F6E62); font-weight: 600; }
.alerte-form .alerte-etat.ko { color: var(--red-dark); }
.alerte-form .alerte-piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.alerte-inline .alerte-form { margin-top: 12px; }
/* 29/09/2026 — la notification de tirage suit l'alerte e-mail dans le bandeau
   du pied : une ligne pleine largeur sous le formulaire ; vide (appareil qui ne
   sait pas recevoir), elle ne prend aucune place. */
.alerte-bandeau .alerte-inline { flex: 1 0 100%; font-size: var(--fs-sm); color: var(--ink); }
.alerte-bandeau .alerte-inline p { margin: 0 0 8px; }
.alerte-bandeau .alerte-inline:empty { display: none; }
/* Même taille que « Me prévenir » juste au-dessus : deux gestes de même poids. */
.alerte-bandeau .alerte-inline .btn { padding: 8px 16px; font-size: var(--fs-sm); }
@media (max-width: 767px) {
  .topbar-item:has(a[href^="mailto:"]) { display: none; }
  .topbar-left { row-gap: 0; }
  .page-hero { padding: 24px 0 20px; }
  .page-hero h1, .page-hero h2.titre-volet { font-size: 1.5rem; letter-spacing: -.4px; line-height: 1.22; }
  .page-hero .crumbs { margin-top: 8px; font-size: .75rem; }
  .page-hero .hero-cta .btn { width: 100%; }
  .hero-inner { padding-top: 26px; gap: 28px; }
  .hero-badge { font-size: .75rem; padding: 6px 12px; }
  .hero-sub { margin: 14px 0 20px; }
  .acces-rapides .container { grid-template-columns: 1fr 1fr; gap: 8px; }
  .acces-rapides a { padding: 10px 12px; }
  .alerte-bandeau .container { flex-direction: column; align-items: stretch; }
  /* En colonne, flex-basis devient une hauteur : on la retire (bandeau creux de 320 px mesuré). */
  .alerte-bandeau .ab-texte, .alerte-bandeau .alerte-form { flex: none; }
  .acces-rapides small { display: none; }
  .alerte-form .btn { width: 100%; }
  /* 24/10/2026 (lot 2) : le champ e-mail était à 14 px (l'iPhone zoomait) et
     35 px de haut. Après sa règle de base, à poids égal : celle-ci l'emporte. */
  .alerte-form input[type="email"] { font-size: var(--fs-md); min-height: 44px; }
}

/* « Nos candidats » — Prépa TCF (04/09/2026) : des chiffres réels, anonymes, rafraîchis en direct. */
.ptcf-candidats { margin-top: var(--sp-6); padding: 18px 22px; border: 1px solid var(--line); border-radius: var(--r); background: var(--white); display: grid; grid-template-columns: auto 1fr; gap: 8px 26px; align-items: center; }
.ptcf-candidats .eyebrow { grid-row: 1 / 3; margin: 0; }
.ptcf-candidats ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 22px; }
.ptcf-candidats li b { color: var(--red-dark); font-size: var(--fs-md); }
.ptcf-candidats li small { color: var(--muted); display: block; font-size: var(--fs-xs); }
.ptcf-candidats p { margin: 0; color: var(--muted); font-size: var(--fs-sm); }
@media (max-width: 767px) {
  .ptcf-candidats { grid-template-columns: 1fr; gap: 10px; }
  .ptcf-candidats .eyebrow { grid-row: auto; }
}

/* Services (04/09/2026) : tableau comparatif des packs, étapes, garanties */
.packs-comparatif, .etapes, .garanties { max-width: 900px; margin: var(--sp-7) auto 0; }
.packs-comparatif h3, .etapes h3, .garanties h3 { font-family: Sora, sans-serif; font-size: var(--fs-h3, 1.35rem); margin-bottom: 14px; text-align: center; }
/* ⚠️ 09/09 — UNE BOÎTE QUI DÉFILE DOIT LE DIRE. Mesure sur services.html à
   375 px : le tableau des packs fait 520 px dans une boîte de 333 — 156 %.
   Il défilait déjà, mais RIEN ne le montrait : on voyait la colonne Premium
   coupée net et on croyait la page cassée. Même constat que sur la check-list
   le 18/08. Le faire tenir à 333 px passerait sous les 14 px que la charte
   interdit de franchir : on garde donc le défilement, et on le rend VISIBLE.

   L'ombre à droite s'efface d'elle-même quand on arrive au bout — c'est le
   `background-attachment: local` qui fait ça, sans une ligne de JavaScript :
   les deux dégradés blancs restent collés aux bords de la boîte, les deux
   ombres suivent le contenu et se glissent dessous. */
.table-scroll {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--white);
  background-image:
    linear-gradient(to right, var(--white), rgba(255, 255, 255, 0)),
    linear-gradient(to left,  var(--white), rgba(255, 255, 255, 0)),
    linear-gradient(to right, rgba(0, 0, 0, .13), rgba(0, 0, 0, 0)),
    linear-gradient(to left,  rgba(0, 0, 0, .13), rgba(0, 0, 0, 0));
  background-position: left center, right center, left center, right center;
  background-repeat: no-repeat;
  background-size: 26px 100%, 26px 100%, 12px 100%, 12px 100%;
  background-attachment: local, local, scroll, scroll;
}
/* Le mot qui dit le geste — sur téléphone seulement : sur un grand écran le
   tableau tient tout entier et la phrase n'apprendrait rien. */
.table-glisser { display: none; }
@media (max-width: 768px) {
  .table-glisser {
    display: block; margin: 0 0 8px; font-size: var(--fs-sm); color: var(--muted);
    text-align: center;
  }
}
.packs-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); min-width: 560px; }
.packs-table th, .packs-table td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: center; vertical-align: middle; }
.packs-table thead th { font-family: Sora, sans-serif; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .6px; color: var(--muted); background: var(--bg); }
.packs-table thead th.star { color: var(--red-dark); }
.packs-table thead th small { display: block; text-transform: none; letter-spacing: 0; font-weight: 500; }
.packs-table tbody th { text-align: left; font-weight: 500; color: var(--ink); }
.packs-table td.oui { color: var(--teal-ink, #0A5C33); font-weight: 700; font-size: var(--fs-md); }
.packs-table td.non { color: var(--muted); }
.packs-table td.star, .packs-table tr.depuis td.star { background: rgba(232, 35, 26, .05); }
.packs-table tr.depuis th, .packs-table tr.depuis td { font-weight: 700; border-bottom: 0; }
.packs-note { margin-top: 10px; font-size: var(--fs-sm); color: var(--muted); text-align: center; }
.etapes ol { list-style: none; counter-reset: etape; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.etapes li { counter-increment: etape; position: relative; padding: 42px 16px 16px; background: var(--white); border: 1px solid var(--line); border-radius: var(--r); font-size: var(--fs-sm); color: var(--muted); }
.etapes li b { display: block; color: var(--ink); margin-bottom: 6px; }
.etapes li::before { content: counter(etape); position: absolute; top: 12px; left: 16px; width: 24px; height: 24px; border-radius: 50%; background: var(--red-fond); color: var(--sur-couleur); font-family: Sora, sans-serif; font-weight: 700; font-size: var(--fs-xs); display: flex; align-items: center; justify-content: center; }
.garanties { padding: 22px 26px; border: 2px solid var(--navy-dark); border-radius: var(--r); background: var(--white); }
.garanties ul { margin: 0 0 14px; padding-left: 20px; font-size: var(--fs-sm); }
.garanties li { margin: 6px 0; }
.garanties .verite { margin: 0; padding: 12px 14px; background: var(--blush); border: 1px solid color-mix(in srgb, var(--red) 24%, transparent); border-radius: var(--r-sm); font-size: var(--fs-sm); }
@media (max-width: 767px) {
  .etapes ol { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .etapes li { padding: 40px 12px 12px; }
  .packs-table { min-width: 520px; }
}

/* « Et maintenant ? » — Calculer mes chances (04/09/2026) */
.et-maintenant { margin-top: 16px; padding: 14px 16px; border: 1px solid color-mix(in srgb, var(--red) 28%, var(--line)); border-radius: var(--r); background: var(--white); text-align: left; }
.et-maintenant h5 { font-family: Sora, sans-serif; font-size: var(--fs-md); margin: 0 0 8px; color: var(--navy-dark); }
.et-maintenant p { margin: 0 0 8px; font-size: var(--fs-sm); color: var(--ink); }
.et-maintenant .leviers { margin: 0 0 10px; padding-left: 18px; font-size: var(--fs-sm); }
.et-maintenant .leviers li { margin: 4px 0; }
.et-maintenant .em-cta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0; }
.et-maintenant .em-cta small { flex: 1 0 100%; color: var(--muted); font-size: var(--fs-xs); }

/* 22/10/2026 — PORTE PRÉPA : l'encart unique qui mène à la Prépa TCF ou IELTS
   depuis les résultats, la confirmation de l'évaluation, les articles et les
   questions. Même famille que .eval-banner (lavis rouge), mais en variables
   seulement : le mode nuit suit tout seul. La classe doublée bat
   « .art-mise .article-contenu p / a » de blog.css quand l'encart est dans un article. */
/* La mise en page suit la LARGEUR DE L'ENCART, pas celle de l'écran : il vit aussi
   dans la colonne étroite du score de Calculer mes chances. Trois blocs souples :
   icône · texte (grandit) · actions (passent dessous quand la place manque). */
.porte-prepa {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px;
  margin: var(--sp-6) 0; padding: var(--sp-5);
  background: var(--blush); border: 1px solid color-mix(in srgb, var(--red) 22%, var(--line));
  border-radius: var(--r); text-align: left;
}
.porte-prepa .porte-ico { flex: 0 0 44px; height: 44px; align-self: flex-start; border-radius: var(--r); background: var(--white); display: grid; place-items: center; }
.porte-prepa .porte-ico svg { width: 22px; height: 22px; fill: none; stroke: var(--red-dark); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.porte-prepa .porte-corps { flex: 999 1 220px; min-width: 0; }
.porte-prepa.porte-prepa p { margin: 0; }
.porte-prepa.porte-prepa .porte-titre { font-family: Sora, sans-serif; font-weight: 700; font-size: var(--fs-lg); line-height: 1.35; color: var(--navy-dark); letter-spacing: -0.2px; text-wrap: balance; }
.porte-prepa .porte-gain { color: var(--red-dark); white-space: nowrap; }
.porte-prepa.porte-prepa .porte-texte { margin-top: 4px; font-size: var(--fs-base); line-height: 1.6; color: var(--ink); max-width: 62ch; text-wrap: pretty; }
.porte-prepa.porte-prepa .porte-faits { margin-top: 8px; font-size: var(--fs-sm); line-height: 1.5; color: var(--muted); }
.porte-prepa .porte-actions { flex: 1 1 200px; display: flex; flex-direction: column; align-items: stretch; gap: 4px; text-align: center; }
.porte-prepa.porte-prepa a.btn { justify-content: center; text-decoration: none; overflow-wrap: normal; }
.porte-prepa.porte-prepa a.btn-red { color: var(--sur-couleur); }
.porte-prepa.porte-prepa .porte-lien { display: inline-flex; align-items: center; justify-content: center; min-height: 36px; font-family: Sora, sans-serif; font-weight: 600; font-size: var(--fs-sm); color: var(--red-dark); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.porte-prepa.porte-prepa .porte-lien:hover { text-decoration-thickness: 2px; }
@media (max-width: 767px) {
  .porte-prepa { padding: var(--sp-4); }
  .porte-prepa.porte-prepa .porte-lien { min-height: 44px; }
}
/* Sous un score, l'encart est déjà dans un panneau : on le resserre, et le lien
   « 🎧 Entraînez-vous gratuitement » qu'il remplace se retire. */
.ivc-panel .porte-prepa { margin: var(--sp-4) 0; padding: var(--sp-4); }
.ivc-panel.a-porte .ivc-train { display: none !important; }

/* 22/10/2026 — LA BANDE PRÉPA DE L'ACCUEIL : la grande sœur de .porte-prepa (même
   lavis rouge), juste sous les chiffres du cabinet. À droite, un relevé blanc des
   résultats RÉELS de la plateforme (tcf_vitrine), caché tant qu'il n'est pas rempli :
   la colonne de gauche prend alors toute la largeur. */
.bande-prepa-zone { padding-bottom: 0; }
.bande-prepa {
  display: grid; gap: var(--sp-6) var(--sp-8); align-items: center;
  padding: var(--sp-6) var(--sp-5);
  background: var(--blush); border: 1px solid color-mix(in srgb, var(--red) 22%, var(--line));
  border-radius: var(--r-lg);
}
@media (min-width: 940px) {
  .bande-prepa { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); padding: var(--sp-8); }
  .bande-prepa:has(.bp-releve[hidden]) { grid-template-columns: minmax(0, 1fr); }
}
.bande-prepa h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-h2); letter-spacing: -0.6px; line-height: 1.2; color: var(--navy-dark); text-wrap: balance; }
.bande-prepa .bp-phrase { margin: 0 0 var(--sp-5); max-width: 56ch; font-size: var(--fs-lg); line-height: 1.6; color: var(--ink); text-wrap: pretty; }
.bande-prepa .bp-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.bande-prepa .bp-note { margin: var(--sp-3) 0 0; font-size: var(--fs-sm); line-height: 1.5; color: var(--muted); }
.bande-prepa .bp-note a { color: var(--red-dark); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.bp-releve { padding: var(--sp-5); background: var(--white); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow-sm); }
.bp-releve .bp-releve-titre { margin: 0 0 var(--sp-2); font-family: Sora, sans-serif; font-weight: 600; font-size: var(--fs-base); color: var(--navy-dark); }
.bp-releve p { margin: 0 0 var(--sp-3); font-size: var(--fs-sm); line-height: 1.55; color: var(--ink); }
.bp-releve p b { font-family: Sora, sans-serif; font-weight: 700; color: var(--navy-dark); font-variant-numeric: tabular-nums; }
.bp-releve ul { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.bp-releve li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; padding: var(--sp-2) 0; border-top: 1px solid var(--line); font-size: var(--fs-sm); line-height: 1.5; color: var(--ink); }
.bp-releve li b { font-family: Sora, sans-serif; font-weight: 700; color: var(--red-dark); font-variant-numeric: tabular-nums; }
.bp-releve li .pp-score { white-space: nowrap; color: var(--muted); }
.bp-releve li small { flex: 1 0 100%; color: var(--muted); font-size: var(--fs-xs); }
@media (max-width: 767px) {
  .bande-prepa-zone { padding-top: var(--sp-7); }
  .bande-prepa { gap: var(--sp-5); }
  .bande-prepa .bp-phrase { margin-bottom: var(--sp-4); font-size: var(--fs-md); }
  /* Au téléphone, un seul 39/39 : la bande ne doit pas faire deux écrans. */
  .bp-releve li:nth-child(n+2) { display: none; }
  .bp-releve { padding: var(--sp-4); }
}
/* Tirages : comparer à mon score */
/* 07/09 : ce lien se repete a chaque tirage et se lit comme un bouton. Il
   mesurait 24 px de haut — trop petit pour un pouce. Cible portee a 44 px
   (mesure de l'etat des lieux : 17 occurrences sous le seuil sur la page). */
.tc-comparer { display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px;
  margin-top: 4px; font-size: var(--fs-sm); color: var(--red-dark); font-weight: 600; text-decoration: none; }
.tc-comparer:hover { text-decoration: underline; }
td.num a.tc-comparer { display: inline-flex; min-height: 44px; margin: 0; color: inherit; font-weight: inherit; text-decoration: underline dotted; }
/* Le livre : la table des matières complète */
.livre-tdm { max-width: 860px; margin: var(--sp-6) auto 0; padding: 14px 20px; border: 1px solid var(--line); border-radius: var(--r); background: var(--white); }
.livre-tdm summary { cursor: pointer; font-family: Sora, sans-serif; font-weight: 700; color: var(--navy-dark); }
.livre-tdm summary small { font-weight: 500; color: var(--muted); }
.livre-tdm .tdm { margin: 14px 0 0; padding-left: 0; list-style: none; columns: 2; column-gap: 32px; font-size: var(--fs-sm); }
.livre-tdm .tdm > li { break-inside: avoid; margin: 0 0 12px; }
.livre-tdm .tdm > li > b { color: var(--ink); }
.livre-tdm .tdm ol { margin: 4px 0 0; padding-left: 18px; color: var(--muted); }
.livre-tdm .tdm ol li { margin: 2px 0; }
.livre-tdm .tdm-note { margin: 12px 0 0; font-size: var(--fs-xs); color: var(--muted); }
/* Paiement : les gestes numérotés, les promesses */
.pay-moyen ol.pay-gestes { list-style: none; counter-reset: geste; padding-left: 0; }
.pay-moyen ol.pay-gestes li { counter-increment: geste; position: relative; padding-left: 40px; margin: 10px 0; }
.pay-moyen ol.pay-gestes li::before { content: counter(geste); position: absolute; left: 0; top: -2px; width: 28px; height: 28px; border-radius: 50%; background: var(--red-fond); color: var(--sur-couleur); font-family: Sora, sans-serif; font-weight: 700; font-size: var(--fs-sm); display: flex; align-items: center; justify-content: center; }
.pay-promesses { margin: 14px 0 0; padding: 12px 14px; border-radius: var(--r); background: var(--bg); border: 1px solid var(--line); font-size: var(--fs-sm); color: var(--ink); }
@media (max-width: 767px) {
  .livre-tdm .tdm { columns: 1; }
}

/* L'offre « livre + consultation » (04/09/2026) */
.offre-livre { margin-top: var(--sp-5); padding: 18px 22px; border: 2px solid var(--navy-dark); border-radius: var(--r); background: var(--white); }
.offre-livre h3 { font-family: Sora, sans-serif; font-size: var(--fs-md); margin: 6px 0 8px; }
.offre-livre h3 b { color: var(--red-dark); }
.offre-livre h3 s { color: var(--muted); font-weight: 500; margin-left: 6px; }
.offre-livre p { font-size: var(--fs-sm); color: var(--muted); margin: 0 0 12px; }


/* ══════════ LA RECHERCHE DU SITE (07/09/2026) ══════════
   Demande d'Alex : « un bouton de recherche pour retrouver des mots, des pages
   ou des onglets ». Le bouton vit dans la barre, à côté de la pastille de
   langue : c'est la seule zone qui reste visible au téléphone comme à l'écran.
   Mesures prises dans les échelles de la charte, comme le reste. */
/* 11/09/2026 — .nav-theme, le bouton lune/soleil (js/main.js), a le même
   habit que la loupe. Pas la même classe : recherche.js ouvre la recherche sur
   tout clic dans un .nav-loupe. */
.nav-loupe, .nav-theme {
  width: 40px; height: 40px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r-sm);
  color: var(--navy-dark); cursor: pointer; transition: border-color .15s ease, color .15s ease;
}
.nav-loupe:hover, .nav-theme:hover { border-color: var(--navy-dark); color: var(--red-dark); }
.nav-loupe:focus-visible, .nav-theme:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }
.nav-loupe svg, .nav-theme svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }

body.rch-ouvert { overflow: hidden; }
.rch { position: fixed; inset: 0; z-index: 300; display: flex; justify-content: center; align-items: flex-start; padding: 7vh var(--sp-4) var(--sp-4); }
.rch-fond { position: absolute; inset: 0; background: rgba(23, 19, 20, .5); }
.rch-boite {
  position: relative; width: min(680px, 100%); max-height: 80vh; display: flex; flex-direction: column;
  background: var(--white); border-radius: var(--r-lg); box-shadow: var(--shadow); overflow: hidden;
  animation: rch-entre .18s ease backwards;
}
@keyframes rch-entre { from { opacity: 0; transform: translateY(-8px); } }
@media (prefers-reduced-motion: reduce) { .rch-boite { animation: none; } }
.rch-tete { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-4); border-bottom: 1px solid var(--line); }
.rch-tete svg { width: 20px; height: 20px; flex: none; fill: none; stroke: var(--muted); stroke-width: 2.2; stroke-linecap: round; }
.rch-tete input {
  flex: 1; min-width: 0; border: 0; outline: none; background: none; font: inherit;
  font-size: var(--fs-lg); color: var(--ink); padding: var(--sp-1) 0;
}
.rch-tete input::-webkit-search-cancel-button { display: none; }
.rch-fermer {
  flex: none; width: 34px; height: 34px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--white); color: var(--muted); font-size: var(--fs-sm); cursor: pointer;
}
.rch-fermer:hover { border-color: var(--red-dark); color: var(--red-dark); }
.rch-corps { overflow-y: auto; padding: var(--sp-2) 0; }
.rch-nb { padding: var(--sp-2) var(--sp-4); margin: 0; font-size: var(--fs-xs); color: var(--muted); }
.rch-liste { list-style: none; margin: 0; padding: 0; }
.rch-liste a {
  display: flex; flex-direction: column; gap: 2px; padding: var(--sp-3) var(--sp-4);
  text-decoration: none; color: var(--ink); border-left: 3px solid transparent;
}
.rch-liste a:hover, .rch-liste a.sur { background: var(--bg); border-left-color: var(--red); }
.rch-page { font-size: var(--fs-sm); font-weight: 600; }
.rch-page b { font-weight: 700; }
.rch-fleche { color: var(--muted); font-weight: 400; }
.rch-extrait { font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }
.rch-corps mark { background: #FDE9C8; color: inherit; border-radius: 3px; padding: 0 2px; }
.rch-info { padding: var(--sp-5) var(--sp-4); margin: 0; font-size: var(--fs-sm); color: var(--muted); line-height: 1.6; }
.rch-info b { color: var(--ink); }
.rch-wa { color: var(--teal-dark); font-weight: 600; }
.rch-sug { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); }
.rch-sug-titre { flex-basis: 100%; font-size: var(--fs-xs); color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.rch-pastille {
  padding: var(--sp-2) var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--white); color: var(--ink); font: inherit; font-size: var(--fs-xs); cursor: pointer;
}
.rch-pastille:hover { border-color: var(--red); color: var(--red-dark); }
.rch-pied { padding: var(--sp-2) var(--sp-4); border-top: 1px solid var(--line); font-size: var(--fs-xs); color: var(--muted); background: var(--bg); }
/* Au téléphone, le panneau prend l'écran : on cherche à une main, sans viser. */
@media (max-width: 640px) {
  .rch { padding: 0; }
  .rch-boite { width: 100%; max-height: 100%; height: 100%; border-radius: 0; }
  .rch-pied { display: none; }
}


/* ══════════ REPERES DE LECTURE (07/09/2026) ══════════
   Un article de deux mille mots n'offrait aucun point d'appui, et les pages
   longues du site montent a 21 ecrans. Reperes poses par
   js/lecture-article.js : un filet de progression, un retour en haut (le
   sommaire des articles est celui de js/blog.js depuis le lot 3 du 12/10/2026,
   .art-plan dans css/blog.css). Rien de tout cela ne touche au texte. */
/* Le titre vise ne se colle pas sous la barre epinglee. */
.article-contenu h2 { scroll-margin-top: 90px; }

.lec-filet { position: fixed; top: 0; left: 0; right: 0; height: 3px; background: transparent; z-index: 60; pointer-events: none; }
.lec-filet span { display: block; height: 100%; width: 0; background: var(--red); transition: width .1s linear; }

.lec-haut {
  position: fixed; right: var(--sp-4); bottom: 84px; z-index: 55;
  width: 44px; height: 44px; display: grid; place-items: center;
  background: var(--white); color: var(--navy-dark); border: 1px solid var(--line);
  border-radius: 50%; box-shadow: var(--shadow-sm); cursor: pointer;
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
}
.lec-haut.visible { opacity: 1; visibility: visible; transform: none; }
.lec-haut:hover { color: var(--red-dark); border-color: var(--red); }
.lec-haut svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* Le bouton WhatsApp flottant occupe deja le coin : on se range au-dessus. */
@media (max-width: 640px) { .lec-haut { bottom: 78px; right: var(--sp-3); } }
@media (prefers-reduced-motion: reduce) { .lec-filet span, .lec-haut { transition: none; } }


/* ══════════ LE THEME SOMBRE (07/09/2026) ══════════
   Etat des lieux : AUCUNE regle de theme sombre dans toute la feuille. Un
   visiteur dont le telephone est en mode sombre — la majorite, le soir —
   recevait une page blanche en pleine figure.
   Les couleurs du site sont deja des variables : il suffit d'en poser un
   second jeu. Deux precautions :
     · le rouge du TEXTE s'eclaircit (#C21510 ne donne que 3,3:1 sur un fond
       sombre ; #F2564C en donne 4,6:1) ;
     · les FONDS rouges, eux, gardent un rouge sombre, sinon le texte blanc
       qu'ils portent devient illisible. */

/* ============================================================
   CÔTE À CÔTE SUR TÉLÉPHONE (08/09/2026, règle d'Alex)
   ------------------------------------------------------------
   « Cet affichage sur mobile est trop long » : une grille qui retombe à
   une colonne oblige à défiler avant de comparer. Sur téléphone, les
   cartes passent à deux par rangée (trois pour des chiffres ou des
   niveaux) en réduisant marges, icônes et ornements — jamais le contenu,
   jamais sous les 14 px. Mesuré à 375 px : services 2 927 → ~1 400 px,
   articles 8 851 → ~2 900, pied de page 1 794 → ~1 000.
   Les témoignages restent seuls sur leur ligne : une citation de cinq
   lignes en colonne de 160 px en ferait quinze.
   ============================================================ */
@media (max-width: 679px) {
  .service-card { padding: 16px 14px; }
  .service-icon { width: 40px; height: 40px; margin-bottom: 12px; }
  .service-icon svg { width: 20px; height: 20px; }
  .service-card h3 { font-size: var(--fs-base); margin-bottom: 6px; }
  .service-link { margin-top: 12px; }
  .price-tag { padding: 4px 10px; margin-bottom: 10px; }
  /* Un nombre impair de cartes : la dernière prend toute la largeur
     plutôt que de rester orpheline à gauche. */
  .services-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* Mesuré à 375 px : « Accompagnement » débordait de 9 px d'une carte de
     160 px, et l'étiquette de prix de 4 px. On laisse un mot long se couper
     plutôt que sortir du cadre. */
  .service-card h3, .service-card .check-list li { overflow-wrap: anywhere; }
  .price-tag { flex-wrap: wrap; white-space: normal; max-width: 100%; }
}
@media (max-width: 719px) {
  .step { padding: 16px 14px; }
  .step-num { width: 32px; height: 32px; margin-bottom: 10px; }
  .step h3 { font-size: var(--fs-sm); margin-bottom: 6px; }
  .steps > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  .formule { padding: 20px 8px 14px; }
  .formule .f-tag { white-space: normal; max-width: 92%; padding: 3px 8px; }
  .formule .f-prix { font-size: var(--fs-base); }
  .footer-brand { grid-column: 1 / -1; }
  /* 24/10/2026 (lot 2, maquette planche-2-pied validée par Alex) : la colonne
     Contact, quatrième et dernière, tenait dans 158 px — e-mail coupé
     « contact@immigrati / on-voyages.com », pied de 1 858 px à 375 px. Elle prend
     toute la largeur (l'e-mail tient d'un bloc : plus besoin de le couper), et
     les écarts se resserrent, sans rien retirer. */
  .footer-grid > :last-child { grid-column: 1 / -1; }
  .footer-grid { gap: var(--sp-5) var(--sp-4); padding-top: var(--sp-6); padding-bottom: var(--sp-5); }
  footer h4, .footer-titre { margin-bottom: var(--sp-2); }
  .footer-contact li { margin-bottom: var(--sp-1); }
}
@media (max-width: 699px) {
  .post-cover { height: 90px; }
  .post-cover svg { width: 30px; height: 30px; }
  .post-body { padding: 12px 12px 14px; }
  .post-meta { flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
  .post-body h3 { font-size: var(--fs-sm); margin-bottom: 6px; }
  /* L'extrait d'article : sur une carte de 160 px, le titre suffit — le
     texte complet est à un clic. */
  .post-body > p { display: none; }
  .post-foot { margin-top: 10px; padding-top: 10px; flex-wrap: wrap; gap: 6px; }
  .link-card { padding: 14px 12px; gap: 10px; flex-direction: column; }
  .link-card h3 { font-size: var(--fs-sm); }
  .links-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ══════════ 11/09/2026 — LE THÈME NUIT OBÉIT À UN ATTRIBUT ══════════
   Demande d'Alex : « je ne vois pas le bouton pour passer en mode nuit ». Ces
   règles vivaient dans @media (prefers-color-scheme: dark) : le téléphone
   décidait seul. Désormais le script d'en-tête de chaque page pose
   data-theme="nuit" ou "clair" sur <html> AVANT l'affichage — le choix du
   bouton lune/soleil (clé iv-theme), sinon le réglage de l'appareil.
   Même contenu, même place dans la feuille, même poids : :where() ne compte
   pas dans la priorité (seuls les jetons, sur :root, pèsent un cran de plus,
   pour passer devant les jetons clairs). */
:root[data-theme="nuit"] {
  /* ⚠️ 09/09 — BLEU NUIT, plus le noir chaud. Demande d'Alex : « trop
     noire ». Chaque couple a ete calcule avant d'etre ecrit ; le plus
     faible de la palette est a 5,70:1 pour 4,50 exiges, et les 54 pages
     ont ete rouvertes ensuite pour le verifier en vrai.
     Le theme CLAIR garde son noir chaud : c'est la couleur de marque. */
  --ink: #EAEFF7;          /* 15,7:1 sur le canevas */
  --muted: #A6B3C9;        /* 8,5:1 sur le canevas, 7,5:1 sur une carte */
  --line: #2C3A55;
  --bg: #0E1626;           /* le canevas : bleu nuit profond */
  --white: #1B2539;        /* les surfaces : ce qui etait blanc devient bleu nuit clair */
  --blush: #2B1E2E;        /* le lavis rouge, accorde au bleu */
  --teal-light: #13272C;
  --amber-light: #292417;
  /* ⚠️ 08/09 : l'encre etait EN DUR (#7A5A10). Sur le fond sombre ci-dessus
     elle ne donnait que 2,5:1 — un texte d'avertissement illisible, sur les
     20 pages qui portent une note ambree. Celle-ci donne 9,1:1. */
  --amber-ink: #E3C271;
  /* ⚠️ 09/09 — MEME PIEGE QUE L'AMBRE : `color: var(--red-ink)` sur fond
     `--blush` donnait 1,8:1 en sombre (le fond s'assombrit, l'encre non),
     sur une quarantaine de pages — toutes les Questions, le blog, la
     check-list. --red-deep reste SOMBRE : il sert de fin de degrade.
     C'est --red-ink, l'encre, qui s'eclaircit. */
  --red-ink: #FF8A82;
  --teal-ink: #6FD9A0;
  --fond-sombre: #25314D;  /* le fond sombre reste sombre : bleu nuit soutenu */     /* meme raison que l'ambre et le rouge */
  --red-fond: #B31410;     /* le fond rouge s'assombrit, l'encre s'eclaircit */
  --red-dark: #FF6B62;     /* le rouge du texte, eclairci pour rester lisible :
                             #F2564C ne donnait que 4,1:1 sur les cartes de la
                             page « introuvable » ; celui-ci passe partout. */
  --navy-dark: #F2EFEE;    /* les titres passent en clair */
  --navy-deep: #F2EFEE;
  --navy-darker: #FFFFFF;
  --shadow: 0 12px 32px rgba(0, 0, 0, .55);
  --shadow-sm: 0 4px 14px rgba(0, 0, 0, .45);
  --ring: 0 0 0 4px rgba(232, 35, 26, .28);
  --line-strong: #3A4A6B;
  --scroll-thumb: #33415F;
  /* 10/09/2026 : les champs, listes et barres que dessine le navigateur
     passent en sombre avec la page (un texte clair sur un champ resté
     blanc tombait à 2,1:1). */
  color-scheme: dark;
}
/* Les fonds rouges : un rouge sombre, pour que le blanc pose dessus tienne.
   Sans cette liste, le rouge eclairci du texte passait aussi en fond et le
   blanc pose dessus tombait a 3,4:1 — mesure faite sur « Aller au contenu ». */
/* ⚠️ 09/09 — LE FOND ET L'ENCRE DANS LA MEME REGLE. Ces douze elements
   avaient bien leur fond rouge sombre, mais seuls QUATRE recevaient du
   blanc : les huit autres gardaient « color: var(--sur-couleur) », devenu
   #201B1A en sombre. Mesure du robot : la pastille « 5 » de l'itineraire,
   sur l'accueil ET les temoignages, a 2,45:1 — un chiffre noir sur rouge
   sombre. Deux listes qui doivent rester identiques finissent toujours par
   diverger : il n'y en a plus qu'une. */
:where(:root[data-theme="nuit"]) .btn-red, :where(:root[data-theme="nuit"]) .btn-red:hover, :where(:root[data-theme="nuit"]) .step:last-child .step-num, :where(:root[data-theme="nuit"]) .carnet-etiq.ko,
:where(:root[data-theme="nuit"]) .comm-avatar, :where(:root[data-theme="nuit"]) .ivc-lead-envoi, :where(:root[data-theme="nuit"]) .plan-jauge span, :where(:root[data-theme="nuit"]) .di-etape.en-cours,
:where(:root[data-theme="nuit"]) .rch-liste a.sur, :where(:root[data-theme="nuit"]) .di-depot-bouton, :where(:root[data-theme="nuit"]) .lang-switch:hover, :where(:root[data-theme="nuit"]) .saut-contenu {
  background: #B31410;
  color: #FFFFFF;
}
/* Les grands blocs en degrade rouge : meme raison, et ils portent du texte. */
:where(:root[data-theme="nuit"]) .hero-card { background: linear-gradient(160deg, #B31410 0%, var(--red-deep) 100%) !important; }
:where(:root[data-theme="nuit"]) .why-visual { background: linear-gradient(160deg, #B31410 0%, var(--red-deep) 70%, #5C0705 100%) !important; }
:where(:root[data-theme="nuit"]) .why-visual.vitrine-livre { background: var(--white) !important; border-color: var(--line); }

/* 28/09/2026 — « il y a encore des zones grises qui s'affichent quand le site
   est en mode nuit » (Alex). Relevé page par page, sur le fond RÉEL composé :
   1. les champs et les boutons sans fond à eux (connexion de la Prépa TCF,
      zone « supprimer mon compte »…) gardaient le gris du navigateur,
      #3B3B3B, posé sur le bleu nuit. Ils prennent la surface des autres
      champs. :where() pèse zéro : ce qui a déjà son fond le garde ;
   2. des teintes claires écrites en dur, sans équivalent de nuit — elles
      n'apparaissent qu'après un geste (un résultat, une erreur, un survol),
      là où le robot, qui ouvre les pages sans y toucher, ne regarde pas. */
:where(:root[data-theme="nuit"] :is(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"], [type="file"], [type="image"], [type="submit"], [type="button"], [type="reset"]), select, textarea)) { background-color: var(--white); }
:where(:root[data-theme="nuit"] :is(button, input[type="submit"], input[type="button"], input[type="reset"])) { background-color: var(--line); border-color: var(--line-strong); }
:where(:root[data-theme="nuit"]) .ivc-lead-toggle:hover { background: #3C2030; }
:where(:root[data-theme="nuit"]) .ivc-lead-err, :where(:root[data-theme="nuit"]) .bm-err { background: var(--blush); }
:where(:root[data-theme="nuit"]) .diag-bloc { background: #1E2840; border-color: var(--line); }
:where(:root[data-theme="nuit"]) .diag-barre, :where(:root[data-theme="nuit"]) .plan-jauge { background: var(--line); }
:where(:root[data-theme="nuit"]) .carnet-choix li, :where(:root[data-theme="nuit"]) .plan-chiffres div { background: #1E2840; }
:where(:root[data-theme="nuit"]) .carnet-choix li.carnet-bonne, :where(:root[data-theme="nuit"]) .plan-carte.plan-jour-j { background: var(--teal-light); border-color: #1F4A3F; }
:where(:root[data-theme="nuit"]) .carnet-choix li.carnet-mienne, :where(:root[data-theme="nuit"]) .plan-carte.plan-urgent { background: var(--blush); border-color: #5A2A30; }
/* Sur la vitrine du livre, les pastilles avaient EXACTEMENT le fond du bloc :
   elles ne tenaient que par leur lisere. Un ton plus clair les repose dessus. */
:where(:root[data-theme="nuit"]) .why-visual.vitrine-livre .badge-float { background: #243050; border-color: #33405F; }
:where(:root[data-theme="nuit"]) .cta-band { background: linear-gradient(140deg, #B31410, var(--red-deep)) !important; }
:where(:root[data-theme="nuit"]) .post-cover { background: linear-gradient(150deg, #B31410, var(--red-deep)) !important; }
:where(:root[data-theme="nuit"]) .livre-cover { background: linear-gradient(160deg, #B31410 0%, var(--red-deep) 62%, #5C0705 100%) !important; }
:where(:root[data-theme="nuit"]) .tirage-vedette { background: linear-gradient(120deg, #B31410, var(--red-deep)) !important; }
/* Ce que ces blocs portent doit rester clair : « --white » est devenu sombre. */
:where(:root[data-theme="nuit"]) .hero-card, :where(:root[data-theme="nuit"]) .hero-card *, :where(:root[data-theme="nuit"]) .cta-band, :where(:root[data-theme="nuit"]) .cta-band *,
:where(:root[data-theme="nuit"]) .post-cover, :where(:root[data-theme="nuit"]) .post-cover *, :where(:root[data-theme="nuit"]) .livre-cover, :where(:root[data-theme="nuit"]) .livre-cover *,
:where(:root[data-theme="nuit"]) .tirage-vedette, :where(:root[data-theme="nuit"]) .tirage-vedette * { color: #FFFFFF; }
/* Le fond de page derriere les cartes, et les images qui portaient du blanc. */
:where(:root[data-theme="nuit"]) body { background: var(--bg); color: var(--ink); }
:where(:root[data-theme="nuit"]) .navbar, :where(:root[data-theme="nuit"]) .topbar { background: var(--white); }
:where(:root[data-theme="nuit"]) img, :where(:root[data-theme="nuit"]) picture img { filter: none; }
/* Les surlignages de la recherche restent lisibles sur sombre. */
:where(:root[data-theme="nuit"]) .rch-corps mark { background: #5C4A16; color: #FFF3D6; }
/* Ce qui portait « --white » comme COULEUR DE TEXTE sur un fond colore :
   la variable est devenue sombre, le texte disparaissait. Mesure : le titre
   « Votre itineraire avec nous » tombait a 1,1:1 — invisible. */
:where(:root[data-theme="nuit"]) .hero-card h3, :where(:root[data-theme="nuit"]) .hero-card .h3-visuel, :where(:root[data-theme="nuit"]) .cta-band h2, :where(:root[data-theme="nuit"]) .cta-band p,
:where(:root[data-theme="nuit"]) .btn-teal, :where(:root[data-theme="nuit"]) .btn-wa, :where(:root[data-theme="nuit"]) .btn-whatsapp, :where(:root[data-theme="nuit"]) .btn-teal:hover, :where(:root[data-theme="nuit"]) .btn-wa:hover, :where(:root[data-theme="nuit"]) .btn-whatsapp:hover { color: #FFFFFF !important; }
/* Trois couleurs ecrites en dur, trop sombres sur un fond sombre (2,4 a 2,5:1). */
:where(:root[data-theme="nuit"]) .community h3 { color: #4FD08A; }
:where(:root[data-theme="nuit"]) .community p { color: #9CC9BB; }
:where(:root[data-theme="nuit"]) .eval-banner p { color: #E8A49E; }
/* Le badge « resultat » des temoignages : vert fonce sur vert sombre = 2:1. */
:where(:root[data-theme="nuit"]) .testi .result { border-color: #2A4A38; }
/* La signature d'une reponse officielle : rouge tres fonce sur sombre = 1,8:1.
   La regle vit dans le <style> de question.html, qui passe APRES cette
   feuille : il faut donc un selecteur plus precis pour la reprendre. */
:root[data-theme="nuit"] .q-reponse.officielle .q-qui { color: #F2564C; }
/* ⚠️ LE PIED DE PAGE, ET TOUT CE QUI ETAIT DEJA SOMBRE. « --navy-dark » sert
   a la fois de couleur de TITRE et de fond des blocs sombres : eclairci pour
   les titres, il retournait le pied de page en clair, avec son texte gris
   dessus — mesure : 1,9:1 sur cinquante liens. Ces fonds-la restent sombres. */
:where(:root[data-theme="nuit"]) footer { background: #080D18; color: #AEBBD0; }
:where(:root[data-theme="nuit"]) footer h4, :where(:root[data-theme="nuit"]) .footer-titre { color: #FFFFFF; }
:where(:root[data-theme="nuit"]) .btn-navy, :where(:root[data-theme="nuit"]) .bm-tab.active, :where(:root[data-theme="nuit"]) .cl-opt.on, :where(:root[data-theme="nuit"]) .etcf-onglets button.on,
:where(:root[data-theme="nuit"]) .di-ligne .di-num, :where(:root[data-theme="nuit"]) .ivc-mark { background: #25314D; color: #EAEFF7; border-color: #25314D; }
:where(:root[data-theme="nuit"]) .btn-navy:hover { background: #31405F; }
:where(:root[data-theme="nuit"]) .burger span { background: var(--ink); }


/* 07/09 — Une ancre profonde (services.html#equivalence) amene son bloc a
   -10 px : il se glissait sous la barre epinglee. Mesure : il faut de la marge
   au-dessus de tout ce qui peut etre vise par un lien. */
.service-detail, .section-head[id], .fus-volet [id] { scroll-margin-top: 88px; }


/* ══════════ LES SERVICES, DEPLIABLES (07/09/2026) ══════════
   Mesure : sur telephone, le volet « Nos services » faisait 13,6 ecrans — huit
   blocs complets empiles. On voit desormais les huit titres d'un coup d'oeil,
   et l'on ouvre celui qui concerne. <details> est natif : le texte reste dans
   la page, donc lu par Google et par la recherche du site. */
details.service-detail { border: 1px solid var(--line); border-radius: var(--r); background: var(--white); margin-bottom: var(--sp-3); box-shadow: var(--shadow-sm); }
details.service-detail[open] { border-color: #DAD4D2; }
.service-tete { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4); cursor: pointer; list-style: none; }
.service-tete::-webkit-details-marker { display: none; }
.service-tete:hover { background: var(--bg); border-radius: var(--r); }
.service-tete:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; border-radius: var(--r); }
.service-tete .big-icon { flex: none; margin: 0; }
.service-mots { flex: 1 1 auto; min-width: 0; }
.service-mots h2 { font-size: var(--fs-lg); margin: 0; }
.service-mots .lead { margin: var(--sp-1) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.service-chevron { flex: none; color: var(--muted); transition: transform .2s ease; }
.service-chevron svg { width: 20px; height: 20px; display: block; }
details.service-detail[open] .service-chevron { transform: rotate(180deg); }
.service-corps { padding: 0 var(--sp-4) var(--sp-4); }
.service-corps > *:first-child { margin-top: 0; }
@media (prefers-reduced-motion: reduce) { .service-chevron { transition: none; } }


/* 07/09 — LA COUVERTURE DU LIVRE dans le bloc rouge du cabinet (demande d'Alex).
   Elle remplace le logo blanc geant. Un vrai livre : une ombre portee, un lisere
   clair, et une legere inclinaison qui se redresse au survol — c'est un objet,
   pas une illustration. Le bloc reste rouge : la couverture l'est aussi, les
   deux se repondent. */
/* La couverture est un PORTRAIT : c'est sa HAUTEUR qu'il faut tenir, sinon elle
   deborde du bloc (mesure : 466 px d'image dans un bloc de 453). */
.why-visual .livre-vitrine { display: block; text-decoration: none; padding: var(--sp-5) 0; max-width: 76%; }
.why-visual img.livre-couv {
  display: block; width: auto; height: auto; max-height: 360px; max-width: 100%; border-radius: var(--r);
  box-shadow: 0 22px 44px rgba(23, 19, 20, .45), 0 0 0 1px rgba(255, 255, 255, .22);
  transform: rotate(-2.5deg); transition: transform .3s ease, box-shadow .3s ease;
}
.why-visual .livre-vitrine:hover img.livre-couv,
.why-visual .livre-vitrine:focus-visible img.livre-couv {
  transform: rotate(0deg) translateY(-4px);
  box-shadow: 0 28px 56px rgba(23, 19, 20, .5), 0 0 0 1px rgba(255, 255, 255, .3);
}
.why-visual .livre-vitrine:focus-visible { outline: 3px solid var(--white); outline-offset: 6px; border-radius: var(--r); }
/* Le bloc doit laisser respirer un portrait : sans cette hauteur, la couverture
   depassait sous les pastilles a 375 px. */
/* Au telephone, la pastille de l'adresse tombait SUR le titre du livre : le
   bloc gagne de la hauteur, la couverture descend, chacun garde sa place. */
@media (max-width: 640px) {
  .why-visual.vitrine-livre { min-height: 470px; }
  .why-visual img.livre-couv { max-height: 300px; }
  .why-visual .livre-vitrine { padding: var(--sp-7) 0 var(--sp-5); }
}
@media (prefers-reduced-motion: reduce) {
  .why-visual img.livre-couv { transform: none; transition: none; }
}

/* ─────────────────────────────────────────────────────────────────
   LE FIL DE CHARGEMENT (19/09/2026, remarque d'Alex : « il n'y a pas de
   rond de chargement »). Dans l'application installée, il n'y a pas de
   barre de navigateur : sans ce fil, toucher un lien ne produit RIEN à
   l'écran. Trois pixels de rouge qui avancent en haut, et rien d'autre.
   Il est posé par js/main.js, il ne gêne aucun clic, et il disparaît
   dès que la page est là. ───────────────────────────────────────── */
#iv-fil {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0;
  background: var(--red);
  z-index: 9999;
  pointer-events: none;
  opacity: 0;
  transition: width .22s ease-out, opacity .25s ease-out;
}

#iv-fil.actif { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  #iv-fil { transition: none; }
}

/* ============================================================
   LE SITE COMME UNE APPLICATION, AU TÉLÉPHONE (13/10/2026)
   ------------------------------------------------------------
   Alex a validé la maquette « barre du bas » (maquettes/barre-bas/) et
   dit OUI pour tout le site : sous 768 px, une interface à elle, sur le
   modèle de l'application Facebook, avec l'identité du cabinet (rouge,
   logo, Sora/Inter, CHARTE.md). À 768 px et plus, RIEN ne change.
   js/main.js pose la classe body.bb et construit tout à partir de ce que
   la page porte déjà (barre d'action, menu, bulle WhatsApp).
   1. le bandeau noir du haut disparaît : numéro et thème vont dans le menu ;
   2. l'en-tête : logo + nom, puis trois boutons ronds (WhatsApp, loupe,
      menu). Passé le bouton principal de la page, le nom laisse la place
      à ce bouton (le rôle que tenait la barre d'action) ;
   3. la barre d'onglets : Accueil · Services · Prépa (au centre) ·
      Chances · Dossier ;
   4. le menu des trois traits garde le secondaire, en tuiles, sans
      répéter un seul onglet.
   La barre d'action, la bulle WhatsApp et « Revenir en haut » ne
   s'affichent plus : toucher l'onglet en cours remonte en haut.
   Pages sans onglets (body.bb-sans-onglets, voir main.js) : Mon dossier,
   l'espace TCF, l'espace IELTS, le formulaire d'évaluation, l'attestation —
   leur propre barre du bas reste ; elles gardent l'en-tête allégé et le
   menu en tuiles (Alex, 13/10). /gestion n'est pas touché.
   « screen » : à l'impression, rien de tout cela.
   ============================================================ */

/* Hors téléphone : rien de ce qui suit n'existe. */
.bb-onglets, .bb-rond, .bb-cta, .bb-ajout, .bb-tuile-ico { display: none; }

/* viewport-fit=cover (pour que la barre descende sous le trait d'accueil
   de l'iPhone) ferait passer le texte sous l'encoche en paysage : le
   corps de page garde ces marges-là. Partout ailleurs, elles valent 0. */
body { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }

@media screen and (max-width: 767px) {
  :root {
    --bb-onglets: 64px;                      /* hauteur de la barre, hors zone du geste d'accueil
                                                (60 → 64 le 14/10 : la place du rond de l'onglet en cours) */
    --bb-bas: calc(var(--bb-onglets) + env(safe-area-inset-bottom, 0px));
    --bb-bosse: 26px;                        /* ce que le rond de Prépa dépasse au-dessus de la barre */
    --bb-rond-fond: var(--line);
  }
  :root[data-theme="nuit"] { --bb-rond-fond: var(--line-strong); }

  /* La page garde sa fin visible au-dessus de la barre, et de la bosse de
     Prépa : la dernière ligne du pied de page (le © centré) tomberait dessous. */
  .js body.bb { padding-bottom: var(--bb-bas); }
  .js body.bb.bb-sans-onglets { padding-bottom: 0; }
  body.bb:not(.bb-sans-onglets) footer::after { content: ""; display: block; height: var(--bb-bosse); }

  /* ---------- 1. Le bandeau noir du haut ---------- */
  body.bb .topbar { display: none; }

  /* ---------- 2. L'en-tête ---------- */
  /* Opaque : à 97 %, le texte de la page se lisait à travers l'en-tête. */
  body.bb .navbar { background: var(--white); }
  body.bb .navbar .container { position: relative; min-height: 56px; gap: var(--sp-1); padding: 0 var(--sp-3) 0 var(--sp-4); }
  body.bb .brand { gap: var(--sp-2); transition: opacity .2s var(--ease-out); }
  body.bb .brand img { width: 32px; height: 32px; }   /* le minimum de la charte : la place va au bouton */
  body.bb .brand-name { font-size: var(--fs-sm); line-height: 1.2; transition: opacity .2s var(--ease-out), visibility .2s; }
  body.bb .nav-cta { gap: var(--sp-1); }
  body.bb .nav-cta .lang-switch { display: none; }
  /* Le rond « Mon compte » (24/10) : 44 px comme ses voisins ; le nom de la
     marque passe sur deux lignes pour lui laisser la place (mesuré à 375 px :
     marque 16-148, WhatsApp 175, rond 271-315, rien ne déborde). */
  @media (max-width: 419px) { body.bb .brand-name { max-width: 6.6em; } }
  /* Mesuré le 24/10 : de 420 à 767 px, ce plafond de 6,6 em coinçait l'accroche
     (77 px de barre en français, 64 en anglais, au lieu de 56). Elle ne tient
     de toute façon pas dans une barre de 56 px à côté de quatre ronds de 44 px :
     masquée dans toute l'interface « application » (elle l'était déjà sous 420 px). */
  body.bb .brand-name small { display: none; }
  body.bb .cpt-rond { width: 44px; height: 44px; font-size: var(--fs-md); box-shadow: none; }
  body.bb .cpt-rond[aria-current="page"] { box-shadow: 0 0 0 2px var(--white), 0 0 0 4px var(--red); }

  body.bb .bb-rond,
  body.bb .navbar .nav-loupe,
  body.bb .navbar .burger {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%;
    background: var(--bb-rond-fond); color: var(--navy-dark);
    transition: background-color .2s ease, transform .15s ease;
  }
  body.bb .navbar .nav-loupe svg { width: 20px; height: 20px; }
  body.bb .bb-rond svg { width: 22px; height: 22px; }
  body.bb .bb-wa { color: var(--teal); }
  body.bb .bb-tel svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
  :root[data-theme="nuit"] body.bb .bb-wa { color: var(--teal-ink); }
  body.bb .navbar .burger { gap: 4px; }
  body.bb .navbar .burger span { width: 18px; }
  body.bb .navbar .burger.open span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
  body.bb .navbar .burger.open span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
  body.bb .navbar .burger.open { background: var(--blush); }
  body.bb .navbar .burger.open span { background: var(--red-dark); }
  body.bb .bb-rond:active, body.bb .navbar .nav-loupe:active, body.bb .navbar .burger:active { transform: scale(.98); }
  body.bb .bb-rond, body.bb .navbar .nav-loupe, body.bb .navbar .burger, body.bb .bb-cta,
  body.bb .mobile-menu .bb-tuile, body.bb .mobile-menu .bb-ligne { -webkit-tap-highlight-color: transparent; }

  /* Le bouton de la page : posé à la place du nom, il n'existe qu'une fois
     le bouton du haut de page sorti de l'écran. */
  body.bb .bb-cta {
    display: inline-flex; position: absolute; left: calc(var(--sp-4) + 32px + var(--sp-2)); top: 50%;
    width: auto; min-height: 44px; gap: 0; padding: 0 var(--sp-3); margin: 0; transform: translateY(-50%);
    font-size: var(--fs-sm); letter-spacing: var(--tracking-title); white-space: nowrap; box-shadow: none;
    color: var(--sur-couleur);
    opacity: 0; visibility: hidden; transition: opacity .2s var(--ease-out), visibility .2s;
  }
  body.bb .navbar.bb-avec-cta .bb-cta { opacity: 1; visibility: visible; }
  body.bb .navbar.bb-avec-cta .brand-name { opacity: 0; visibility: hidden; }
  body.bb .bb-cta:active { transform: translateY(-50%) scale(.98); }
  body.bb .bb-cta .bb-suite { white-space: pre; }
  body.bb .bb-cta.bb-court .bb-suite { display: none; }

  /* ---------- 3. La barre d'onglets ---------- */
  /* z-index 101 (96 avant, 24/10/2026, lot 2) : le menu des trois traits vit dans
     l'en-tête (z 100) et s'arrête au ras de la barre — il coupait la moitié haute
     du rond de Prépa (menu y 56→748, rond y 726→782 à 375×812). La barre passe
     au-dessus : le rond reste entier, la marge du bas du menu compte déjà la bosse. */
  body.bb .bb-onglets {
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 101;
    padding: 0 max(var(--sp-1), env(safe-area-inset-right, 0px)) env(safe-area-inset-bottom, 0px) max(var(--sp-1), env(safe-area-inset-left, 0px));
    background: var(--white); border-top: 1px solid var(--line);
  }
  /* Le rond part d'un haut fixe (et non centré) : la bosse de Prépa se cale
     au pixel sur le filet de la barre, quelle que soit la taille du texte. */
  .bb-onglets a {
    position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 2px;
    min-width: 0; min-height: var(--bb-onglets); padding: var(--sp-1) 0 0;
    color: var(--muted); font-family: Inter, sans-serif; font-size: var(--fs-xs); font-weight: 600;
    line-height: 1.25; letter-spacing: -.005em; text-decoration: none;
    -webkit-tap-highlight-color: transparent;
  }
  .bb-onglets .bb-ico {
    display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 50%;
    transition: background-color .2s ease, transform .15s ease;
  }
  .bb-onglets svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
  .bb-onglets .bb-mot { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* La page où l'on est (Alex, 14/10) : l'icône posée dans un rond foncé,
     le libellé en gras. En nuit, --navy-dark s'éclaircit : le rond devient
     clair et l'icône prend la couleur de la barre — un rond sombre sur la
     barre bleu nuit ne se verrait pas. */
  .bb-onglets a[aria-current="page"] { color: var(--navy-dark); font-weight: 700; }
  .bb-onglets a[aria-current="page"] .bb-ico { background: var(--navy-dark); color: var(--white); }

  /* Prépa : un rond rouge surélevé, au centre (Alex, 14/10). 56 px, dont
     26 px remontent au-dessus de sa case et 6 px de marge dessous : il tient
     la place d'un rond ordinaire, et son libellé reste sur la ligne des autres. */
  .bb-onglets .bb-prepa .bb-ico {
    width: 56px; height: 56px; margin: -26px 0 6px;
    background: var(--red-fond); color: var(--sur-couleur);
    box-shadow: 0 3px 8px -2px rgba(23, 19, 20, .35);
  }
  .bb-onglets .bb-prepa svg { width: 26px; height: 26px; }
  .bb-onglets .bb-prepa[aria-current="page"] .bb-ico { background: var(--navy-dark); color: var(--white); }
  /* La bosse : un disque couleur de barre, cerné du même filet, derrière le
     rond (4 px de marge, 1 px de filet), coupé au ras du filet de la barre
     pour que celui-ci passe par-dessus le rond sans cassure.
     Centre du rond : 4 − 26 + 28 = 6 px sous le haut de la case ; disque de
     66 px → haut à −27 px ; 27 px visibles, 39 coupés. */
  .bb-onglets .bb-prepa::before {
    content: ""; position: absolute; z-index: -1; left: 50%; top: -27px;
    width: 66px; height: 66px; margin-left: -33px; border-radius: 50%;
    background: var(--white); border: 1px solid var(--line);
    clip-path: inset(0 0 39px 0);
  }
  .bb-onglets a:active .bb-ico { transform: scale(.98); }
  .bb-onglets a:focus-visible { outline: none; }
  .bb-onglets a:focus-visible .bb-ico { outline: 2px solid var(--red); outline-offset: 2px; }
  :root[data-theme="nuit"] .bb-onglets .bb-prepa .bb-ico { box-shadow: 0 3px 8px -2px rgba(0, 0, 0, .6); }

  /* ---------- 4. Sous 360 px (petits téléphones) ----------
     Mesuré le 24/10 : à 320 px, « Immigration » (88 px) mordait de 24 px sur
     le rond WhatsApp (44 px à 300 px) : quatre ronds de 44 px et le logo ne
     laissaient que 60 px au nom. Rien ne disparaît : les ronds reprennent les
     40 px du bureau (la cible tactile garde 44 px par son ::after, qui remplit
     tout juste l'écart de 4 px), les marges passent à 12 et 8 px, et le nom
     suit la largeur : 14 px dès 325 px, 10 px à 300. Calcul : 236 px fixes
     (4 × 40 + 3 × 4 + 12 + 8 + logo 32 + 8 + 4) ; « Immigration » en Sora 700
     mesure 6,44 × taille − 2,2 px. Dans la barre du bas, « Checklist » (63 px)
     dépassait sa case de 62 px en anglais : cases sans marge et texte de 13 px
     (12 px à 300, où « Chances » et « Checklist » en gras se touchaient presque).
     Seuil à 360 px et non 345 : à 345, l'ancienne mise en page ne laissait que
     1 px entre le nom et le rond ; à 360 (l'Android courant), 16 px. */
  @media (max-width: 359px) {
    body.bb .navbar .container { padding: 0 var(--sp-2) 0 var(--sp-3); }
    body.bb .brand-name { font-size: clamp(10px, calc((100vw - 234px) / 6.5), var(--fs-sm)); }
    body.bb .bb-rond, body.bb .navbar .nav-loupe, body.bb .navbar .burger, body.bb .cpt-rond { position: relative; width: 40px; height: 40px; }
    body.bb .bb-rond::after, body.bb .navbar .nav-loupe::after, body.bb .navbar .burger::after, body.bb .cpt-rond::after {
      content: ""; position: absolute; inset: -2px; border-radius: 50%;
    }
    body.bb .bb-cta { left: calc(var(--sp-3) + 32px + var(--sp-2)); min-height: 40px; }
    body.bb .bb-onglets { padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); }
    .bb-onglets a { font-size: clamp(.75rem, calc(.75rem + (100vw - 300px) / 20), .8125rem); letter-spacing: -.01em; }
  }

  /* Ce qui flottait au-dessus du texte se range ailleurs :
     la barre d'action → le bouton de l'en-tête ; la bulle → le rond vert ;
     « Revenir en haut » → toucher l'onglet de la page en cours. */
  body.bb .barre-action,
  body.bb .wa-float,
  body.bb .etcf-assistance,
  body.bb .lec-haut { display: none !important; }

  /* Ce qui reste collé en bas se pose AU-DESSUS des onglets : le bandeau
     « Installer l'application », la barre du score (Calculer mes chances),
     la barre « Commander » du livre. La zone du geste d'accueil est déjà
     comptée par les onglets. */
  /* La bosse de Prépa passe par-dessus leur bas : leur contenu remonte d'autant. */
  body.bb:not(.bb-sans-onglets) .iv-install-bandeau { bottom: var(--bb-bas); padding-bottom: calc(var(--sp-3) + var(--bb-bosse)); }
  body.bb:not(.bb-sans-onglets) .score-mini { bottom: var(--bb-bas); padding-bottom: calc(var(--sp-2) + var(--bb-bosse)); }
  body.bb:not(.bb-sans-onglets) .livre-barre { bottom: var(--bb-bas); padding-bottom: calc(var(--sp-3) + var(--bb-bosse)); }

  /* ---------- 4. Le menu des trois traits : le secondaire, en tuiles ---------- */
  body.bb .mobile-menu.open {
    position: fixed; left: 0; right: 0; top: var(--bb-menu-haut, 56px); bottom: var(--bb-bas);
    max-height: none !important;
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: start; gap: var(--sp-2);
    padding: var(--sp-4) var(--sp-4) calc(var(--sp-5) + var(--bb-bosse)); background: var(--bg); border-top: 1px solid var(--line);
  }
  body.bb.bb-sans-onglets .mobile-menu.open { bottom: 0; padding-bottom: calc(var(--sp-5) + env(safe-area-inset-bottom, 0px)); }
  body.bb .mobile-menu > * { grid-column: 1 / -1; margin: 0; }
  body.bb .mobile-menu [hidden] { display: none !important; }
  body.bb .mobile-menu .mobile-grp,
  body.bb .mobile-menu .bb-doublon,
  body.bb .mobile-menu .bb-emoji { display: none; }
  body.bb .mobile-menu .bb-ajout { display: flex; }

  body.bb .mobile-menu .bb-tuile {
    grid-column: auto; display: flex; align-items: center; gap: var(--sp-3);
    min-height: 64px; padding: var(--sp-3);
    background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
    color: var(--ink); font-weight: 600; font-size: var(--fs-base); line-height: 1.3;
  }
  /* La page où l'on est : sa tuile parle en rouge. */
  body.bb .mobile-menu .bb-tuile.active { color: var(--red-dark); border-color: var(--red-dark); }
  body.bb .mobile-menu .bb-ligne {
    display: flex; align-items: center; gap: var(--sp-3); min-height: 52px; padding: var(--sp-2) var(--sp-3);
    background: var(--white); border: 1px solid var(--line); border-radius: var(--r);
    color: var(--ink); font: inherit; font-weight: 500; font-size: var(--fs-base); text-align: left; cursor: pointer;
  }
  body.bb .mobile-menu .bb-ligne-1 { margin-top: var(--sp-2); }
  body.bb .mobile-menu .bb-ligne small { margin-left: auto; color: var(--muted); font-size: var(--fs-sm); font-weight: 500; }
  body.bb .mobile-menu .bb-tuile-ico {
    display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 50%;
    background: var(--blush); color: var(--red-dark);
  }
  body.bb .mobile-menu .bb-ligne .bb-tuile-ico { background: var(--bb-rond-fond); color: var(--navy-dark); }
  body.bb .mobile-menu .bb-tuile-ico svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
  body.bb .mobile-menu .bb-tuile:active, body.bb .mobile-menu .bb-ligne:active { transform: scale(.98); }
  body.bb .mobile-menu > .btn { margin-top: var(--sp-2); min-height: 48px; }
  body.bb .mobile-menu .iv-install { margin-top: var(--sp-2); }
  body.bb .mobile-menu:has(.iv-install) .bb-installer { display: none; }

  /* L'ordre des tuiles : ce que les visiteurs cherchent le plus d'abord
     (Search Console, accès rapides du 04/09). */
  body.bb .bb-o1 { order: 1; } body.bb .bb-o2 { order: 2; } body.bb .bb-o3 { order: 3; } body.bb .bb-o4 { order: 4; }
  body.bb .bb-o5 { order: 5; } body.bb .bb-o6 { order: 6; } body.bb .bb-o7 { order: 7; } body.bb .bb-o8 { order: 8; }
  body.bb .bb-o9 { order: 9; } body.bb .mobile-menu .iv-install { order: 10; } body.bb .mobile-menu > .btn { order: 12; }
  /* 16/10/2026 — EN SOMBRE, les tuiles et les lignes se fondaient dans le menu
     (Alex : « des tuiles dont le contraste n'est pas bon »). Mesuré à 375 px :
     bord 1,59:1 sur le fond du menu, rond rose des tuiles 1,03:1 sur la tuile,
     rond gris des lignes 1,73:1. Le bord prend un mélange des jetons sombres
     --muted et --white (4,2:1 sur le menu) ; chaque rond reçoit un liseré :
     rouge (--red-dark) pour les tuiles, celui du bord pour
     les lignes. Le thème clair ne bouge pas. */
  :where(:root[data-theme="nuit"]) body.bb .mobile-menu .bb-tuile:not(.active),
  :where(:root[data-theme="nuit"]) body.bb .mobile-menu .bb-ligne { border-color: color-mix(in srgb, var(--muted) 60%, var(--white)); }
  :where(:root[data-theme="nuit"]) body.bb .mobile-menu .bb-tuile-ico { box-shadow: inset 0 0 0 1.5px var(--red-dark); }
  :where(:root[data-theme="nuit"]) body.bb .mobile-menu .bb-ligne .bb-tuile-ico { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--muted) 60%, var(--white)); }

  /* ---------- 5. Les cartes vont d'un bord à l'autre (comme un fil d'application) ----------
     Une carte posée à 20 px des bords perdait 40 px de ligne : bord à bord,
     le texte gagne 13 % de largeur (303 → 343 px), donc des lignes en moins.
     Seules les listes de cartes de Services, rien d'autre. */
  body.bb .cartes-liste > .service-card,
  body.bb .choix-volets .fus-onglet,
  body.bb .fus-volet details.service-detail {
    margin-left: -20px; margin-right: -20px; border-radius: 0; border-left: 0; border-right: 0;
  }
  body.bb .fus-barre.choix-volets { padding-left: 20px; padding-right: 20px; }
  body.bb .cartes-liste > .service-card,
  body.bb .fus-volet details.service-detail .service-tete,
  body.bb .fus-volet details.service-detail .service-corps { padding-left: 20px; padding-right: 20px; }
  body.bb #services .service-link { border-radius: 0; }
  body.bb #services .service-link::after { border-radius: 0; }
}

@media screen and (max-width: 767px) and (hover: hover) {
  .bb-onglets a:not([aria-current="page"]):hover { color: var(--navy-dark); }
  body.bb .bb-rond:hover, body.bb .navbar .nav-loupe:hover, body.bb .navbar .burger:hover { background: var(--line-strong); }
  body.bb .mobile-menu a.bb-tuile:hover, body.bb .mobile-menu .bb-ligne:hover { color: var(--red-dark); }
}

@media screen and (max-width: 767px) and (prefers-reduced-motion: reduce) {
  body.bb .brand, body.bb .brand-name, body.bb .bb-cta, .bb-onglets .bb-ico,
  body.bb .bb-rond, body.bb .navbar .nav-loupe, body.bb .navbar .burger { transition: none; }
}
